cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
Announcements
 
ISE 2.3 Patch 7 has been posted. This will be the last patch for the ISE 2.3 release!
Choose one of the topics below to view our ISE Resources to help you on your journey with ISE

This community is for technical, feature, configuration and deployment questions.
For production deployment issues, please contact the TAC! We will not comment or assist with your TAC case in these forums.
Please see How to Ask the Community for Help for other best practices.

240
Views
25
Helpful
13
Replies
Highlighted
Enthusiast

Python Script that Stores & then calls Cisco ISE Rest response

I have a python script that I am attempting to use to automate creating or statically assigning an already existing endpoint to an endpoint group.  Essentially I am trying to do this:

Prompt user to determine if MAC address is a new host or existing host (Completed)

If new, leverage json and run requests.post to create endpoint in ISE (Completed & works)

If existing endpoint, use json and run requests.get to get endpoint information.  Then store part of the json response "href" and call that in a requests.put that moves the existing MAC in ISE to the newly desired endpoint group.  

 

This is where I my code is breaking down.  Can anyone provide an example of parsing the response from ISE, storing what I need, and then calling it in my requests.put?  Any help is greatly appreciated.

1 ACCEPTED SOLUTION

Accepted Solutions
Enthusiast

Re: Python Script that Stores & then calls Cisco ISE Rest response

Sorry for the delay. I appreciate all inputs as it definitely helped me troubleshoot & learn. Here is the snippet I used to accomplish storing the requests response and extracting what I needed to statically assign the group if already existed:
#declared temp further up
temp = ("")
r = requests.get(url=API_OLD_DEVICE, auth=API_ERS_USER, headers=HEADERS, verify=True)
data = r.text
hostIDJSON = json.loads(data)
for host in hostIDJSON['SearchResult']['resources']:
temp = host['id']
print temp

API_OLD_DEVICE2 = "https://XXX:9060/ers/config/endpoint/"+ temp

Thank you all for the assistance!
13 REPLIES 13
Cisco Employee

Re: Python Script that Stores

I don’t think you can get the output of GET requests for endpoint in json format. I’ve tried this and it does not seen to work. You can get the XML output though. Also, you need to know the available endpoint identity groups and their corresponding IDs.

 

For Endpoint Identity Group ID :

=================================================================

GET request API

 

URL : https://10.127.196.95:9060/ers/config/endpointgroup?filter=name.Android

 

Hearders :

 

Accept : application/vnd.com.cisco.ise.identity.endpointgroup.1.1+xml

Accept-Search-Result : application/vnd.com.cisco.ise.ers.searchresult.2.0+xml

 

The output will be something like follows :

 

<?xml version="1.0" encoding="utf-8" standalone="yes"?>

<ns3:searchResult total="23" xmlns:ns5="ers.ise.cisco.com" xmlns:ers-v2="ers-v2" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ns3="v2.ers.ise.cisco.com">

    <ns3:nextPage rel="next" href="" type="application/xml"/>

    <ns3:resources>

        <ns5:resource description="Identity Group for Profile: Android" id="3f0798c0-f17c-11e6-8986-005056a573d3" name="Android">

            <link rel="self" href="https://<IP>:9060/ers/config/endpointgroup/3f0798c0-f17c-11e6-8986-005056a573d3" type="application/xml"/>

        </ns5:resource>

    </ns3:resources>

</ns3:searchResult>

 

Get the ID of the endpoint identity group name from this output.

 

Here is how you get the endpoint ID  :

==============================================================

GET request API

 

URL : “https://10.127.196.95:9060/ers/config/endpoint?filter=mac.EQ.11:22:33:44:55:66

 

Headers :

 

Accept : application/vnd.com.cisco.ise.identity.endpoint.1.1+xml

Accept-Search-Result : application/vnd.com.cisco.ise.ers.searchresult.2.0+xml

 

Output :

 

<?xml version="1.0" encoding="utf-8" standalone="yes"?>

<ns3:searchResult total="1" xmlns:ns5="ers.ise.cisco.com" xmlns:ers-v2="ers-v2" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ns3="v2.ers.ise.cisco.com">

    <ns3:resources>

        <ns5:resource id="21884770-6893-11e7-b83f-005056a573d3" name="11:22:33:44:55:66">

            <link rel="self" href="https://<IP>:9060/ers/config/endpoint/21884770-6893-11e7-b83f-005056a573d3" type="application/xml"/>

        </ns5:resource>

    </ns3:resources>

</ns3:searchResult>

 

