vRA Developer: Part 3 – Performing CRUD Operations on IaaS Entity Objects

In a previous post vRA Developer: Part 1 – IaaS & Understanding The Entity Framework I detailed what the Entity Framework is and how objects and their properties could be discovered using an application called LINQPad.

This post is going to detail how we can interact with the IaaS servers and work with the objects within the Entity Framework. I have also written a number of actions that provide a standard interface to use when working with the entities and perform CRUD (Create, Read, Update, Delete) operations on them. 

Note: these actions are designed to be used with wrappers for your code (i.e. other actions performing a task, which call these actions) and not directly in your workflows (although there is no real harm if you want to, it’s just cleaner not to). Read more “vRA Developer: Part 3 – Performing CRUD Operations on IaaS Entity Objects”

vRA Developer: Part 2 – Dynamically Discover vCAC and vCACCAFE endpoints in vRO

When I work with endpoints in vRO, I like to use actions to discover these instead of hard coding them as attributes or within configuration elements. Hard coding of these endpoints requires manual configuration steps when moving code between environments, which is not ideal. I felt it would be a good idea to include this post early on within this series, as these hosts are often dependencies when working with a lot of my code.

All code that I have provided or talked about in this post can be downloaded as a vRO package for your consumption here.

Discover vRealize Automation Infrastructure (vCAC IaaS) Endpoint

You will generally only have a single vCAC IaaS endpoint in your vRO inventory. I have never worked in an environment where there was more than one. Therefore, the action I have created below requires no inputs and will attempt to discover this single vCAC IaaS endpoint. If you have more than one host for some reason then it should be fairly easy to incorporate this.

/*global System Server*/

 * Searches the vRO inventory for any instance of a vCACHost object and returns it.
 * Note that this action assumes that only a single vCACHost is present (as is usually the case).
 * @author Gavin Stephens <gavin.stephens@simplygeek.co.uk>
 * @version 1.1.0
 * @function getVcacHost
 * @returns {vCAC:vCACHost} returns the vCAC host object.

var logType = "Action";
var logName = "getVcacHost";
var Logger = System.getModule("com.simplygeek.library.util").logger(logType, logName);
var log = new Logger(logType, logName);
var vcacHosts = [];
var vcacHost;

