For the native REST APIs, this lab will start with Cisco Unity Connection's Provisioning API (CUPI).
You have already configured the generic REST portion, and we have extended that class for you with the
CUPI-specific components, namely the header and then the response parsing. Specifically, in
flaskr/cuc/v1/cupi.py, a CUPI class has been built
which extends the REST class
using a base_url of /vmrest and a header defined as:
In this CUPI class, we have two methods:
_cupi_request() - sends the request using the REST _send_request(),
checks for basic errors and then returns the parsed response from
_cupi_parse_response(). The _cupi_request()
method takes the following variables:
api_method: The API method, such as "users" that will be used with the existing
base_url to form a complete url, such as "/vmrest/users"
parameters: A dictionary of URL parameters to be sent, such as {'offset': 10}
payload: The payload to be sent, used with a POST or PUT
http_method: The request verb. CUPI only supports 'GET', 'PUT', 'POST', and 'DELETE'
_cupi_parse_response() - this function parses the response and then
performs the following tasks:
Decodes the JSON response and looks at its contents to make sure they are returned
consistently (i.e. handle the case for a single item)
If the results content is just a string, then return it. This is the situation you observed
in the response of a POST message.
In some situations, Unity Connection will return a web page describing an error
exception. Instead of the whole web page, only the Exception message will be
returned.
With the CUPI class built, you can initialize this class. This will be done globally, so that the same
session can be used and reused by subsequent requests. With the class initialized, you can implement
functions that send requests similar to what you did with Postman, such as a Get Version. When that
is successful, you can implement business functions, searching for users to import, importing a user, modifying
a user, and deleting a user account. This should be done using just the user ID, so the user import function, for
instance, will need to first look up a user to get the pkid, to reuse in the import. Each of these
functions will be tested using your Swagger UI page.
In this section, you will implement the following Unity Connection Provisioning API tasks:
Get Version
Get LDAP Users Available for Import
Import an LDAP User by User Id
Get a User by ID
Modify user settings and voicemail PIN by User Id
Delete the voicemail account by User Id
Verification
Step 1 - Get Version
As with Postman, start with something simple: retrieving the Unity Connection version.
If you recall, we sent a GET request to /version/product/, which is what you can
recreate here.
Near the top, you can instantiate the CUPI object. This will allow you to re-use the same object--and more importantly,
re-use the connections--for each request.
In the cuc_version_api() class, under the get() function, replace the
pass line with the following highlighted line. Since the CUPI object
has already been instantiated as myCUPI, you can simply call the
_cupi_request() method. Remember that the base_url for this object
is /vmrest, so the full URL requested will be /vmrest/version/product/
using the default http_method of GET.
Save this file.
Step 2 - Get LDAP Users Available for Import
Now that you are able to perform CUPI queries, build the front-end API to implement the
LDAP users query, to find out who is available to be imported into the system.
In the cuc_import_ldapuser_api() class, add the following
highlighted line after the arguments are read. The get_search_params()
function uses the argments to create a valid filter, like query=(alias is user1).
Feel free to take a look at get_search_params() in this same file.
Then you can call the _cupi_request()
method using the parameters built from the arguments.
Save this file.
When you were working with Postman and, for example, importing users into Unity Connection,
you would also retrieve a list of users and then look for the pkid, which you would later use
in the POST request to import that specific user. You don't want your
front-end web developers to have to worry about something like a pkid or how to retrieve
this for each of the product APIs. To perform an import of a user, you really want them to be able
to supply only the user ID. In your code on the backend, you can look up the pkid
based on that user and perform the import if that user is found.
Step 3 - Import an LDAP User by User Id
To import an LDAP user using your API, you must implement the following logic:
Read in the user id for the user you want to import.
Use myCUPI's send_request to request "import/users/ldap" for
the desired user, using the query=(alias is <userid>) parameter
to look them up in the Unity Connection LDAP database:
myCUPI._cupi_request("import/users/ldap", parameters=params), where params
is the query.
If you receive a user in the response, use that user's
pkid to construct a POST request to "import/users/ldap",
which imports the user, just as you had seen with Postman.
E.g.: myCUPI._cupi_request("import/users/ldap", parameters=params, payload=args,
http_method='POST'), where the parameter specifies the voicemail templateAlias.
Handle errors, such as no user found or an error in querying for the user.
In the post() function in the cuc_user_api
class, add the following:
Save this file.
Step 4 - Get a User by ID
The Unity Connection-related tasks such as modifying and deleting a user should require only
the user ID as an input. For that, you need a function that can look up a Unity Connection user
account and retrieve their pkid. Luckily, we have already seen that Unity Connection
allows for a specific user search using a GET to /vmrest/users with a query parameter such as the following:
?query=(alias is <userid>). You should put this in its own function, because
every one of the subsequent requests will need that exact same lookup.
In the get_user_by_id() function, replace the pass
line with the following:
To test this later, add the following to the get() function:
This will search for and return a specific Unity Connection user, with all their settings, given only the user ID.
Step 5 - Modify User Settings and Voicemail PIN by User Id
Now that you have a way to look up a user account, you can then add the ability to modify
them. You may also want to provide a simple flag for a user to reset a mailbox and
change a user's PIN. We have handled gathering the input for you. Now, a few
API calls in succession will be required to implement user modifications, based
on what was supplied. Keep in mind that the credential/PIN changes are a different
API method than other user settings.
The following logic will need to be implemented:
Read in the arguments. This is done for you and will include the following
dictionary keys:
ListInDirectory - True/False - controls whether the account is listed in the Unity directory
IsVmEnrolled - True/False - controls whether the account's initial enrollment prompt will play
PIN - Integer - a new PIN for the account
ResetMailbox - True/False - ability to reset the ResetMailbox and TimeHacked,
which, in effect, allows the user to try to log in again after being locked out (which usually happens
when a password was forgotten)
Look up the user in order to get the account's ObjectId
If there are user settings to change, issue the PUT request to /users/ObjectId to do so.
If credential/voicemail reset settings were supplied then issue a PUT
request for that (since it's a different URL, /users/ObjectId/credential/pin)
You need to handle errors such as the user not found, or if one of these requests
generates an error
Now turn your attention to implementing this in your code.
In the put() function of the cuc_user_api
class, replace the pass line with the following to check if any arguments
were actually supplied and look up the user and then the user's object ID:
Save this file.
Step 6 - Delete the Voicemail Account by User Id
As with other userid operations, you must first look up the user in
order to get its Object ID. Then, if there were no errors, issue the
DELETE to remove the account.
In the delete_user() function, replace the pass
line with the following return line:
Save this file.
Step 7 - Verification
You have added a lot of code so far, now it is time to make sure it works as expected.
In VS Code, make sure flaskr/api/v1/cuc.py is saved
Restart your Flask app by clicking the green restart button from the controller:
which you should always see along the top of the window, when Flask is running.
Or, if Flask is not started at all, click the Debug button on the left side
followed by
the green start/play button next to Start LTRCOL-2574 Portal
If the Terminal window at bottom right shows: * Running on http://10.0.106.40.40:5000/ (Press CTRL+C to quit), then
your Flask app is running.
Examine the response. You should note a Server response code of
200 and a response body with the users that can be imported.
Make sure pod6user1 user appears in the list, or you
won't be able to import that user
Import an LDAP User by User Id
Click the POST /cuc/users/{userid} operation.
At right, click Try it out.
For the userid setting, enter
pod6user1
Click Execute.
Examine the response. You should note a Server response code of
200 and a response body that should indicate success such as in this example:
The response message, is just as you saw with Postman. The difference is that you don't really need to pay attention
to the ID assigned, since your code can retrieve this any time using the user ID.
Modify user settings and voicemail PIN by User Id
Click the PUT /cuc/users/{userid} operation.
At right, click Try it out.
Set the following:
For ListInDirectory, select false
For IsVmEnrolled, select false
For ResetMailbox, select true
Set userid to
pod6user1
Click Execute.
Examine the response. You should note a Server response code of
200 to indicate a success.
Get a User by ID
Click the GET /cuc/users/{userid} option.
At right, click Try it out.
Set userid to
pod6user1
Click Execute.
Examine the response and make sure you received a response of
200. Check to see if ListInDirectory
and IsVmEnrolled are now false.
Delete the voicemail account by User Id
Click the red DELETE /cuc/users/{userid} method.
At right, click Try it out.
Set userid to
pod6user1
Click Execute.
Examine the response. You should note a Server response code of
200 and a response body that shows success as
true. To test a failure, try executing this again and you should see
something like:
You have a functional CUPI API! Now you are ready to implement the same for Cisco Meeting Server.