id: servicenow_cmdb
name: ServiceNow CMDB
version: 1.0.0
description: "ServiceNow CMDB (CMDB Instance API) — query configuration items by CI class, read a record with its attributes and inbound/outbound relations, create and update records with attributes and relations, and add or delete relations between CIs. Basic or OAuth 2.0 (password grant) authentication."
changelog: "1.0.0 — Initial release: records list by class, record get by sys_id (attributes + relations), record create/update with attributes and discovery source, add/delete relations."
category: asset_management

# Per-instance configuration. The base URL is the instance root, e.g.
# https://company.service-now.com (scripts append /api/now/cmdb/instance).
config_schema:
  properties:
    url:
      type: string
      description: "ServiceNow instance URL, e.g. https://company.service-now.com"
    auth_type:
      type: string
      description: "Authentication method: basic (username + password) or oauth (OAuth 2.0 password grant via /oauth_token.do — also requires client_id/client_secret)"
      default: basic
    username:
      type: string
      description: "ServiceNow username (needs CMDB read/write ACLs on the target CI classes)"
    password:
      type: string
      description: "ServiceNow password"
      x-soar-sensitive: true
    client_id:
      type: string
      description: "OAuth client ID (oauth auth_type only — from an Application Registry entry)"
    client_secret:
      type: string
      description: "OAuth client secret (oauth auth_type only)"
      x-soar-sensitive: true
    api_version:
      type: string
      description: "Optional REST API version segment (e.g. v1). Leave empty to use the unversioned endpoints."
    test_class:
      type: string
      description: "CI class queried by the Test button (default cmdb_ci_computer)"
      default: cmdb_ci_computer
  required:
    - url
    - username
    - password

# Documented for reference; the bundled scripts build the headers themselves.
# Basic:  Authorization: Basic base64(username:password)
# OAuth:  POST /oauth_token.do (grant_type=password) then Authorization: Bearer <access_token>
auth:
  - id: basic
    type: basic
    username_field: username
    password_field: password

commands:
  - id: records_list
    name: servicenow-cmdb-records-list
    description: "List the records of a CMDB CI class, optionally filtered by an encoded sysparm_query."
    risk: read
    inputs_schema:
      properties:
        class: { type: string, description: "CI class name (e.g. cmdb_ci_linux_server)" }
        query: { type: string, description: "Encoded sysparm_query filter" }
        limit: { type: number, description: "Maximum records per page (default 50)" }
        offset: { type: number, description: "Starting record index (default 0)" }
      required: [class]
    outputs_schema: { properties: {} }
  - id: get_record
    name: servicenow-cmdb-get-record
    description: "Get a CI record by sys_id: attributes plus inbound and outbound relations."
    risk: read
    inputs_schema:
      properties:
        class: { type: string, description: "CI class name of the record" }
        sys_id: { type: string, description: "Record sys_id" }
        fields: { type: string, description: "Comma-separated attributes to return (sys_id and name always included)" }
        relation_limit: { type: number, description: "Maximum relations returned (default 50)" }
        relation_offset: { type: number, description: "Starting relation index (default 0)" }
      required: [class, sys_id]
    outputs_schema: { properties: {} }
  - id: create_record
    name: servicenow-cmdb-create-record
    description: "Create a CI record with attributes and optional inbound/outbound relations."
    inputs_schema:
      properties:
        class: { type: string, description: "CI class name to create the record in" }
        attributes: { type: string, description: "Attributes as name=value;name2=value2 (e.g. name=srv01;ram=1024)" }
        source: { type: string, description: "Discovery source (default ServiceNow) — values live in the sys_choice table (element discovery_source, name cmdb_ci)" }
        inbound_relations: { type: string, description: "JSON array of inbound relations, each {\"type\": \"<rel type sys_id>\", \"target\": \"<CI sys_id>\"}" }
        outbound_relations: { type: string, description: "JSON array of outbound relations, each {\"type\": \"<rel type sys_id>\", \"target\": \"<CI sys_id>\"}" }
        fields: { type: string, description: "Comma-separated attributes to return (sys_id and name always included)" }
        relation_limit: { type: number, description: "Maximum relations returned (default 50)" }
        relation_offset: { type: number, description: "Starting relation index (default 0)" }
      required: [class, attributes]
    outputs_schema: { properties: {} }
  - id: update_record
    name: servicenow-cmdb-update-record
    description: "Update a CI record's attributes."
    inputs_schema:
      properties:
        class: { type: string, description: "CI class name of the record" }
        sys_id: { type: string, description: "Record sys_id" }
        attributes: { type: string, description: "Attributes as name=value;name2=value2" }
        source: { type: string, description: "Discovery source (default ServiceNow)" }
        fields: { type: string, description: "Comma-separated attributes to return (sys_id and name always included)" }
        relation_limit: { type: number, description: "Maximum relations returned (default 50)" }
        relation_offset: { type: number, description: "Starting relation index (default 0)" }
      required: [class, sys_id, attributes]
    outputs_schema: { properties: {} }
  - id: add_relations
    name: servicenow-cmdb-add-relations
    description: "Add inbound and/or outbound relations to an existing CI record."
    inputs_schema:
      properties:
        class: { type: string, description: "CI class name of the record" }
        sys_id: { type: string, description: "Record sys_id" }
        source: { type: string, description: "Discovery source (default ServiceNow)" }
        inbound_relations: { type: string, description: "JSON array of inbound relations, each {\"type\": \"<rel type sys_id>\", \"target\": \"<CI sys_id>\"}" }
        outbound_relations: { type: string, description: "JSON array of outbound relations, each {\"type\": \"<rel type sys_id>\", \"target\": \"<CI sys_id>\"}" }
        fields: { type: string, description: "Comma-separated attributes to return (sys_id and name always included)" }
        relation_limit: { type: number, description: "Maximum relations returned (default 50)" }
        relation_offset: { type: number, description: "Starting relation index (default 0)" }
      required: [class, sys_id]
    outputs_schema: { properties: {} }
  - id: delete_relation
    name: servicenow-cmdb-delete-relation
    description: "Delete a relation from a CI record by the relation's sys_id."
    inputs_schema:
      properties:
        class: { type: string, description: "CI class name of the record" }
        sys_id: { type: string, description: "Record sys_id" }
        relation_sys_id: { type: string, description: "sys_id of the relation to delete" }
        fields: { type: string, description: "Comma-separated attributes to return (sys_id and name always included)" }
        relation_limit: { type: number, description: "Maximum relations returned (default 50)" }
        relation_offset: { type: number, description: "Starting relation index (default 0)" }
      required: [class, sys_id, relation_sys_id]
    outputs_schema: { properties: {} }

  - id: test_connection
    name: servicenow-cmdb-test-connection
    description: "Verify connectivity and credentials (used by the Test button)."
    risk: read
    inputs_schema:
      properties: {}
      required: []
    outputs_schema: { properties: {} }
