SendAllPANWIoTDevicesToServiceNow

Gets all available devices from the IoT cloud and sends them to the ServiceNow. server

python · IoT 3rd Party Integrations by Palo Alto Networks (Deprecated)

Source

import demistomock as demisto
from CommonServerPython import *

PANW_IOT_INSTANCE = "PANW IoT 3rd Party Integration Instance"
SERVICENOW_INSTANCE = "PANW IoT 3rd Party ServiceNow Integration Instance"
PAGE_SIZE = 100
SERVICENOW_TABLE_NAME = "u_zingbox_discovered_devices"


def send_status_to_panw_iot_cloud(status=None, msg=None):
    """
    To send error/success status back to PANW IoT cloud
    :param status: status needs to send back
    :param msg: message
    """
    resp = demisto.executeCommand(
        "panw-iot-3rd-party-report-status-to-panw",
        {
            "status": status,
            "message": msg,
            "integration_name": "servicenow",
            "playbook_name": "Bulk Export Devices to ServiceNow - PANW IoT 3rd Party Integration",
            "asset_type": "device",
            "timestamp": int(round(time.time() * 1000)),
            "using": PANW_IOT_INSTANCE,
        },
    )
    if isError(resp[0]):
        err_msg = f'Error, failed to send status to PANW IoT Cloud - {resp[0].get("Contents")}'
        raise Exception(err_msg)


def get_devices_from_panw_iot_cloud(offset):
    """
    To retrieve a list of devices list from PANW IoT cloud controled by offset and PAGE_SIZE
    :param offset: The index from DB to return the results.
    :return: list of device
    """
    resp = demisto.executeCommand(
        "panw-iot-3rd-party-get-asset-list",
        {"asset_type": "device", "offset": offset, "page_length": PAGE_SIZE, "using": PANW_IOT_INSTANCE},
    )
    if isError(resp[0]):
        err_msg = f'Error, could not get assets from PANW IoT Cloud - {resp[0].get("Contents")}'
        raise Exception(err_msg)

    return resp[0]["Contents"]


def query_servicenow_table(query):
    """
    To query Servicenow table to get a deviceid and Servicenow table row id map
    :param query: Servicenow table query with device information
    :return: the deviceid and Servicenow table row id map
    """
    sn_query_resp = demisto.executeCommand(
        "servicenow-query-table",
        {
            "table_name": SERVICENOW_TABLE_NAME,
            "limit": 10000,
            "query": query,
            "fields": "sys_id,mac_address",
            "using": SERVICENOW_INSTANCE,
        },
    )
    return sn_query_resp[0]["Contents"]["result"]


def get_servicenow_upsert_device_list(sn_query_result, device_list):
    """
    To get Upsert device json object
    :param sn_query_result: the deviceid and Servicenow table row id map
    :param device_list: list of device
    :return: upsert device json object
    """
    upsert_devices_resp = demisto.executeCommand(
        "panw-iot-3rd-party-convert-assets-to-external-format",
        {
            "asset_type": "device",
            "output_format": "ServiceNow",
            "servicenow_map": sn_query_result,
            "asset_list": device_list,
            "using": PANW_IOT_INSTANCE,
        },
    )
    return upsert_devices_resp[0]["Contents"]


def create_servicenow_record(insert_list):
    """
    To create Servicenow record
    :param insert_list: device list that needs to insert into Servicenow table
    """
    for x in range(len(insert_list)):
        device = insert_list[x]
        fields = device["fields"]
        custom_fields = device["custom_fields"]
        demisto.executeCommand(
            "servicenow-create-record",
            {"table_name": SERVICENOW_TABLE_NAME, "fields": fields, "custom_fields": custom_fields, "using": SERVICENOW_INSTANCE},
        )


def update_servicenow_record(update_list):
    """
    To update existing device record in Servicenow
    :param update_list: device list that needs to be updated
    """
    for x in range(len(update_list)):
        device = update_list[x]
        fields = device["fields"]
        custom_fields = device["custom_fields"]
        sys_id = device["sys_id"]
        demisto.executeCommand(
            "servicenow-update-record",
            {
                "table_name": SERVICENOW_TABLE_NAME,
                "fields": fields,
                "custom_fields": custom_fields,
                "id": sys_id,
                "using": SERVICENOW_INSTANCE,
            },
        )


def get_all_panw_iot_devices_and_send_to_servicenow():
    """
    To send all devices from PANW IoT cloud to Servicenow
    :return: A summary message
    """
    run_time_count = 1
    offset = 0
    update_num = 0
    insert_num = 0
    total_update_num = 0
    total_insert_num = 0
    while True:
        size = 0
        device_list = get_devices_from_panw_iot_cloud(offset)
        size = len(device_list)
        deviceid_list = [device["deviceid"] for device in device_list]
        query = "mac_addressIN" + ",".join(deviceid_list)
        sn_query_result = query_servicenow_table(query)

        if len(sn_query_result) > 0:
            upsert_devices_result = get_servicenow_upsert_device_list(sn_query_result, device_list)
            insert_count = upsert_devices_result["insert_count"]
            update_count = upsert_devices_result["update_count"]
            total_update_num += update_count
            total_insert_num += insert_count
            update_num = update_count
            insert_num = insert_count
            if insert_count == 0 and update_count == 0:
                err_msg = f"Error, Bulk Servicenow sync failed to get upsert devices from PANW IoT cloud {upsert_devices_result}"
                send_status_to_panw_iot_cloud("error", err_msg)
                LOG(f"{PANW_IOT_INSTANCE} {err_msg}")
                raise Exception(err_msg)
            if insert_count > 0:
                insert_list = upsert_devices_result["insert"]
                create_servicenow_record(insert_list)
            if update_count > 0:
                update_list = upsert_devices_result["update"]
                update_servicenow_record(update_list)
        if size == PAGE_SIZE:
            offset += PAGE_SIZE
            msg = (
                f"{str(run_time_count)}. Successfully update {str(update_num)}"
                f" Devices and insert {str(insert_num)} to Servicenow"
            )
            send_status_to_panw_iot_cloud("success", msg)
            run_time_count += 1
        else:
            break
    summary_msg = (
        f"Successfully total update {str(total_update_num)} devices to Servicenow and "
        f"total insert {str(total_insert_num)} devices to Servicenow"
    )
    return summary_msg


def main():
    summary_msg = ""
    try:
        summary_msg = get_all_panw_iot_devices_and_send_to_servicenow()
    except Exception as ex:
        send_status_to_panw_iot_cloud("error", str(ex))
        return_error(str(ex))
    send_status_to_panw_iot_cloud("success", summary_msg)
    return_results(summary_msg)


if __name__ in ["__main__", "builtin", "builtins"]:
    main()

README

Gets all available devices from PANW IoT Cloud and sends them to ServiceNow.

Script Data


Name Description
Script Type python
Tags servicenow, PANW IoT 3rd Party Integration
Cortex XSOAR Version 6.0.0

Dependencies


This script uses the following commands and scripts.

  • panw-iot-3rd-party-report-status-to-panw
  • panw-iot-3rd-party-get-asset-list
  • servicenow-query-table
  • panw-iot-3rd-party-convert-assets-to-external-format
  • servicenow-create-record
  • servicenow-update-record

Inputs


There are no inputs for this playbook.

Outputs


There are no outputs for this playbook.