cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
5933
Views
1
Helpful
0
Comments
Orf Gelbrich
Cisco Employee
Cisco Employee
Task Name


1) Get DNA 1.0 Center Ticket

2) Make GET API call to DNA 1.0 Center

3) Get DNA 1.1 Center Tickewt

4) Make GET API call to DNA 1.1 Center


Description
Prerequisites
  1. Tested on 6.5
CategoryWorkflow
Components
User Inputs
Output

Instructions for Regular Workflow Use:

  1. Download the attached .ZIP file below to your computer. *Remember the location of the saved file on your computer.
  2. Unzip the file on your computer. Should end up with a .WFD file.
  3. Log in to UCS Director as a user that has "system-admin" privileges.
  4. Navigate to "Policies-->Orchestration" and click on "Import".
  5. Click "Browse" and navigate to the location on your computer where the .WFD file resides. Choose the .WFD file and click "Open".
  6. Click "Upload" and then "OK" once the file upload is completed. Then click "Next".
  7. Click the "Select" button next to "Import Workflows". Click the "Check All" button to check all checkboxes and then the "Select" button.
  8. Click "Submit".
  9. A new folder should appear in "Policies-->Orchestration" that contains the imported workflow. You will now need to update the included tasks with information about the specific environment.

DNA Center has a ticket/token based authentication and many thanks go out to Russ W. for all the help.

The workflow:

Screen Shot 2017-09-30 at 7.08.11 AM.png

Workflow task inputs:

Screen Shot 2017-09-30 at 7.17.27 AM.png

Screen Shot 2017-09-30 at 7.17.13 AM.png

The workflow run:

Screen Shot 2017-09-30 at 7.03.34 AM.png

The input / output variables:

Screen Shot 2017-09-30 at 7.03.14 AM.png

The GET ticket code:

importPackage(java.util);

importPackage(java.lang);

importPackage(java.io);

importPackage(com.cloupia.lib.util);

importPackage(org.apache.commons.httpclient);

importPackage(org.apache.commons.httpclient.cookie);

importPackage(org.apache.commons.httpclient.methods);

importPackage(org.apache.commons.httpclient.auth);

importPackage(org.apache.commons.httpclient.protocol);

importClass(org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory);

importPackage(com.cloupia.lib.cIaaS.vcd.api);

importPackage(com.google.gson);

/****************************************************************************************/

/**                                                                                    **/

/**                           !!! IMPORTANT NOTE !!!                                   **/

/**                                                                                    **/

/**                                                                                    **/

/**         THIS SCRIPT REQUIRES A MINIMUM UCS DIRECTOR VERSION OF 5.4.0.0             **/

/**                                                                                    **/

/****************************************************************************************/

//----------------------------------------------------------------------------------------

//

//        Author: Russ Whitear (rwhitear@cisco.com)

//

// Workflow Task Name: HTTP_Function_v3_5.4.0.0

//

//            Version: 3.0

//

//            Updates: SSL Socket Factory modified for JDK8.

//

//      Modifications: Script now retrieves the network comment field from within the

//                     Infoblox token message response.

//

//             Inputs: none.

//

//            Outputs: none.

//

//----------------------------------------------------------------------------------------

//----------------------------------------------------------------------------------------

//                                 ### FUNCTIONS ###

//----------------------------------------------------------------------------------------

//----------------------------------------------------------------------------------------

//

//        Author: Russ Whitear (rwhitear@cisco.com)

//

// Function Name: httpRequest()

//

//       Version: 3.0

//

// Modifications: Added HTTP header Connection:close to execute method to overcome the

//                CLOSE_WAIT issue caused with releaseConnection().

//

//                Modified SSL socket factory code to work with UCS Director 5.4.0.0.

//

//   Description: HTTP Request function - httpRequest.

//

//                I have made the httpClient functionality more object like in order to

//                make cloupia scripts more readable when making many/multiple HTTP/HTTPS

//                requests within a single script.

//

//      Usage: 1. var request = new httpRequest();                   // Create new object.

//           

//             2. request.setup("192.168.10.10","https","admin","cisco123");      // SSL.

//          or:   request.setup("192.168.10.10","http","admin","cisco123");       // HTTP.

//          or:   request.setup("192.168.10.10","https");           // SSL, no basicAuth.

//          or:   request.setup("192.168.10.10","http");            // HTTP, no basicAuth.

//

//             3. request.getRequest("/");                    // HTTP GET (URI).

//          or:   request.postRequest("/","some body text");  // HTTP POST (URI,BodyText).

//          or:   request.deleteRequest("/");                 // HTTP DELETE (URI).

//

//  (optional) 4. request.contentType("json");            // Add Content-Type HTTP header.

//          or:   request.contentType("xml");

//

//  (optional) 5. request.addHeader("X-Cloupia-Request-Key","1234567890");  // Any Header.

//

//             6. var statusCode = request.execute();                     // Send request.

//

//             7. var response = request.getResponse("asString");   // Response as string.

//          or:   var response = request.getResponse("asStream");   // Response as stream.

//

//             8. request.disconnect();                             // Release connection.

//

//

//          Note: Be sure to add these lines to the top of your script:

//

//          importPackage(java.util);

//          importPackage(com.cloupia.lib.util);

//          importPackage(org.apache.commons.httpclient);

//          importPackage(org.apache.commons.httpclient.cookie);

//          importPackage(org.apache.commons.httpclient.methods);

