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

Multi VM Provisioning with Post Provisioning and Rollback

Description

Prerequisites
  1. Tested on 5.4
  2. update for UCSD 6.5 with cores and sockets
CategoryWorkflow
ComponentsvSphere 5.x
User Inputse-mail address
Outpute-mail with counter

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 .WFDX file resides. Choose the .WFDX 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

The Workflow:

Screen Shot 2015-11-17 at 4.04.53 PM.png'

The workflow input with marked changes for different environment:

Screen Shot 2015-11-17 at 4.04.24 PM.png

Catalog and VDC need to change from drop down in admin Input Value!

If desired the starting VM number needs to change as well.

The mapped input in the VM deploy task:

Screen Shot 2015-11-17 at 4.05.05 PM.png

Screen Shot 2015-11-17 at 4.05.22 PM.png

Screen Shot 2015-11-17 at 4.05.37 PM.png

Workflow execution:

Screen Shot 2015-11-17 at 4.06.16 PM.png

The catalog with the post Provisioning workflow selected:

Screen Shot 2015-11-17 at 4.07.01 PM.png

The workflow will e-mail 2 inout variables:

Screen Shot 2015-11-17 at 4.07.42 PM.png

The post provisioning workflow:

Screen Shot 2015-11-17 at 4.07.51 PM.png

This workflow is also in the attached zip file.

The workflow will kick off 2 child workflows (Since deploy 2 VMs was selected):

Screen Shot 2015-11-17 at 4.25.09 PM.png

The e-mail from the post provisioning workflow:

Screen Shot 2015-11-17 at 4.30.03 PM.png

System Policy:

Screen Shot 2016-11-18 at 2.17.59 PM.png

The Code:

importPackage(com.cloupia.model.cIM);

importPackage(java.util);

importPackage(java.lang);

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);

importPackage(com.cloupia.model.cEvent.notify);

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

importPackage(com.cloupia.fw.objstore);

importPackage(com.cloupia.lib.cIaaS.vmware);

importPackage(com.cloupia.feature.customactions.configs);

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

var delaySecondsBetweenInvocation = 30;

function sleep()

{

              var milliseconds = delaySecondsBetweenInvocation * 1000;

              Thread.sleep(milliseconds);

}

var catID = input.CatalogName;

var vdcID = input.VDCName;

var vmowner = input.VMOwner;

var vmname = input.VMName;

var vmcomment = input.VMComment;

var vmcpu = input.VMCPU;

var vmmemory = input.VMMemory;

var vmdisksize = input.VMDiskSize;

var wfi1 = input.WorkflowInput1;

var wfi2 = input.WorkflowInput2;

var counter = input.Counter;

var startcounter = input.StartCounter;

//

// Convert the VDC and Catalog ID to a name

//

var vdc2 = VDCUtil.getVDC(vdcID);

var vdcName = vdc2.getVdcName();

var cat2 = VDCUtil.getVDCCatalogItem(catID);

var catName = cat2.getCatalogItemName();

logger.addInfo("---------------------------------");

logger.addInfo("params vdcID = "+vdcID);

logger.addInfo("params vdcName = "+vdcName);

logger.addInfo("params catID = "+catID);

logger.addInfo("params cat = "+catName);

logger.addInfo("---------------------------------");

//

// Set up the provision VM information

//

var params = new APIProvisionParams();

logger.addInfo("params cat = "+catName);

params.setCatalogName(catName);

logger.addInfo("VDC  = "+vdcName);

params.setVdcName(vdcName);

logger.addInfo("params vmowner = "+vmowner);

params.setUserID(vmowner);

logger.addInfo("params vmname = "+vmname);

params.setVmName(vmname);

logger.addInfo("params vmcomment = "+vmcomment);

params.setComments(vmcomment);

logger.addInfo("params vmcpu = "+vmcpu);

params.setCores(vmcpu);

logger.addInfo("params vmmemory = "+vmmemory);

params.setMemoryMB(vmmemory);

logger.addInfo("params disksize1 = "+vmdisksize);

params.setDiskGB(vmdisksize);

//

//If Post Provision workflow has user inputs then the following code is required to pass user inputs to API.

//If the post provision workflow has only task inputs then skip the below code.

//It is not required to setPostProvWFUserInputs.

//remember the catalog has the post provisioning workflow

//here only the inout parameters for the postprovisioning workflow are set

//

logger.addInfo("params wfi1 = "+wfi1);

var nv1 = new APINameValue("A1",wfi1);

logger.addInfo("params wfi2 = "+wfi2);

var nv2 = new APINameValue("A2",wfi2);

logger.addInfo("---------------------------------");

var list = new APINameValueList();

list.addNameValue(nv1);

list.addNameValue(nv2);

//Add this inputs list to provision params.

params.setPostProvWFUserInputs(list);

//

// Call New Service Request provision VM

//

var qty = 1;

try {

    qty = Integer.valueOf(counter);

} catch( e) {

    logger.addWarning("Invalid counter specified:"+counter+ " provisioning one VM");

}

try {

    sc = Integer.valueOf(startcounter);

} catch( e) {

    logger.addWarning("Invalid start counter specified:"+startcounter+ " provisioning one VM");

}

logger.addInfo("Start Counter ="+ startcounter);

var childSrIdArray = [];

// start loop

for (var ctr = 0; ctr < qty; ctr = ctr + 1)

{

  logger.addInfo("Provision VM ="+ (ctr+1) + " of "+qty);

  var number = sc + ctr + 1;

  logger.addInfo("VM Number ="+ number);

  logger.addInfo("params vmname = "+vmname+number);

  params.setVmName(vmname+number);

  logger.addInfo("params vmcomment = "+vmcomment+number);

  params.setComments(vmcomment+number);

  logger.addInfo("-------------------Provsion VM---------------------------------");

  var srId = ctxt.getAPI().userAPIProvisionRequest(params);

  logger.addInfo("childSrId= "+srId);

  childSrIdArray[ctr] = srId;

  logger.addInfo("Sleeping for a bit (30 sec...");

  sleep();

}

// end loop

logger.addInfo("-------------------Waiting for Child Workflow(s) to Finish---------------------------------");

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");

                }

}

rollbackMultiVM(childSrIdArray);

function rollbackMultiVM(childSrIdArray){

  for(var i=0; i<childSrIdArray.length; i++){

  var srId = childSrIdArray[i];

  var vmList = GroupManagerImpl.getVMsAssociatedWithServiceRequest(srId);

  ctxt.getChangeTracker().undoableResourceModified(VMwareAssetTypeConstants.VMWARE_RELEASE_IP, srId+"",srId+"",

                "IP to be released for SR:" + srId,

                RemoveIPAddressReservationConfig.HANDLER_NAME,

                new RemoveIPAddressReservationConfig(srId));

  if(vmList != null && vmList.size()>0){

  for(var j=0; j<vmList.size(); j++){

  var gvm = vmList.get(j);

  ctxt.getChangeTracker().undoableResourceModified(VMwareAssetTypeConstants.VMWARE_VM, String.valueOf(gvm.getVmId()),

  gvm.getInstanceId(), "VM " + gvm.getInstanceId() + " provisioned on the host " + gvm.getParentHost(),

  DeleteVMConfig.HANDLER_NAME,

  new DeleteVMConfig(gvm.getVmId()));

  }

  }

  }

}

Run with 3 VM's and rollback:

Workflow Inputs:

- VMname

- VMComment

- VDC

- Catalog

- Memory

- CPU

- Disk

- HowManyVMs

- VMStartCounter

- WorkFlowInput1

- WorkFlowInput2

- VMOwner

Nov 24, 2015 17:52:43 UTC Request submitted

Nov 24, 2015 17:52:48 UTC Executing workflow item number 1

Nov 24, 2015 17:52:48 UTC Completed workflow item number 0, with status Completed

Nov 24, 2015 17:52:55 UTC Executing workflow item number 2

Nov 24, 2015 17:52:55 UTC Trigger context executeWorkFlowStep called

Nov 24, 2015 17:52:55 UTC Executing custom action MultiVMDeploymentWithPostprovisioning (custom_MultiVMDeploymentwithPostProvisioning)

Nov 24, 2015 17:52:55 UTC Executing custom action MultiVMDeploymentWithPostprovisioning (custom_MultiVMDeploymentwithPostProvisioning)

Nov 24, 2015 17:52:55 UTC Executing custom script for MultiVMDeploymentwithPostProvisioning

Nov 24, 2015 17:52:58 UTC ---------------------------------

Nov 24, 2015 17:52:58 UTC params vdcID = 127

Nov 24, 2015 17:52:58 UTC params vdcName = VDC-Prod

Nov 24, 2015 17:52:58 UTC params catID = 154

