09-30-2017 05:11 AM - edited 03-01-2019 06:47 AM
Task Name |
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 |
|
Category | Workflow |
Components | |
User Inputs | |
Output |
Instructions for Regular Workflow Use:
DNA Center has a ticket/token based authentication and many thanks go out to Russ W. for all the help.
The workflow:
Workflow task inputs:
The workflow run:
The input / output variables:
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:
Custom Tasks:
Workflow with JSON Parser Task:
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"];
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: