cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
5616
Views
0
Helpful
9
Replies

ISE Guest creation using Python script

Gagandeep Singh
Cisco Employee
Cisco Employee

Hi All,

 

I would like to create guest users using Python script.

I have installed 3.8.3 Python and saved the .py file and run the execution using ERS SDK guide for ISE

 

However getting an error:-

 

GAGSING3-M-93JT:Desktop gagsing3$ python3 guestcreat.py 10.x.x.x test Team@aaa1 2c380122-ec89-11e4-92cc-005056b46759 chris Chris Colombus Password1 chris@cisco.com  90 05/25/2020 14:00 08/23/2020 14:00
 
Status: 400
Header:
Set-Cookie: JSESSIONIDSSO=C341793060C1D013AF22DD6D51C03225; Path=/; Secure; HttpOnly
Set-Cookie: APPSESSIONID=0E87BEF5BBD9F2DAB6943C4F3D281883; Path=/ers; Secure; HttpOnly
Cache-Control: no-cache, no-store, must-revalidate
Pragma: no-cache
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Date: Mon, 25 May 2020 23:52:14 GMT
Content-Type: application/json;charset=utf-8
Content-Length: 384
Connection: close
Server: 
 
 
Body:
{
  "ERSResponse" : {
    "operation" : "POST-create-guestuser",
    "messages" : [ {
      "title" : "Resource Initialization Failed(10)",
      "type" : "ERROR",
      "code" : "Application resource validation exception"
    } ],
    "link" : {
      "rel" : "related",
      "href" : "https://10.x.x.x:9060/ers/config/guestuser/",
      "type" : "application/xml"
    }
  }
}
GAGSING3-M-93JT:Desktop gagsing3$

 

 Any help would be appreciated!!!

 

Regards

Gagandeep Singh

1 Accepted Solution

Accepted Solutions

Added some basic print statements to see your JSON request body...

print('-'*80)
print(req_body_json)
print('-'*80)

and it revealed

--------------------------------------------------------------------------------
{
"GuestUser" : {
"guestType": "Contractor (default)",
"reasonForVisit": "Business meetng",
"portalId": "b7e7d773-7bb3-442b-a50b-42837c12248a",
"guestInfo" : {
"userName": "chris",
"firstName": "Chris",
"lastName": "Colombus",
"password": "C1sco12345",
"emailAddress": "chris@cisco.com",
"enabled": true,
"notificationLanguage": "English",
"smsServiceProvider": "Global Default"
},
"guestAccessInfo" : {
"validDays": "90",
"fromDate": "05/25/2020",
"toDate": "14:00",
"location": "San Jose"
}
}
}
--------------------------------------------------------------------------------

and it looks like you are not parsing your From/To Dates properly because you forgot to account for the Time as separate arguments on the CLI.

Use this instead:

fromDate = f'{sys.argv[11]} {sys.argv[12]}' # "05/25/2020"
toDate = f'{sys.argv[13]} {sys.argv[14]}' # "08/23/2020"

 

 

View solution in original post

9 Replies 9

thomas
Cisco Employee
Cisco Employee

You did not include your Python code or actual REST input (JSON or XML) to ISE so hard to compare with the ERS documentation or run your code independently and debug / troubleshoot.

ISE ERS API Examples points to Guest & Sponsor API which has sections

using both XML and JSON for comparison.

I did this on my setup...

Follow the instructions @ Guest & Sponsor API for

  1. Access Permissions
  2. Give Sponsor group access to the API

Find my Sponsor Portal ID:

curl -k --include --header 'Content-Type:application/json' --header 'Accept: application/json' --user admin:C1sco12345 https://198.18.133.27:9060/ers/config/portal

which gave me (edited for brevity) :

"id" : "b7e7d773-7bb3-442b-a50b-42837c12248a", "name" : "Sponsor Portal (default)",
"id" : "deaaa863-1df0-4198-baf1-8d5b690d4361", "name" : "Self-Registered Guest Portal (default)",
"id" : "50fbc805-6bde-4e28-8a3e-17750f938538", "name" : "Sponsored Guest Portal (default)",
"id" : "f9b94c2f-a3fc-4154-acbb-d4c4fbed899d", "name" : "Hotspot Guest Portal (default)",

 

So I put that together in a JSON POST request using cURL with a mix of your settings with changes to match my environment (portal ID, minimum password complexity, future date/times) and please note the use of sponsor-api as the user to configure the guest user via API as explained in Guest & Sponsor API :