Get the link from href attribute and send another GET request with only the Accept header. You will get the following output :

 

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<ns4:endpoint description="description" id="id" name="name" xmlns:ers="ers.ise.cisco.com" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ns4="identity.ers.ise.cisco.com">

    <customAttributes>

        <customAttributes>

            <entry>

                <key>key1</key>

                <value>value1</value>

            </entry>

            <entry>

                <key>key2</key>

                <value>value2</value>

            </entry>

        </customAttributes>

    </customAttributes>

    <groupId>groupId</groupId>

    <identityStore>identityStore</identityStore>

    <identityStoreId>identityStoreId</identityStoreId>

    <mac>11:22:33:44:55</mac>

    <portalUser>portalUser</portalUser>

    <profileId>profileId</profileId>

    <staticGroupAssignment>true</staticGroupAssignment>

    <staticProfileAssignment>false</staticProfileAssignment>

</ns4:endpoint>

 

 

At this point you have the endpoint ID and the Endpoint Group ID. All you need to do is to send an update request to update the endpoint using the following :

 

PUT request API :

 

URL : https://10.127.196.95:9060/ers/config/endpoint/21884770-6893-11e7-b83f-005056a573d3

 

Headers:

 

Content-Type : application/vnd.com.cisco.ise.identity.endpoint.1.1+xml; charset=utf-8

Accept : application/vnd.com.cisco.ise.identity.endpoint.1.1+xml

 

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<ns4:endpoint description="description" id="id" name="name" xmlns:ers="ers.ise.cisco.com" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ns4="identity.ers.ise.cisco.com">

    <customAttributes>

        <customAttributes>

            <entry>

                <key>key1</key>

                <value>value1</value>

            </entry>

            <entry>

                <key>key2</key>

                <value>value2</value>

            </entry>

        </customAttributes>

    </customAttributes>

    <groupId>3f0798c0-f17c-11e6-8986-005056a573d3</groupId>

    <identityStore>identityStore</identityStore>

    <identityStoreId>identityStoreId</identityStoreId>

    <mac>11:22:33:44:55</mac>

    <portalUser>portalUser</portalUser>

    <profileId>profileId</profileId>

    <staticGroupAssignment>true</staticGroupAssignment>

    <staticProfileAssignment>false</staticProfileAssignment>

</ns4:endpoint>

===========================================================

 

How you do it in python is something that I’ll leave with you. I usually use regex or the ElementTree XML API to parse these outputs and httplib2 to send API requests.

Enthusiast

Re: Python Script that Stores

I think my current problem is the fact that I am trying to pass a user string to the href link & ISE is returning unsupported media. For example here is a small snippet of what I mean:
HW_ADDR = raw_input("Enter MAC: ")
if len(HW_ADDR) != 17:
print "Error! Must be 17 characters & in the following format: aa:bb:cc:dd:ee:ff"
sys.exit()
API_OLD_DEVICE = "https://XXXXXX:9060/ers/config/endpoint?filter=mac.EQ."(HW_ADDR)
API_ERS_USER = "XXXX","XXXX"

r = requests.get(url=API_OLD_DEVICE, auth=API_ERS_USER, verify=True)

Then from here store the id of the mac to then reference that in a requests.put. I have attempted to format that "url" with the user string and I am unsuccessful. Any help is greatly appreciated.

Cisco Employee

Re: Python Script that Stores

How about concatenating it like “https://XXXXXX:9060/ers/config/endpoint?filter=mac.EQ.”+ HW_ADDR
Enthusiast

Re: Python Script that Stores

@Surendra Are you able to provide or point me to a valid source that has examples of ElementTree XML API to parse outputs? 

Cisco Employee

Re: Python Script that Stores

I have scripts written using ElementTree for internal platform in Cisco which I will not be able to share. https://docs.python.org/2/library/xml.etree.elementtree.html is a decent document which you can have a look at. Also, if you intend to use JSON, what @hslai has mentioned works well.
Cisco Employee

Re: Python Script that Stores & then calls Cisco ISE Rest response

Solved: Re: X-CSRF-TOKEN handling - Cisco Community has a python example and it should work if CSRF enforcement not enabled.

JSON should work, as well. Not sure how it not working for Surendra

VIP Engager

Re: Python Script that Stores & then calls Cisco ISE Rest response

Mike,

 

I have done all this in JSON without an issue.  If you don't use Postman I would recommend it.  I use it to mock up all my REST calls and then code them in whatever language I am using at the time.

VIP Engager

