iot-security-check-servicenow

Close the XSOAR incident if the IoT ServiceNow ticket was closed. This command should be run in a Job.

python · IoT by Palo Alto Networks

Details

IDiot-security-check-servicenow
Languagepython
From Version5.0.0
Docker Imagedemisto/python3:3.12.13.10116658
Tagsiot

README

Close the XSOAR incident if the IoT ServiceNow ticket was closed. This command should be run in a Job.

Script Data


Name Description
Script Type python3
Tags iot
Cortex XSOAR Version 5.5.0

This script is run by a playbook ‘iot-check-service-playbook’, that is run by a recurring XSOAR job.

First of all, we are looping all the open XSOAR incidents based on two incident types:
“IoT Alert” and “IoT Vulnerability”

Then we are only interested of the ones with a customized instance field: ServiceNow table name, that tells us a
corresponding ServiceNow ticket was created. Looping each one of this incident, and query ServiceNow for the ticket
status. If the status is “Closed”, we are closing the XSOAR incident.

Used In


This script is used in the following playbooks and scripts.

  • PANW IoT ServiceNow Tickets Check

Inputs


There are no inputs for this script.

Outputs


There are no outputs for this script.

import time

import demistomock as demisto  # noqa: F401
from CommonServerPython import *  # noqa: F401

from CommonServerUserPython import *  # noqa: E402 lgtm [py/polluting-import]


def get_opened_iot_incidents():
    resp = demisto.executeCommand(
        "getIncidents",
        {"query": '-status:Closed and (type:"IoT Alert" or type:"IoT Vulnerability")', "sort": "created.desc", "size": 1000},
    )
    if is_error(resp):
        raise Exception("error in getIncidents command")
    return demisto.get(resp[0], "Contents.data")


def get_servicenow_record(table, record_id):
    snow_record = demisto.executeCommand("servicenow-get-record", {"id": record_id, "table_name": table})
    if is_error(snow_record):
        raise Exception("error in servicenow-get-record command")
    return snow_record[0]


def close_incident(incident, servicenow_close_code):
    demisto.info(f"closing incident {incident['id']} {incident['status']} {incident['type']}")
    demisto.executeCommand(
        "closeInvestigation",
        {"id": incident["id"], "close_reason": "Resolved" if "Resolved" in servicenow_close_code else "Other"},
    )


def check_servicenow_and_close():
    incidents = get_opened_iot_incidents()
    if incidents:
        closed_count = 0
        for incident in incidents:
            servicenow_tablename = demisto.get(incident, "CustomFields.servicenowtablename")
            servicenow_recordid = demisto.get(incident, "CustomFields.servicenowrecordid")
            if servicenow_tablename:
                # if servicenow_tablename is defined, there's a corresponding ticket created in ServiceNow
                snow_record = get_servicenow_record(servicenow_tablename, servicenow_recordid)

                incident_state = demisto.get(snow_record, "Contents.result.incident_state")
                close_code = demisto.get(snow_record, "Contents.result.close_code")
                if incident_state and int(incident_state) == 7:
                    # 7 is the close state
                    close_incident(incident, close_code)
                    closed_count += 1
                else:
                    demisto.debug(f"keep incident {incident['id']} {incident['status']}: {incident_state}")

                # not going to spam the ServiceNow server
                time.sleep(1)
        return f"found {len(incidents)} incidents, closed {closed_count} incidents"
    return "no incidents found"


def main():
    try:
        demisto.results(check_servicenow_and_close())
    except Exception as ex:
        return_error(f"Failed to execute iot-security-check-servicenow. Error: {ex!s}")


if __name__ in ("__main__", "__builtin__", "builtins"):
    main()