//          importPackage(org.apache.commons.httpclient.auth);

//          importPackage(org.apache.commons.httpclient.protocol);

//          importClass(org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory);

//          importPackage(com.cloupia.lib.cIaaS.vcd.api);

//

//----------------------------------------------------------------------------------------

var httpRequest = function () {};

httpRequest.prototype.setup = function(serverIp, transport, username, password) {

    this.serverIp = serverIp;

    this.transport = transport;

    this.username = username;

    this.password = password;

    this.httpClient = new HttpClient();

    // Decide whether to create an HTTP or HTTPS connection based up 'transport'.

    if( this.transport == "https" ) {

this.httpClient = CustomEasySSLSocketFactory.getIgnoreSSLClient(this.serverIp, 443);

this.httpClient.getParams().setCookiePolicy("default");

    } else {

        // Create new HTTP connection.

        this.httpClient.getHostConfiguration().setHost(this.serverIp, 80, "http");  

    }

    this.httpClient.getParams().setCookiePolicy("default");

    // If username and password supplied, then use basicAuth.

    if( this.username && this.password ) {

        this.httpClient.getParams().setAuthenticationPreemptive(true);

        this.defaultcreds = new UsernamePasswordCredentials(this.username, this.password);

        this.httpClient.getState().setCredentials(new AuthScope(this.serverIp, -1, null), this.defaultcreds);

    }

};

httpRequest.prototype.contentType = function(contentType) {

    this.contentType = contentType;

    this.contentTypes = [

        ["xml","application/xml"],

        ["json","application/json"]

    ];

    for( this.i=0; this.i<this.contentTypes.length; this.i++)

        if(this.contentTypes[this.i][0] == this.contentType)

            this.httpMethod.addRequestHeader("Content-Type", this.contentTypes[this.i][1]);

};

httpRequest.prototype.addHeader = function(headerName,headerValue) {

    this.headerName = headerName;

    this.headerValue = headerValue;

    this.httpMethod.addRequestHeader(this.headerName, this.headerValue);

};

httpRequest.prototype.execute = function() {

    // Connection:close is hard coded here in order to ensure that the TCP connection

    // gets torn down immediately after the request. Comment this line out if you wish to

    // experiment with HTTP persistence.

    this.httpMethod.addRequestHeader("Connection", "close");

    this.httpClient.executeMethod(this.httpMethod);

    // Retrieve status code.

    this.statusCode = this.httpMethod.getStatusCode();

    return this.statusCode;

}

httpRequest.prototype.getRequest = function(uri) {

    this.uri = uri;

    // Get request.

    this.httpMethod = new GetMethod(this.uri);

};

httpRequest.prototype.postRequest = function(uri,bodytext) {

    this.uri = uri;

    this.bodytext = bodytext;

    // POST Request.

    this.httpMethod = new PostMethod(this.uri);

    this.httpMethod.setRequestEntity(new StringRequestEntity(this.bodytext));

};

httpRequest.prototype.getResponse = function(asType) {

    this.asType = asType;

    if( this.asType == "asStream" )

        return this.httpMethod.getResponseBodyAsStream();

    else

        return this.httpMethod.getResponseBodyAsString();

};

httpRequest.prototype.deleteRequest = function(uri) {

    this.uri = uri;

    // Get request.

    this.httpMethod = new DeleteMethod(this.uri);

};

httpRequest.prototype.disconnect = function() {

    // Release connection.

    this.httpMethod.releaseConnection();

};

// main();

var apicem_ip = input.DNACenterIP;

var username = input.USER;

var password = input.PASSWORD;

var version = input.VERSION;

var bodytext = "{ \"username\": \""+username+"\", \"password\": \""+password+"\" }";

//logger.addInfo("bodytext: " + bodytext );

var request = new httpRequest();

request.setup( apicem_ip ,"https");

request.postRequest("/api/"+version+"/ticket", bodytext );

request.contentType("json");

var statusCode = request.execute();

var response = request.getResponse("asString");

logger.addInfo("Status Code: " + statusCode );

logger.addInfo("Response data: " + response );

request.disconnect();  

// Parse the response for the service ticket...

var parser = new JsonParser();

var jsonTree = parser.parse(response);

logger.addInfo("jsonTree - JSON Object: " + jsonTree.isJsonObject());

var jsonObj = jsonTree.getAsJsonObject();

var serviceTicketObj = jsonObj.get("response").get("serviceTicket");

logger.addInfo("Service Ticket: " + serviceTicketObj.toString());

var a=serviceTicketObj.toString();

logger.addInfo("a = " + a);

