Skip to content

ServiceNow#

Description ServiceNow creates incidents from EDA query results.
Author Nokia
Supported OS N/A
Catalog nokia-eda/catalog
Language Go

Overview#

The ServiceNow app connects EDA to a ServiceNow instance and creates incidents from matching EDA state.

It exposes four resources:

  • Instance: namespace-scoped connection details for a ServiceNow instance.
  • Incident: namespace-scoped incident generator that references one or more Instance objects.
  • ClusterInstance: cluster-scoped connection details created in the EDA base namespace.
  • ClusterIncident: cluster-scoped incident generator created in the EDA base namespace.

Installation#

Install the app from EDA Store or with kubectl:

apiVersion: appstore.eda.nokia.com/v1
kind: AppInstaller
metadata:
  name: service-now-install
  namespace: eda-system
spec:
  operation: install
  apps:
    - appId: snow.eda.nokia.com
      catalog: eda-catalog-builtin-apps
      version:
        value: v4.0.0
cat << 'EOF' | kubectl apply -f -
apiVersion: appstore.eda.nokia.com/v1
kind: AppInstaller
metadata:
  name: service-now-install
  namespace: eda-system
spec:
  operation: install
  apps:
    - appId: snow.eda.nokia.com
      catalog: eda-catalog-builtin-apps
      version:
        value: v4.0.0

EOF

Getting Started#

The setup has two steps:

  1. Create an Instance or ClusterInstance that can authenticate to ServiceNow.
  2. Create an Incident or ClusterIncident that references that instance and defines a query source.

Namespace behavior

Instance and Incident resources must be created outside the EDA base namespace. ClusterInstance and ClusterIncident resources must be created in the EDA base namespace.

ServiceNow Credentials Secret#

Each instance references a Kubernetes secret through spec.clientCredentials.

The secret must contain these keys:

  • client_id
  • client_secret
  • username
  • password

When the secret is referenced by name, the app looks for it in the namespace where Instance is defined. You can also refer to a secret by namespace/name to explicitly set the namespace the secret resides in.

Example credentials secret in namespace eda:

apiVersion: v1
kind: Secret
metadata:
  name: sn-creds
  namespace: eda
type: Opaque
data:
  client_id: <base64-encoded-client-id>
  client_secret: <base64-encoded-client-secret>
  username: <base64-encoded-username>
  password: <base64-encoded-password>
cat << 'EOF' | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
  name: sn-creds
  namespace: eda
type: Opaque
data:
  client_id: <base64-encoded-client-id>
  client_secret: <base64-encoded-client-secret>
  username: <base64-encoded-username>
  password: <base64-encoded-password>
EOF

Instance Resource#

An instance defines how EDA connects to ServiceNow.

Important fields:

  • url: base URL of the ServiceNow instance.
  • version: optional ServiceNow API version, for example v2.
  • clientCredentials: secret reference containing OAuth and user credentials.
  • timeout, retryInterval, retryCount: request behavior for ServiceNow API calls.

After the resource is created, the controller continuously checks connectivity and updates:

  • status.reachable
  • status.errorReason
  • status.lastChecked

Example namespace-scoped Instance:

apiVersion: snow.eda.nokia.com/v1alpha1
kind: Instance
metadata:
  name: instance-sample
  namespace: eda
spec:
  url: https://your-instance.service-now.com
  version: v2
  clientCredentials: sn-creds
  timeout: 15s
  retryInterval: 5s
  retryCount: 5
cat << 'EOF' | kubectl apply -f -
apiVersion: snow.eda.nokia.com/v1alpha1
kind: Instance
metadata:
  name: instance-sample
  namespace: eda
spec:
  url: https://your-instance.service-now.com
  version: v2
  clientCredentials: sn-creds
  timeout: 15s
  retryInterval: 5s
  retryCount: 5

EOF

Incident Resource#

An Incident or ClusterIncident subscribes to EDA state and creates incidents in all referenced ServiceNow instances.