try {
    log.log("Locating vCAC IaaS Host...");
    vcacHosts = Server.findAllForType("VCAC:VCACHost");
    if (vcacHosts.length === 1) {
        vcacHost = vcacHosts[0];
        log.log("Found vCAC IaaS host: " + vcacHost.name + " [" + vcacHost.url + "]");
    } else if (vcacHosts.length > 1) {
        log.error("More than 1 vCAC IaaS host was found, which this action does not support.");
    } else {
        log.error("Unable to find vCAC IaaS host from the vRO plugins.");
} catch (e) {
    log.error("Failed to locate vCAC IaaS Host.",e);

return vcacHost;

Log output:

[] [I] [Action: getVcacHost] Locating vCAC IaaS Host...
[] [I] [Action: getVcacHost] Found vCAC IaaS host: IaaS host for Default [https://web.vra.sgroot.local/]

Read more “vRA Developer: Part 2 – Dynamically Discover vCAC and vCACCAFE endpoints in vRO”

vRealize Orchestrator: Standardised Logger Action

I have updated this page on 22nd Jan 2019 to introduce enhancements over the original logging action. I have converted the original function calls to an object based approach. This allows a logger object to be used, which looks cleaner and is initialised once. I have also introduced JSDoc documentation styles into my code.

One bugbear that I have with vRO is the limitation around system (console) logging. There is currently no way to dynamically output the name of an action or sub-workflow (see end of the post). I like to see exactly which action or workflow is executing code. This makes it easier for me to troubleshoot a defect, when I am looking at the output logs.

It is possible to use ‘workflow.name’ or ‘this.name’ inside an action, but this will always be set to the name of the initial workflow that was executed. This is because the workflow object is implicitly passed to the action that is called. The result, is that it will look like all the code is executing from the workflow (which is technically true, but I needed more granularity).

I therefore created a standardised way that workflow and action logging should be handled. This is achieved by using an action that will actually handle all the logging for me. The idea is, that an action or workflow will call the ‘logger‘ action, providing some parameters, that allow for a consistent and useful logging experience. Read more “vRealize Orchestrator: Standardised Logger Action”

vRealize Orchestrator: Standardising Modules & Actions

I have updated this page on 22nd Jan 2019 to introduce improvements over the original Action template and module structure. I have introduced the new logger object and JSDoc documentation styles into my code.

Managing your code base in vRealize Orchestrator can be quite challenging and complex. Often, you won’t realise this until you’ve reached a point where it becomes difficult and time consuming to both organise or locate existing code that you have written. In this post, I am going to suggest ways to help you organise your code better, using methods that I have adopted with my time using vRO.

I am not suggesting this be the perfect solution, but it should provide a working standard to adopt to your own needs. I would also argue that the extra time spent getting this in place on the outset, will lead to time saved later on.

Just for reference, from this point on, I am going to refer to ‘code base‘ and ‘actions‘ interchangeably, because your vRO actions ARE your code base. Almost every single line of code you write in vRO should be in an action (I will discuss this in more detail in a later post which I will link here).


Here are some general principles I like to follow when creating actions: As a general rule, actions should:

  • Contain small, manageable chunks of code that perform a specific task. Actions are just functions and just like any function, it should contain code that performs a specific task. If your action is doing many different tasks, then consider breaking these down into multiple, smaller actions.
  • Validate inputs. I appreciate that some may debate this idea, but actions are not ‘private functions’. They are public code where you can never guarantee that the action ‘caller’ is properly validating its inputs. This is the nature of vRO, it is a ‘hub’ that has many different uses cases and scenarios for executing the same actions. I have seen dozens of cases where developers and support engineers have wasted time tracking unexpected errors;
  • Be named appropriate to the task they perform. I generally like to use verbs in my action names, like, ‘getVirtualMachineNames’, ‘getVirtualMachineNetworks’ or ‘setCustomProperty’. Actions named this way will make it easier for other developers to identify what they are used for;
  • Have variables declared in a single block. This will just make it easier to see what variables are being used. The data type can also be defined, but is not always necessary or as important;
  • Provide consistent logging throughout. Make it so, the action almost tells the story of what is happening. Don’t go overboard, but generally a before, during and after style to logging works quite well;
  • Nesting actions within an action is generally ‘OK’ but keep it to a minimum if possible. Too many nested actions can create depth that may be more difficult to maintain and troubleshoot later on. Typical use cases are ‘helper’ or ‘utility’ actions (you’ll be completely forgiven with actions used for workflow presentation as these are a pain);
  • Perform singular tasks. Don’t write actions that perform plural tasks. Write the singular version first, then use a looping mechanism that re-uses the singular action (there are also ways this can be achieved with performance in mind in vRO). This way you’ll only have 1 version of the code;
  • Be based on a user-defined template. Yup, I’m not crazy. Have a defined template (aka boilerplate) set out on how an action should generally look and have the team follow this. It will make code reviews far easier;
  • Always use camel cased alphabetical characters (no dots);

Read more “vRealize Orchestrator: Standardising Modules & Actions”

Using the indexOf() method for Arrays and Strings for vRO and vRA

I’ve never been a developer so getting into JavaScript was quite a challenge at first and I probably always went the longest route possible to achieve something. As I use it more and more, I am picking up these neat little tricks and uses for built in methods that make my life easier.

In the world of vRA and vRO, I find that most of my time is spent iterating over arrays or parsing custom properties. One method that I have come to find extremely useful is the indexOf() that is available on Arrays and Strings. The methods are very similar but have very different use cases. Let’s take a look at each of them in turn.

String indexOf() Method

w3schools.com defines this as:

The indexOf() method returns the position of the first occurrence of a specified value in a string.

This method returns -1 if the value to search for never occurs.

So as an example, if we had the string “simplygeek.co.uk is fun”

string.indexOf(“m”) would return 2, which is the index within the string that ‘m’ first appears. Note that if ‘m’ appeared twice then only the first match would return a result. Indexes within arrays and strings always start at 0.

Another use case, one which I find the most useful, is being able to provide a string for the lookup. Take the following example:

string.indexOf(“simplygeek”) would return 0, because in a contiguous match the first index is returned.

When writing JavaScript that interacts with vRA you are often required to parse through custom properties, which are key value pairs of data. Such properties can contain useful information that relates to a deployment, such as virtual machine configuration. If custom properties follow a standardised naming convention, it can be easy to discover a set of properties. Let’s assume I have created the following custom properties in vRA for a deployment:

Custom.Deployment.Virtualmachine.Config.hotcpu : true
Custom.Deployment.Virtualmachine.Config.hotmem : true
Custom.Deployment.Virtualmachine.Config.sched.swap.vmxSwapEnabled : true

When the payload is sent to my vRO workflow it could contain over a 100 different key:value pairs of data. To find these easily I can use the indexOf method to iterate over each pair as follows:

var deploymentProp = new Properties;
var arrayOfDeploymentProps = [];
for each (var key in props.keys) {
    if (key.indexOf("Custom.Deployment.Virtualmachine.Config") === 0) {
        // We found a deployment property!
        deploymentProp.put(key, props.get(key));

The above will result in an array of properties related to virtual machine configs. I can then pass this array to some code that will handle the implementation of these advanced virtual machine settings. This allows for a very dynamic way to manage custom properties in property groups within vRA.

Array indexOf() method

Very similar to the String method, on an array, the indexOf() method returns the first index at which a given element can be found in the array, or -1 if it is not present. I find this method useful when I need to return a set of unique values from another array. let’s assume we have the following array:

myArray = [‘one’, ‘two’, ‘two’, ‘three’, ‘three’, ‘three’]

If I wanted to return only unique items from myArray, I could use the indexOf method as follows:

var myArray = ['one', 'two', 'two', 'three', 'three', 'three'];
var uniqueItems = [];
for each (var item in myArray) {
    if (uniqueItems.indexOf(item) === -1) {
        // we didn't find this item in the array so add it.
        // When we get to the second 'two', the value of indexOf() will return '2' and the code above will not be executed.

The above code will result in an array:

[‘one’, ‘two’, ‘three’]

I hope that someone else finds these as useful as I have. If you know of more use cases, then please let me know.

vRO Coding Pet Hate – Badly formed IF statements

I was optimising some vRO actions today and came across something that always annoys me when I see it, badly formed IF statements (for one of a better description). When I write my code, I have learned that formatting and consistency is key to produce code that is easier to read and understand. I also like to keep things simple. However, I am constantly surprised at how much sloppy coding practices I encounter from the code that is shipped with vRO. Here are a couple of small examples of the kind of thing I am talking about.

if (ip == null) throw  "ReferenceError: ip cannot be null";
if (netBIOS != null)
    ipSettings.netBIOS = VcCustomizationNetBIOSMode.fromString(netBIOS.name) ;

Both of the above statements are pretty much identical in how they function. They are checking if a given variable is null (or not) and if the condition returns ‘true’ then execute the following statement. As you can see from the code snippets above, the structure of these statements are different. Why? Because this is a valid way to write conditionals in JavaScript, if you are only performing an action when the result is ‘true’. That said, it doesn’t mean we should use it in practice. The reason for this, is that it forces a lack of consistency in your code (which you can already see from the code above).

If we wanted to add another action for a result that returns ‘false’, we would need to add an ‘else’ clause. With the conditional statements above, we wouldn’t be able to do this as it would require adding curly braces so that the interpreter knows when to apply the correct code based on the result. Here is an example.

if (condition) {
} else {

This is the structure that I like to adhere to every time I write a conditional. I also apply the ‘4 spaces rule’ for my indentation (and don’t get me started on the use of tab!). The two code snippets revised using this structure would look like:

if (ip == null) {
    throw  "ReferenceError: IP cannot be null";
if (netBIOS != null) {
    ipSettings.netBIOS = VcCustomizationNetBIOSMode.fromString(netBIOS.name);

I believe this is a much neater approach for the sake of a few more lines, which aren’t worth saving if the code is more readable.

Get a list of Datastores, quickly, using XPATH

The vCenter plugin has a very useful method for retrieving a list of objects quickly and easily. However, if your inventory is quite large, then this can be quite slow. There are two ways that this can be improved. 1) only retrieve the attributes that are useful for our code requirements, 2) use an XPATH query filter to limit the scope of the search.

In my situation there were over a 100 Datastores but I only wanted to retrieve a list based on a given prefix (of which there were less than 10). The Datastore names end with an incrementing number and I wanted to return all of these in an array.

// Set the Datastore name Prefix to search on.
var DsNamePrefix = "DS_MYDATASTORE_";

// Declare which Datastore properties we care about to speed up processing.
var DsProps = ['info', 'summary'];
// Setting the XPATH massively improves performance retrieving the Datastore list.
var XPath = "xpath:@name[starts-with(.,'" + DsNamePrefix + "')]";
// Get an array of all the datastores found.
var VcDsArray = VcPlugin.getAllDatastores(DsProps, XPath);
System.debug("Number of datastores found: " + VcDsArray.length);

I have used a similar approach which allowed me to retrieve several thousand virtual machines in approximately 3-5 seconds.

Get Datastore with Most Free Space & Check Datastore Meets Capacity Reservation

I do a lot of work that involves either creating new virtual hard disks or attaching existing ones to virtual machines in VMware vSphere. I do all of this through vRealize Orchestrator, written in JavaScript (yum).

As part of this task, I always ensure that the datastores that I am creating disks on have sufficient capacity for these new disks. I use two simple functions that I have written which perform these checks for me, which is ‘getDatastoreWithMostFreeSpace’ and ‘DoesDSMeetCapcityReserve’. An additional function ‘convertToGB’, which is used by these functions is also provided at the end.

Function : getDatastoreWithMostFreeSpace

Return a single VcDatastore object that has the most free space from an Array of provided VcDatastore objects. The function will always return a VcDatastore, regardless of how much free space is found.

– VcDatastores (Array of VcDatastore)

Return Type : VcDatastore

function getDatastoreWithMostFreeSpace(VcDatastores) {
    // Initilize variables.
    var DsWithMostFreeSpace = "";
	var maxFreeSpaceFound = 0;
	System.log("Selecting the datastore with the most free space:");
	// Loop through each VcDatastore in the Array.
	for (d in VcDatastores) {
	    // Set dsIndex to an increment of the array index (nicer than seeing numbers that start from 0).
	    var dsIndex = Number(d+1);
	    // Check if the Datastore is in maintenance mode.
	    if (VcDatastores[d].summary.maintenanceMode === 'normal') {
	        // Update free space and capacity usage information for the current Datastore.
            // Output Datastore info.
		    System.log("Datastore " + dsIndex + " information:");
		    System.log("\tname: " + VcDatastores[d].name);
			System.log("\tID: " + VcDatastores[d].id);
			// Get Datastore Capacity value.
		    var DsCapacityGB = convertToGB(VcDatastores[d].summary.capacity);
		    System.log("\tCapacity: " + DsCapacityGB + " GB");
		    // Get Datastore Free Space value.
			var DsFreeSpaceGB = convertToGB(VcDatastores[d].summary.freeSpace);
		    System.log("\tFree Space: " + DsFreeSpaceGB + " GB");
		    // Get Datastore Used Space value.
		    var DsUsedSpaceGB = DsCapacityGB - DsFreeSpaceGB;
		    System.log("\tUsed Space: " + DsUsedSpaceGB + " GB");
		    // Get maximum supported VMDK size.
		    var DsMaxVMDKSizeGB = convertToGB(VcDatastores[d].info.maxVirtualDiskCapacity);
		    System.log("\tMaxVMDKSize: " + DsMaxVMDKSizeGB + " GB");
		    // Check if the current datastore has the most free space and remember this datastore.
		    if (DsFreeSpaceGB > maxFreeSpaceFound) {
		        maxFreeSpaceFound = DsFreeSpaceGB;
				DsWithMostFreeSpace = VcDatastores[d];
		    } // End if
        } else {
            // Output a warning if current datastore is currently in maintenance mode.
            System.warn("Datastore: '" + DsWithMostFreeSpace.name + "' in state: '" + VcDatastores[d].summary.maintenanceMode + "'. Skipping.");
        } //End if
	} // End for
    // Return a single VcDatastore object.
	return DsWithMostFreeSpace;

Function : DoesDSMeetCapcityReserve

Checks that a given VcDatastore has enough free space in which to place the virtual disk, taking into account current usage and a defined reservation value (in percent) that should be guaranteed. Returns true if the Datastore passes the capacity checks.

– datastore (VcDatastore)
– reservation (Number)
– totalSizeRequired (Number)

Return Type : Boolean

function DoesDSMeetCapcityReserve(datastore, reservation, totalSizeRequired) {
    // Set meetsReservation to default to false.
    var meetsReservation = false;
    var DsCapacityGB = convertToGB(datastore.summary.capacity);
    var DsFreeSpaceGB = convertToGB(datastore.summary.freeSpace);
    // Get the percentage of free space available.
    var DsPercentFree = Math.ceil((DsFreeSpaceGB/DsCapacityGB)*100);
    System.log("Datastore reservation is set to " + reservation + "%");
    System.log("Datastore has: " + DsPercentFree + "% free space");

    if (DsPercentFree > reservation) {
        System.log("Datastore meets " + reservation + "% reservation threshold.")
        System.log("Checking that enough storage is available for the disks");
        var reservationSizeGB = Math.ceil((DsCapacityGB/100)*reservation);

        System.log("The reserved size at " + reservation +  "% is: " + reservationSizeGB + " GB");
        var freeSpaceWithoutReserve = (DsFreeSpaceGB - reservationSizeGB);
        System.log("Free space available taking into account the reservation: " + freeSpaceWithoutReserve + " GB");

        var freeSpaceAfterCommit = (freeSpaceWithoutReserve - totalSizeRequired);
        System.log("The datastore will have " + freeSpaceAfterCommit + " GB of usable space remaining after the commit");

        if (freeSpaceAfterCommit > 0) {
            System.log("Datastore meets capacity requirements");
            meetsReservation = true;
    return meetsReservation;

Function : convertToGB

Converts a value in Bytes to GB.

– size (Number)

Return Type : Number

function convertToGB(size) {
    sizeGB = Math.ceil(size/1024/1024/1024);
    return sizeGB;

Example Output

[2017-09-18 15:09:37.459] [I] Selecting the datastore with the most free space:
[2017-09-18 15:09:37.714] [I] Datastore 1 information:
[2017-09-18 15:09:37.715] [I] name: DATASTORE1
[2017-09-18 15:09:37.717] [I] ID: datastore-99999
[2017-09-18 15:09:37.718] [I] Capacity: 2048 GB
[2017-09-18 15:09:37.719] [I] Free Space: 1762 GB
[2017-09-18 15:09:37.721] [I] Used Space: 286 GB
[2017-09-18 15:09:37.725] [I] MaxVMDKSize: 63488 GB
[2017-09-18 15:09:37.726] [I] Selected Candidate Datastore: DATASTORE1
[2017-09-18 15:09:37.728] [I] Performing capacity validation checks on the datastore.
[2017-09-18 15:09:37.729] [I] Datastore reservation is set to 10%
[2017-09-18 15:09:37.730] [I] Datastore has: 87% free space
[2017-09-18 15:09:37.733] [I] Datastore meets 10% reservation threshold.
[2017-09-18 15:09:37.735] [I] Checking that enough storage is available for the virtual disk(s)
[2017-09-18 15:09:37.737] [I] The reserved size at 10% is: 205 GB
[2017-09-18 15:09:37.738] [I] Free space available taking into account the reservation: 1557 GB
[2017-09-18 15:09:37.740] [I] The datastore will have 1556 GB of usable space remaining after the commit
[2017-09-18 15:09:37.741] [I] Datastore meets capacity requirements
[2017-09-18 15:09:37.744] [I] The Virtual Disk(s) will be located on: DATASTORE1