Nov 24, 2015 17:52:58 UTC params cat = LinuxWebApp

Nov 24, 2015 17:52:58 UTC ---------------------------------

Nov 24, 2015 17:52:58 UTC params cat = LinuxWebApp

Nov 24, 2015 17:52:58 UTC VDC = VDC-Prod

Nov 24, 2015 17:52:58 UTC params vmowner = orf

Nov 24, 2015 17:52:58 UTC params vmname = Rock

Nov 24, 2015 17:52:58 UTC params vmcomment = Rock

Nov 24, 2015 17:52:58 UTC params vmcpu = 2

Nov 24, 2015 17:52:58 UTC params vmmemory = 2048

Nov 24, 2015 17:52:58 UTC params disksize1 = 10

Nov 24, 2015 17:52:58 UTC params wfi1 = happy

Nov 24, 2015 17:52:58 UTC params wfi2 = tuesday

Nov 24, 2015 17:52:58 UTC ---------------------------------

Nov 24, 2015 17:52:58 UTC Start Counter =99

Nov 24, 2015 17:52:58 UTC Provision VM =1 of 3

Nov 24, 2015 17:52:58 UTC VM Number =100

Nov 24, 2015 17:52:58 UTC params vmname = Rock100

Nov 24, 2015 17:52:58 UTC params vmcomment = Rock100

Nov 24, 2015 17:52:58 UTC -------------------Provsion VM---------------------------------

Nov 24, 2015 17:53:04 UTC childSrId= 5903

Nov 24, 2015 17:53:04 UTC Sleeping for a bit (30 sec...

Nov 24, 2015 17:53:34 UTC Provision VM =2 of 3

Nov 24, 2015 17:53:34 UTC VM Number =101

Nov 24, 2015 17:53:34 UTC params vmname = Rock101

Nov 24, 2015 17:53:34 UTC params vmcomment = Rock101

Nov 24, 2015 17:53:34 UTC -------------------Provsion VM---------------------------------

Nov 24, 2015 17:53:41 UTC childSrId= 5904

Nov 24, 2015 17:53:41 UTC Sleeping for a bit (30 sec...

Nov 24, 2015 17:54:11 UTC Provision VM =3 of 3

Nov 24, 2015 17:54:11 UTC VM Number =102

Nov 24, 2015 17:54:11 UTC params vmname = Rock102

Nov 24, 2015 17:54:11 UTC params vmcomment = Rock102

Nov 24, 2015 17:54:11 UTC -------------------Provsion VM---------------------------------

Nov 24, 2015 17:54:17 UTC childSrId= 5905

Nov 24, 2015 17:54:17 UTC Sleeping for a bit (30 sec...

Nov 24, 2015 17:54:47 UTC -------------------Done Waiting for Child Workflow to Finish---------------------------------

Nov 24, 2015 18:08:40 UTC Workflow with SR-ID 5903 is complete

Nov 24, 2015 18:08:40 UTC Provisioned SR ID =5903 successfully.

Nov 24, 2015 18:08:50 UTC Workflow with SR-ID 5904 is complete

Nov 24, 2015 18:08:50 UTC Provisioned SR ID =5904 successfully.

Nov 24, 2015 18:09:00 UTC Workflow with SR-ID 5905 is complete

Nov 24, 2015 18:09:00 UTC Provisioned SR ID =5905 successfully.

Nov 24, 2015 18:09:00 UTC Task #1 (MultiVMDeploymentWithPostprovisioning (custom_MultiVMDeploymentwithPostProvisioning)) completed successfully in 965 seconds

Nov 24, 2015 18:09:00 UTC Input/Output values for Task #1 (MultiVMDeploymentWithPostprovisioning (custom_MultiVMDeploymentwithPostProvisioning)):

Nov 24, 2015 18:09:00 UTC [Mapped Input: CatalogName = 154]

Nov 24, 2015 18:09:00 UTC [Mapped Input: VDCName = 127]

Nov 24, 2015 18:09:00 UTC [Template Input:VMOwner = ${INITIATING_USER}]

Nov 24, 2015 18:09:00 UTC [Resolved Template Input: VMOwner = orf]

Nov 24, 2015 18:09:00 UTC [Mapped Input: VMOwner = orf]

Nov 24, 2015 18:09:00 UTC [Mapped Input: VMName = Rock]

Nov 24, 2015 18:09:00 UTC [Mapped Input: VMComment = Rock]

Nov 24, 2015 18:09:00 UTC [Mapped Input: VMCPU = 2]

Nov 24, 2015 18:09:00 UTC [Mapped Input: VMMemory = 2048]

Nov 24, 2015 18:09:00 UTC [Mapped Input: VMDiskSize = 10]

Nov 24, 2015 18:09:00 UTC [Mapped Input: WorkflowInput1 = happy]

Nov 24, 2015 18:09:00 UTC [Mapped Input: WorkflowInput2 = tuesday]

Nov 24, 2015 18:09:00 UTC [Mapped Input: Counter = 3]

Nov 24, 2015 18:09:00 UTC [Mapped Input: StartCounter = 99]

Nov 24, 2015 18:09:00 UTC Completed workflow item number 1, with status Completed

Nov 24, 2015 18:09:06 UTC Executing workflow item number 3

Nov 24, 2015 18:09:06 UTC Completed workflow item number 2, with status Completed

The rollback options:

Screen Shot 2015-11-24 at 12.20.48 PM.png

The rollback:

Screen Shot 2015-11-24 at 12.23.27 PM.png

Here are the other options that the current workflow does not account for as input to the API call:

Screen Shot 2016-03-09 at 1.34.59 PM.png

In ASCII form:

/app/api/rest?formatType=json&opName=userAPIProvisionRequest&opData={param0:{"catalogName":"sample","vdcName":"sample","userID":"sample","durationHours":1000,"beginTime":0,"quantity":1000,"memoryMB":0,"diskGB":1000,"cores":1000,"estimatedCost":1000.0,"comments":"sample","additionalInfo":"sample","chargeFrequency":1000,"nicAliasName":"sample","nicPortGroupName":"sample","resourceAllocated":true,"allocatedHost":"sample","allocatedDataStore":"sample","allocatedResourcePool":"sample","altAllocatedHost":"sample","altAllocatedDataStore":"sample","altAllocatedResourcePool":"sample","customStartupMemory":1000.0,"customMaxMemory":1000.0,"customMemoryBuffer":1000.0,"customMemoryConfig":true,"customStoragePolicy":"sample","allocatedCluster":"sample","customCpuSockets":1000,"customCpuCoresPerSocket":1000,"altAllocatedCluster":"sample","allocatedAddnlDatastores":"sample","altAllocatedAddnlDatastores":"sample","altAllocatedAddnlVNICs":"sample","altAllocatedAddnlVNICsIpv6":"sample","selectedDiskDataStore":"sample","actionId":"sample","vmName":"sample","vdcCategory":"sample","windowsLicensePool":"sample","templateUserId":"sample","templatePassword":"sample","credentialOption":"sample","provisionAllDisk":true,"enableGuestCustomization":true,"enablePostProvisioningCustomActions":true,"workflow":"sample","vmId":1000,"vMAppChargeFrequency":1000,"activeVMAppCost":1000.0,"inactiveVMAppCost":1000.0,"useLinkedClone":true,"snapshotId":1000,"snapshotKey":"sample","newSnapshotName":"sample","isHighlyAvailable":true,"overrideCatalogCategoryId":1000,"nicIPAddressOverride":"sample","postProvWFUserInputs":{"list":[{"name":"sample","value":"sample"},{"name":"sample","value":"sample"}]}}}

Notes on the rollback Function.

Thank you goes to Gabor Szabo and Tejeswar Sahu

Questions:

I would like to ask some clarification question:

1.)    [endif]Is there a mandatory rule for the format of the „undoHandler” variable or can I choose it freely?

2.)    [endif]What is the role of the first four parameter of the “ChangeTracker().undoableResourceModified()” method (assetType, assetId, assetLabel, description)? Where are these used and are there any rule for the values I need to be aware of?

3.)    [endif]Do I need to clean-up the resources I have used for the rollback (like the undoContext or undoConfig)? Or it is done automatically?



answer for my Q1:


the format of the „undoHandler” string MUST be „custom_<Name-Of-A-Custom-Task>”, otherwise UCSD Javascript interpreter throws an exception.

Example: if a custom task is called “MyTask”, the undoHandler must be “custom_MyTask”. Either “custom1_MyTask” or “custom_xxMyTask” throws exception. Interestingly the undoHandler don’t need to refer to the same task, only it must include a valid custom task name (example: if I have another custom task called “MyOtherTask”, the undoHandler of “MyTask” can be “custom_MyOtherTask”). In such case the “MyTask” rollback workflow will call the “MyOtherTask” task with the prepared undoConfig oblect.