Important fields:

  • enabled: whether the incident generator is active.
  • instance: list of instance names to use as destinations.
  • sources.query.table: the EDA table to watch.
  • sources.query.where: filter applied to the subscription.
  • sources.query.fields: optional list of fields to fetch. If omitted, all fields of the subscribed table are used.
  • sources.query.autoResolve: resolves matching ServiceNow incidents when the object disappears.

The controller generates a deterministic correlation_id from the incident name and object path. When autoResolve is enabled, it looks up incidents with that correlation ID and updates them to a resolved state.

Query Templates#

The query source builds the ServiceNow incident body using Go templates. Common fields include:

  • shortDescription
  • description
  • callerId
  • assignedTo
  • assignmentGroup
  • state
  • priority
  • urgency
  • impact
  • category
  • subCategory
  • closeCode
  • closeNotes
  • resolutionCode
  • cmdbci
  • location
  • customFields[]

Because many returned keys contain dots, index is usually the easiest way to reference them, for example {{ index . "node.name" }}.

For a namespace-scoped Incident, paths that start with .namespace are automatically rewritten so the subscription stays inside that namespace.

Example Incident:

apiVersion: snow.eda.nokia.com/v1alpha1
kind: Incident
metadata:
  name: incident-sample
  namespace: eda
spec:
  description: Interface incident sample
  enabled: true
  instance:
    - instance-sample
  sources:
    query:
      table: .namespace.node.srl.interface
      fields:
        - oper-state
        - admin-state
      where: 'name = "ethernet-1/1" AND admin-state = "disable"'
      autoResolve: true
      shortDescription: '{{ index . "node.name" }}-{{ index . "interface.name" }}-{{ index . "oper-state" }}'
      description: 'Interface {{ index . "interface.name" }} has oper-state {{ index . "oper-state" }} and admin-state {{ index . "admin-state" }} on node {{ index . "node.name" }}'
      callerId: admin
      assignedTo: Incident.Manager
      assignmentGroup: Incident Management
      state: "1"
      priority: "1"
      urgency: "1"
      impact: "1"
      category: Network
      location: Sunnyvale, CA
      customFields:
        - name: field1
          value: value1
        - name: field2
          value: value2
cat << 'EOF' | kubectl apply -f -
apiVersion: snow.eda.nokia.com/v1alpha1
kind: Incident
metadata:
  name: incident-sample
  namespace: eda
spec:
  description: Interface incident sample
  enabled: true
  instance:
    - instance-sample
  sources:
    query:
      table: .namespace.node.srl.interface
      fields:
        - oper-state
        - admin-state
      where: 'name = "ethernet-1/1" AND admin-state = "disable"'
      autoResolve: true
      shortDescription: '{{ index . "node.name" }}-{{ index . "interface.name" }}-{{ index . "oper-state" }}'
      description: 'Interface {{ index . "interface.name" }} has oper-state {{ index . "oper-state" }} and admin-state {{ index . "admin-state" }} on node {{ index . "node.name" }}'
      callerId: admin
      assignedTo: Incident.Manager
      assignmentGroup: Incident Management
      state: "1"
      priority: "1"
      urgency: "1"
      impact: "1"
      category: Network
      location: Sunnyvale, CA
      customFields:
        - name: field1
          value: value1
        - name: field2
          value: value2

EOF

Cluster-Scoped Resources#

Use ClusterInstance and ClusterIncident when you want to manage ServiceNow integration from the EDA base namespace.

The fields are the same as the namespace-scoped resources, but:

  • ClusterInstance must exist in the EDA base namespace.
  • ClusterIncident references ClusterInstance names.
  • Query subscriptions are not namespace-rewritten, so they can watch cross-namespace data.

Advanced Configuration#

The app installer exposes the following runtime settings:

  • snowCpuLimit: CPU limit for the controller.
  • snowMemoryLimit: memory limit for the controller.
  • snowProxyConfig: config map name used for HTTP_PROXY, HTTPS_PROXY, and NO_PROXY.

If you need a proxy, create or reuse a config map such as proxy-config in the EDA base namespace with those standard keys.