Executing a vRO action via REST API

The ability to execute a vRO workflow or action via API is useful if you are using vRA or vRO as part of an overall CI/CD pipeline. If a vRA catalog item uses vRO actions to filter or set values on a custom form how can this be done if the vRA catalog item will be requested via REST.

In the example below I have a simple action that takes two inputs:

  • firstName – Type:String
  • secondName – Type:String

In order to be able to execute a vRO action you need to submit basic auth credentials. This will require the user account to be a member of the vco-admins group in vRO. This can either be a local user or an Active Directory user if vRA has been configured to integrate with Active Directory

The process for being able to execute the action via REST is a three part step. Part 1 is to determine the ID of the action that you wish to call. Execute the following operation:

GET - https://vro-fqdn/vco/api/actions

The result will be a large array of actions that looks something like this:

{
     "link": [
         {
             "attributes": [
                 {
                     "value": "d7e461f6-b88f-4f63-a2cc-7f3c76d1bd19",
                     "name": "id"
                 },
                 {
                     "value": "isBlocking",
                     "name": "name"
                 },
                 {
                     "name": "description"
                 },
                 {
                     "value": "com.vmware.library.vcaccafe.workflow.subscription/isBlocking",
                     "name": "fqn"
                 },
                 {
                     "value": "0.0.0",
                     "name": "version"
                 }
             ],
             .......

You’ll need to process this array to search for the name of the action that you wish to execute.

Part 2 is to retrieve the inputs for the action which is achieved via the following REST operation:

GET - https://vro-fqdn/vco/api/actions/{actionid}

The result will look something like this:

{

    "href": "https://192.168.1.26:443/vco/api/actions/278a1622-1924-4f37-bb24-0c5d36346ae9/",
    "relations": {
        "link": [
            {
                "href": "https://192.168.1.26:443/vco/api/actions/com.cloudkindergarten.examples/executedByApi/",
                "rel": "alternate"
            },
            {
                "href": "https://192.168.1.26:443/vco/api/actions/278a1622-1924-4f37-bb24-0c5d36346ae9/permissions/",
                "rel": "permissions"
            },
            {
                "href": "https://192.168.1.26:443/vco/api/actions/278a1622-1924-4f37-bb24-0c5d36346ae9/executions/",
                "rel": "executions"
            }
        ]
    },
    "id": "278a1622-1924-4f37-bb24-0c5d36346ae9",
    "output-type": "string",
    "name": "executedByApi",
    "description": "",
    "version": "0.0.0",
    "fqn": "com.cloudkindergarten.examples/executedByApi",
    "script": "var fullName = (firstName + \" \" + secondName);\nreturn fullName;",
    "input-parameters": [
        {
            "description": "",
            "type": "string",
            "name": "firstName"
        },
        {
            "description": "",
            "type": "string",
            "name": "secondName"
        }
    ]
}

From this we can see that action is expecting two input parameters; firstName and secondName both of type string.

Part 3 is to execute this action. We do this by using the following body content

{"parameters":
 [
  {
   "value": {"string":{ "value": "Andy"}},
   "type": "string",
   "name": "firstName",
   "scope": "local"
  },
  {
   "value":{"string":{"value": "Davies"}},
   "type": "string",
   "name": "secondName",
   "scope": "local"
  }
 ]
}

This is then executed with the REST Operation:

POST https://{vro-fqdn}/vco/api/actions/{actionid}/executions/

The response will hopefully be the returned value from the action. In this case the full name of the person:

{
    "value": {
        "string": {
            "value": "Andy Davies"
        }
    },
    "type": "string"
}

Configuring vRO to send emails for gmail

Overview

Google allows you to relay up to 2000 emails per rolling 24 hour period, which can be useful for development of workflows via vRO. The steps below are written for standard gmail accounts. If you have a G Suite account then the steps are subtly different in that the SMTP host name is ‘smtp-relay.gmail.com’ and not ‘smtp.gmail.com’. The message per day limit is also increased when using a G Suite account is that you can send up to 10000 messages per rolling 24 hour period. Lastly, when using vRO with a G Suite account security needs to be relaxed within G Suite to permit sending emails from less secure apps.

Required Steps

  1. Start vRO control center service – The service is disabled by default
  2. /etc/init.d/vco-configurator start
  3. Browse to the vRO control center
  4. https://vro-server-hostname:8283/vco-controlcenter/#/
  5. Go to Manage > CertificatesScreen Shot 2018-05-02 at 22.18.10
  6. Click Import > Import from URLScreen Shot 2018-05-02 at 22.20.15
  7. Enter the URL as ‘smtp.gmail.com:587’ or ‘smtp-relay.gmail.com:587’Screen Shot 2018-05-02 at 22.21.53
  8. Review the certificate and then click ImportScreen Shot 2018-05-02 at 22.22.12
  9. Once the certificate is imported you can use the OOTB workflow called ‘Send notification’. The settings used will be as follows:
Input Name Value
smtpHost smtp.gmail.com
smtpPort 587
username gmail email address
password gmail password
useSsl No
useStartTls Yes

 

 

Parsing of XML with vRealize Orchestrator

Parsing of XML is fairly straightforward with vRO, however there is one major gotcha you should be aware of; namespaces.

Depending on the XML content that vRO is trying to parse it may not return any values if certain namespaces are used. One way around this is to do a string.replace on the xml prior to parsing it.

An example of how to parse XML is shown below:

The code below is based on the following XML

<?xml version="1.0" encoding="UTF-8"?>

<CreateITDCIResponse xmlns="http://www.ibm.com/maximo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" creationDateTime="2016-06-22T13:07:11+00:00" transLanguage="EN" baseLanguage="EN" messageID="1466600831635951728" maximoVersion="7 1 20110105-1024 V7118-37"><ITDCISet>
<CI>
<CHANGEBY>Someuser</CHANGEBY>
<CHANGEDATE>2016-06-22T13:07:11+00:00</CHANGEDATE>
<CIID>123456</CIID>
<CINAME>CINAMETEST</CINAME>
<CINUM>CITEST</CINUM>
<ITDCIMANAGEDBY>TBD</ITDCIMANAGEDBY>
<ITDCIOPERATINGENV>TBD</ITDCIOPERATINGENV>
<ITDSERVCONTPLAN>0</ITDSERVCONTPLAN>
<STATUS>VERIFY</STATUS>
<STATUSDATE>2016-06-22T13:07:11+00:00</STATUSDATE>
</CI>
</ITDCISet>
</CreateITDCIResponse>

And this is the vRO code used to extract a specific field, in this case the CIID

// Strip out the namespace definition as vRO doesn't handle the definitions very well

var modifiedXMLString = xmlString.replace('xmlns="http://www.ibm.com/maximo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"',"");


var parsedXML = new XML(modifiedXMLString)

// Check to see whether we have any content

if (!parsedXML) {
 var errorCode = "Invalid XML Document";
 throw "Invalid XML document";
}

// Validate that only 1 CI has been returned

if (parsedXML.ITDCISet.CI.length() != 1) {
 var errorCode = "Invalid number of CIs returned";
 throw "Invalid number of CIs returned";
}

else {
 for each (CI in parsedXML.ITDCISet.CI) {
 System.log("The CI number is: " + CI.CIID);
 }
 }

Manipulating virtual machine advanced parameters with vRO

I’ve recently had to manipulate virtual machine advanced parameters via vRO workflows due to a need to manipulate the multi-writer flag of virtual machine disks. I’ve written vRO actions to perform the following:

  1. Add new advanced parameter
  2. Amend an existing advanced parameter
  3. Read the value of an existing advanced parameter
  4. Read the values of all existing advanced parameters

addAdvancedSettingtoVM

This action can be used both to add a new advanced parameter and also amend an existing advanced parameter.

var changedValue = new Array()
changedValue[0] = new VcOptionValue();
changedValue[0].key = optionKey;
changedValue[0].value = optionValue;
var ConfigSpec = new VcVirtualMachineConfigSpec();
ConfigSpec.extraConfig = changedValue;
vmTask = vm.reconfigVM_Task(ConfigSpec);
return vmTask;

Inputs:

optionKey – type string

optionValue – type string

vm – type VC:VirtualMachine

Return Type:

VC:Task

getAdvancedSettingsfromVM

This action will return all of the advanced parameters of a virtual machine as an array.

var advancedProperties = new Array()
var extraConfig = vm.config.extraConfig
for each (var i in extraConfig) {
advancedProperties.push(i);
}
return advancedProperties;

Inputs:

vm – type VC:VirtualMachine

Return Type:

Array/string