SendPANWIoTDevicesToCiscoISE
This script takes (as a required argument) custom attributes from PANW IoT cloud and creates or updates endpoints in ISE with the input custom attributes. This automation runs using the default Limited User role, unless you explicitly change the permissions. For more information, see the section about permissions here: - For Cortex XSOAR 6 see https://docs-cortex.paloaltonetworks.com/r/Cortex-XSOAR/6.x/Cortex-XSOAR-Playbook-Design-Guide/Automations - For Cortex XSOAR 8 Cloud see https://docs-cortex.paloaltonetworks.com/r/Cortex-XSOAR/8/Cortex-XSOAR-Cloud-Documentation/Create-a-script - For Cortex XSOAR 8.7 On-prem see https://docs-cortex.paloaltonetworks.com/r/Cortex-XSOAR/8.7/Cortex-XSOAR-On-prem-Documentation/Create-a-script
python · IoT 3rd Party Integrations by Palo Alto Networks (Deprecated)
Source
import demistomock as demisto # noqa: F401 from CommonServerPython import * # noqa: F401 PANW_IOT_INSTANCE = demisto.args().get("panw_iot_3rd_party_instance") CISCO_ISE_ACTIVE_INSTANCE = demisto.args().get("active_ise_instance") GET_EP_ID_CMD = "cisco-ise-get-endpoint-id-by-name" def send_status_to_panw_iot_cloud(status, msg): """ Reports status details back to PANW IoT Cloud. param status: Status (error, disabled, success) to be send to PANW IoT cloud. param msg: Debug message to be send to PANW IoT cloud. """ resp = demisto.executeCommand( "panw-iot-3rd-party-report-status-to-panw", { "status": status, "message": msg, "integration_name": "ise", "playbook_name": "PANW IoT 3rd Party Cisco ISE Integration - Bulk Export to Cisco ISE", "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 extract_ise_api_error(err_msg): """ Extract any connection error or error code if possible, Otherwise just return the original error """ err_msg = err_msg.split("-")[0] if err_msg.startswith("Error in API call to Cisco"): start = err_msg.find("[") + 1 end = err_msg.find("]") return err_msg[start:end] elif err_msg.startswith("Connection Error. Verify"): return "Connection Error" else: return err_msg def update_existing_endpoint(mac, attr_map, ep_id, active_instance): """ Update an existing endpoint with the given custom attributes. Param mac: mac address of the endpoint that needs to be updated. Param attr_map: a map containing various ise custom attributes. Param ep_id: ID for endpoint that needs to be updated. Param active_instance: The primary/active ISE instance. """ attribute_names = "" attribute_values = "" for key in attr_map: attribute_names += key + "," attribute_values += str(attr_map[key]) + "," attribute_names = attribute_names[:-1] attribute_values = attribute_values[:-1] resp = demisto.executeCommand( "cisco-ise-update-endpoint-custom-attribute", { "id": ep_id, "macAddress": mac, "attributeName": attribute_names, "attributeValue": attribute_values, "using": active_instance, }, ) if isError(resp[0]): err_msg = f'Error, failed to update custom attributes for endpoint {id} - {resp[0].get("Contents")}' raise Exception(err_msg) def create_new_ep(mac, attr_map, active_instance): """ Create a new endpoint with the given params Param mac: mac address of the endpoint that needs to be created. Param attr_map: a map containing various ise custom attributes. Param active_instance: The primary/active ISE instance. """ resp = demisto.executeCommand( "cisco-ise-create-endpoint", {"mac_address": mac, "attributes_map": attr_map, "using": active_instance} ) if isError(resp[0]): err_msg = f'Failed to create new Endpoint {mac} - {resp[0].get("Contents")}' raise Exception(err_msg) def create_or_update_ep(mac, attr_map): """ Check if an enpoint exists in ISE, if not create one with the custom attributes otherwise update it. If at any point the connection goes down or we get a 401 - unautherized access we will attempt to get the new active instance. Params mac: Mac adress of the endpoint. attr_map: Custom attributes for the endpoint. """ global CISCO_ISE_ACTIVE_INSTANCE global GET_EP_ID_CMD cmd_mac_syntax_map = {"cisco-ise-get-endpoint-id-by-name": "mac_address", "cisco-ise-get-endpoint-id": "macAddress"} # Check if this mac address (endpoint) is present in ISE by attempting to get its ID resp = demisto.executeCommand(GET_EP_ID_CMD, {cmd_mac_syntax_map[GET_EP_ID_CMD]: mac, "using": CISCO_ISE_ACTIVE_INSTANCE}) if isError(resp[0]): err_msg = extract_ise_api_error(resp[0].get("Contents")) # 404 Not Found or empty results, we need to create a new EP if err_msg == "404" or err_msg == "list index out of range": create_new_ep(mac, attr_map, CISCO_ISE_ACTIVE_INSTANCE) # 405 - Method not allowed means we need to switch to an old filter based API elif err_msg == "405": GET_EP_ID_CMD = "cisco-ise-get-endpoint-id" else: raise Exception(resp[0].get("Contents")) else: ep_id = resp[0]["EntryContext"]["Endpoint(val.ID === obj.ID)"]["ID"] update_existing_endpoint(mac, attr_map, ep_id, CISCO_ISE_ACTIVE_INSTANCE) def send_panw_iot_devices_to_send_to_cisco_ise(device_list): """ For given device lists consisting of custom attributes, create or update endpoints in Cisco ISE. Param device_list: a list of devices and their custom attributes. """ count = 0 for device in device_list: mac = device["mac"] attr_map = device["zb_attributes"] create_or_update_ep(mac, attr_map) count += 1 return f"Successfully exported {count} devices to Cisco ISE" def main(): device_list = demisto.args().get("device_maps") status_msg = None try: status_msg = send_panw_iot_devices_to_send_to_cisco_ise(device_list) except Exception as ex: send_status_to_panw_iot_cloud("error", str(ex)) return_error(str(ex)) send_status_to_panw_iot_cloud("success", status_msg) return_results( CommandResults(readable_output=status_msg, outputs_prefix="PaloAltoIoTIntegrationBase.Status", outputs=status_msg) ) if __name__ in ("__main__", "__builtin__", "builtins"): main()
README
This script takes PANW IoT cloud devices as input and exports them as endpoints with custom attributes in Cisco ISE.
Permissions
This automation runs using the default Limited User role, unless you explicitly change the permissions.
For more information, see the section about permissions here: For Cortex XSOAR 6, see the https://docs-cortex.paloaltonetworks.com/r/Cortex-XSOAR/6.x/Cortex-XSOAR-Playbook-Design-Guide/Automations for Cortex XSOAR 8 Cloud, see the https://docs-cortex.paloaltonetworks.com/r/Cortex-XSOAR/8/Cortex-XSOAR-Cloud-Documentation/Create-a-script for Cortex XSOAR 8 On-prem, see the https://docs-cortex.paloaltonetworks.com/r/Cortex-XSOAR/8.7/Cortex-XSOAR-On-prem-Documentation/Create-a-script.
Script Data
| Name | Description |
|---|---|
| Script Type | python3 |
| Tags | PANW IoT 3rd Party Integration, Cisco ISE |
| Cortex XSOAR Version | 6.0.0 |
Used In
This script is used in the following playbooks and scripts.
- Incremental Export to SIEM - PANW IoT 3rd Party Integration
Dependencies
This script uses the following commands and scripts.
- cisco-ise-get-endpoint-id
- cisco-ise-get-endpoint-id-by-name
- cisco-ise-create-endpoint
- cisco-ise-update-endpoint-custom-attribute
Inputs
| Argument Name | Description |
|---|---|
| device_maps | List of device maps from PANW IoT cloud. |
| active_ise_instance | Name of the Active Cisco ISE instance. |
| panw_iot_3rd_party_instance | Name of the configured PANW Iot 3rd Party instance. |
Outputs
| Path | Description | Type |
|---|---|---|
| PaloAltoIoTIntegrationBase.Status | Total count of devices updated or created on ISE | unknown |