var b=a.replace(/["']/g, "");

logger.addInfo("b= "+b);

output.TICKET = b;

The GET API call code:

importPackage(java.util);

importPackage(java.lang);

importPackage(java.io);

importPackage(com.cloupia.lib.util);

importPackage(org.apache.commons.httpclient);

importPackage(org.apache.commons.httpclient.cookie);

importPackage(org.apache.commons.httpclient.methods);

importPackage(org.apache.commons.httpclient.auth);

importPackage(org.apache.commons.httpclient.protocol);

importClass(org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory);

importPackage(com.cloupia.lib.cIaaS.vcd.api);

importPackage(com.google.gson);

/****************************************************************************************/

/**                                                                                    **/

/**                           !!! IMPORTANT NOTE !!!                                   **/

/**                                                                                    **/

/**                                                                                    **/

/**         THIS SCRIPT REQUIRES A MINIMUM UCS DIRECTOR VERSION OF 5.4.0.0             **/

/**                                                                                    **/

/****************************************************************************************/

//----------------------------------------------------------------------------------------

//

//        Author: Russ Whitear (rwhitear@cisco.com)

//

// Workflow Task Name: HTTP_Function_v3_5.4.0.0

//

//            Version: 3.0

//

//            Updates: SSL Socket Factory modified for JDK8.

//

//      Modifications: Script now retrieves the network comment field from within the

//                     Infoblox token message response.

//

//             Inputs: none.

//

//            Outputs: none.

//

//----------------------------------------------------------------------------------------

//----------------------------------------------------------------------------------------

//                                 ### FUNCTIONS ###

//----------------------------------------------------------------------------------------

//----------------------------------------------------------------------------------------

//

//        Author: Russ Whitear (rwhitear@cisco.com)

//

// Function Name: httpRequest()

//

//       Version: 3.0

//

// Modifications: Added HTTP header Connection:close to execute method to overcome the

//                CLOSE_WAIT issue caused with releaseConnection().

//

//                Modified SSL socket factory code to work with UCS Director 5.4.0.0.

//

//   Description: HTTP Request function - httpRequest.

//

//                I have made the httpClient functionality more object like in order to

//                make cloupia scripts more readable when making many/multiple HTTP/HTTPS

//                requests within a single script.

//

//      Usage: 1. var request = new httpRequest();                   // Create new object.

//      

//             2. request.setup("192.168.10.10","https","admin","cisco123");      // SSL.

//          or:   request.setup("192.168.10.10","http","admin","cisco123");       // HTTP.

//          or:   request.setup("192.168.10.10","https");           // SSL, no basicAuth.

//          or:   request.setup("192.168.10.10","http");            // HTTP, no basicAuth.

//

//             3. request.getRequest("/");                    // HTTP GET (URI).

//          or:   request.postRequest("/","some body text");  // HTTP POST (URI,BodyText).

//          or:   request.deleteRequest("/");                 // HTTP DELETE (URI).

//

//  (optional) 4. request.contentType("json");            // Add Content-Type HTTP header.

//          or:   request.contentType("xml");

//

//  (optional) 5. request.addHeader("X-Cloupia-Request-Key","1234567890");  // Any Header.

//

//             6. var statusCode = request.execute();                     // Send request.

//

//             7. var response = request.getResponse("asString");   // Response as string.

//          or:   var response = request.getResponse("asStream");   // Response as stream.

//

//             8. request.disconnect();                             // Release connection.

//

//

//          Note: Be sure to add these lines to the top of your script:

//

//          importPackage(java.util);

//          importPackage(com.cloupia.lib.util);

//          importPackage(org.apache.commons.httpclient);

//          importPackage(org.apache.commons.httpclient.cookie);

//          importPackage(org.apache.commons.httpclient.methods);

//          importPackage(org.apache.commons.httpclient.auth);

//          importPackage(org.apache.commons.httpclient.protocol);

//          importClass(org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory);

//          importPackage(com.cloupia.lib.cIaaS.vcd.api);

//

//----------------------------------------------------------------------------------------

var httpRequest = function () {};

httpRequest.prototype.setup = function(serverIp, transport, username, password) {

    this.serverIp = serverIp;

    this.transport = transport;

    this.username = username;

    this.password = password;

    this.httpClient = new HttpClient();

    // Decide whether to create an HTTP or HTTPS connection based up 'transport'.

    if( this.transport == "https" ) {

this.httpClient = CustomEasySSLSocketFactory.getIgnoreSSLClient(this.serverIp, 443);

this.httpClient.getParams().setCookiePolicy("default");

    } else {

        // Create new HTTP connection.

        this.httpClient.getHostConfiguration().setHost(this.serverIp, 80, "http");

    }

    this.httpClient.getParams().setCookiePolicy("default");

    // If username and password supplied, then use basicAuth.

    if( this.username && this.password ) {

        this.httpClient.getParams().setAuthenticationPreemptive(true);

        this.defaultcreds = new UsernamePasswordCredentials(this.username, this.password);

        this.httpClient.getState().setCredentials(new AuthScope(this.serverIp, -1, null), this.defaultcreds);

    }

};

httpRequest.prototype.contentType = function(contentType) {

    this.contentType = contentType;

    this.contentTypes = [

        ["xml","application/xml"],

        ["json","application/json"]

    ];

    for( this.i=0; this.i<this.contentTypes.length; this.i++)

        if(this.contentTypes[this.i][0] == this.contentType)

            this.httpMethod.addRequestHeader("Content-Type", this.contentTypes[this.i][1]);

};

httpRequest.prototype.addHeader = function(headerName,headerValue) {

    this.headerName = headerName;

    this.headerValue = headerValue;

    this.httpMethod.addRequestHeader(this.headerName, this.headerValue);

};

httpRequest.prototype.execute = function() {

    // Connection:close is hard coded here in order to ensure that the TCP connection

    // gets torn down immediately after the request. Comment this line out if you wish to

    // experiment with HTTP persistence.

    this.httpMethod.addRequestHeader("Connection", "close");

    this.httpClient.executeMethod(this.httpMethod);

    // Retrieve status code.

    this.statusCode = this.httpMethod.getStatusCode();

    return this.statusCode;

}

httpRequest.prototype.getRequest = function(uri) {

    this.uri = uri;

    // Get request.

    this.httpMethod = new GetMethod(this.uri);

};

httpRequest.prototype.postRequest = function(uri,bodytext) {

    this.uri = uri;

    this.bodytext = bodytext;

    // POST Request.

    this.httpMethod = new PostMethod(this.uri);

    this.httpMethod.setRequestEntity(new StringRequestEntity(this.bodytext));

};

httpRequest.prototype.getResponse = function(asType) {

    this.asType = asType;

    if( this.asType == "asStream" )

        return this.httpMethod.getResponseBodyAsStream();

    else

        return this.httpMethod.getResponseBodyAsString();

};

httpRequest.prototype.deleteRequest = function(uri) {

    this.uri = uri;

    // Get request.

    this.httpMethod = new DeleteMethod(this.uri);

};

httpRequest.prototype.disconnect = function() {

    // Release connection.

    this.httpMethod.releaseConnection();

};

// main();

var apicem_ip = input.DNACenterIP;

//var username = "admin";

//var password = "blabla";

var version = input.VERSION;

//var bodytext = "{ \"username\": \""+username+"\", \"password\": \""+password+"\" }";

//logger.addInfo("bodytext: " + bodytext );

//var request = new httpRequest();

//request.setup( apicem_ip ,"https");

//request.postRequest("/api/"+version+"/ticket", bodytext );

//request.contentType("json");

//var statusCode = request.execute();

//var response = request.getResponse("asString");

//logger.addInfo("Status Code: " + statusCode );

//logger.addInfo("Response data: " + response );

//request.disconnect();

// Parse the response for the service ticket...

//var parser = new JsonParser();

//var jsonTree = parser.parse(response);

//logger.addInfo("jsonTree - JSON Object: " + jsonTree.isJsonObject());

//var jsonObj = jsonTree.getAsJsonObject();

//var serviceTicketObj = jsonObj.get("response").get("serviceTicket");

//logger.addInfo("Service Ticket: " + serviceTicketObj.toString());

//var a=serviceTicketObj.toString();

//logger.addInfo("a = " + a);

//var b=a.replace(/["']/g, "");

//logger.addInfo("b= "+b);

//headers = {"content-type" : "application/json","X-Auth-Token": ticket}

//var bodytext = "{\"content-type\" : \"application/json\",\"X-Auth-Token\": \""+b+"\" }";

//var bodytext = "{\"X-Auth-Token\": \""+b+"\" }";

var bodytext = "";

//logger.addInfo("Body = "+bodytext);

var request = new httpRequest();

request.setup( apicem_ip ,"https");

//request.postRequest("/api/"+version+"/network-device", bodytext );

//request.getRequest("/api/"+version+"/network-device", bodytext );

request.getRequest("/api/"+version+input.API, bodytext );

request.contentType("json");

var b=input.TICKET;

request.addHeader("X-Auth-Token",b);

var statusCode = request.execute();

var response = request.getResponse("asString");

logger.addInfo("Status Code: " + statusCode );

logger.addInfo("Response data: " + response );

request.disconnect();

output.RESULT = response;

The Log:

Service Request ID: 461

-------------------------------------

Sep 30, 2017 12:01:33 UTC Request submitted

Sep 30, 2017 12:01:35 UTC Executing workflow item number 1

Sep 30, 2017 12:01:35 UTC Completed workflow item number 1, with status Completed

Sep 30, 2017 12:01:41 UTC Executing workflow item number 2

Sep 30, 2017 12:01:41 UTC Trigger context executeWorkFlowStep called

Sep 30, 2017 12:01:41 UTC Executing custom action DNA Center GET API Example (custom_DNACenterGetTicket)

Sep 30, 2017 12:01:41 UTC Executing custom action DNA Center GET API Example (custom_DNACenterGetTicket)

Sep 30, 2017 12:01:41 UTC Executing custom script for DNACenterGetTicket

Sep 30, 2017 12:01:41 UTC Status Code: 200

Sep 30, 2017 12:01:41 UTC Response data: {'response':{'serviceTicket':'ST-32-SWCclW9mch72oFRTiaED-cas','idleTimeout':1800,'sessionTimeout':21600},'version':'1.0'}

Sep 30, 2017 12:01:41 UTC jsonTree - JSON Object: true

Sep 30, 2017 12:01:41 UTC Service Ticket: 'ST-32-SWCclW9mch72oFRTiaED-cas'

Sep 30, 2017 12:01:41 UTC a = 'ST-32-SWCclW9mch72oFRTiaED-cas'

Sep 30, 2017 12:01:41 UTC b= ST-32-SWCclW9mch72oFRTiaED-cas

Sep 30, 2017 12:01:41 UTC Processing output: TICKET

Sep 30, 2017 12:01:42 UTC Task #2 (DNA Center GET API Example (custom_DNACenterGetTicket)) completed successfully in 0 seconds

Sep 30, 2017 12:01:42 UTC Input/Output values for Task #2 (DNA Center GET API Example (custom_DNACenterGetTicket)):

Sep 30, 2017 12:01:42 UTC [Local Input: DNACenterIP = 172.16.50.57]

Sep 30, 2017 12:01:42 UTC [Local Input: USER = admin]

Sep 30, 2017 12:01:42 UTC [Local Input: PASSWORD = **masked-value**]

Sep 30, 2017 12:01:42 UTC [Local Input: VERSION = v1]

Sep 30, 2017 12:01:42 UTC [Output: TICKET = ST-32-SWCclW9mch72oFRTiaED-cas]

Sep 30, 2017 12:01:42 UTC Completed workflow item number 2, with status Completed

Sep 30, 2017 12:01:47 UTC Executing workflow item number 3

Sep 30, 2017 12:01:47 UTC Trigger context executeWorkFlowStep called

Sep 30, 2017 12:01:47 UTC Executing custom action DNA Center GET API Example (custom_DNACenterGET)

Sep 30, 2017 12:01:47 UTC Executing custom action DNA Center GET API Example (custom_DNACenterGET)

Sep 30, 2017 12:01:47 UTC Executing custom script for DNACenterGET

Sep 30, 2017 12:01:47 UTC Status Code: 200

Sep 30, 2017 12:01:47 UTC Response data: {'items':[{'attributes':{'id':131164,'instanceUuid':'679ef7f5-1709-417a-ad8a-c721e8f752b0','name':'AP2c54.2d60.235d','macaddress':'2c:54:2d:60:23:5d','type':27,'typeString':'AP3600I','mode':0,'model':'AIR-CAP3602I-N-K9','wlc':'','locationGroup':null,'domain':null,'owningEntity':'125131_125131','mneId':131158,'generatesCoverageHeatmap':null,'generatesIdsHeatmap':null,'lastUpdated':null},'location':{'lattitude':null,'longtitude':null,'altitude':null},'position':{'x':-1.0,'y':-1.0,'z':10.0},'metrics':{'adminStatus':'up','opStatus':'up','dot11aClientCount':0,'dot11bClientCount':0,'alarmsCount':null,'controllerIpAddress':'172.16.50.58','softwareVersion':'8.5.103.0','productTypeString':'Cisco Virtual Wireless LAN Controller'},'radios':null,'status':null,'errorType':null,'errorMessage':null},{'attributes':{'id':131163,'instanceUuid':'3fa73c1f-e12f-4c94-9c65-2106f3211809','name':'AP30f7.0d28.fe29','macaddress':'30:f7:0d:28:fe:29','type':27,'typeString':'AP3600I','mode':0,'model':'AIR-CAP3602I-N-K9','wlc':'','locationGroup':null,'domain':null,'owningEntity':'125131_125131','mneId':131158,'generatesCoverageHeatmap':null,'generatesIdsHeatmap':null,'lastUpdated':null},'location':{'lattitude':null,'longtitude':null,'altitude':null},'position':{'x':-1.0,'y':-1.0,'z':10.0},'metrics':{'adminStatus':'up','opStatus':'up','dot11aClientCount':0,'dot11bClientCount':0,'alarmsCount':null,'controllerIpAddress':'172.16.50.58','softwareVersion':'8.5.103.0','productTypeString':'Cisco Virtual Wireless LAN Controller'},'radios':null,'status':null,'errorType':null,'errorMessage':null},{'attributes':{'id':131161,'instanceUuid':'423d184c-d556-4797-9af7-38680586c254','name':'AP30f7.0d28.ff05','macaddress':'30:f7:0d:28:ff:05','type':27,'typeString':'AP3600I','mode':0,'model':'AIR-CAP3602I-N-K9','wlc':'','locationGroup':null,'domain':null,'owningEntity':'125131_125131','mneId':131158,'generatesCoverageHeatmap':null,'generatesIdsHeatmap':null,'lastUpdated':null},'location':{'lattitude':null,'longtitude':null,'altitude':null},'position':{'x':-1.0,'y':-1.0,'z':10.0},'metrics':{'adminStatus':'up','opStatus':'up','dot11aClientCount':0,'dot11bClientCount':0,'alarmsCount':null,'controllerIpAddress':'172.16.50.58','softwareVersion':'8.5.103.0','productTypeString':'Cisco Virtual Wireless LAN Controller'},'radios':null,'status':null,'errorType':null,'errorMessage':null}],'total':3}

Sep 30, 2017 12:01:47 UTC Processing output: RESULT

Sep 30, 2017 12:01:48 UTC Task #3 (DNA Center GET API Example (custom_DNACenterGET)) completed successfully in 0 seconds

Sep 30, 2017 12:01:48 UTC Input/Output values for Task #3 (DNA Center GET API Example (custom_DNACenterGET)):

Sep 30, 2017 12:01:48 UTC [Mapped Input: TICKET = ST-32-SWCclW9mch72oFRTiaED-cas]

Sep 30, 2017 12:01:48 UTC [Local Input: API = /dna-maps-service/domains/root/aps]

Sep 30, 2017 12:01:48 UTC [Local Input: VERSION = v1]

Sep 30, 2017 12:01:48 UTC [Local Input: DNACenterIP = 172.16.50.57]

Sep 30, 2017 12:01:48 UTC [Output: RESULT = {'items':[{'attributes':{'id':131164,'instanceUuid':'679ef7f5-1709-417a-ad8a-c721e8f752b0','name':'AP2c54.2d60.235d','macaddress':'2c:54:2d:60:23:5d','type':27,'typeString':'AP3600I','mode':0,'model':'AIR-CAP3602I-N-K9','wlc':'','locationGroup':null,'domain':null,'owningEntity':'125131_125131','mneId':131158,'generatesCoverageHeatmap':null,'generatesIdsHeatmap':null,'lastUpdated':null},'location':{'lattitude':null,'longtitude':null,'altitude':null},'position':{'x':-1.0,'y':-1.0,'z':10.0},'metrics':{'adminStatus':'up','opStatus':'up','dot11aClientCount':0,'dot11bClientCount':0,'alarmsCount':null,'controllerIpAddress':'172.16.50.58','softwareVersion':'8.5.103.0','productTypeString':'Cisco Virtual Wireless LAN Controller'},'radios':null,'status':null,'errorType':null,'errorMessage':null},{'attributes':{'id':131163,'instanceUuid':'3fa73c1f-e12f-4c94-9c65-2106f3211809','name':'AP30f7.0d28.fe29','macaddress':'30:f7:0d:28:fe:29','type':27,'typeString':'AP3600I','mode':0,'model':'AIR-CAP3602I-N-K9','wlc':'','locationGroup':null,'domain':null,'owningEntity':'125131_125131','mneId':131158,'generatesCoverageHeatmap':null,'generatesIdsHeatmap':null,'lastUpdated':null},'location':{'lattitude':null,'longtitude':null,'altitude':null},'position':{'x':-1.0,'y':-1.0,'z':10.0},'metrics':{'adminStatus':'up','opStatus':'up','dot11aClientCount':0,'dot11bClientCount':0,'alarmsCount':null,'controllerIpAddress':'172.16.50.58','softwareVersion':'8.5.103.0','productTypeString':'Cisco Virtual Wireless LAN Controller'},'radios':null,'status':null,'errorType':null,'errorMessage':null},{'attributes':{'id':131161,'instanceUuid':'423d184c-d556-4797-9af7-38680586c254','name':'AP30f7.0d28.ff05','macaddress':'30:f7:0d:28:ff:05','type':27,'typeString':'AP3600I','mode':0,'model':'AIR-CAP3602I-N-K9','wlc':'','locationGroup':null,'domain':null,'owningEntity':'125131_125131','mneId':131158,'generatesCoverageHeatmap':null,'generatesIdsHeatmap':null,'lastUpdated':null},'location':{'lattitude':null,'longtitude':null,'altitude':null},'position':{'x':-1.0,'y':-1.0,'z':10.0},'metrics':{'adminStatus':'up','opStatus':'up','dot11aClientCount':0,'dot11bClientCount':0,'alarmsCount':null,'controllerIpAddress':'172.16.50.58','softwareVersion':'8.5.103.0','productTypeString':'Cisco Virtual Wireless LAN Controller'},'radios':null,'status':null,'errorType':null,'errorMessage':null}],'total':3}]

Sep 30, 2017 12:01:48 UTC Completed workflow item number 3, with status Completed


The Workflow:

Screen Shot 2017-09-30 at 7.12.07 AM.png

Custom Tasks:

Screen Shot 2017-09-30 at 7.14.07 AM.png

Workflow with JSON Parser Task:

Screen Shot 2017-10-02 at 7.38.23 AM.png

In DNA Center 1.1 the ticket API was changed.  Below please find very ugly code to retrieve ticket:

importPackage(java.util);

importPackage(java.lang);

importPackage(java.io);

importPackage(com.cloupia.lib.util);

importPackage(org.apache.commons.httpclient);

importPackage(org.apache.commons.httpclient.cookie);

importPackage(org.apache.commons.httpclient.methods);

importPackage(org.apache.commons.httpclient.auth);

importPackage(org.apache.commons.httpclient.protocol);

importClass(org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory);

importPackage(com.cloupia.lib.cIaaS.vcd.api);

/****************************************************************************************/

/**                                                                                    **/

/**                           !!! IMPORTANT NOTE !!!                                   **/

/**                                                                                    **/

/**                                                                                    **/

/**         THIS SCRIPT REQUIRES A MINIMUM UCS DIRECTOR VERSION OF 5.4.0.0             **/

/**                                                                                    **/

/****************************************************************************************/

//----------------------------------------------------------------------------------------

//

//        Author: Russ Whitear (rwhitear@cisco.com)

//

// Workflow Task Name: Infoblox_Get_Next_Available_IP_v3_5.4.0.0

//

//            Version: 3.0

//

//            Updates: SSL Socket Factory modified for JDK8.

//

//      Modifications: Script now retrieves the network comment field from within the

//                     Infoblox token message response.

//

//             Inputs: ibUser         ;Infoblox username.

//                     ibPassword     ;Infoblox password.

//                     ibIP           ;Infoblox Grid Manager IP address.

//                     network        ;Network range to query (e.g. 192.168.55.0/24).

//

//            Outputs: INFOBLOX_NETWORK_COMMENT     ;Infoblox network comment field.

//                     NEXT_AVAILABLE_IP            ;Infoblox supplied next available IP.

//

//----------------------------------------------------------------------------------------

//----------------------------------------------------------------------------------------

//                                 ### FUNCTIONS ###

//----------------------------------------------------------------------------------------

//----------------------------------------------------------------------------------------

//

//        Author: Russ Whitear (rwhitear@cisco.com)

//

// Function Name: httpRequest()

//

//       Version: 3.0

//

// Modifications: Added HTTP header Connection:close to execute method to overcome the

//                CLOSE_WAIT issue caused with releaseConnection().

//

//                Modified SSL socket factory code to work with UCS Director 5.4.0.0.

//

//   Description: HTTP Request function - httpRequest.

//

//                I have made the httpClient functionality more object like in order to

//                make cloupia scripts more readable when making many/multiple HTTP/HTTPS

//                requests within a single script.

//

//      Usage: 1. var request = new httpRequest();                   // Create new object.

//               

//             2. request.setup("192.168.10.10","https","admin","cisco123");      // SSL.

//          or:   request.setup("192.168.10.10","http","admin","cisco123");       // HTTP.

//          or:   request.setup("192.168.10.10","https");           // SSL, no basicAuth.

//          or:   request.setup("192.168.10.10","http");            // HTTP, no basicAuth.

//

//             3. request.getRequest("/");                    // HTTP GET (URI).

//          or:   request.postRequest("/","some body text");  // HTTP POST (URI,BodyText).

//          or:   request.deleteRequest("/");                 // HTTP DELETE (URI).

//

//  (optional) 4. request.contentType("json");            // Add Content-Type HTTP header.

//          or:   request.contentType("xml");

//

//  (optional) 5. request.addHeader("X-Cloupia-Request-Key","1234567890");  // Any Header.

//

//             6. var statusCode = request.execute();                     // Send request.

//

//             7. var response = request.getResponse("asString");   // Response as string.

//          or:   var response = request.getResponse("asStream");   // Response as stream.

//

//             8. request.disconnect();                             // Release connection.

//

//

//          Note: Be sure to add these lines to the top of your script:

//

//          importPackage(java.util);

//          importPackage(com.cloupia.lib.util);

//          importPackage(org.apache.commons.httpclient);

//          importPackage(org.apache.commons.httpclient.cookie);

//          importPackage(org.apache.commons.httpclient.methods);

//          importPackage(org.apache.commons.httpclient.auth);

//          importPackage(org.apache.commons.httpclient.protocol);

//          importClass(org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory);

//          importPackage(com.cloupia.lib.cIaaS.vcd.api);

//

//----------------------------------------------------------------------------------------

var httpRequest = function () {};

httpRequest.prototype.setup = function(serverIp, transport, username, password) {

    this.serverIp = serverIp;

    this.transport = transport;

    this.username = username;

    this.password = password;

   

   

    this.httpClient = new HttpClient();

   

    // Decide whether to create an HTTP or HTTPS connection based up 'transport'.

    if( this.transport == "https" ) {  

this.httpClient = CustomEasySSLSocketFactory.getIgnoreSSLClient(this.serverIp, 443);

this.httpClient.getParams().setCookiePolicy("default");

    } else {

        // Create new HTTP connection.

        this.httpClient.getHostConfiguration().setHost(this.serverIp, 80, "http");      

    }

   

    this.httpClient.getParams().setCookiePolicy("default");

   

    // If username and password supplied, then use basicAuth.

    if( this.username && this.password ) {

        this.httpClient.getParams().setAuthenticationPreemptive(true);

        this.defaultcreds = new UsernamePasswordCredentials(this.username, this.password);

        this.httpClient.getState().setCredentials(new AuthScope(this.serverIp, -1, null), this.defaultcreds);

    }

};

httpRequest.prototype.contentType = function(contentType) {

    this.contentType = contentType;

   

    this.contentTypes = [

        ["xml","application/xml"],

        ["json","application/json"]

    ];

   

    for( this.i=0; this.i<this.contentTypes.length; this.i++)

        if(this.contentTypes[this.i][0] == this.contentType)

            this.httpMethod.addRequestHeader("Content-Type", this.contentTypes[this.i][1]);

};

httpRequest.prototype.addHeader = function(headerName,headerValue) {

    this.headerName = headerName;

    this.headerValue = headerValue;

   

    this.httpMethod.addRequestHeader(this.headerName, this.headerValue);

};

httpRequest.prototype.execute = function() {   

    // Connection:close is hard coded here in order to ensure that the TCP connection

    // gets torn down immediately after the request. Comment this line out if you wish to

    // experiment with HTTP persistence.

    this.httpMethod.addRequestHeader("Connection", "close");

   

    this.httpClient.executeMethod(this.httpMethod);

   

    // Retrieve status code.

    this.statusCode = this.httpMethod.getStatusCode();

   

    return this.statusCode;

}

httpRequest.prototype.getRequest = function(uri) {

    this.uri = uri;

    // Get request.

    this.httpMethod = new GetMethod(this.uri);

};

httpRequest.prototype.postRequest = function(uri,bodytext) {

    this.uri = uri;

    this.bodytext = bodytext;

   

    // POST Request.

    this.httpMethod = new PostMethod(this.uri);

    this.httpMethod.setRequestEntity(new StringRequestEntity(this.bodytext));

};

httpRequest.prototype.getResponse = function(asType) {

    this.asType = asType;

    if( this.asType == "asStream" )

        return this.httpMethod.getResponseBodyAsStream();

    else

        return this.httpMethod.getResponseBodyAsString();

};

httpRequest.prototype.deleteRequest = function(uri) {

    this.uri = uri;

    // Get request.

    this.httpMethod = new DeleteMethod(this.uri);

};

httpRequest.prototype.disconnect = function() {

    // Release connection.

    this.httpMethod.releaseConnection();

};

//----------------------------------------------------------------------------------------

//

//        Author: Russ Whitear (rwhitear@cisco.com)

//

// Function Name: getInfobloxNetworkToken(ibIP,ibUser,ibPassword,network)

//

//       Version: 1.1

//

// Modifications: v1.1; Also retrieve the comment field from the Infoblox network

//                      configuration for Orf.

//

//    Parameters: ibIP;         Infoblox Grid Manager management IP address.

//                ibUser;       Infoblox administrative username.

//                ibPassword;   Infoblox administrative password.

//                network;      Network range to request token for (e.g. 192.168.55.0/24)

//                              (Network range must exist on Grid Manager).

//

//       Returns: token;        Returns a valid token for the specified network to be used

//                              in subsequent API calls.

//       Returns: {

//                    "token":token,                   Returns Infoblox token and network

//                    "comment":netComment             comment field data.                         

//                };      

//

//      Requires: function httpRequest();

//               

//   Description: Request Infoblox token for querying network range.

//

//

//----------------------------------------------------------------------------------------

function getInfobloxNetworkToken(ibIP,ibUser,ibPassword,network) {

    this.ibIP = ibIP;

    this.ibUser = ibUser;

    this.ibPassword = ibPassword;

    this.network = network;

    var request = new httpRequest();

    request.setup(this.ibIP,"https",this.ibUser,this.ibPassword);

    request.postRequest('/api/system/v1/auth/token'+this.network);

    request.contentType("json");

    var statusCode = request.execute();

     

       

    if (statusCode != 200)

    {  

        logger.addError("Request failed. HTTP response code: "+statusCode);

   

        request.disconnect();

    

        // Set this task as failed.

        ctxt.setFailed("Request failed.");

    } else {

        var response = request.getResponse("asString");

        logger.addInfo("Response: " +response);

       

        var getResponse = new InputStreamReader(request.getResponse("asStream"));

   

        var jsonResponse = JSON.getJsonElement(getResponse, null);

  //  logger.addInfo("Response2: " +jsonResponse);

   // var refStr = jsonResponse.get(0).get("Token").getAsString();

        var refStr = jsonResponse.get("Token").getAsString();

       

        // Cast refStr as a string.

        var refStr = ""+refStr;

   

    //    var token = refStr.replace(/network\/(.*):.*/, "$1");

      var token = refStr;

   

        // Get comment field for Orf.

//       var netComment = jsonResponse.get(0).get("comment").getAsString();

       var netComment = "";

//       logger.addInfo("Comment: " +netComment);

        

        // All done. Release HTTP connection anyway.

        request.disconnect();

       

        //return token;

        return {"token":token,"comment":netComment};

    }

}

//----------------------------------------------------------------------------------------

//

//        Author: Russ Whitear (rwhitear@cisco.com)

//

// Function Name: InfobloxGetNextAvailableIp(ibIP,ibUser,ibPassword,network)

//

//       Version: 1.0

//

//    Parameters: ibIP;         Infoblox Grid Manager management IP address.

//                ibUser;       Infoblox administrative username.

//                ibPassword;   Infoblox administrative password.

//                network;      Network range to request token for (e.g. 192.168.55.0/24)

//                              (Network range must exist on Grid Manager).

//

//       Returns: {                                     Returns next available IP address

//                    "nextIp":nextIp,                  for network range.

//                    "ibNetComment":comment

//                };      

//

//      Requires: function getInfobloxNetworkToken();

//                function httpRequest();

//

//   Description: Request Infoblox token for querying network range.

//

//

//----------------------------------------------------------------------------------------

function InfobloxGetNextAvailableIp(ibIP,ibUser,ibPassword,network) {

    this.ibIP = ibIP;

    this.ibUser = ibUser;

    this.ibPassword = ibPassword;

    this.network = network;

    this.ibNetInfo = getInfobloxNetworkToken(this.ibIP,this.ibUser,this.ibPassword,this.network);

    this.token = ibNetInfo["token"];

   

//    var request = new httpRequest();

//

//    request.setup(this.ibIP,"https",this.ibUser,this.ibPassword);

//    request.postRequest('/wapi/v1.2/network/'+this.token+'?_function=next_available_ip', '{"num": 1}');

//    request.contentType("json");

//    var statusCode = request.execute();

//

//    if (statusCode != 200)

//    {  

//        logger.addError("Request failed. HTTP response code: "+statusCode);

//        logger.addError("Response = "+request.getResponse("asString"));

//

//        var response = request.getResponse("asString");

//        logger.addInfo("Response: " +response);

//       

//        request.disconnect(); 

//   

//        ctxt.setFailed("Request failed.");

//    } else {

//        var getResponse = new InputStreamReader(request.getResponse("asStream"));

//   

//        var resp = JSON.getJsonElement(getResponse, null);

//

//        resp = ""+resp;

//   

//        // {'ips':['192.168.55.2']}

//        var nextIp = resp.replace(/(.*[^0-9])([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)(.*)/, "$2" );

//

//        request.disconnect();

//        return {"nextIp":nextIp,"ibNetComment":ibNetInfo["comment"]};

   

        return {"Token":this.token};

//    }

}

//////////////////////////////////////////////////////////////////////////////////////////

//

// main();

//

//

// Workflow Inputs.

//

var ibUser = input.User;

var ibPassword = input.Password;

var ibIP = input.IP;

//var network = input.network;

//

//var ibUser = "admin";

//var ibPassword = "blabliblbla";

//var ibIP = "172.16.50.57";

var network = "";

//logger.addInfo("Retrieving next available Infoblox IP address for network [" +network+ "].");

var request = InfobloxGetNextAvailableIp(ibIP,ibUser,ibPassword,network);

//logger.addInfo("Next available IP: "+request["Token"]);

//output.INFOBLOX_NETWORK_COMMENT = request["ibNetComment"];

output.TOKEN = request["Token"];

Getting Started

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:

Quick Links