Details
| ID | Cisco ISE |
|---|---|
| Provider | Cisco Systems |
| Category | Network Security |
| From Version | 5.0.0 |
| Docker Image | demisto/python3:3.12.13.10116658 |
| Supported Modules | Agentix XSIAM |
README
Use the Cisco ISE integration to get endpoint data, and to manage and update endpoints and ANC policies.
Configure Cisco ISE on Cortex XSOAR
- Navigate to Settings > Integrations > Servers & Services.
- Search for Cisco ISE.
- Click Add instance to create and configure a new integration instance.
- Name: a textual name for the integration instance.
- Cisco ISE server URL (e.g., https://123.123.123.65 )
- Server port (e.g., 9060)
- Cisco ISE username
- Use system proxy settings
- Trust any certificate (not secure)
- Click Test to validate the URLs, token, and connection.
Commands
You can execute these commands from the Cortex XSOAR CLI, as part of an automation, or in a playbook. After you successfully execute a command, a DBot message appears in the War Room with the command details.
- Get an endpoint ID: cisco-ise-get-endpoint-id
- Get information for an endpoint: cisco-ise-get-endpoint-details
- Re-authenticate an endpoint: cisco-ise-reauthenticate-endpoint
- Get data for all existing endpoints: cisco-ise-get-endpoints
- Update custom attributes of an endpoint: cisco-ise-update-endpoint-custom-attribute
- Update the group of an endpoint: cisco-ise-update-endpoint-group
- Get a collection of endpoint identity groups: cisco-ise-get-groups
- Get all ANC policies: cisco-ise-get-policies
- Get a single ANC policy: cisco-ise-get-policy
- Create an ANC policy: cisco-ise-create-policy
- Assign an ANC policy to an endpoint: cisco-ise-assign-policy
- Get all endpoints on block list: cisco-ise-get-blacklist-endpoints
1. Get an endpoint ID
Returns an endpoint ID, by its MAC address.
Base Command
cisco-ise-get-endpoint-id
Input
| Argument Name | Description | Required |
|---|---|---|
| macAddress | MAC address of the endpoint (format: 11:22:33:44:55:66). | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| Endpoint.ID | string | Endpoint ID. |
| Endpoint.MACAddress | string | Endpoint MAC address. |
Command Example
!cisco-ise-get-endpoint-id macAddress=00:0E:35:D4:D8:51
Human Readable Output
The endpoint ID is: 327b0120-4ba1-11e8-93bd-000c296ec148
2. Get information for an endpoint
Returns details for a specified endpoint.
Base Command
cisco-ise-get-endpoint-details
Input
| Argument Name | Description | Required |
|---|---|---|
| endpointID | The ID of the endpoint for which to return details. | Optional |
| macAddress | MAC address of the endpoint (format 11:22:33:44:55:66). | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| CiscoISE.Endpoint.ID | string | Endpoint ID. |
| CiscoISE.Endpoint.Description | string | Endpoint description. |
| CiscoISE.Endpoint.MACAddress | string | Endpoint MAC address. |
| CiscoISE.Endpoint.Group | string | Endpoint group name |
| Endpoint.ID | string | Endpoint ID. |
| Endpoint.MACAddress | string | Endpoint MAC address. |
| CiscoISE.Endpoint.CustomAttributes | string | Endpoint custom attributes. |
| CiscoISE.Endpoint.StaticGroupAssignment | boolean | True if the endpoint has a static group assignment. |
| CiscoISE.Endpoint.StaticProfileAssignment | boolean | Whether the endpoint has a static profile assignment. |
| CiscoISE.Endpoint.User | string | Profile of the user associated with the endpoint. |
Command Example
!cisco-ise-get-endpoint-details endpointID=327b0120-4ba1-11e8-93bd-000c296ec148
Context Example
{
"CiscoISE.Endpoint": {
"MACAddress": "00:0E:35:D4:D8:51",
"Group": "Internal Dev",
"ID": "327b0120-4ba1-11e8-93bd-000c296ec148",
"StaticProfileAssignment": false,
"StaticGroupAssignment": false
},
"Endpoint": {
"MACAddress": "00:0E:35:D4:D8:51",
"ID": "327b0120-4ba1-11e8-93bd-000c296ec148"
}
}
Human Readable Output
Endpoint details - 327b0120-4ba1-11e8-93bd-000c296ec148
| Group | ID | MACAddress | StaticGroupAssignment | StaticProfileAssignment |
|---|---|---|---|---|
| Internal Dev | 327b0120-4ba1-11e8-93bd-000c296ec148 | 00:0E:35:D4:D8:51 | false | false |
3. Re-authenticate an endpoint
Re-authenticates an endpoint (Change of Authorization - CoA).
Base Command
cisco-ise-reauthenticate-endpoint
Input
| Argument Name | Description | Required |
|---|---|---|
| macAddress | MAC address of the endpoint (format 11:22:33:44:55:66). | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| CiscoISE.Endpoint.MACAddress | string | MAC address of the endpoint. |
| CiscoISE.Endpoint.reauthenticateResult | boolean | Re-authentication result. |
Command Example
!cisco-ise-reauthenticate-endpoint macAddress=00:0E:35:D4:D8:51
Human Readable Output
'Activation result was : True
4. Get data for all existing endpoints
Returns data for existing endpoints.
Base Command
cisco-ise-get-endpoints
Input
There are no arguments for this command.
Context Output
| Path | Type | Description |
|---|---|---|
| Endpoint.ID | string | Endpoint ID. |
| Endpoint.MACAddress | string | Endpoint MAC address. |
| CiscoISE.Endpoint.ID | string | Endpoint ID. |
| CiscoISE.Endpoint.MACAddress | string | Endpoint MAC address. |
Command Example
!cisco-ise-get-endpoints
Context Example
{
"CiscoISE.Endpoint": [
{
"MACAddress": "00:0A:35:11:A9:00",
"ID": "50080fc0-a07a-11e8-808e-000c295fdd32"
},
{
"MACAddress": "00:0E:35:D4:D8:51",
"ID": "327b0120-4ba1-11e8-93bd-000c296ec148"
},
{
"MACAddress": "11:22:33:AA:BB:CC",
"ID": "7d5e0530-133c-11e9-a5db-02420d3c5249"
}
],
"Endpoint": [
{
"MACAddress": "00:0A:35:11:A9:00",
"ID": "50080fc0-a07a-11e8-808e-000c295fdd32"
},
{
"MACAddress": "00:0E:35:D4:D8:51",
"ID": "327b0120-4ba1-11e8-93bd-000c296ec148"
},
{
"MACAddress": "11:22:33:AA:BB:CC",
"ID": "7d5e0530-133c-11e9-a5db-02420d3c5249"
}
]
}
Human Readable Output
Cisco ISE Endpoints
| ID | MACAddress |
|---|---|
| 50080fc0-a07a-11e8-808e-000c295fdd32 | 00:0A:35:11:A9:00 |
| 327b0120-4ba1-11e8-93bd-000c296ec148 | 00:0E:35:D4:D8:51 |
| 7d5e0530-133c-11e9-a5db-02420d3c5249 | 11:22:33:AA:BB:CC |
5. Update custom attributes of an endpoint
Updates the custom attributes of an endpoint.
Base Command
cisco-ise-update-endpoint-custom-attribute
Input
| Argument Name | Description | Required |
|---|---|---|
| id | Endpoint ID. | Optional |
| macAddress | MAC address of the endpoint (format 11:22:33:44:55:66). | Optional |
| attributeName | A CSV list of attributes, for example, "attributeName=firstAttribute,secondAttribute". | Required |
| attributeValue | A CSV list of attribute values, for example, "attributeValue=firstValue,secondValue". | Required |
Context Output
There is no context output for this command.
Command Example
!cisco-ise-update-endpoint-custom-attribute macAddress=00:0E:35:D4:D8:51 attributeName=mytest attributeValue=test1=testing
Human Readable Output
Successfully updated endpoint 327b0120-4ba1-11e8-93bd-000c296ec148, the new custom fields are: "{test1=testing}"
6. Update the group of an endpoint
Updates the group of an endpoint.
Base Command
cisco-ise-update-endpoint-group
Input
| Argument Name | Description | Required |
|---|---|---|
| groupId | The group ID to assign to this endpoint, e.g. 1 | Optional |
| macAddress | MAC address of the endpoint (format 11:22:33:44:55:66). | Optional |
| id | Endpoint ID of the endpoint to update. | Optional |
| groupName | Name of the group to update for the endpoint. | Optional |
Context Output
There is no context output for this command.
Command Example
!cisco-ise-update-endpoint-group groupName=Blacklist id=7d5e0530-133c-11e9-a5db-02420d3c5249
Human Readable Output
Endpoint 7d5e0530-133c-11e9-a5db-02420d3c5249 updated successfully
7. Get a collection of endpoint identity groups
Retrieves a collection of endpoint identity groups.
Base Command
cisco-ise-get-groups
Input
There are no arguments for this command.
Context Output
| Path | Type | Description |
|---|---|---|
| CiscoISE.Group.Description | String | The description of the endpoint identity groups. |
| CiscoISE.Group.ID | String | The ID of the endpoint identity groups. |
| CiscoISE.Group.Name | String | The name of the endpoint identity groups. |
Command Example
!cisco-ise-get-groups
Context Example
{
"CiscoISE.Group": [
{
"Name": "Sony-Device",
"Description": "Identity Group for Profile: Sony-Device",
"ID": "38a73670-8c00-11e6-996c-525400b48521"
},
{
"Name": "Cisco-Meraki-Device",
"Description": "Identity Group for Profile: Cisco-Meraki-Device",
"ID": "1e2700a0-8c00-11e6-996c-525400b48521"
},
{
"Name": "Apple-iDevice",
"Description": "Identity Group for Profile: Apple-iDevice",
"ID": "0a4a50f0-8c00-11e6-996c-525400b48521"
},
{
"Name": "BlackBerry",
"Description": "Identity Group for Profile: BlackBerry",
"ID": "0cc7ad00-8c00-11e6-996c-525400b48521"
},
{
"Name": "Android",
"Description": "Identity Group for Profile: Android",
"ID": "ffa36b00-8bff-11e6-996c-525400b48521"
},
{
"Name": "Axis-Device",
"Description": "Identity Group for Profile: Axis-Device",
"ID": "0c4eac70-8c00-11e6-996c-525400b48521"
},
{
"Name": "Juniper-Device",
"Description": "Identity Group for Profile: Juniper-Device",
"ID": "2b07d100-8c00-11e6-996c-525400b48521"
},
{
"Name": "Epson-Device",
"Description": "Identity Group for Profile: Epson-Device",
"ID": "22c6c780-8c00-11e6-996c-525400b48521"
},
{
"Name": "Profiled",
"Description": "Profiled Identity Group",
"ID": "aa10ae00-8bff-11e6-996c-525400b48521"
},
{
"Name": "Blacklist",
"Description": "Blacklist Identity Group",
"ID": "aa000c30-8bff-11e6-996c-525400b48521"
},
{
"Name": "GuestEndpoints",
"Description": "Guest Endpoints Identity Group",
"ID": "aa178bd0-8bff-11e6-996c-525400b48521"
},
{
"Name": "Synology-Device",
"Description": "Identity Group for Profile: Synology-Device",
"ID": "3a1b38d0-8c00-11e6-996c-525400b48521"
},
{
"Name": "Vizio-Device",
"Description": "Identity Group for Profile: Vizio-Device",
"ID": "3b113190-8c00-11e6-996c-525400b48521"
},
{
"Name": "Trendnet-Device",
"Description": "Identity Group for Profile: Trendnet-Device",
"ID": "3a88eec0-8c00-11e6-996c-525400b48521"
},
{
"Name": "RegisteredDevices",
"Description": "Asset Registered Endpoints Identity Group",
"ID": "aa13bb40-8bff-11e6-996c-525400b48521"
},
{
"Name": "Cisco-IP-Phone",
"Description": "Identity Group for Profile: Cisco-IP-Phone",
"ID": "14f5cac0-8c00-11e6-996c-525400b48521"
},
{
"Name": "Unknown",
"Description": "Unknown Identity Group",
"ID": "aa0e8b20-8bff-11e6-996c-525400b48521"
},
{
"Name": "Workstation",
"Description": "Identity Group for Profile: Workstation",
"ID": "3b76f840-8c00-11e6-996c-525400b48521"
}
]
}
Human Readable Output
Cisco pxGrid ISE Groups
| ID | Name | Description |
|---|---|---|
| 38a73670-8c00-11e6-996c-525400b48521 | Sony-Device | Identity Group for Profile: Sony-Device |
| 1e2700a0-8c00-11e6-996c-525400b48521 | Cisco-Meraki-Device | Identity Group for Profile: Cisco-Meraki-Device |
| 0a4a50f0-8c00-11e6-996c-525400b48521 | Apple-iDevice | Identity Group for Profile: Apple-iDevice |
| 0cc7ad00-8c00-11e6-996c-525400b48521 | BlackBerry | Identity Group for Profile: BlackBerry |
| ffa36b00-8bff-11e6-996c-525400b48521 | Android | Identity Group for Profile: Android |
| 0c4eac70-8c00-11e6-996c-525400b48521 | Axis-Device | Identity Group for Profile: Axis-Device |
| 2b07d100-8c00-11e6-996c-525400b48521 | Juniper-Device | Identity Group for Profile: Juniper-Device |
| 22c6c780-8c00-11e6-996c-525400b48521 | Epson-Device | Identity Group for Profile: Epson-Device |
| aa10ae00-8bff-11e6-996c-525400b48521 | Profiled | Profiled Identity Group |
| aa000c30-8bff-11e6-996c-525400b48521 | Blacklist | Blacklist Identity Group |
| aa178bd0-8bff-11e6-996c-525400b48521 | GuestEndpoints | Guest Endpoints Identity Group |
| 3a1b38d0-8c00-11e6-996c-525400b48521 | Synology-Device | Identity Group for Profile: Synology-Device |
| 3b113190-8c00-11e6-996c-525400b48521 | Vizio-Device | Identity Group for Profile: Vizio-Device |
| 3a88eec0-8c00-11e6-996c-525400b48521 | Trendnet-Device | Identity Group for Profile: Trendnet-Device |
| aa13bb40-8bff-11e6-996c-525400b48521 | RegisteredDevices | Asset Registered Endpoints Identity Group |
| 14f5cac0-8c00-11e6-996c-525400b48521 | Cisco-IP-Phone | Identity Group for Profile: Cisco-IP-Phone |
| aa0e8b20-8bff-11e6-996c-525400b48521 | Unknown | Unknown Identity Group |
| 3b76f840-8c00-11e6-996c-525400b48521 | Workstation | Identity Group for Profile: Workstation |
8. Get all ANC policies
Returns all Adaptive Network Control policies.
Base Command
cisco-ise-get-policies
Input
There are no arguments for this command.
Context Output
| Path | Type | Description |
|---|---|---|
| CiscoISE.Policy.Description | String | The description of the ANC policy. |
| CiscoISE.Policy.ID | String | The ID of the ANC policy. |
| CiscoISE.Policy.Name | String | The name of the ANC policy. |
Command Example
!cisco-ise-get-policies
Context Example
{
"CiscoISE.Policy": [
{
"ID": "ANCPortBounce",
"Name": "ANCPortBounce"
},
{
"ID": "ANCQuarantine",
"Name": "ANCQuarantine"
},
{
"ID": "ANCShutdown",
"Name": "ANCShutdown"
},
{
"ID": "azoce",
"Name": "azoce"
},
{
"ID": "dpkef",
"Name": "dpkef"
},
{
"ID": "dvgoy",
"Name": "dvgoy"
},
{
"ID": "gfibg",
"Name": "gfibg"
},
{
"ID": "jzbhh",
"Name": "jzbhh"
},
{
"ID": "last-test",
"Name": "last-test"
},
{
"ID": "ljnba",
"Name": "ljnba"
},
{
"ID": "mhxab",
"Name": "mhxab"
},
{
"ID": "mxiiw",
"Name": "mxiiw"
},
{
"ID": "ncxer",
"Name": "ncxer"
},
{
"ID": "phzbe",
"Name": "phzbe"
},
{
"ID": "pjrgp",
"Name": "pjrgp"
},
{
"ID": "policy0",
"Name": "policy0"
},
{
"ID": "policy09",
"Name": "policy09"
},
{
"ID": "policy1",
"Name": "policy1"
},
{
"ID": "policy2",
"Name": "policy2"
},
{
"ID": "policy3",
"Name": "policy3"
}
]
}
Human Readable Output
CiscoISE Adaptive Network Control Policies
| ID | Name |
|---|---|
| ANCPortBounce | ANCPortBounce |
| ANCQuarantine | ANCQuarantine |
| ANCShutdown | ANCShutdown |
| azoce | azoce |
| dpkef | dpkef |
| dvgoy | dvgoy |
| gfibg | gfibg |
| jzbhh | jzbhh |
| last-test | last-test |
| ljnba | ljnba |
| mhxab | mhxab |
| mxiiw | mxiiw |
| ncxer | ncxer |
| phzbe | phzbe |
| pjrgp | pjrgp |
| policy0 | policy0 |
| policy09 | policy09 |
| policy1 | policy1 |
| policy2 | policy2 |
| policy3 | policy3 |
9. Get a single ANC policy
Returns a single Adaptive Network Control policy.
Base Command
cisco-ise-get-policy
Input
| Argument Name | Description | Required |
|---|---|---|
| policy_name | The name of the ANC policy to return. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| CiscoISE.Policy.Action | String | The action of the policy. Can be "QUARANTINE", "PORTBOUNCE", or "SHUTDOWN". |
| CiscoISE.Policy.ID | String | The ID of the ANC policy. |
| CiscoISE.Policy.Link | String | The link for the ANC policy (GUI). |
| CiscoISE.Policy.Name | String | The name of the ANC policy. |
Command Example
!cisco-ise-get-policy policy_name=policy3
Context Example
{
"CiscoISE.Policy": [
{
"Action": [
"QUARANTINE"
],
"Name": "policy3"
}
]
}
Human Readable Output
CiscoISE Policy
| Action | Name |
|---|---|
| QUARANTINE | policy3 |
10. Create an ANC policy
Creates an ANC policy.
Base Command
cisco-ise-create-policy
Input
| Argument Name | Description | Required |
|---|---|---|
| policy_actions | The actions of the policy. Can be "QUARANTINE", "PORTBOUNCE", or "SHUTDOWN". | Required |
| policy_name | The name of the new adaptive network control policy. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| CiscoISE.Policy.Action | String | The actions of the ANC policy. |
| CiscoISE.Policy.Name | String | The name of the new ANC policy. |
Command Example
!cisco-ise-create-policy policy_name=quarantinePolicy policy_actions=QUARANTINE
Context Example
{
"CiscoISE.Policy": {
"Action": [
"QUARANTINE"
],
"Name": "quarantinePolicy"
}
}
Human Readable Output
The policy "quarantinePolicy" has been created successfully
11. Assign an ANC policy to an endpoint
Assigns an Adapative Network Control policy to an endpoint.
Base Command
cisco-ise-assign-policy
Input
| Argument Name | Description | Required |
|---|---|---|
| mac_address | The MAC address to which to apply the policy. | Required |
| policy_name | The name of the policy to assign to the endpoint. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| CiscoISE.Endpoint.MACAddress | String | The MAC address of the endpoint. |
| CiscoISE.Endpoint.PolicyName | String | The policy name that was applied to the endpoint. |
Command Example
!cisco-ise-assign-policy mac_address=50080fc0-a07a-11e8-808e-000c295fdd32 policy_name=policy3
Human Readable Output
The policy "policy3" has been applied successfully
12. Get all endpoints on block list.
Returns all blacklisted endpoints.
Base Command
cisco-ise-get-blacklist-endpoints
Input
There are no arguments for this command.
Context Output
| Path | Type | Description |
|---|---|---|
| CiscoISE.Endpoint.ID | String | The endpoint ID. |
| CiscoISE.Endpoint.Name | String | The name of the endpoint. |
| CiscoISE.Endpoint.Description | String | The endpoint description. |
| CiscoISE.Endpoint.Link | String | The link for the endpoint |
Command Example
!cisco-ise-get-blacklist-endpoints
Context Example
{
"CiscoISE.Endpoint": [
{
"GroupName": "Blacklist",
"ID": "327b0120-4ba1-11e8-93bd-000c296ec148",
"Name": "00:0E:35:D4:D8:51"
}
]
}
Human Readable Output
CiscoISE Blacklist Endpoints
| GroupName | ID | Name |
|---|---|---|
| Blacklist | 327b0120-4ba1-11e8-93bd-000c296ec148 | 00:0E:35:D4:D8:51 |
cisco-ise-create-endpoint
Creates a new endpoint on Cisco ISE according to the passed MAC address and custom attribute list.
Base Command
cisco-ise-create-endpoint
Input
| Argument Name | Description | Required |
|---|---|---|
| mac_address | MAC address of the endpoint (format: 11:22:33:44:55:66). | Required |
| attributes_map | A list of custom attributes. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| CiscoISE.Endpoint.MACAddress | string | MAC address of the new endpoint. |
cisco-ise-get-nodes
Returns data for all Cisco ISE nodes in the deployment.
Base Command
cisco-ise-get-nodes
Input
There are no input arguments for this command.
Context Output
| Path | Type | Description |
|---|---|---|
| CiscoISE.NodesData | unknown | Details of all deployment ISE nodes. |
cisco-ise-get-endpoint-id-by-name
Returns an EndpointID using its name (Available on ISE 2.3 and later versions).
Base Command
cisco-ise-get-endpoint-id-by-name
Input
| Argument Name | Description | Required |
|---|---|---|
| mac_address | MAC address of the endpoint (format: 11:22:33:44:55:66). | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| Endpoint.ID | string | Endpoint ID. |
| Endpoint.MACAddress | string | Endpoint MAC address. |
cisco-ise-remove-policy
Removes an Adapative Network Control policy from an endpoint.
Base Command
cisco-ise-remove-policy
Input
| Argument Name | Description | Required |
|---|---|---|
| mac_address | The MAC address from which to remove the policy. | Required |
| policy_name | The name of the policy to remove from the endpoint. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| CiscoISE.Endpoint.MACAddress | string | The MAC address of the endpoint. |
| CiscoISE.Endpoint.PolicyName | string | The policy name that was removed from the endpoint. |
cisco-ise-get-session-data-by-ip
Queries an IP address and returns its session data from an active endpoint.
Base Command
cisco-ise-get-session-data-by-ip
Input
| Argument Name | Description | Required |
|---|---|---|
| ip_address | IP address to query in the ISE platform. | Required |
Context Output
There is no context output for this command.
Configuration parameters
serverURL— Cisco ISE server URL (e.g., https://123.123.123.65) (required)serverPort— Server port (e.g., 9060)credentials— Cisco ISE username (required)proxy— Use system proxy settingsinsecure— Trust any certificate (not secure)
Commands (17)
-
cisco-ise-assign-policyAssigns an Adapative Network Control policy to an endpoint.
-
cisco-ise-create-endpointCreates a new endpoint on Cisco ISE according to the passed MAC address and custom attribute list.
-
cisco-ise-create-policyCreates an Adapative Network Control policy.
-
cisco-ise-get-blacklist-endpointsReturns all block listed endpoints.
-
cisco-ise-get-endpoint-detailsReturns details for a specified endpoint.
-
cisco-ise-get-endpoint-idReturns an endpoint ID, by its MAC address.
-
cisco-ise-get-endpoint-id-by-nameReturns an EndpointID using its name (Available on ISE 2.3 and later versions).
-
cisco-ise-get-endpointsReturns data for existing endpoints.
-
cisco-ise-get-groupsRetrieves a collection of endpoint identity groups.
-
cisco-ise-get-nodesReturns data for all Cisco ISE nodes in the deployment.
-
cisco-ise-get-policiesReturns all Adaptive Network Control policies.
-
cisco-ise-get-policyReturns a single Adaptive Network Control policy.
-
cisco-ise-get-session-data-by-ipQueries an IP address and returns its session data from an active endpoint.
-
cisco-ise-reauthenticate-endpointRe-authenticates an endpoint (Change of Authorization - CoA).
-
cisco-ise-remove-policyRemoves an Adapative Network Control policy from an endpoint.
-
cisco-ise-update-endpoint-custom-attributeUpdates the custom attributes of an endpoint.
-
cisco-ise-update-endpoint-groupUpdates the group of an endpoint.
import demistomock as demisto from CommonServerPython import * from CommonServerUserPython import * """ IMPORTS """ import requests from urllib.parse import urlparse import urllib3 # disable insecure warnings urllib3.disable_warnings() """ GLOBAL VARS """ BASE_URL = re.sub(r"/+$", "", demisto.params().get("serverURL")) SERVER_PORT = demisto.params().get("serverPort") SERVER_URL = BASE_URL + ":" + SERVER_PORT SERVER_ADMIN_URL = BASE_URL USERNAME = demisto.params().get("credentials").get("identifier") PASSWORD = demisto.params().get("credentials").get("password") USE_SSL = not demisto.params().get("insecure", False) DEFAULT_HEADERS = { "Content-Type": "application/json", "Accept": "application/json", "Connection": "keep_alive", } DEFAULT_ADMIN_HEADERS = { "Content-Type": "application/json", "Accept": "application/xml", "Connection": "keep_alive", } """ HELPER FUNCTIONS """ def http_request(method, url_suffix, params=None, data=None, headers=None, is_admin_api=False): params = params if params is not None else {} if headers is None: headers = DEFAULT_ADMIN_HEADERS if is_admin_api else DEFAULT_HEADERS if is_admin_api: url = SERVER_ADMIN_URL + url_suffix else: url = SERVER_URL + url_suffix try: LOG(f"running {method} request with url={url}") response = requests.request( method, url, auth=(USERNAME, PASSWORD), headers=headers, verify=USE_SSL, params=params, data=data ) except requests.exceptions.SSLError: err_msg = "Could not connect to Cisco ISE: Could not verify certificate." return_error(err_msg) except requests.exceptions.ConnectionError: err_msg = "Connection Error. Verify that the Server URL and port are correct, and that the port is open." return_error(err_msg) # handle request failure if response.status_code not in {200, 201, 202, 204}: message = parse_error_response(response) err_msg = f"Error in API call to Cisco ISE Integration [{response.status_code}] - {response.reason}, {message}" return_error(err_msg) if response.status_code in (201, 204): return None if is_admin_api: return response.content try: response = response.json() except ValueError: return_error(response.content) return response def parse_error_response(response): try: res = response.json() msg = res.get("ERSResponse").get("messages") err = msg[0].get("title", "") except Exception: return response.text return err def translate_group_id(group_id): """ Translates group ID to group name """ api_endpoint = f"/ers/config/identitygroup/{group_id}" identity_group = http_request("GET", api_endpoint)["IdentityGroup"] return identity_group["name"] """ COMMANDS FUNCTIONS """ def get_groups_request(): api_endpoint = "/ers/config/endpointgroup" return http_request("GET", api_endpoint) def get_groups(): """ Retrieve a collection of endpoint identity groups. """ groups_data: dict = get_groups_request().get("SearchResult", {}) if groups_data.get("total", 0) < 1: return "No groups were found." groups = groups_data.get("resources", []) context = [] humanreadable = [] for group in groups: context_dict = {"ID": group.get("id"), "Name": group.get("name"), "Description": group.get("description")} hr_dict = dict(context_dict) context.append(context_dict) humanreadable.append(hr_dict) entry_context = {"CiscoISE.Group(val.ID === obj.ID)": context} return_outputs( tableToMarkdown("Cisco ISE Groups", humanreadable, ["ID", "Name", "Description"], removeNull=True), entry_context, groups_data, ) return None def get_endpoint_id(mac_address=None): """ Returns endpoint id by specific mac address """ api_endpoint = f"/ers/config/endpoint?filter=mac.EQ.{mac_address}" if mac_address is not None else "" return http_request("GET", api_endpoint, "") def get_endpoint_id_command(): """ corresponds to 'cisco-ise-get-endpoint-id' command. Returns endpoint's id """ mac_address = demisto.args().get("macAddress") if not is_mac_address(mac_address): return_error("Given MAC address is invalid") endpoint_data = get_endpoint_id(mac_address) resources = endpoint_data.get("SearchResult", {}).get("resources", []) if resources: endpoint_id = resources[0].get("id", None) else: endpoint_id = None entry_context = {"Endpoint(val.ID === obj.ID)": {"ID": endpoint_id, "MACAddress": mac_address}} return_outputs(f"The endpoint ID is: {endpoint_id}", entry_context, endpoint_id) def get_endpoint_details(endpoint_id): """ Gets endpoint details by specific id """ api_endpoint = f"/ers/config/endpoint/{endpoint_id}" response = http_request("GET", api_endpoint) if response: return response else: return_error("Endpoint was not found.") return None def get_endpoint_details_command(): """ corresponds to 'cisco-ise-get-endpoint-details' command. Returns information about a specific endpoint """ endpoint_id = demisto.args().get("endpointID") endpoint_mac_address = demisto.args().get("macAddress") if endpoint_mac_address and not is_mac_address(endpoint_mac_address): return_error("Given MAC address is invalid") if not endpoint_id and not endpoint_mac_address: return_error("Either endpoint ID or MAC address should be provided") if endpoint_mac_address and not endpoint_id: resources = get_endpoint_id(endpoint_mac_address).get("SearchResult", {}).get("resources", []) if resources: endpoint_id = resources[0].get("id", None) endpoint_data = get_endpoint_details(endpoint_id) endpoint_details = endpoint_data.get("ERSEndPoint") if endpoint_details: custom_attributes = endpoint_details.get("customAttributes") if custom_attributes: custom_attributes = custom_attributes.get("customAttributes") portal_user = endpoint_details.get("portalUser") description = endpoint_details.get("description") group_name = translate_group_id(endpoint_details["groupId"]) hr = { "ID": endpoint_details["id"], "MACAddress": endpoint_details["mac"], "Group": group_name, "CustomAttributes": custom_attributes, "StaticGroupAssignment": endpoint_details["staticGroupAssignment"], "StaticProfileAssignment": endpoint_details["staticProfileAssignment"], } detailed_ec = { "ID": endpoint_details["id"], "MACAddress": endpoint_details["mac"], "Group": group_name, "StaticGroupAssignment": endpoint_details["staticGroupAssignment"], "StaticProfileAssignment": endpoint_details["staticProfileAssignment"], } if custom_attributes: detailed_ec["CustomAttributes"] = {} for attribute in custom_attributes: detailed_ec["CustomAttributes"][attribute] = custom_attributes[attribute] if portal_user: hr["User"] = portal_user detailed_ec["User"] = portal_user if description: hr["Description"] = description detailed_ec["Description"] = description ec = { "Endpoint(val.ID === obj.ID)": {"ID": endpoint_details["id"], "MACAddress": endpoint_details["mac"]}, "CiscoISE.Endpoint(val.ID === obj.ID)": detailed_ec, } title = "Endpoint details - " + (endpoint_id or endpoint_mac_address) return_outputs(tableToMarkdown(title, hr, removeNull=True), ec, endpoint_details) else: demisto.results("No results found") def reauthenticate_endpoint(mac_address, psn_address): """ Reauthenticates an endpoint """ api_endpoint = f"/admin/API/mnt/CoA/Reauth/{psn_address}/{mac_address}/1" response = http_request("GET", api_endpoint) return response def get_psn_for_mac(mac_address): """ Retrieves psn for an endpoint """ api_endpoint = f"/admin/API/mnt/AuthStatus/MACAddress/{mac_address}/86400/0/0" response = http_request("GET", api_endpoint) if response: return response else: return_error("Could not reauthenticate the endpoint") return None def reauthenticate_endpoint_command(): """ corresponds to 'cisco-ise-reauthenticate-endpoint' command. Reauthenticates an endpoint """ mac_address = demisto.args().get("macAddress").upper() if not is_mac_address(mac_address): return "Please enter a valid mac address" mac_address = mac_address.upper() mac_address_psn = get_psn_for_mac(mac_address) if not mac_address_psn: return "Couldn't find psn address for mac: " + mac_address psn_address = ( json.loads(xml2json(mac_address_psn)) .get("restAuthStatusOutputList", {}) .get("authStatusList", {}) .get("authStatusElements", {})[0] .get("acs_server") ) if not psn_address: return ( "Couldn't find psn address for mac: " + mac_address + " response from psn endpoint was: " + json.dumps(mac_address_psn) ) activation_result = reauthenticate_endpoint(mac_address, psn_address).text json_activation_result = json.loads(xml2json(activation_result)).get("remoteCoA").get("results") activation_result_boolean = "true" in json_activation_result entry_context = { "CiscoISE.Endpoint(val.MACAddress==obj.MACAddress)": { "MACAddress": json_activation_result, "reauthenticateResult": activation_result_boolean, } } return_outputs("Activation result was : " + str(activation_result_boolean), entry_context, activation_result) return None def get_endpoints(): """ Gets data about existing endpoints """ api_endpoint = "/ers/config/endpoint" return http_request("GET", api_endpoint) def get_endpoints_command(return_bool: bool = False): """ corresponds to 'ise-get-endpoints' command. Get data about the existing endpoints """ endpoints_data = get_endpoints().get("SearchResult", {}) if endpoints_data.get("total", 0) < 1: return "No endpoints were found." endpoints = endpoints_data.get("resources", []) context = [] hr = [] for endpoint in endpoints: context_dict = {"ID": endpoint.get("id"), "MACAddress": endpoint.get("name")} hr_dict = dict(context_dict) context.append(context_dict) hr.append(hr_dict) if return_bool: return True entry_context = {"Endpoint(val.ID == obj.ID)": context, "CiscoISE.Endpoint(val.ID == obj.ID)": context} return_outputs(tableToMarkdown("Cisco ISE Endpoints", hr, ["ID", "MACAddress"], removeNull=True), entry_context, endpoints) return None def update_endpoint_by_id(endpoint_id, endpoint_details): """ Updates endpoint status """ api_endpoint = f"/ers/config/endpoint/{endpoint_id}" response = http_request("PUT", api_endpoint, data=json.dumps(endpoint_details)) return response def update_endpoint_custom_attribute_command(): """ corresponds to 'cisco-ise-update-endpoint-custom-attribute' command. Blocks endpoint using predefined custom fields """ endpoint_id = demisto.args().get("id") endpoint_mac_address = demisto.args().get("macAddress") if endpoint_mac_address and not is_mac_address(endpoint_mac_address): return_error("Please enter a valid mac address") if not endpoint_id and not endpoint_mac_address: return_error("Please enter either endpoint id or endpoint mac address") if endpoint_mac_address and not endpoint_id: endpoint_id = get_endpoint_id(endpoint_mac_address).get("SearchResult", {}).get("resources", [])[0].get("id", None) endpoint_details = get_endpoint_details(endpoint_id) if "ERSEndPoint" not in endpoint_details: return_error(f"Failed to get endpoint {endpoint_id}") attribute_names = demisto.args().get("attributeName").split(",") attribute_values = demisto.args().get("attributeValue").split(",") attributes_dic = {} for couple in zip(attribute_names, attribute_values): attributes_dic[couple[0]] = couple[1] try: del endpoint_details["ERSEndPoint"]["link"] if endpoint_details["ERSEndPoint"].get("customAttributes"): endpoint_details["ERSEndPoint"]["customAttributes"]["customAttributes"] = attributes_dic else: endpoint_details["ERSEndPoint"]["customAttributes"] = {"customAttributes": attributes_dic} update_result = update_endpoint_by_id(endpoint_id, endpoint_details) if not update_result: demisto.results( "Update failed for endpoint " + endpoint_id + ". Please check if the custom " "fields are defined in the system. " "Got the following response: " + update_result.get("ERSResponse", {}).get("messages", []) ) updated_fields_dict_list = update_result.get("UpdatedFieldsList", {}).get("updatedField", []) if len(updated_fields_dict_list) > 0: updated_fields_string = " the new custom fields are: " + json.dumps(updated_fields_dict_list[0].get("newValue")) else: updated_fields_string = ", but the fields that you've tried to update already had that specific value or do not exist" demisto.results(f"Successfully updated endpoint {endpoint_id + updated_fields_string}") except Exception as e: raise Exception(f"Exception: Failed to update endpoint {endpoint_id}: " + str(e)) def update_endpoint_group_command(): """ corresponds to 'cisco-ise-update-endpoint-group' command. Updates endpoint status """ endpoint_group_name = demisto.args().get("groupName") endpoint_group_id = demisto.args().get("groupId") if not endpoint_group_name and not endpoint_group_id: return_error("Please enter either group id or group name") if endpoint_group_name and not endpoint_group_id: endpoint_group_data = get_endpoint_id(endpoint_group_name).get("SearchResult", {}) if endpoint_group_data.get("total", 0) < 1: return_error("No endpoints were found. Please make sure you entered the correct group name") else: endpoint_group_id = endpoint_group_data.get("resources")[0].get("id") endpoint_id = demisto.args().get("id") endpoint_mac_address = demisto.args().get("macAddress") if endpoint_mac_address and not is_mac_address(endpoint_mac_address): return_error("Please enter a valid mac address") if not endpoint_id and not endpoint_mac_address: return_error("Please enter either endpoint id or endpoint mac address") if endpoint_mac_address and not endpoint_id: endpoint_id = get_endpoint_id(endpoint_mac_address).get("SearchResult", {}).get("resources", [])[0].get("id", None) endpoint_details = get_endpoint_details(endpoint_id) if "ERSEndPoint" not in endpoint_details: return_error(f"Failed to get endpoint {endpoint_id}") try: updated_endpoint_details = {"ERSEndPoint": {}} # type: Dict[str, Any] updated_endpoint_details["ERSEndPoint"]["groupId"] = endpoint_group_id updated_endpoint_details["ERSEndPoint"]["id"] = endpoint_details.get("ERSEndPoint", {}).get("id") updated_endpoint_details["ERSEndPoint"]["mac"] = endpoint_details.get("ERSEndPoint", {}).get("mac") updated_endpoint_details["ERSEndPoint"]["name"] = endpoint_details.get("ERSEndPoint", {}).get("name") update_result = update_endpoint_by_id(endpoint_id, updated_endpoint_details) if update_result: # Create result msg = "Endpoint " + endpoint_id + " updated successfully" else: msg = ( "Update failed for endpoint " + endpoint_id + ", got the following response: " + update_result.get("ERSResponse", {}).get("messages", []) ) except Exception as e: raise Exception(f"Exception: Failed to update endpoint {endpoint_id}: " + str(e)) demisto.results(msg) def list_number_of_active_sessions(): """ This function is used for test-module to check connectivity """ api_endpoint = "/admin/API/mnt/Session/ActiveCount" response = http_request("GET", api_endpoint) return response def get_policies_request(): api_endpoint = "/ers/config/ancpolicy" response = http_request("GET", api_endpoint) return response def get_policies(): """ Return all ANC policies """ data = [] policies_data = get_policies_request().get("SearchResult", {}) if policies_data.get("total", 0) < 1: return "No policies were found." policies = policies_data.get("resources", []) for policy in policies: data.append({"ID": policy.get("id"), "Name": policy.get("name")}) context = {"CiscoISE.Policy(val.ID && val.ID === obj.ID)": data} return_outputs(tableToMarkdown("CiscoISE Adaptive Network Control Policies", data, removeNull=True), context, policies_data) return None def get_policy_by_name(policy_name): api_endpoint = f"/ers/config/ancpolicy/name/{policy_name}" response = http_request("GET", api_endpoint) return response def get_policy(): """ Returns: the specific ANC policy """ data = [] policy_name = demisto.args().get("policy_name") if not policy_name: return_error("Please enter either policy name or policy id") policy_data = get_policy_by_name(policy_name).get("ErsAncPolicy", {}) if policy_name else None if policy_data: data.append({"Name": policy_data.get("name"), "Action": policy_data.get("actions")}) context = {"CiscoISE.Policy(val.ID && val.ID === obj.ID)": data} return_outputs(tableToMarkdown("CiscoISE Policy", data, removeNull=True), context, policy_data) def create_policy_request(data): api_endpoint = "/ers/config/ancpolicy" http_request("POST", api_endpoint, data=json.dumps(data)) def create_policy(): """ Create ANC Policy """ policy_name = demisto.args().get("policy_name") policy_actions = demisto.args().get("policy_actions", "") data = {"ErsAncPolicy": {"name": policy_name, "actions": [policy_actions]}} create_policy_request(data) policy_context = {"Name": policy_name, "Action": [policy_actions]} context = {"CiscoISE.Policy(val.Name && val.Name === obj.Name)": policy_context} return_outputs(f'The policy "{policy_name}" has been created successfully', context) def assign_policy_request(data): api_endpoint = "/ers/config/ancendpoint/apply" http_request("PUT", api_endpoint, data=json.dumps(data)) def assign_policy_to_endpoint(): """ Apply ANC policy to an endpoint """ policy_name = demisto.args().get("policy_name") mac_address = demisto.args().get("mac_address") if not is_mac_address(mac_address): return_error("Please enter a valid mac address") data = { "OperationAdditionalData": { "additionalData": [{"name": "macAddress", "value": mac_address}, {"name": "policyName", "value": policy_name}] } } assign_policy_request(data) endpoint_context = {"MACAddress": mac_address, "PolicyName": policy_name} context = {"CiscoISE.Endpoint(val.ID && val.ID === obj.ID)": endpoint_context} return_outputs(f'The policy "{policy_name}" has been assigned successfully', context) def remove_policy_request(data): api_endpoint = "/ers/config/ancendpoint/clear" http_request("PUT", api_endpoint, data=json.dumps(data)) def remove_policy_from_endpoint(): """ Remove ANC policy from an endpoint """ policy_name = demisto.args().get("policy_name") mac_address = demisto.args().get("mac_address") if not is_mac_address(mac_address): return_error("Please enter a valid mac address") data = { "OperationAdditionalData": { "additionalData": [{"name": "macAddress", "value": mac_address}, {"name": "policyName", "value": policy_name}] } } remove_policy_request(data) endpoint_context = {"MACAddress": mac_address, "PolicyName": policy_name} context = {"CiscoISE.Endpoint(val.ID && val.ID === obj.ID)": endpoint_context} return_outputs(f'The policy "{policy_name}" has been removed successfully', context) def get_blacklist_group_id(): api_endpoint = "/ers/config/endpointgroup?filter=name.EQ.Blacklist" response = http_request("GET", api_endpoint) return response def get_blacklist_endpoints_request(): blacklist = get_blacklist_group_id().get("SearchResult", {}) resources = blacklist.get("resources", []) blacklist_id = {} if resources: blacklist_id = resources[0] else: return_error("No blacklist endpoint were found.") black_id = blacklist_id.get("id") api_endpoint = f"/ers/config/endpoint?filter=groupId.EQ.{black_id}" blacklist_response = http_request("GET", api_endpoint) return blacklist_response def get_blacklist_endpoints(): data = [] blacklist_endpoints = get_blacklist_endpoints_request().get("SearchResult", {}) if blacklist_endpoints.get("total", 0) < 1: demisto.results("No endpoints were found.") endpoints = blacklist_endpoints.get("resources", []) for endpoint in endpoints: data.append({"ID": endpoint.get("id"), "Name": endpoint.get("name"), "GroupName": "Blacklist"}) context = {"CiscoISE.Endpoint(val.ID && val.ID === obj.ID)": data} return_outputs(tableToMarkdown("CiscoISE Blacklist Endpoints", data, removeNull=True), context, endpoints) def get_endpoint_id_by_name(mac_address=None): """ Returns endpoint id by specific mac address Only compatible with Cisco ISE versions 2.3 """ if not is_mac_address(mac_address): return_error("Given MAC address is invalid") api_endpoint = f"/ers/config/endpoint/name/{mac_address}" return http_request("GET", api_endpoint, "") def get_endpoint_id_by_name_command(): mac_address = demisto.args().get("mac_address") if not is_mac_address(mac_address): return_error("Given MAC address is invalid") endpoint_data = get_endpoint_id_by_name(mac_address) endpoint_id = endpoint_data.get("ERSEndPoint", {}).get("id", None) entry_context = {"Endpoint(val.ID === obj.ID)": {"ID": endpoint_id, "MACAddress": mac_address}} return_outputs(f"The endpoint ID is: {endpoint_id}", entry_context, endpoint_id) def get_node_details(name=None): """ Returns details for the given Cisco ISE node """ if not name: return_error("Given Cisco ISE node is invalid") api_endpoint = f"/ers/config/node/name/{name}" return http_request("GET", api_endpoint, "") def get_all_nodes_command(): """ Returns all nodes in the Cisco ISE Deployment Also sets isLocalIstance in the output """ instance_ip = urlparse(BASE_URL).netloc try: instance_ip = socket.gethostbyname(instance_ip) except Exception as e: err_msg = f"Failed to get ip address of configured Cisco ISE instance - {e}" raise Exception(err_msg) data = [] api_endpoint = "/ers/config/node" response = http_request("GET", api_endpoint) results = response.get("SearchResult", {}) if results.get("total", 0) < 1: demisto.results("No Nodes were found") node_data = results.get("resources", []) for node in node_data: is_local_istance = False name = node.get("name") node_details = get_node_details(name).get("Node", {}) ip = node_details.get("ipAddress") if ip == instance_ip: is_local_istance = True data.append( { "Name": name, "ip": ip, "isLocalIstance": is_local_istance, # if false then standalone mode.. ie single node "inDeployment": node_details.get("inDeployment"), # primary means active node "primaryPapNode": node_details.get("primaryPapNode"), } ) context = {"CiscoISE.NodesData": data} return_outputs(tableToMarkdown("CiscoISE deployment nodes", data, removeNull=True), context) def create_new_endpoint_command(): """ Creates a new Endpoint in Cisco ISE with the given Mac address and Custom attributes """ attr_map = demisto.args().get("attributes_map") mac_address = demisto.args().get("mac_address") if not is_mac_address(mac_address): return_error("Please enter a valid mac address") if attr_map is not None: attr_map = json.loads(attr_map) data = {"ERSEndPoint": {"mac": mac_address, "customAttributes": {"customAttributes": attr_map}}} api_endpoint = "/ers/config/endpoint" http_request("POST", api_endpoint, data=json.dumps(data)) endpoint_context = { "MACAddress": mac_address, } context = {"CiscoISE.Endpoint(val.Name && val.Name === obj.Name)": endpoint_context} return_outputs(f'Endpoint "{mac_address}" has been created successfully', context) def get_session_data_by_ip_request(ip): ip_address = f"/admin/API/mnt/Session/EndPointIPAddress/{ip}" response = http_request("GET", ip_address, is_admin_api=True) byte_conversion = str(response, "utf-8") json_data = xml2json(byte_conversion) session_data = json.loads(json_data) context = {"CiscoISE.Endpoint(val.ID && val.ID === obj.ID)": session_data} return_outputs("The targeted users session xml is being returned.", context) def get_session_data_by_ip(): """ Returns: the session data given an ip address """ ip = demisto.args().get("ip_address") if not ip: return_error("Please enter the ip") get_session_data_by_ip_request(ip) """ EXECUTION CODE """ def main(): LOG(f"Command being called is {demisto.command()}") try: handle_proxy() if demisto.command() == "test-module": if get_endpoints_command(True): demisto.results("ok") else: demisto.results("test failed") elif demisto.command() == "cisco-ise-get-endpoint-id": get_endpoint_id_command() elif demisto.command() == "cisco-ise-get-endpoint-details": get_endpoint_details_command() elif demisto.command() == "cisco-ise-reauthenticate-endpoint": reauthenticate_endpoint_command() elif demisto.command() == "cisco-ise-get-endpoints": get_endpoints_command() elif demisto.command() == "cisco-ise-update-endpoint-custom-attribute": update_endpoint_custom_attribute_command() elif demisto.command() == "cisco-ise-update-endpoint-group": update_endpoint_group_command() elif demisto.command() == "cisco-ise-get-groups": get_groups() elif demisto.command() == "cisco-ise-get-policies": get_policies() elif demisto.command() == "cisco-ise-get-policy": get_policy() elif demisto.command() == "cisco-ise-create-policy": create_policy() elif demisto.command() == "cisco-ise-assign-policy": assign_policy_to_endpoint() elif demisto.command() == "cisco-ise-remove-policy": remove_policy_from_endpoint() elif demisto.command() == "cisco-ise-get-blacklist-endpoints": get_blacklist_endpoints() elif demisto.command() == "cisco-ise-create-endpoint": create_new_endpoint_command() elif demisto.command() == "cisco-ise-get-nodes": get_all_nodes_command() elif demisto.command() == "cisco-ise-get-endpoint-id-by-name": get_endpoint_id_by_name_command() elif demisto.command() == "cisco-ise-get-session-data-by-ip": get_session_data_by_ip() except Exception as e: return_error(str(e)) # python2 uses __builtin__ python3 uses builtins if __name__ == "__builtin__" or __name__ == "builtins": main()