The documentation set for this product strives to use bias-free language. For the purposes of this documentation set, bias-free is defined as language that does not imply discrimination based on age, disability, gender, racial identity, ethnic identity, sexual orientation, socioeconomic status, and intersectionality. Exceptions may be present in the documentation due to language that is hardcoded in the user interfaces of the product software, language used based on RFP documentation, or language that is used by a referenced third-party product. Learn more about how Cisco is using Inclusive Language.
This chapter contains the following sections:
Print messages to the Service Request log.
You want to view the output log statements.
None
logger.addDebug(“About to process the user request”); logger.addInfo(“User “+ctxt.getUserId()+” has requested to provision this”); logger.addWarning(“Resource has reached maximum capacity.”); logger.addError(“Failed to provision the resource.”);
The messages that are passed to the logger object are printed.
No modifications required to implement this code.
Process a numeric input in a custom task.
The custom task must first be defined in Cisco UCS Director with a text or numeric input.
Custom task libraries are not required.
// Handle a number defined as a text input function handleNumbers() { var strInput = input.stringInput; var convertedCustomTaskStringInput = null; if(strInput != null) { // Use the Java Integer wrapper object convertedCustomTaskStringInput = new java.lang.Integer(strInput); logger.addInfo("convertedCustomTaskStringInput = " + convertedCustomTaskStringInput); } } handleNumbers(); // Handle a number defined as a numeric input function handleNumbers() { var strInput = input.Input * 2; var convertedCustomTaskStringInput = null; if(strInput != null) { // Use the java Integer wrapper object convertedCustomTaskStringInput = strInput; logger.addInfo("convertedCustomTaskStringInput = " + convertedCustomTaskStringInput); } } handleNumbers();
The script prints the input value to the log.
The implementation is straightforward: take the input variable from the custom task's built-in input object and provide it as an argument to the Java Integer wrapper object. If the given input is not a number, a NumberFormatException error is thrown that appears in the log.
Access a network device using SSH.
You want a custom task to log into a device (for example, a VM) using SSH and run a command on the device.
com.cloupia.lib.util.ssh.SSHClient - This API connects to a remote ssh server or device and executes a command, printing the result to standard out (stdout).
importPackage(com.cloupia.lib.util.ssh); importPackage(java.io); function testSSHClient() { var client = new SSHClient(input.ipAddress, 22, // 22 = SSH standard port input.userName, input.password); client.connect(); var session = client.openShell(511,25); // (511, 25) = (columns, rows) var shellStream = new PrintStream(session.getOutputStream()); shellStream.println(input.command); shellStream.flush(); client.disconnect(); } testSSHClient();
An SSH connection is opened and the command is sent to the remote device. The connection is then closed.
The client.openShell() method in the example code internally uses a thirdparty library API: com.maverick.ssh.SshSession.requestPseudoTerminal().
This script does not verify the result of the command. In fact, it does not open the session input stream at all, and simply disconnects after sending the command. You would obviously want to do more error checking if you implemented this script in production.
Connect the network device and send CLI commands.
You want to send the CLI command to the device.
The network device should have been added in UCS Director.
NetworkDeviceManager - This component accepts device details as an argument and establishes a connection to the device. After the connection is created, the user can manage the network device by sending the commands.
com.cloupia.lib.cIaaS.network.model.DeviceCredential - The ‘DeviceCredential’ API holds device details.
importPackage(com.cloupia.feature.networkController); importPackage(com.cloupia.feature.networkController.model); importPackage(com.cloupia.lib.cIaas.network.model); importPackage(com.cloupia.feature.networkController.collector); importPackage(com.cloupia.lib.util); var devCreds = NetworkPersistenceUtil.getDeviceCredential(dcName, devIP); var status = NetworkPersistenceUtil.getDeviceStatus(dcName, devIP); var device = NetworkDeviceManager.getDevice(devCreds); var failedMessages = new ArrayList(); var cmdAndOutputMsgs = new ArrayList(); var errCounter = new Counter(); var script = new CLIScript(); script.addLine("<cli command here>"); script.execute(device, errCounter, failedMessages, cmdAndOutputMsgs); // Log commands and their responses NetworkDBUtil.logCommandsAndResponses(actionLogger, devCreds, cmdAndOutputMsgs); // Append any exceptions to action logger NetworkDBUtil.logCommandExceptions(actionLogger, devCreds, errCounter, failedMessages);
The command is executed on the device and the command output is printed in the log.
No modifications required to implement this code.
Create a session object and access the Cisco UCS Director API.
You want to connect the device, a virtual account, or a physical account to send queries. To achieve this, you need to establish a connection to the account, which is called creating a session.
The virtual or physical account should be added in UCS Director.
NetAppSession - This API creates a session on the NetAPP device and sends XML commands to the device
NetAppAPI - This API obtains details about the NetApp device. The API has several built-in methods to obtain details and configure the NetApp device. For example, This API has the built-in method to obtain the 'InitiatorGroups.'
For NetApp
After the connection is established, you can send commands to the respective account.
The functions are defined in the Cisco UCS Director features. If required, they can be reused by accessing the feature API instead of redefining the same functions. Also, session objects are defined in Cisco UCS Director.
Access the existing Cisco UCS Director reports and filter the report data.
You want to obtain a report and filter the data in the report per requirements.
Report Name and Context are required to fetch the reports.
ctxt.getAPI().getConfigTableReport - This method returns the TabularReport object, which contains the report details.
ctxt.getAPI().getTabularReport - This method returns the TabularReport object, which contains the report details.
importPackage(com.cloupia.model.cIM); importPackage(com.cloupia.lib.util.managedreports); function getReport(reportContext, reportName) { var report = null; try { report = ctxt.getAPI().getConfigTableReport(reportContext, reportName); } catch(e) { } if (report == null) { return ctxt.getAPI().getTabularReport(reportName, reportContext); } else { var source = report.getSourceReport(); return ctxt.getAPI().getTabularReport (source, reportContext); } } function getReportView(reportContext, reportName) { var report = getReport(reportContext, reportName); if (report == null) { logger.addError("No such report exists for the specified context "+reportName); return null; } return new TableView(report); } function accessReports(){ //Refer the following code to create report context. var reportName="TABULAR_REPORT_PER_CLOUD_VMS_CONFIG_REPORT"; //To create a context, pass the values for arguments in the given order: type, cloudName, APIReportID. To get these values, click Report Metadata in the corresponding report. var repContext = new ReportContext( 1, "vmware109","VMS-T0" ); logger.addInfo("reportContext "+repContext); var report = getReportView(repContext, reportName); logger.addInfo("Report:"+report); //The report can be filtered by coloumns. //To retrieve the VMs in the ON power state, use the following line: report = report.filterRowsByColumn("Power State", "ON", false); var rowCnt = report.rowCount(); logger.addInfo("Number of powered on Vms: "+ rowCnt ); } accessReports();
The code fetches the VM report and filters the data according to the 'ON' Power State.
No modifications required to implement this code.
Access the delegate API by passing the namespace of delegate in the accessDelegateAPI method of APIProvider.java.
You want to access delegate APIs using namespace and perform further operations.
Namespace is required to access delegate API implementation instance.
function accessDelegateAPI(){ var api = ctxt.getAPI(); var delegateOdj = api.getAPIDelegate(“chargeback:userAPICheckFunds”); } accessDelegateAPI();
The above sample returns the delegate API implementation instance (delegateOdj). You can execute any method in the delegate class.
No modifications required to implement this code.
Access and operate a table of a Cisco UCS Director database by passing the corresponding PoJo. (PoJo represents a database table.)
You want a script to access a database table and obtain its details.
Requires a valid PoJo class name and a valid query to retrieve information.
ObjStoreHelper.getStore - This method accesses the database table and obtains its details.
var accountName ="UCSM_98"; var spDn ="org-root/org-DEV_Org/ls-finalTemp2"; var query = "accountName == '" + accountName + "' && serviceProfileName == '" + spDn + "'"; var store = ObjStoreHelper.getStore(new UcsServer().getClass()); var server = store.query(query); logger.addInfo("SIZE:"+server.size());
The getStore() method of the ObjStoreHelper class takes the name of a model class as input and returns the corresponding object store as output.
No modifications required to implement this code.
Provision a catalog multiple times.
You want to provision multiple VMs.
VDCUtil - Use this API to obtain VDC details.
var catId = ctxt.getInput(CATALOG_ID); var vdcId = ctxt.getInput(VDC_ID); var quantity = Integer.valueOf ( ctxt.getInput(PROVISION_QTY));
var vdc = VDCUtil.getVDC(vdcId); var vdcName = vdc.getVdcName(); var cat = VDCUtil.getVDCCatalogItem(catId); var catName = cat.getCatalogItemName();
Create a loop to provision the catalogs n number of times and use thread sleep method to delay between provisioning. Also create an additional parameter for execution.
Array of service request ID to view status:
var childSrIdArray = [];
Comment is passed as an input parameter to call method:
var comment = "";
Set the duration of the VMs as -1 (or number of hours):
var duration = -1;
Set the begin time:
var beginTime = -1; for (var ctr = 0; ctr < quantity; ctr = ctr + 1) { logger.addInfo("Provision VM ="+ (ctr+1) + " of "+qty); var srId = ctxt.getAPI().userAPISubmitServiceRequest(catName, vdcName, duration, beginTime, 1, comment); childSrIdArray[ctr] = srId; var milliseconds = delaySecondsBetweenInvocation * 1000; Thread.sleep(milliseconds); }
Check the successful execution of API using the following code.
for (var i=0; i<childSrIdArray.length; i++) { var childSrId = childSrIdArray[i]; var status = ctxt.waitForCompletion(childSrId, 1800000); if (status == 0) { logger.addInfo("Provisioned SR ID ="+ childSrId+ " successfully."); } else { logger.addError("SR ID ="+ childSrId+ " failed"); } }
The script provisions VMs as per PROVISION_QTY input. The userAPISubmitServiceRequest class provisions the VMs.
See the code above for modifications you might require to implement the code.
Invoke a workflow task from CloupiaScript using an inner task.
Inner task name and set of inputs are required.
ctxt.createInnerTaskContext() - Use this method to access the task variables and to set the input values.
// Task Label: Create VM Disk // Task Name: Create VM Disk function Create_VM_Disk() { var task = ctxt.createInnerTaskContext("Create VM Disk"); // Input 'Select VM', mandatory=true, mappableTo=vm task.setInput("Select VM", input.vmId); // Input 'Disk Size (GB)', mandatory=true, mappableTo=gen_text_input task.setInput("Disk Size (GB)", input.diskSize); // Input 'Select Disk Type', mandatory=true, mappableTo=gen_text_input task.setInput("Select Disk Type", input.diskType); // Input 'Select Datastore', mandatory=false, mappableTo=dataStoreName task.setInput("Select Datastore", input.datastoreName); // Input 'Thin Provisioning', mandatory=false, mappableTo= task.setInput("Thin Provisioning", input.thinProvision); // Execute the task. On failure, the task throws an exception error task.execute(); } // Invoke the task Create_VM_Disk();
The script executes the Create VM task as inner task.
No modifications required to implement this code.
Set the Task status to Successful or Failed based on the given condition.
None
ctxt - Used to set the status message of the workflow task.
if (true) { ctxt.setFailed(“Error output message”); // to set the task status as failed ctxt.exit(); // to exit task flow normally } else { ctxt.setSuccessful(); // to set the task status to successful }
Sets the task status as failed or successful based on the given condition.
No modifications required to implement this code.
Invoke a workflow from another workflow.
You want to invoke another workflow using Cloupia script.
Workflow name and workflow parameters are required.
var params = util.createNameValueList(); params.addNameValue(util.createNameValue(“Input_A”, “Value_A”)); params.addNameValue(util.createNameValue(“Input_B”, “Value_B”)); params.addNameValue(util.createNameValue(“Input_C”, “Value_C”)); var childSrId= ctxt.getAPI().userAPISubmitWorkflowServiceRequest( “Task_Y”, params, ctxt.getSrId()); // wait for completion of the workflow. Or a maximum of 60 seconds // status code can be one 0 (Success), 1 (failed), -1 (Invalid SR ID) var status = ctxt.waitForCompletion(childSrId, 60000); // Now that workflow is complete, we can access the output variable D of the workflow Task_Y var output_y = ctxt.getOutput(”Task_Y.D”", childSrId);
The above script invokes another workflow with the given inputs and generates a service request.
The Input_Name provided in the parameter list must be the same as the Input_Name defined in the workflow that is being invoked. The parameter parent_srId is required to make the invoking workflow as child.
The child service request won’t be visible in the Service Request logs. If you want to invoke the workflow as separate service request, pass parent_srId as -1.
Execute an API remotely by selecting the required server IP address in the API browser.
You want to call an API on a remote Cisco UCS Director.
Requires a remote UCSD server.
JsonUtil - Sends the RestAPI call remotely.
CloupiaClient - Creates the connection.
var client = new CloupiaClient(server, 443, key); // first parameter is the remote server-address, the second parameter is remote //server-port, while the third parameter is rest-api-access-key. JsonUtil.prettyPrint(client.sendJSONRequest(opName, paramList))); // first parameter is operationName / or API name, second parameter is the API argument list as specified in the API signature.
To obtain a tabular report:
client.sendJSONRequest("userAPIGetTabularReport", Arrays.asList(new String[]{"vm", "2319", "DISKS-T0"})));
To obtain all catalogs:
client.sendJSONRequest("userAPIGetAllCatalogs", null);
To obtain all VM actions:
client.sendJSONRequest("userAPIGetAvailableVMActions", Arrays.asList(new String[] {"2293"}));
To submit a service request:
client.sendJSONRequest("userAPISubmitServiceRequest" , Arrays.asList(new String[] {cata-logName, vdcName, durationHours, beginTime, qty, comments }));
To execute a workflow :
client.sendJSONRequest("userAPISubmitWorkflowServiceRequest", Arrays.asList(new Object[] {workflowName, nameValueList, -1 })); // param 1 is workflowName
The script calls the API from the remote UCS Director.
Provide the server IP address and port number to the CloupiaClient method.
Allow exclusive access to a thread to execute a critical section using the CriticalSection API.
The CriticalSection API helps a workflow thread (running with a context srId) gain exclusive access to a critical section with a specified sectionName or lockName. Any other thread wanting access to the critical section must wait until the exitCriticalSection API releases the section from the thread holding the lock.
None
CriticalSectionUtil - use the class to guard the critical section.
To enter a critical section and effectively obtain a lock, use:
public static void enterCriticalSection(CustomActionTriggerContext context, CustomAction- Logger logger, String lockName) throws Exception
When the thread wants to release all locks held by the service request, use the following API:
public static void exitCriticalSection(CustomActionTriggerContext context, CustomAction- Logger logger) throws Exception
When there are multiple requests, the above mentioned APIs help execute requests, one at a time.
No modifications required to implement this code.
Obtain all VLAN IDs available within an account.
You want to obtain all the VLAN IDs that are configured on the UCS device.
You require access to a UCSM account.
UcsDataPersistenceUtil - This class fetches the VLAN IDs.
importPackage(com.cloupia.feature.ucsController); //UcsDataPersistenceUtil //importPackage(java.lang); importPackage(java.util); importPackage(com.cloupia.lib.cIaaS.ucs.model); //UcsVLAN //var accountName = input.name; var accountName = "DR_UCSM30"; var vlanIdsPerAccount = ""; var ucsVlanList = UcsDataPersistenceUtil.getVLAN(accountName); var vLanList = new ArrayList(); for(var i=0;i<ucsVlanList.size();i++){ var ucsVLAN = ucsVlanList.get(i); vlanIdsPerAccount = vlanIdsPerAccount+ucsVLAN.getId()+","; vLanList.add(ucsVLAN.getId()); } logger.addInfo("No of vlan ids:"+ucsVlanList.size()); vlanIdsPerAccount = vlanIdsPerAccount.substring(0, vlanIdsPerAccount.length()-1); logger.addInfo(accountName+":"+vlanIdsPerAccount); //output.vlanIdsPerAccount = vlanIdsPerAccount;
Comma separated VLAN IDs. For example: DR_UCSM30:1,1,205,1135,1136,1001.
No modifications required to implement this code.
Obtain all the virtual account IPs available in one pod.
You know a pod name and want to obtain all the Virtual Account IPs from the pod.
Virtual account should be available in the pod.
InfraPersistenceUtil.getAllFlexPodAccounts - Returns all the account names added in the pod.
importPackage(com.cloupia.model.cIM); //Account importPackage(com.cloupia.service.cIM.inframgr); //InfraPersistenceUtil var podName = "Default Pod"; // var podName = input. podName; var allAcct = ctxt.getAPI().getAllAccounts(); logger.addInfo("No of accounts:"+allAcct.length); var accList = InfraPersistenceUtil.getAllFlexPodAccounts(podName); logger.addInfo("No of accounts in the pod "+podName+" is:"+accList.size()); var listOfIPsPerPod = ""; for(var count = 0;count < accList.size();count++){ var acc = accList.get(count); logger.addInfo("Account name:"+acc.getAccountName()); if(acc.getAccountType()==CloudTypes.VMWARE){ listOfIPsPerPod = listOfIPsPerPod+acc.getVServer()+","; } else if(acc.getAccountType()==CloudTypes.HYPERV){ listOfIPsPerPod = listOfIPsPerPod+acc.getHServer()+","; } } listOfIPsPerPod = listOfIPsPerPod.substring(0, listOfIPsPerPod.length()-1); logger.addInfo(podName+":"+listOfIPsPerPod); output.listOfIPsPerPod = listOfIPsPerPod;} getListOfIPs();
The output is a comma separated list of all the IPs in the pod. For example: 172.29.110.196, 172.25.168.80, 172.29.109.82.
No modifications required to implement this code.
To lock or unlock a VDC.
VDC must be created.
VDCUtil - Use the method to lock the VDC
VDCUtil.setLocked() - Use the method to lock or unlock VDC
importPackage(com.cloupia.model.cIM); importPackage(com.cloupia.service.cIM.inframgr); importPackage(java.util); function lock() { var flag=false; vdcId=input.VDC; var vdc; try { vdc=VDCUtil.getVDC(input.VDC); vdc.setLocked(input.VdcLocked);//Pass the value ‘true’ to lock the VDC. //To unlock the VDC, pass the value as false. flag=VDCUtil.modifyVDC(vdc); } catch (e) { logger.addError("Exception error when modifying VDC."); ctxt.setFailed(e); ctxt.exit(); } if(flag){ logger.addInfo("Successfully modified VDC." ); vdc=VDCUtil.getVDC(vdcId); output.vdcId=vdcId; output.isLocked=vdc.isLocked(); } else { logger.addInfo("Unable to modify VDC." ); } } lock();
The script locks the VDC. This can be verified in UCS Director.
No modifications required to implement this code.
Obtain the list of hosts from a VMware Cluster.
You want to view all the hosts in a VMware cluster.
A VMware cluster must be available.
InfraPersistenceUtil - This object obtains the list of hosts from a VMware cluster.
importPackage(com.cloupia.service.cIM.inframgr); importPackage(java.util); function getListOfHosts(){ var listofHosts = InfraPersistenceUtil.getVMWareHostsByCluster(input.VMWAREACCOUNT,input.CLUSTER); return listOfHosts; }
Comma separated hosts are mapped to the Associate VNX LUN as a datastore task. However, this operation is applicable on all hosts in a cluster, not just a single host.
No modifications required to implement this code.
Move all VMs from one VDC to another VDC.
VDC should be available to move the VMs.
VDCUtil - This object obtains the VDC details.
GroupManagerImpl.getVMDataByVMId(vmId) - This object obtains the VM details by passing the VM ID as argument.
importPackage(com.cloupia.service.cIM.inframgr); importPackage(java.util); function moveVMsAcrossVDC(){ var sourceVdc = input.sourceVDC; var sourceVdcId = parseInt(sourceVdc); var sourceVdcName = VDCUtil.getVDC(sourceVdcId).getVdcName(); logger.addInfo("vDC:"+sourceVdcName + "--> vDC Id: "+sourceVdcId); var destinationVdc = input.destinationVDC; var destinationVdcId = parseInt(destinationVdc); var destinationVdcName = VDCUtil.getVDC(destinationVdcId).getVdcName(); logger.addInfo("vDC:"+destinationVdcName+"--> vDC Id: "+destinationVdcId); var vmLists = VDCUtil.getVMsAssociatedWithVDC(sourceVdcId); for(var i=0; i<vmLists.size();i++){ var vmId = vmLists.get(i); logger.addInfo("vmId:"+vmId); try{ var vmData = GroupManagerImpl.getVMDataByVMId(vmId); var vmsummary = ctxt.getAPI().getVMBasicInfo(vmId); var vmType = vmsummary.getVmType(); var vmName = ""; if(vmType.equals("VMWare")) vmName = ctxt.getAPI().getVMwareVMInfo(vmId).getName(); else if(vmType.equals("Hyper-V")) vmName = InfraPersistenceUtil.getHyperVVMSummary(vmId).getName(); if (vmData != null) { logger.addInfo("Assigning VM:"+vmName+" to vDC:"+vdcName); vmData.setVdcId(destinationVdcId); GroupManagerImpl.assignGroupToVM(vmData); }else{ logger.warn("The VM has no assignment (VM User Data )"); vmData = new VMUserData(); vmData.setVmId(vmId); vmData.setVdcId(destinationVdcId); GroupManagerImpl.assignGroupToVM(vmData); } }catch(e){ logger.addError("Error while assigning VMs to VDC"); ctxt.setFailed("Failed to assign VM to VDC"); ctxt.exit(); } } output.Result = " VMs successfully assigned to destination VDC:"+ destinationVdc; }
All VMs in VDC 1 are now moved to VDC 2.
No modifications required to implement this code.
Roll back a task in a workflow using the change tracker API.
You performed an operation and you now want to revert it. For example, you created a VM, but then want to roll back and delete the VM.
The workflow should have been successfully executed.
The undo task handler name and undo config object are the important parameters to execute the undo task. The undo task needs the data for the original task to undo the actions done by the original task.
Related API for undoing modify/delete operations: ChangeTracker.undoableResourceModified and ChangeTracker.undoableResourceDeleted.
Both the API calls have the same set of parameters. Each task in the workflow needs undo support using the change tracker API to successfully roll back the entire workflow.
importPackage(com.cloupia.service.cIM.inframgr.customactions); importPackage(com.cloupia.feature.accounts.wftasks); function doRollBack(){ var undoTaskHandlerName = DeleteGroupConfig.HANDLER_NAME; var configObject = new DeleteGroupConfig(input.groupId+ "") ChangeTracker.undoableResourceModified(input.assetType, input.assetId, input.assetLabel, input.description, undoTaskHandlerName, configObject) ; } doRollBack();
The group with the given ID is deleted after executing the task.
No modifications required to implement this code.
Reset data on a demo instance using ServiceNow.
ServiceNow is a software platform that supports IT service management and automates common business processes. This software as a service (SaaS) platform contains a number of modular applications that can vary by instance and user. It uses the HttpClient API to send the HTTP request and handle the HTTP response.
ServiceNow provides several demo instances, which you can use for testing. The demo login and password is admin/admin. The demo login and password should be verified in ServiceNow, because they change regularly.
ServiceNow resets the data on each demo instance daily. You must enable JSON plugin on ServiceNow to make this API work. Refer to the Service Now Website on how to activate the Plugin section.
HttpClient - Used to communicate with the ServiceNow software.
importPackage(java.util); importPackage(java.io); importPackage(com.cloupia.lib.util); importPackage(com.cloupia.model.cIM); importPackage(com.cloupia.service.cIM.inframgr); importPackage(org.apache.commons.httpclient); importPackage(org.apache.commons.httpclient.cookie); importPackage(org.apache.commons.httpclient.methods); importPackage(org.apache.commons.httpclient.auth); //var login= ctxt.getInput("LOGIN") //var password = ctxt.getInput("PASSWORD"); var login = "admin"; var password = "admin"; var instance = "demo011.service-now.com"; var url = "/incident.do?JSON&sysparm_action=insert"; // Link to Service-now documentation //http://wiki.servicenow.com/index.php?title=JSON_Web_Service#insert var map = new HashMap(); map.put("sysparm_action", "insert"); map.put("short_description", "Sample incident #5"); map.put("impact", "2"); map.put("urgency", "2"); map.put("caller_id", "Joe Z"); map.put("category", "software"); var data = JSON.javaToJsonString(map, map.getClass()); logger.addInfo("JSON Data = "+data); var httpClient = new HttpClient(); httpClient.getHostConfiguration().setHost(instance, 443, "https"); httpClient.getParams().setAuthenticationPreemptive(true); httpClient.getParams().setCookiePolicy("default"); var defaultcreds = new UsernamePasswordCredentials(login, password); httpClient.getState().setCredentials(new AuthScope(instance, -1, null), defaultcreds); var httpMethod = new PostMethod(url); httpMethod.setRequestEntity(new StringRequestEntity(data)); httpMethod.addRequestHeader("Content-Type", "application/json"); httpClient.executeMethod(httpMethod); var statuscode = httpMethod.getStatusCode(); logger.addInfo("STATUSCODE = "+statuscode); if (statuscode != 200) { logger.addError("Ticket failed to open, with the following code "+statuscode); if (statuscode == 302) { logger.addWarning("Likely cause of failure is that the JSON plugin is not activated on the Service Now instance. "); logger.addWarning("Check documentation on how to enable the plugin: "+ "http://wiki.servicenow.com/index.php?title=JSON_Web_Service#insert "+ " (see section 2)"); } httpMethod.releaseConnection(); // Set this task as failed. ctxt.setFailed("Unable to open ticket"); } else { var reader = new InputStreamReader(httpMethod.getResponseBodyAsStream()); var resp = JSON.getJsonElement(reader, null); logger.addInfo("Response = "+resp); var entry = resp.get("records").get(0); logger.addInfo("Ticket Number "+entry.get("number")); logger.addInfo("Ticket Sys_id "+entry.get("sys_id")); httpMethod.releaseConnection(); }
The script communicates with the ServiceNow software.
Mention the server address and username/passwords before executing the script.
Send an email after a specific operation has been completed.
You want to send an email after a particular operation is completed. For example, you want to send an email after a VM has been provisioned.
Log on to UCS Director and navigate to Administration > System > Mail Setup. In Mail Setup, make sure that the report values are not empty.
MailManager - Used to send email.
importPackage(com.cloupia.model.cIM); importPackage(com.cloupia.lib.util.mail); importPackage(com.cloupia.fw.objstore); function getMailSettings() { return ObjStoreHelper.getStore((new MailSettings()).getClass()).getSingleton(); } // Assume the To Email Address is in the input variable 'Email Address' var toEmail = [ ctxt.getInput("Email Address") ]; Cisco UCS Director Cloupia Script Configuration Guide, Release 5.0 17 Cloupia Script Samples Sending Emails from the Cloupia Script var message = new EmailMessageRequest(); message.setToAddrs(toEmail); // other methods in the message object are // setToAddr(emailAddress) -- Sets a single email address in To list // setCcAddr(emailAddress) -- Sets a single email address in Cc list // setBccAddr(emailAddress) -- Sets a single email address in Bcc list // setCcAddrs(emailAddressArray) -- Sets an array of email addresses in the CC //list // setBccAddrs(emailAddressArray) -- Sets an array of email addresses in BCC //list message.setSubject("Test Email"); message.setFromAddress("no-reply@cisco.com"); var body = "<h1>This is a sample Email </h1><br><b>Sample content</b>"; message.setMessageBody(body); // By default, content type is text or HTML. The following method can be used to modify //content type message.setContentType("text/plain"); logger.addInfo("Sending email"); MailManager.sendEmail("Sample Email", getMailSettings(), message);
An email is sent to the respective email recipient.
No modifications required to implement this code.
Set up the Cloupia script to archive all service requests (SRs) that are older than 30 days.
You find that the number of SR IDs are high and want to hide the SR IDs in the UI. You want to execute an workflow that makes sure that only the SRs in the last 30 days are shown in the daily report.
Service request ID should be created.
WorkFlowManager.getInstance().archive() - This method is used to archive SR IDs.
importPackage(com.cloupia.model.cIM); importPackage(com.cloupia.fw.objstore); importPackage(com.cloupia.service.cIM.inframgr.workflowmgr); importPackage(com.cloupia.service.cIM.inframgr.cmdb); importPackage(java.lang); function getOlderSRs(ageInDays) { var timeStamp = System.currentTimeMillis() - (ageInDays*(24*60*60*1000)); var store = ObjStoreHelper.getStore((new ServiceRequest()).getClass()); return store.query("isArchived == false && requestTime < "+timeStamp); } var srList = getOlderSRs(30); logger.addInfo("There are "+srList.size()+" SRs to be archived"); for (var i=0; i<srList.size(); i++) { try { var sr = srList.get(i); logger.addDebug("["+i+"] Archiving SR "+sr.getRequestId()); // Archive the SR WorkFlowManager.getInstance().archive(sr.getRequestId()); // Add an entry into the Change Log CMDB.getInstance().change(ctxt.getUserId(), 0, "Request archived by Workflow", sr); } catch(e){ logger.addError("Error :"+e.message); } }
The SR IDs are archived and not shown in UI after the workflow is executed.
Need to pass the number of days as argument in the line getOlderSRs(). The above example archives all service requests that are older than 30 days.
Access the user details of the person who submitted the workflow, such as the first name, last name, and email address.
You want to know the details of the person that submitted the workflow, such as the User ID, first name, last name, and email ID.
None
APILoginProfile - The ctxt.getAPI().and userAPIGetMyLoginProfile() methods return the APILoginProfile object, which contains the user details.
importPackage(java.lang); importPackage(com.cloupia.model.cIM); importPackage(com.cloupia.service.cIM.inframgr); var userId = ctxt.getUserId(); // Get the current workflow submitter’s profile var userProfile = ctxt.getAPI().userAPIGetMyLoginProfile(); var firstName = userProfile.getFirstName(); var lastName = userProfile.getLastName(); var groupName = userProfile.getGroupName(); var groupId = userProfile.getGroupId(); var role = userProfile.getRole(); var email = userProfile.getEmail(); // Add debug statements to SR log logger.addDebug("UserId="+userId+", Name="+firstName + " "+ lastName +", Email="+email+", group="+groupName+", "+"Role="+role); // Save to workflow variables as necessary ctxt.updateInput("SUBMITTER_EMAIL", email); ctxt.updateInput("SUBMITTER_FIRSTNAME", firstName); ctxt.updateInput("SUBMITTER_LASTNAME", lastName); ctxt.updateInput("SUBMITTER_GROUPNAME", groupName);
The example script prints the User ID, name, email, group, and the role of the workflow submitter.
No modifications required to implement this code.
Resize the disk of a VM after it has been provisioned.
The VM should have the disk. The library task 'Resize VM Disk' is available for reference.
VMWareVMSummary - The ctxt.getAPI().getVMwareVMInfo(vmid) method returns the object, VMWareVMSummary
ctxt.getAPI().performAction() - Performs VM disk resize operation
vmid - Input variable, which points to the VM that needs to be resized
importPackage(java.lang); importPackage(java.util); importPackage(com.cloupia.model.cIM); importPackage(com.cloupia.service.cIM.inframgr); function resizeVmDisk(vmidstr, diskName, sizeInGB) { var vmid = Integer.parseInt(vmidstr); // create the context to var vmcontext = util.createContext("vm", null, vmidstr); // obtain VM details var vminfo = ctxt.getAPI().getVMwareVMInfo(vmid); var vmname = vminfo.getName(); var nameparam = new ActionParam("vmName", vmname); var sizeparam = new ActionParam("vmSize", sizeInGB); var diskparam = new ActionParam("vmDiskLabel", diskName); var paramarr = [ nameparam, sizeparam, diskparam ]; logger.addInfo("About to resize VM "+vmidstr+" name="+vmname); var status = ctxt.getAPI().performAction(vmcontext,"diskResize","Resizing VM to test the script",ctxt.getUserId(),paramarr); logger.addInfo("status = "+status); } var vmidstr1 = ctxt.getInput("VMID"); resizeVmDisk(vmidstr1, "Hard Disk 1", "10");
The VM disk is resized after the script is executed.
No modifications required to implement this code.
Make available an external JAR file for a custom task by uploading the JAR file through the Script Module.
You want to access an external JAR file for a custom task.
In UCS Director, navigate to Orchestration > Script Module and upload the JAR file.
Script Module
Suppose the sample JAR file "Calculatedemo.jar" contains the following code:
package com.calculate; public class CalculateDemo { public int add(int n1,int n2){ return n1+n2; } public int multiply(int n1,int n2){ return n1*n2; } }
The following script helps complete the custom task using the Calculatedemo.jar file.
loadJar("Mod1/calculatedemo.jar"); importPackage(com.calculate); var demo = new CalculateDemo(); var demo1 = new com.calculate.CalculateDemo(); logger.addInfo(demo); var sum = demo.add(5,6); logger.addInfo("Sum:"+sum); logger.addInfo(demo1); var mul = demo1.multiply(3,4); logger.addInfo("Multiplication:"+mul);
The uploaded JAR file is accessed from the custom task successfully.
No modifications required to implement this code.
Invoke library functions for a custom task.
You have some reusable code and want to use it across multiple custom tasks. You can add the reusable code in a library and invoke the library from the custom task.
In UCS Director, navigate to Orchestration > Script Module. Create a library with the reusable code.
Script Module
Suppose the library "lib1" contains the following reusable code:
function mul(a,b){ return a*b; } function add(a,b){ return a+b; }
Invoke the library using the following script:
loadLibrary(“Mod1/lib1”); var mul = mul(5,6); logger.addInfo("The product is:"+mul); var add = add(5,6); logger.addInfo("The sum is:"+add);
The library is accessed and the custom task is executed successfully.
No modifications required to implement this code.
Access a registered LOV from a custom task.
In UCS Director, navigate to Orchestration > Script Module and register the List of Values (LOV).
Script Module
{ var lovProvider = new.com.cloupia.service.cIM.inframgr.forms.wizard.LOVProviderIf({ getLOVs : function(session) { //Implement this section based on your requirement var SiteList = SitePersistenceUtil.getAllClusterSites(); var formlovs==[]; if(SiteList==null){ return formlovs; } if(SiteList.size()==0){ return formlovs; } var formlov; for(var count = 0;count<SiteList.size();count++) { var clusterSite = SiteList.get(count); var siteName = clusterSite.getSiteName(); formlov = new FormLOVPair(siteName, siteName); formlovs[count] = formlov; } return formlovs; //End of implementation for Lovprovider } }); return lovProvider;
The script helps access a site list of LOVs from a custom task.
To access an LOV from the custom task, create a custom task and define a variable. The variable name should be the same as the LOV created in the Script Module.
Access a registered tabular report from a custom task.
In UCS Director, navigate to Orchestration > Script Module and add a tabular report. Then modify the table to add column entries.
Script Module
Add the following code to the tabular report.
{ Varmodel = new TabularReportInternalModel(); model.addNumberColumn(“Site ID”, “Site ID”); model.addTextColumn(“Site Name”, “Site Name”); model.addTextColumn(“Description”, “Description”); model.completedHeader(); //Obtain values from the database and populate the model object as shown below. //The model object is generated depending on the Column entries. //model.addNumberValue(0); //model.addTextValue(“Site Name”); //model.addTextValue(“Description”); //model.completedRow(); //Start of your implementation. Implement this section based on your requirements. Var SiteList = SitePersistenceUtil.getAllClusterSites(); For (count = 0;count<SiteList.size();count++) { Var site = SiteList.get(count); model.addNumberValue(site.getClusterSiteId()); model.addTextValue(site.getSiteName()); model.addTextValue(site.getDescription()); model.addTextValue(site.getContactName()); model.completedRow(); } //End of your implementation model.updateReport(report); }
The tabular report is accessed from the custom task and your requirement is implemented.
To access the tabular report from the custom task, create a custom task and define a variable. The variable name should be the same as the tabular report name created in the Script Module.