04-04-2018 10:10 AM - edited 03-01-2019 06:48 AM
API Document containing information about Generic API Task, its usage and examples.
UCSD has always been a repository of many out of the box tasks. These tasks are built around specific operations for a particular device. These have got pre-defined inputs and pre-defined outputs. These tasks are developed by developers who understand UCSD framework and also have domain expertise around the device for which the task is meant for.
In certain situations these out-of-the box task doesn’t suffice the user requirements.
For example:
To circumvent these situations, UCSD provides a custom task framework where users can utilize cloupia script to write any device specific logic and achieve the desired result.
Custom tasks do provide the required flexibility but at the same time requires users to have good understanding about the UCSD exposed APIs and at the same time good knowledge of writing logic in cloupia script (which is mainly Java Script).
There are generic tasks available in UCSD like “SSH task” which allows user to automate operations on device which can be accessed via SSH. Since SSH is a standard way of interacting with devices, users can easily automate such operations in case there is no out-of-the-box task available for the same.
Most of the devices which requires the use of custom tasks expose their functionalities via APIs (XML/JSON). The standard way of consuming any API is a normal HTTP/HTTPs based call which clients like Postman etc. provides in a very simple way.
Currently, a generic API task using which a user can make a normal HTTP/HTTPs call to a device or service is missing in UCSD.
Generic API task tries to fill this gap and helps users to consume any API in a standard HTTP/HTTPs manner.
Any HTTP/HTTPs based API consists of a pre-defined structure:
As we see in the above snapshots, the Generic API task provides an additional page to user to define the API structure and required variables.
User can choose to define outputs based on the xPath or JsonPath of the variables inside the API response. User can also choose to output the complete response as an output or hide the complete response during task execution.
Let’s say we execute a login API for the UCSM account using generic API task. The successful response for the API will be something like:
<aaaLogin
response="yes"
outCookie="<real_cookie>"
outRefreshPeriod="600"
outPriv="aaa,ext-lan-policy,ext-lan-qos,ext-san-policy,operations,
pod-policy,pod-qos,read-only"
outDomains="mgmt02-dummy"
outChannel="noencssl"
outEvtChannel="noencssl">
</aaaLogin>
Now we want the value of outCookie attribute from this response which can be used as parameter for further operations.
The xPath for the outCookie attribute will be: /aaaLogin/@outCookie
So we can define an output variable like:
Let’s take an example of making a JSON based Login REST API call to an APIC device.
The JSON response for a successful login API call to APIC device will look something like below:
RESPONSE:
{
"imdata" : [{
"aaaLogin" : {
"attributes" : {
"token" :
"GkZl5NLRZJl5+jqChouaZ9CYjgE58W/pMccR+LeXmdO0obG9NB
Iwo1VBo7+YC1oiJL9mS6I9qh62BkX+Xddhe0JYrTmSG4JcKZ4t3
bcP2Mxy3VBmgoJjwZ76ZOuf9V9AD6Xl83lyoR4bLBzqbSSU1R2N
IgUotCGWjZt5JX6CJF0=",
"refreshTimeoutSeconds" : "300",
"lastName" : "Washington",
"firstName" : "George"
},
"children" : [{
...
...
}
We want to fetch the value for the “token” attribute as it is the value which is required to perform any other API calls to the device.
Since the response is a JSON response, we shall find out the JsonPath for the “token” attribute. The JsonPath is similar to xPath where we traverse the element from the parent element. The JsonPath for the “token” attribute in above response will be:
JsonPath: $.imdata[0].aaaLogin.attributes.token
We can define the output inside the Generic API task as below:
Using xPath or JsonPath built-in filtering capability
xPath and JsonPath provides some in-built filtering capability. We can define the xPath or JsonPath of an element and provide some filtering criteria as well.
For example, let’s say an API execution results in a JSON response having list of employee details.
Response:
[
{
'name': 'John',
'address1': null,
'empId': 10,
'salary': 0.0
},
{
'name': 'George',
'address1': null,
'empId': 11,
'salary': 0.0
},
{
'name': Frank',
'address1': null,
'empId': 12,
'salary': 0.0
}
]
We want to output the employee id of the employee with employee name “Frank”.
The following JsonPath expression will help find out the employee object in the above response and provide the required employee id:
$.[?(@.name=="Frank")].empId
We can than define the task output with above JsonPath expression:
NOTE: If in case there are multiple employees with name “Frank”, the output will be a comma separated Employee IDs of the employees with name as “Frank”. Example: [13, 14, 20]
Similar to above example, we can use xPath filtering capabilities as well to filter XML response and output the desired node/element value from the response.
User can define variables inside a task definition using following format:
@{INPUT VARIABLE} For e.g. @{Username}, @{Employee Name}
Variables can be used in following places:
User can define variables inside the API path which will form the URL for the API call. These variables become task input. The API Path is evaluated during task execution.
User can define variables inside the request body content. These variables become task Input. The body content is evaluated during the task execution.
User can define variables inside the output xPath or JsonPath expression. These variables become task input. The output path is evaluated during task execution and used to find required output from XML or JSON response.
These variables will become task input and the values for the same can be fed either as a mapped input or task input.
Examples for defining variables in various sections
Let’s say we need to execute an API available at following URL:
https://[IP]:[Port]/getEmployeeDetails/[Employee ID]
Now since we want to be able to execute this API for different values of employee ID, we would need the employee id as a variable and should be able to provide the value at run time.
The IP Address and Port values are also required but can be static in nature.
We can define the above API structure using the Generic API task in below manner –
The @{Employee_ID} notation will create a task input named Employee_ID and now we can map the input to either WF input or define the value statically as task input.
Most of the HTTP API calls requires a body content to be sent as a payload. The payload contains the information required to perform the operation (Post, Put etc.).
Let’s take an example of getting a session id information from UCS Manager which can further be used as a parameter to perform other operation.
The API Path required to get session id is /nuova. The request content which need to be sent to the URL is:
<aaaLogin inName= [User Name] inPassword= [Password] />
Below is the API structure defined using Generic API Task to perform the above operation:
<aaaLogin inName= @{User_Name} inPassword= @{Password.encrypt} />
Here the variables defined using User_Name and Password becomes the task input and the values can be provided either statically or as mapped input.
The .encrypt keyword can be used to make sure the generated task input type for the defined variable is password and will not be visible inside the task or during execution of the task.
By default the generated task input type for the defined variables is generic text.
For managed devices in UCSD, the above request content can also be defined using below keywords:
<aaaLogin inName= @{Account.username} inPassword= @{Account.password} />
OR
<aaaLogin inName= @{CredPolicy.username} inPassword= @{CredPolicy.password} />
The @{Account.username} and @{Account.password} keywords can be used to provide information from an already managed account in UCSD. The generic API task fetches the information internally for the selected account and use the same during API execution. These keywords don’t become task input, as values are fetched internally within UCSD.
The @{CredPolicy.username} and @{CredPolicy.password} keywords can be used if user wants to provide credential information from a credential policy defined inside UCSD. This can be used for devices which are not managed by UCSD but credential information is fed from the credential policy within UCSD. These keywords also don’t become task input as values are fetched internally within UCSD.
There are certain situations where we want to use variables inside the xPath or the JsonPath of the element value which we want from the response. For example, let’s take the same example as above where an API execution results in a JSON response having list of employee details.
Response:
[
{
'name': 'John',
'address1': null,
'empId': 10,
'salary': 0.0
},
{
'name': 'George',
'address1': null,
'empId': 11,
'salary': 0.0
},
{
'name': Frank',
'address1': null,
'empId': 12,
'salary': 0.0
}
]
Now we want to output the employee ID of an employee with a particular name. As we saw in above examples, the JsonPath to find out the same will be:
$.[?(@.name=="Frank")].empId
But let’s say the employee name is a variable and we want to provide employee name at run time and want the employee Id for the same as task output.
Generic API task allows us to define variables inside the output path definition as well. We can define variable using @{Variable_Name} notation.
In above example, the JsonPath to find employee Id for a variable employee name would become like:
$.[?(@.name=="@{Employee_Name}")].empId
The variable Employee_Name will become a task input and can get value as a task input or a mapped input. The variable value will be evaluated at runtime during task execution and then the JsonPath will be evaluated based on the JSON Response. Finally the evaluated JsonPath value will be outputted as task output.
Similar variable usage is possible inside xPath definition as well while defining the output of the Generic API task.
Any HTTP/HTTPs based API execution may require some information present inside the HTTP header.
Generic API task allows user to define the header names required for API execution. All the header parameters become task input automatically and can get value statically or as a mapped input during run time.
In situations where the header value might require some fixed and some variable part, we can use the normal dollar variable ($) concept to define the value for the particular header.
For example, in the below screenshot, there are two headers parameters required for API Execution:
Both these header parameters will automatically become task input and the values can be provided either statically or as a mapped input.
Now let’s say the value required the Cookie parameter is of following format:
X-Device-Token=[TOKEN_VALUE]
Here the X-Device-Token is a fixed part and TOKEN_VALUE is a value which can be a variable. In order to define this value for the “Cookie” task input, we can use dollar variable to provide a fixed value and at the same time define a variable value:
In certain situations, API execution may require authentication parameters to be passed using HTTP basic authentication method.
HTTP Basic Authentication is a standard way to authenticate clients with server. The authentication information is passed using an “Authorization” header parameter that contains the word Basic
word followed by a space and a base64-encoded string username:password.
Generic API task allows user to define basic authentication mechanism in following ways:
In this case, two task inputs are auto-generated (Auth_Username and Auth_Password) and user can provide the required values as task input or mapped input.
NOTE: Generic API task automatically adds the required header for HTTP Basic authentication (Authorization) with required formatted value while making the API call. User don’t need to define this header manually.
Generic API Task, like any other task in UCSD, also provides a way to define rollback. The rollback can be defined in two ways:
Thats sounds cool actually, but I let the BU answer this one. I suspect since this task is very special and autogenerates input from your variables it has to record that some how in the DB and hence the task is not clonable in the workflow editor and is not cleanly clonable in the custom task section.
call this from cloupia-script would be a great solution to avoid having to encode https/basic-auth-stuff in javascript within a custom task.
Might be off-topic, but any other "elegant" solution to call a set of rest-api-calls with dynamically generated urls/parameters?
Find answers to your questions by entering keywords or phrases in the Search bar above. New here? Use these resources to familiarize yourself with the community: