Making vCO Workflow Wrappers

A vCO workflow wrapper is a set of workflow tasks that are added at the beginning of a workflow in order to take string values and look up a more complex data type or pre-defining inputs using attributes. You may have done these in the past already in vCO. Some examples would be finding a virtual machine by name or finding an Active Directory user by email address.

If you’re running the vCO workflow from within the vCO client or vSphere web client, you probably don’t need to worry about this as both of those tools understand the complex data types that come with plugins. On the other hand, if you’re calling the vCO workflow from a tool like vCAC, it becomes extremely important to make it so that the vCO workflows only require strings as inputs–meaning that you need to add a vCO workflow wrapper to convert these string values to their more complex data types.

There are two ways to create this wrapper functionality: add a pre-built task or workflow that came with the plugin, or to pull back all objects of that type and then pick through the array where some conditions match.

Let’s take a look at this further.

A typical use case might be that you want to tell vCO to clone a virtual machine. To do this, we can use the vCenter plug in and the built in workflow called “Clone Virtual Machine, No Customization”. Below is a look at all the inputs and data types that this workflow is expecting to be provided with:

You’ll note that we have some complex data types. One of which is the field called “vm” which is a type of VC:VirutalMachine. This is a complex data type for the vCenter plugin (as denoted by the VC) for the object of virtual machines.

First we should figure out if there’s something already built to help us find a virtual machine by its name with the output being a VC:VirtualMachine:

  1. Open the workflow you want to change and press edit. If you’re using an out of the box one, it’s very recommended (and often required) to make a duplicate of the workflow in order to edit it.

  2. Go into the schema tab and at the top left corner of the workflow you’ll see a search field

  3. I usually enter in what kind of object it is I’m looking for. Here I searched for “virtual machine”. There is no science to this part. I simply know that I want a workflow that find the complex VC:VirtualMachine type by a string that I provide to it–probably the machine name

  4. After some perusing the list of results, I find a workflow called “Get Virtual Machine by Name”. Hey, that sounds about right!

  5. Drag and drop that task into the beginning of your workflow

  6. Go to the inputs tab, select the “vm” parameter and click the button that says “Move as attribute”.

  7. Still in the inputs screen, click the “Add Parameter” button. Rename the new parameter something descriptive like “vmName” and leave it as a string type.

  8. Switch over to the General tab and find the “vm” parameter that we just moved to be an attribute. Because the “Get Virtual Machine from name” task outputs the virtual machine into an array of virtual machines (for potential multiple results), we need to tweak the type of our attribute so that it will be able to match up to the output of the “Get Virtual Machine from name” task. Click on the VC:VirtualMachine type associated to the “vm” parameter and a box will pop up. At the top left of the box, use the radio button to set the type to “Array of” and click “Accept”.

  9. Go back to the schema tab, and click the edit button on the “Get Virtual Machine” task.

  10. Go to the Visual Binding tab and link the input of “vmName” to the search criteria in the task, and the output of “vms” to the “vm” attribute.

  11. Close that task screen. Congrats! you have just created a vCO workflow wrapper for the VC:VirtualMachine type. Your vCO workflow will now accept a string name of the virtual machine, find the complex object of VC:VirtualMachine, and pass it to the later “CloneVM” task, where it’s needed.

OK, so now let’s take a more complex issue of creating a wrapper for a object type that doesn’t have a handy piece of code already built for you. We can still use this copy of the “Clone Virtual Machine, no customization” workflow from the above instructions to demonstrate how we do this.

The rough process is that we’re going to create a scriptable task, have it pull all of the objects of that type into an array, and then compare the sting input from the user with a value on the object (usually input string = object name).

  1. You should still be in the workflow from above if you’re following along, if not open the workflow you want to change and press edit. If you’re using an out of the box one, it’s very recommended (and often required) to make a duplicate of the workflow in order to edit it.

  2. We’re going to now create a wrapper for the datastore input value. We’ll start in the inputs tab, because we know that there’s no helpful bits for looking up. Select the “datastore” parameter and press the button to “Move as Attribute”

  3. Create a new string input parameter in this screen and name it something descriptive. I named mine “stringDatastore”

  4. Go into the schema tab and at the top left corner of the workflow and, if you’re not already, go to the Generic tab in the toolbar to the right.

  5. Drag a “Scriptable Task” task into the workflow. It doesn’t really matter where it goes as long as it’s before the task that needs it–so anywhere before the “Clone VM” activity.

  6. Press edit on the Scriptable Task and do some housekeeping by giving it a descriptive task name in the Info tab’s “Name” field

  7. Go to the “In” tab, and press the “Bind to workflow parameter/attribute”. Select your string input that we’ll be using as our lookup criteria.

  8. Go to the “Out” tab, and press the “Bind to workflow parameter/attribute”. Select your complex data type that you want to end up with and store in an attribute to be used later in the workflow.

  9. Here comes the fun part. Go to the “Scripting” tab and click on the “Search API” button. In the resulting search field, put in what you’re looking for–in this case, it’s “datastore”. Make it easier on yourself by filtering to only show attributes and methods. Immediately I see a few methods that say they return all datastores in the description. TIP I find it easiest to call the VcPlugin methods. Use these ones when you can. We’re in luck, there’s a VcPlugin method to “getAllDatastores”.

  10. Click the “Go to selection” button, and then the “Close” button. It will land you back on the scripting screen with the method highlighted. You call call it using standard JavaScript addressing. This would be “VcPlugin.getAllDatastores()”.

  11. Now we have to confirm the field on the datastore object that we’ll be comparing our input string against. Again, click the “Search API” button. Search for “datastore” again, but this time filter on “Types & enumerations”. You’ll see “VC/VC:Datastores” so click “Go to selection” then “Close” to get back to the scripting screen.

  12. On the left side of the screen, it now gives me details about the object type. It tells me that there is a “name” field on this object, so I will be able to compare my input string to the object’s “name” property.

  13. Here comes the JavaScript. Basically all we’re doing here is creating a variable array to catch all the datastores. We then count how many there are in the array, then compare each one’s name, one at a time, to the string until we get a match. When we get a match, we’re going to assign it to our output variable. This code snippet comes in handy:

var datastores = VcPlugin.getAllDatastores();
var arraylength = datastores.length;
var i = 0;
while (i < arraylength){
if (datastores[i].name == stringDatastore){
    datastore = datastores[i];
  1. Close this scripting task. Congratulations! You have now created a wrapper to lookup a complex object type from its name without any help from pre-created workflows.

Now that you know how to build a wrapper for your workflows you can call them from tools like VMware’s vCloud Automation Center (vCAC). For more information on how to make calls to vCO from vCAC, please visit How to call vCO workflows from vCAC