curl -k --include --header 'Content-Type:application/json' --header 'Accept: application/json' --user sponsor-api:C1sco12345 --request POST https://198.18.133.27:9060/ers/config/guestuser --data '
{
"GuestUser": {
"name": "chris",
"guestType": "Contractor (default)",
"portalId": "b7e7d773-7bb3-442b-a50b-42837c12248a",
"guestInfo": {
"userName": "chris",
"emailAddress": "chris@cisco.com",
"password": "Password1234",
"enabled": true
},
"guestAccessInfo": {
"validDays": 90,
"fromDate": "05/29/2020 14:00",
"toDate": "08/27/2020 14:00",
"location": "San Jose"
},
"customFields": {}
}
}'
HTTP/1.1 201
Set-Cookie: JSESSIONIDSSO=D3A42162BB80C0C73A135DD1E1755191; Path=/; Secure; HttpOnly
Set-Cookie: APPSESSIONID=4C8376ECD638954B2D619279A4E325DE; Path=/ers; Secure; HttpOnly
Cache-Control: no-cache, no-store, must-revalidate
Pragma: no-cache
Expires: Thu, 01 Jan 1970 00:00:00 GMT
X-Frame-Options: SAMEORIGIN
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Content-Type-Options: nosniff
X-Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data:;
X-WebKit-CSP: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data:;
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data:;
X-XSS-Protection: 1; mode=block
Location: https://198.18.133.27:9060/ers/config/guestuser/bdc8287e-4fd2-492a-b21f-8feecb638749
Date: Thu, 28 May 2020 18:34:34 GMT
Content-Type: application/json;charset=utf-8
Content-Length: 0
Server

It worked, returning the Location field resource for my new Guest User :

curl -k --include --header 'Content-Type:application/json' --header 'Accept: application/json' --user sponsor-api:C1sco12345 --request GET https://198.18.133.27:9060/ers/config/guestuser/bdc8287e-4fd2-492a-b21f-8feecb638749
{
"GuestUser" : {
"id" : "bdc8287e-4fd2-492a-b21f-8feecb638749",
"name" : "chris",
"guestType" : "Contractor (default)",
"status" : "AWAITING_INITIAL_LOGIN",
"sponsorUserName" : "sponsor-api",
"sponsorUserId" : "2ef8ec82-dfc4-4fda-81be-4475c294d923",
"guestInfo" : {
"userName" : "chris",
"emailAddress" : "chris@cisco.com",
"password" : "Password1234",
"creationTime" : "05/28/2020 11:34",
"enabled" : false,
"notificationLanguage" : "English"
},
"guestAccessInfo" : {
"validDays" : 90,
"fromDate" : "05/29/2020 14:00",
"toDate" : "08/27/2020 14:00",
"location" : "San Jose"
},
"customFields" : { },
"link" : {
"rel" : "self",
"href" : "https://198.18.133.27:9060/ers/config/guestuser/bdc8287e-4fd2-492a-b21f-8feecb638749",
"type" : "application/json"
}
}
}

 

 

Thanks Thomas for helping on this request.

 

Script as below:-

 

 

#!/usr/bin/env python

###########################################################################
# #
# This script demonstrates how to create guest user through ISE ERS Guest #
# users API by executing a Python script. #
# #
# SECURITY WARNING - DO NOT USE THIS SCRIPT IN PRODUCTION! #
# The script allows connections to SSL sites without trusting #
# the server certificates. #
# For production, it is required to add certificate check. #
# #
# Usage: create-guest-user.py <ISE host><Sponsor user><Sponsor password> #
# <portalId><username><firstName><lastName><password><email><validDays> #
# <fromDate><toDate> #
###########################################################################

import http.client
import base64
import ssl
import sys

#parameters
portalId = sys.argv[4] # "2c380122-ec89-11e4-92cc-005056b46759"
userName = sys.argv[5] # "chris"
firstName = sys.argv[6] # "Chris"
lastName = sys.argv[7] # "Colombus"
password = sys.argv[8] # "Password1"
emailAddress = sys.argv[9] # "chris@cisco.com"
validDays = sys.argv[10] # "90"
fromDate = sys.argv[11] # “05/25/2020”
toDate = sys.argv[12] # "08/23/2020”

# host and authentication credentials
host = sys.argv[1] # "10.201”.232.126
user = sys.argv[2] # “test”
password = sys.argv[3] # “Team@aaa1”


conn = http.client.HTTPSConnection("{}:9060".format(host), context=ssl.SSLContext(ssl.PROTOCOL_TLS))

creds = str.encode(':'.join((user, password)))
encodedAuth = bytes.decode(base64.b64encode(creds))

req_body_json = """ {{
"GuestUser" : {{
"guestType": "Contractor (default)",
"reasonForVisit": "Business meetng",
"portalId": "{}",
"guestInfo" : {{
"userName": "{}",
"firstName": "{}",
"lastName": "{}",
"password": "{}",
"emailAddress": "{}",
"enabled": true,
"notificationLanguage": "English",
"smsServiceProvider": "Global Default"
}},
"guestAccessInfo" : {{
"validDays": "{}",
"fromDate": "{}",
"toDate": "{}",
"location": "San Jose"
}}
}}
}}
""".format(portalId,userName,firstName,lastName,password,emailAddress,validDays,fromDate,toDate)

