TL;DR
Based off this article I show how to pass a composite type array via json to a vRO workflow.

##Introduction##

In a previous article I demonstrated how to execute a workflow using a json payload from Powershell. If you are not sure how this is done, please refer to it before reading below.

A recent Puppet based vRO workflow I have been working on takes an optional composite type array to be POSTed. This is a slightly more complex looking piece of json and it took me sometime, and lost hair, to get it working.

To give some background, the workflow used in this example is the Puppet plugin workflow “Classify Node with Manifest” that has an optional type called “Array/CompositeType(name:string,value:string):PuppetClassParameters”.
This can be used to pass in parameters to a Puppet class on the node from the vRO workflow.

The Puppet plugin offers many workflows, including remdiation, but here we are only discussing the “Classify Node with Manifest” workflow.

Below I will show you the json and then how I managed to work out what the workflow was expecting to receive.

##The vRO workflow##

The vRO workflow in this example is expecting the following parameters;

className 		= The classname you want to inject into the <nodename.pp> file
classParameters 	= Parameters you need to pass for a configured Puppet class
masterName 		= The Puppet master server
environment		= The environment that the Puppet master is going to use. i.e., dev, prod etc
vmMoRefID		= The VM Managed Object Reference ID, for example 'vm-246870'  

##The JSON##

Here is the section related to composite type. It is part of a bigger piece of json that you can view here.

  
    {
      "value": {
        "array": {
          "elements": [
            {
              "composite": {
                "type": "CompositeType(name:string,value:string):PuppetClassParameters",
                "property": [
                  {
                    "id": "name",
                    "value": {
                      "string": {
                        "value": "CLASS-NAME-VALUE"
                      }
                    }
                  },
                  {
                    "id": "value",
                    "value": {
                      "string": {
                        "value": "CLASS-VALUE"
                      }
                    }
                  }
                ]
              }
            }
          ]
        }
      },
      "type": "Array/CompositeType(name:string,value:string):PuppetClassParameters",
      "name": "classParameters",
      "scope": "local"
    }
	

##The Powershell Code##

Function GenerateJsonForPuppetWorkflow - creates a correctly formatted json string to be used with the REST API call.

Note that the following function isn’t taking more than one key/value pair but could be easily modified to do so.

	<#
	.SYNOPSIS Generates required json formatted payload for invocation against the vRO API
	
	.Description

	Parameters
	$strVMName		= VM Name
	$strClassName	= Classname that you want injecting into the node definition ,<vmName>.pp on your Puppet master
	$hashClassParams = key/value hash
	$strMasterName	= Puppet master
	$strEnvironment	= Puppet master environment. (dev, prod, ua etc)

	#>

	Function GenerateJsonForPuppetWorkflow($strVMName, $strClassName, $strMasterName, $strEnvironment) {
	
	$strVMMoRefID = GetMoRefFromVMName $strVMName

	# Prepare the Json formatted string
	$strJsonBody = "{""parameters"":[{""value"":{""string"":{""value"":""$($strClassName)""}},""type"":""string"",""name"":""className"",""scope"":""local""},`
	{""value"":{""array"":{""elements"":[{""composite"":{""type"":""CompositeType(name:string,value:string):PuppetClassParameters"",`
	""property"":[{""id"":""name"",""value"":{""string"":{""value"":""$($hashClassParams.Keys)""}}},{""id"":""value"",""value"":{""string"":{""value"":""$($hashClassParams.Values)""}}}]}}]}},`
	""type"":""Array/CompositeType(name:string,value:string):PuppetClassParameters"",""name"":""classParameters"",""scope"":""local""},`
	{""value"":{""string"":{""value"":""$($strMasterName)""}},""type"":""string"",""name"":""masterName"",""scope"":""local""},{""value"":{""string"":{""value"":""cdads""}},`
	""type"":""string"",""name"":""environment"",""scope"":""local""},{""value"":{""string"":{""value"":""$($strVMMoRefID)""}},""type"":""string"",""name"":""vmMoRefID"",""scope"":""local""}]}"

	return $strJsonBody

	}
	

The LogWrite function call you will see below is a function I use to create my log files. I haven’t supplied that function here, so you can just comment it out.

Function GetMoRefFromVMName - returns the MoRefID of a virtual machine from a currently established vCenter connection This is used to identify the VC:Virtualmachine object of the VM as a required input to the vRO workflow that runs later.

  
    <# .SYNOPSIS Returns the VMs unique vCenter MoRefID (Machine Object Reference ID). This is used to identify the VC:Virtualmachine
			  object of the VM as a required input to the vRO workflow that runs later. #>  

	Function GetMoRefFromVMName($strVMName) {

	$vmMoRef = Get-VM | select name,id | where {$_.name -EQ $strVMName}
	[string]$strVMMoRefID = $vmMoRef.Id
	$strVMMoRefID = $strVMMoRefID.Replace("VirtualMachine-","")
	return $strVMMoRefID
	}
	

##How to determine what the workflow is expecting

Working out how the workflow wanted the parameters formatted turned out to be a head banging affair until I came across the excellent vCO Team post that explained how to do it. I won’t repeat their work here, but i’ll give a brief synopsis of how it’s done.

Basically you execute the workflow with all the parameters within the vRO client. Once this has been achieved you can then perform a REST GET request on the executed workflow id. To explain, each workflow has a unique ‘id’ as does an executed workflow.

So with the executed workflow you now have a new id that you can use to view details of the execution.

Cutting to the chase, here is an example of a GET request on an executed workflow. ID’s are made up for example purposes.

I have been using the Chrome Advanced REST Client to perform the GET request.

https://**vCOSERVER**:8281/vco/api/workflows/9966dfg43sd-4b31-466c-bfd4-f46333dgdfg6/executions/ff864643141c156470141c1e22f2a0012  

                                            {          The workflow id              }          {    The executed workflow id    }  

In the response from this request you will be able to see all the parameters passed to the workflow and the format in which they were passed. You can also download the resultant json to further analyse the format.

If you have any questions, comments or praise/criticsm please drop it into the comments thread below.

##Useful Links and Tools##

How to use the REST API to Start a Workflow

Read the section “That’s nice, but HOW did you figure that out?” for enlightenment!
VMware Puppet Plugin v1.0 Documentation

Tools
Online JSON Viewer
Chrome Advanced REST Client Extension