Re: Python Script that Stores & then calls Cisco ISE Rest response

I just Postman'd it up and worked as expected.  I am assuming you already have the coding done to find the group ID you want to statically assign to.

 

Does the MAC address exist:

 

https://<ISE>:9060/ers/config/endpoint?filter=mac.EQ.11:11:11:11:11:11

 

If MAC doesn't exists:

Method POST:

 

https://<ISE>:9060/ers/config/endpoint

 

JSON:

{
"ERSEndPoint" : {
"groupId" : "ac6d0110-a942-11e7-a23c-02426004eacf",
"mac" : "11:11:11:11:11:11",
"staticGroupAssignment" : true
}
}

 

If MAC does exist:

Parse out the ID or HREF making sure to remove the "".

 

Method PUT:

 

https://<ISE>:9060/ers/config/endpoint/3ffb6bc0-acc4-11e9-8dca-4ac97c2aba5f

 

JSON:

{
"ERSEndPoint" : {
"groupId" : "ac6d0110-a942-11e7-a23c-02426004eacf",
"mac" : "11:11:11:11:11:11",
"staticGroupAssignment" : true
}
}

Cisco Employee

Re: Python Script that Stores & then calls Cisco ISE Rest response

paul is correct. We need not include all attributes in order to update the static group assignment. The body of the PUT request could include the new groupID and the staticGroupAssignment only. Here is an example.

{
 "ERSEndPoint" : 
 {
  "groupId" : "aa000c30-8bff-11e6-996c-525400b48521",
  "staticGroupAssignment" : true
 }
}
Enthusiast

Re: Python Script that Stores & then calls Cisco ISE Rest response

I appreciate the valuable information. I am fairly new to utilizing this realm. I think my main issue now is the parsing of the response to get either the endpoint ID or href link. Here is a snippet from my code if device exists:
if ENDPOINT == "False":
#Get deviceID so we can later update the groupId. HW_ADDR is raw code from user input.
API_OLD_DEVICE = "https://XXXX:9060/ers/config/endpoint?filter=mac.EQ."+ HW_ADDR
API_ERS_USER = "XXXX","XXXX"
HEADERS = {
'accept': "application/json",
'content-type': "application/json",
}

r = requests.get(url=API_OLD_DEVICE, auth=API_ERS_USER, headers=HEADERS, verify=True)
data = r.content
groupJSON = json.loads(data.decode("utf-8"))
hostID = groupJSON['SearchResult']['resources']['id']
print "HostID: ", hostID

API_OLD_DEVICE2 = "https://XXXXXX:9060/ers/config/endpoint/" + hostID
API_ERS_USER = "XXXX","XXXX"
API_DATA = {
"ERSEndPoint" : {
"staticGroupAssignment" : "true",
"groupId" : "a1649530-6840-11e9-aa97-0242f38bcc8a",
}
}

r = requests.put(url=API_OLD_DEVICE2, auth=API_ERS_USER, verify=True, json=API_DATA)
#print ISE response
print "ISE Request", r.reason

I get errors when testing and I think it is due to the json.loads section. Done in python 2.7.
VIP Engager

Re: Python Script that Stores & then calls Cisco ISE Rest response

All my work has been Excel for REST API work because most of my customers want the results in Excel format.  I don't read the JSON structure into anything other than a string variable.  The logic is simple string manipulation.  I find the ID instead of the HREF but either works:

 

Find the position of the "id": in the string.

String cut left everything at position + 7 (that cuts out "id" : ")

Find ", in the remaining string (which is the end of the ID)

String cut right everything after that position

Now I have the ID

 

I use the same string manipulation logic to get group ID.  Sure reading things into an actual JSON structure would be cooler, but string manipulation is easy enough and works perfectly.

Cisco Employee

Re: Python Script that Stores & then calls Cisco ISE Rest response

Enthusiast

Re: Python Script that Stores & then calls Cisco ISE Rest response

Sorry for the delay. I appreciate all inputs as it definitely helped me troubleshoot & learn. Here is the snippet I used to accomplish storing the requests response and extracting what I needed to statically assign the group if already existed:
#declared temp further up
temp = ("")
r = requests.get(url=API_OLD_DEVICE, auth=API_ERS_USER, headers=HEADERS, verify=True)
data = r.text
hostIDJSON = json.loads(data)
for host in hostIDJSON['SearchResult']['resources']:
temp = host['id']
print temp

API_OLD_DEVICE2 = "https://XXX:9060/ers/config/endpoint/"+ temp

Thank you all for the assistance!