headers = {
'accept': "application/json",
'content-type': "application/json",
'authorization': " ".join(("Basic",encodedAuth)),
'cache-control': "no-cache",
}

conn.request("POST", "/ers/config/guestuser/", headers=headers, body=req_body_json)

res = conn.getresponse()
data = res.read()

print("Status: {}".format(res.status))
print("Header:\n{}".format(res.headers))
print("Body:\n{}".format(data.decode("utf-8")))

Added some basic print statements to see your JSON request body...

print('-'*80)
print(req_body_json)
print('-'*80)

and it revealed

--------------------------------------------------------------------------------
{
"GuestUser" : {
"guestType": "Contractor (default)",
"reasonForVisit": "Business meetng",
"portalId": "b7e7d773-7bb3-442b-a50b-42837c12248a",
"guestInfo" : {
"userName": "chris",
"firstName": "Chris",
"lastName": "Colombus",
"password": "C1sco12345",
"emailAddress": "chris@cisco.com",
"enabled": true,
"notificationLanguage": "English",
"smsServiceProvider": "Global Default"
},
"guestAccessInfo" : {
"validDays": "90",
"fromDate": "05/25/2020",
"toDate": "14:00",
"location": "San Jose"
}
}
}
--------------------------------------------------------------------------------

and it looks like you are not parsing your From/To Dates properly because you forgot to account for the Time as separate arguments on the CLI.

Use this instead:

fromDate = f'{sys.argv[11]} {sys.argv[12]}' # "05/25/2020"
toDate = f'{sys.argv[13]} {sys.argv[14]}' # "08/23/2020"

 

 

Thanks Thomas. It worked for me :)

@thomas Hi  Thomas 

I was trying to use the same code to create internal user instead of guest user 

This is my code and the error I got while i run it  . can you help me out

Sorry, I'm not going to open random zip file attachments for security reasons. 8-)

From the attached image it appears that you are trying to run Python with "py" and not "python.exe" which is why windows cannot find the file. Cisco DevNet has an excellent video series on Network Programmability Basics - specifically the Programming Fundamentals module gives you the background on using Python.

Please submit any additional questions as a new thread in the community with our specific issue.

OK . thank you  for  assistance . Can you check this last one 

I don't know what I am checking since you have not explained anything.

You have not stated what you are trying to do or what the error is.

I cannot copy and paste and run it from a PNG file.

Please read How to Ask the Community for Help.

HI Thomas 

I am try to  create internal  users with my Python script. This is my code I  created 

#!/usr/bin/python
import http.client
import base64
import ssl
import sys
import os
argv = sys.argv[1]
print ("The name of the script: ", sys.argv[0])
print ("The argument are: ", argv)
#parameters

Id = sys.argv[4] # "B100"
userName = sys.argv[5] # "Robert"
firstName = sys.argv[6] # "Robert"
lastName = sys.argv[7] # "Mensah"
password = sys.argv[8] # "Password1"
emailAddress = sys.argv[9] # "rmensah@cisco.com
expiryDate = sys.argv[11] # “12/26/2020”
identityGroups = sys.argv[10] # “identityGroups”


# host and authentication credentials
host = sys.argv[1] # "192.198”.1.1
user = sys.argv[2] # “ers-admin”
password = sys.argv[3] # “admin20!”

conn = http.client.HTTPSConnection("{}:9060".format(host), context=ssl.SSLContext(ssl.PROTOCOL_TLS))

creds = str.encode(':'.join((user, password)))
encodedAuth = bytes.decode(base64.b64encode(creds))

req_body_json = """{{

\"InternalUser"\ : {

"id" : "\{}\",

"userName" : "\{}\",

"description" : "\{}\",

"enabled" : true,

"email" : "\{}\",

"password" : "\{}\",

"firstName" : "\{}\",

"lastName" : "\{}\",

"changePassword" : true,

"identityGroups" : "\{}\",

"expiryDateEnabled" : false,

"expiryDate" : "\{}\",

"enablePassword" : "enablePassword",

"customAttributes" : {

"key1" : "value1",

"key2" : "value3"

},

"passwordIDStore" : "Internal Users"

}

}}
}}""".format(Id,UserNname,firstName,lastName,emailAddress,password,identityGroups,expiryDate)
headers = {
'accept': "application/json",
'content-type': "application/json",
'authorization': " ".join(("Basic",encodedAuth)),
'cache-control': "no-cache",
}
conn.request("POST", "/ers/config/internaluser/", headers=headers, body=req_body_json)

es = conn.getresponse()
data = res.read()

print("Status: {}".format(res.status))
print("Header:\n{}".format(res.headers))
print("Body:\n{}".format(data.decode("utf-8")))
print (req_req_json) 

 

I got this error while  executing the above code

Traceback (most recent call last):
File "C:\Users\ghibuser\Desktop\ISEInternalUserTest.py", line 38, in <module>
req_body_json = """{{
IndexError: Replacement index 7 out of range for positional args tuple

 

Any support will be welcomed