3 answers from the BU:

Generally we use the below line of code for registering the rollback task in the script part of custom task.

ctxt.getChangeTracker().undoableResourceModified(String assetType, String assetId, String assetLabel, String description, String undoTaskHandlerName, Object undoTaskConfigPOJO)

Here the last two parameters (undoTaskHandlerName, undoTaskConfigPOJO) are most important.

1.)    [endif] Is there a mandatory rule for the format of the “undoHandler” variable or can I choose it freely?(In this case “undoTaskHandlerName”)?

Ans:We can’t choose it freely.It should and must be the task name which we want to register for the rollback purpose. We can get this task name as shown below.

First we need to drag and drop the task into the workflow designer and from there we can find the task name.


Unknown.png


2.)    [endif] What is the role of the first four parameter of the “ChangeTracker().undoableResourceModified()” method (assetType, assetId, assetLabel, description)? Where are these used and are there any rule for the values I need to be aware of?

Ans: assetId and description is used as shown below when we right click on the SR and try to roll back it.


Unknown-1.png


As per my understanding ,assetType and assetLabel is not holding much significant role in our case and can be passed any string types.

[if !supportLists]3.)    [endif]Do I need to clean-up the resources I have used for the rollback (like the undoContext or undoConfig)? Or it is done automatically?

      Ans: Here undoContext or undoconfig are just like any other script variable in the script section.So these things will be taken care by the UCSD platform.



Update for UCSD 6.5 with Cores and Sockets:



     From REST API browser

          "customCpuSockets":1000,"customCpuCoresPerSocket":1000,


Screen Shot 2017-09-23 at 8.09.07 AM.png



Comments

Good afternoon

This workflow is good, but don't have the Interface/portgroup selection.

Do you have another version with this feature?

Orf Gelbrich
Cisco Employee
Cisco Employee

I would add a few tasks to the top of this workflow to change the network policy for the VDC you are going to deploy the VM into.  I do that in #123

Orf Gelbrich
Cisco Employee
Cisco Employee

in UCSD 6.6 this call needs to be adjusted to handle the pre-provisioning

app/api/rest?formatType=json&opName=userAPIProvisionRequest&opData={param0:{"catalogName":"sample","vdcName":"sample","userID":"sample","durationHours":1000,"beginTime":0,"quantity":1000,"memoryMB":0,"diskGB":1000,"cores":1000,"estimatedCost":1000.0,"comments":"sample","additionalInfo":"sample","chargeFrequency":1000,"nicAliasName":"sample","nicPortGroupName":"sample","resourceAllocated":true,"allocatedHost":"sample","allocatedDataStore":"sample","allocatedResourcePool":"sample","altAllocatedHost":"sample","altAllocatedDataStore":"sample","altAllocatedResourcePool":"sample","customStartupMemory":1000.0,"customMaxMemory":1000.0,"customMemoryBuffer":1000.0,"customMemoryWeight":1000,"customMemoryConfig":true,"customStoragePolicy":"sample","allocatedCluster":"sample","customCpuSockets":1000,"customCpuCoresPerSocket":1000,"altAllocatedCluster":"sample","allocatedAddnlDatastores":"sample","altAllocatedAddnlDatastores":"sample","altAllocatedAddnlVNICs":"sample","altAllocatedAddnlVNICsIpv6":"sample","selectedDiskDataStore":"sample","actionId":"sample","vmName":"sample","vdcCategory":"sample","windowsLicensePool":"sample","templateUserId":"sample","templatePassword":"sample","credentialOption":"sample","provisionAllDisk":true,"enableGuestCustomization":true,"enablePostProvisioningCustomActions":true,"workflow":"sample","vmId":1000,"vMAppChargeFrequency":1000,"activeVMAppCost":1000.0,"inactiveVMAppCost":1000.0,"useLinkedClone":true,"snapshotId":1000,"snapshotKey":"sample","newSnapshotName":"sample","isHighlyAvailable":true,"overrideCatalogCategoryId":1000,"nicIPAddressOverride":"sample","resourceUserName":"sample","postProvWFUserInputs":{"list":[{"name":"sample","value":"sample"},{"name":"sample","value":"sample"}]},"preProvWfUserInputs":{"list":[{"name":"sample","value":"sample"},{"name":"sample","value":"sample"}]},"enablePreProvisioningCustomActions":true,"preProvisionWorkFlowName":"sample"}}

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