vRA Developer: Part 7 – Working with vCAC Reservation Entities


Reservations are created in vRA to allocate memory, storage and network resources to a business group. Business groups can consume these resources by provisioning virtual machines.

In this post, I am going to cover the vCAC Reservation Entities and provide some workflows and actions that can be used to get information about reservations programmatically. This can be useful to gather information about the reservations if you are using custom XaaS processes that would not trigger the standard built-in reservation checks.

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

I have also included several workflows in the package, which provide examples of these actions being used.

You can find these under ‘Simplygeek -> Library -> Common Workflows -> vRealize Automation -> Examples -> Reservations

Get a List of Available Reservations or Get a Specific Reservation

The following code can be used to get a list of all reservations that are available for the specified tenant or retrieve a specific reservation based on its name or unique id.

This is specifically the reservation that I will be working with and will appear in the log outputs.

Get List of Available Reservations For a Tenant

The following code will accept a tenant Id and a toggle for retrieving only enabled reservations. A list of reservation string names will be returned. This isn’t as straight forward as you would hope (at least from an entities point of view), because there is no property for the tenant id on the reservation. Instead, I had to inspect the business group that the reservation is assigned to, which does have a tenant id property (this may be how the GUI does it too).

/*global vcacHost tenantId enabledOnly*/

/**
 * Gets a list of reservations that have been created for the
 * specified tenant id.
 * @author Gavin Stephens <gavin.stephens@simplygeek.co.uk>
 * @version 1.0.0
 * @function getListOfReservationNamesForTenant
 * @param {vCAC:VCACHOST} vcacHost - The vCAC Host.
 * @param {string} tenantId - The tenant id.
 * @param {boolean} [enabledOnly] - Show only Enabled reservations?
 * @returns {string[]} return a list of reservations for the tenant.
 */

function checkParams(vcacHost, tenantId) {
    var inputErrors = [];
    var errorMessage;

    if (!vcacHost || System.getObjectType(vcacHost) !== "vCAC:VCACHost") {
        inputErrors.push(" - vcacHost missing or not of type 'vCAC:VCACHost'");
    }
    if (!tenantId || typeof tenantId !== "string") {
        inputErrors.push(" - tenantId missing or not of type 'string'");
    }
    if (inputErrors.length > 0) {
        errorMessage = "Mandatory parameters not satisfied:\n" + inputErrors.join("\n");
        log.error(errorMessage);
    }
}

var logType = "Action";
var logName = "getListOfReservationNamesForTenant"; // This must be set to the name of the action
var Logger = System.getModule("com.simplygeek.library.util").logger(logType, logName);
var log = new Logger(logType, logName);
var entitySetName = "HostReservations";
var reservationNames = [];
var numReservations = 0;
var query = "";
var reservationEntities = [];
var enabledReservations = true;

try {
    checkParams(vcacHost, tenantId);
    log.log("Getting a list of reservations for tenant: " + tenantId);
    if (!enabledOnly) {
        enabledReservations = false;
    }
    query = "ProvisioningGroup/TenantID eq '" + tenantId.toLowerCase() + "'";
    if (enabledReservations) {
        query += " and Enabled eq " + enabledReservations;
    }
    reservationEntities = System.getModule("com.simplygeek.library.vcac.entities").getVcacEntitiesBySystemQuery(vcacHost,
                                                                                                                entitySetName,
                                                                                                                query);
    numReservations = reservationEntities.length;
    reservationNames = reservationEntities.map(function(x){return x.getProperty("HostReservationName");});
    for (var i = 0; i < numReservations; i++) {
        var reservationName = reservationEntities[i].getProperty("HostReservationName");
        var reservationId = reservationEntities[i].getProperty("HostReservationID");

        log.log("Found reservation '" + reservationName + "' with id '" + reservationId + "'");
    }
    log.log("Found a total of " + numReservations + " reservation(s).");
} catch (e) {
    log.error("Failed to get a list of reservations for tenant.",e);
}

return reservationNames;

Log output:

[] [I] [Action: getListOfReservationNamesForTenant] Getting a list of reservations for tenant: sg
[] [I] [Action: getListOfReservationNamesForTenant] Found reservation 'RES-SITEA-vSphere-Resource-01' with id '8e1534f6-c65c-412b-af8b-b4ad8ee3c6cb'
[] [I] [Action: getListOfReservationNamesForTenant] Found a total of 1 reservation(s).

Find Reservation Entity By Name

The following code accepts the tenant id and the reservation name and will return the vcac reservation entity object. I decided to get the reservation for a specific tenant, although I’m not sure if a name collision can occur with reservations. Either way, I prefer to narrow the search field but this can be removed if required (but I can’t see any reason to do that).

/*global vcacHost tenantId reservationName*/

/**
 * Finds the vCAC reservation entity for a tenant by name.
 * @author Gavin Stephens <gavin.stephens@simplygeek.co.uk>
 * @version 1.0.0
 * @function findReservationEntityByName
 * @param {vCAC:VCACHOST} vcacHost - The vCAC Host.
 * @param {string} tenantId - The tenant id.
 * @param {string} reservationName - The reservation name.
 * @returns {vCAC:Entity} returns the vcac reservation entity.
 */

function checkParams(vcacHost, tenantId, reservationName) {
    var inputErrors = [];
    var errorMessage;

    if (!vcacHost || System.getObjectType(vcacHost) !== "vCAC:VCACHost") {
        inputErrors.push(" - vcacHost missing or not of type 'vCAC:VCACHost'");
    }
    if (!tenantId || typeof tenantId !== "string") {
        inputErrors.push(" - tenantId missing or not of type 'string'");
    }
    if (!reservationName || typeof reservationName !== "string") {
        inputErrors.push(" - reservationName missing or not of type 'string'");
    }
    if (inputErrors.length > 0) {
        errorMessage = "Mandatory parameters not satisfied:\n" + inputErrors.join("\n");
        log.error(errorMessage);
    }
}

var logType = "Action";
var logName = "findReservationEntityByName"; // This must be set to the name of the action
var Logger = System.getModule("com.simplygeek.library.util").logger(logType, logName);
var log = new Logger(logType, logName);
var vcacEntity;
var entitySetName = "HostReservations";
var entityId = "";
var numEntities = 0;
var reservationEntities = [];
var query = "";

try {
    checkParams(vcacHost, tenantId, reservationName);
    log.log("Finding vCAC reservation entity with name '" + reservationName + "'");
    query = "ProvisioningGroup/TenantID eq '" + tenantId.toLowerCase() +
            "' and HostReservationName eq '" + reservationName + "'";
    reservationEntities = System.getModule("com.simplygeek.library.vcac.entities").getVcacEntitiesBySystemQuery(vcacHost,
                                                                                                                entitySetName,
                                                                                                                query);
    numEntities = reservationEntities.length;
    if (numEntities > 0) {
        vcacEntity = reservationEntities[0];
        entityId = vcacEntity.getProperty("HostReservationID");
        log.log("Found vCAC reservation entity '" + reservationName + "' with id '" + entityId + "'");
    } else {
        log.error("No vCAC reservation entity was found.");
    }
} catch (e) {
    log.error("Unable to find vCAC reservation entity.",e);
}

return vcacEntity;

Log output:

[] [I] [Action: findReservationEntityByName] Finding vCAC Reservation entity with name 'RES-SITEA-vSphere-Resource-01'
[] [I] [Action: findReservationEntityByName] Found vCAC reservation entity 'RES-SITEA-vSphere-Resource-01' with id '8e1534f6-c65c-412b-af8b-b4ad8ee3c6cb'

Find Reservation Entity By ID

The following code accepts the tenant id and the reservation id and will return the vcac reservation entity object. Also, see my other comments for ‘Get Reservation Entity By Name’.

/*global vcacHost tenantId reservationId*/

/**
 * Finds the vCAC reservation entity for a tenant by its id.
 * @author Gavin Stephens <gavin.stephens@simplygeek.co.uk>
 * @version 1.0.0
 * @function getReservationEntityById
 * @param {vCAC:VCACHOST} vcacHost - The vCAC Host.
 * @param {string} tenantId - The tenant id.
 * @param {string} reservationId - The reservation id.
 * @returns {vCAC:Entity} returns the vcac reservation entity.
 */

function checkParams(vcacHost, tenantId, reservationId) {
    var inputErrors = [];
    var errorMessage;

    if (!vcacHost || System.getObjectType(vcacHost) !== "vCAC:VCACHost") {
        inputErrors.push(" - vcacHost missing or not of type 'vCAC:VCACHost'");
    }
    if (!tenantId || typeof tenantId !== "string") {
        inputErrors.push(" - tenantId missing or not of type 'string'");
    }
    if (!reservationId || typeof reservationId !== "string") {
        inputErrors.push(" - reservationId missing or not of type 'string'");
    }
    if (inputErrors.length > 0) {
        errorMessage = "Mandatory parameters not satisfied:\n" + inputErrors.join("\n");
        log.error(errorMessage);
    }
}

var logType = "Action";
var logName = "getReservationEntityById"; // This must be set to the name of the action
var Logger = System.getModule("com.simplygeek.library.util").logger(logType, logName);
var log = new Logger(logType, logName);
var vcacEntity;
var entitySetName = "HostReservations";
var entityName = "";
var numEntities = 0;
var reservationEntities = [];
var query = "";

try {
    checkParams(vcacHost, tenantId, reservationId);
    log.log("Finding vCAC reservation entity with id '" + reservationId + "'");
    query = "ProvisioningGroup/TenantID eq '" + tenantId.toLowerCase() +
            "' and HostReservationID eq guid'" + reservationId + "'";
    reservationEntities = System.getModule("com.simplygeek.library.vcac.entities").getVcacEntitiesBySystemQuery(vcacHost,
                                                                                                                entitySetName,
                                                                                                                query);
    numEntities = reservationEntities.length;
    if (numEntities > 0) {
        vcacEntity = reservationEntities[0];
        entityName = vcacEntity.getProperty("HostReservationName");
        log.log("Found vCAC reservation entity '" + entityName + "' with id '" + reservationId + "'");
    } else {
        log.error("No vCAC reservation entity was found.");
    }
} catch (e) {
    log.error("Unable to find vCAC reservation entity.",e);
}

return vcacEntity;

Log output:

[] [I] [Action: findReservationEntityById] Finding vCAC Reservation entity with id '8e1534f6-c65c-412b-af8b-b4ad8ee3c6cb'
[] [I] [Action: findReservationEntityById] Found vCAC reservation entity 'RES-SITEA-vSphere-Resource-01' with id '8e1534f6-c65c-412b-af8b-b4ad8ee3c6cb'

Get Reservation Property Values

The reservation entity object has a method ‘.getProperty(“key_string”)‘ that can be used to retrieve a value for a specified property key. When I need to retrieve a value for a property on a reservation, I use a helper Action that calls this method and does the main part of the work. I then wrap other Actions around this for the specific property that I need the value for. This can seem a little repetitive but with all the Actions in place, I simply drop them onto my workflows without any thought.

I have created Actions that can retrieve the value for the following reservation properties, where the correct data type is returned (note this is not the complete set of properties available but the only ones you are ever going to need).

Property Data Type Description
HostReservationID string The reservation entity id
HostReservationName string The reservation name
Enabled boolean A flag to indicate whether the reservation is enabled or not
ReservationMemorySizeMB number The total memory that has been allocated to the reservation
ReservationStorageSizeGB number The total storage that has been allocated to the reservation. Note this includes all storage reserved across all datastores
ReservationPriority number The reservation priority

I will provide example code for getting one of these properties, but the package link at the beginning of this post will provide Actions for all the above properties.

The following code is the main helper action that retrieves the property value (you will have seen this same code in my previous posts as it’s common code).

/*global vcacEntity, propertyKey*/

/**
 * Retrieves the property value from the provided vCAC Entity and property key.
 * @author Gavin Stephens <gavin.stephens@simplygeek.co.uk>
 * @version 1.1.0
 * @function getPropertyValueFromVcacEntity
 * @param {vCAC:Entity} vcacEntity - The vCAC Entity to get the property value from.
 * @param {string} propertyKey - The property key.
 * @returns {Any} returns the property value.
 */

function checkParams(vcacEntity, propertyKey) {
    var inputErrors = [];
    var errorMessage;
    if (!vcacEntity || System.getObjectType(vcacEntity) !== "vCAC:Entity") {
        inputErrors.push(" - vcacEntity missing or not of type 'vCAC:Entity'");
    }
    if (!propertyKey || typeof propertyKey !== "string") {
        inputErrors.push(" - propertyKey missing or not of type 'string'");
    }
    if (inputErrors.length > 0) {
        errorMessage = "Mandatory parameters not satisfied:\n" + inputErrors.join("\n");
        log.error(errorMessage);
    }
}

var logType = "Action";
var logName = "getPropertyValueFromVcacEntity"; // This must be set to the name of the action
var Logger = System.getModule("com.simplygeek.library.util").logger(logType, logName);
var log = new Logger(logType, logName);
var propertyValue;

try {
    checkParams(vcacEntity, propertyKey);
    log.debug("Getting property value from vcac entity using key: " + propertyKey);
    propertyValue = vcacEntity.getProperty(propertyKey);
    if (!propertyValue) {
        if (propertyValue !== false) {
            log.error("No property value found for '" + propertyKey + "' on vcac entity.");
        }
    }
    log.debug("Found value: " + propertyValue);
} catch (e) {
    log.error("Action failed to get property value from vcac entity.",e);
}

return propertyValue;

This is an example of one of the Actions which acts as a wrapper for the above, that is used to get the reservation priority.

/*global reservationEntity*/

/**
 * Retrieves the value of the 'ReservationPriority' property for the provided vCAC reservation entity.
 * @author Gavin Stephens <gavin.stephens@simplygeek.co.uk>
 * @version 1.0.0
 * @function getReservationPriorityForReservationEntity
 * @param {vCAC:Entity} reservationEntity - The vCAC reservation entity.
 * @returns {number} Returns the reservation priority.
 */

function checkParams(reservationEntity) {
    var inputErrors = [];
    var errorMessage;

    if (!reservationEntity || System.getObjectType(reservationEntity) !== "vCAC:Entity") {
        inputErrors.push(" - reservationEntity missing or not of type 'vCAC:Entity'");
    }
    if (inputErrors.length > 0) {
        errorMessage = "Mandatory parameters not satisfied:\n" + inputErrors.join("\n");
        log.error(errorMessage);
    }
}

var logType = "Action";
var logName = "getReservationPriorityForReservationEntity"; // This must be set to the name of the action
var Logger = System.getModule("com.simplygeek.library.util").logger(logType, logName);
var log = new Logger(logType, logName);
var propertyKey = "ReservationPriority";
var propertyValue;

try {
    checkParams(reservationEntity);
    log.log("Retrieving property '" + propertyKey + "' from reservation entity.");
    try {
        propertyValue = System.getModule("com.simplygeek.library.vcac.entities").getPropertyValueFromVcacEntity(reservationEntity,
                                                                                                                propertyKey);
    } catch (e) {
        propertyValue = 0;
    }
    log.log("Found " + propertyKey + ": " + propertyValue);
} catch (e) {
    log.error("Action failed to get property from reservation entity.",e);
}

return propertyValue;

Log output:

[] [I] [Action: getReservationPriorityForReservationEntity] Retrieving property 'ReservationPriority' from reservation entity.
[] [I] [Action: getReservationPriorityForReservationEntity] Found ReservationPriority: 1

Get Reservation Custom Properties

Just like virtual machines, custom properties can also be created on reservations (see my previous post: vRA Developer: Part 6 – Working with vCAC Virtual Machine Custom Properties. Although these are generally not used extensively, they can be useful for storing metadata on the reservation that is then inherited by the virtual machine. One use case I have seen is assigning a site-specific ID as a custom property on the reservation, which is then assigned to the virtual machines using the reservation.

I added some custom properties to the reservation to run this code:

Get Reservation Custom Properties Set

The following code will accept a reservation entity and will return a Properties object that contains all the key/value pairs of the custom properties. In my example, I have created 2 custom properties on the reservation which you can see are being returned in the log output:

/*global System Properties vcacHost reservationEntity*/

/**
 * Gets the custom properties that are associated with the provided vcac reservation.
 * @author Gavin Stephens <gavin.stephens@simplygeek.co.uk>
 * @version 1.0.0
 * @function getReservationCustomProperties
 * @param {vCAC:VCACHOST} vcacHost - The vCAC Host.
 * @param {vCAC:Entity} reservationEntity - The vCAC reservation entity.
 * @returns {Properties} Returns the custom properties.
 */

function checkParams(vcacHost, reservationEntity) {
    var inputErrors = [];
    var errorMessage;

    if (!vcacHost || System.getObjectType(vcacHost) !== "vCAC:VCACHost") {
        inputErrors.push(" - vcacHost missing or not of type 'vCAC:VCACHost'");
    }
    if (!reservationEntity || System.getObjectType(reservationEntity) !== "vCAC:Entity") {
        inputErrors.push(" - reservationEntity missing or not of type 'vCAC:Entity'");
    }
    if (inputErrors.length > 0) {
        errorMessage = "Mandatory parameters not satisfied:\n" + inputErrors.join("\n");
        log.error(errorMessage);
    }
}

var logType = "Action";
var logName = "getReservationCustomProperties"; // This must be set to the name of the action
var Logger = System.getModule("com.simplygeek.library.util").logger(logType, logName);
var log = new Logger(logType, logName);
var customProperties = new Properties();
var propertiesEntities = [];
var propertyName = "";
var propertyValue = "";
var numProperties = 0;

try {
    checkParams(vcacHost, reservationEntity);
    log.debug("Retrieving custom properties for vcac reservation.");
    propertiesEntities = reservationEntity.getLink(vcacHost, "HostReservationProperties");
    numProperties = propertiesEntities.length;
    if (numProperties > 0) {
        log.debug("The following custom properties were found:");
        for (var i = 0; i < numProperties; i++) {
            propertyName = propertiesEntities[i].getProperty("PropertyName");
            propertyValue = propertiesEntities[i].getProperty("PropertyValue");
            log.debug(propertyName + ": " + propertyValue);
            customProperties.put(propertyName, propertyValue);
        }
        log.debug("Found " + numProperties + " custom properties.");
    } else {
        log.debug("No custom properties found.");
    }
} catch (e) {
    log.error("Action failed to retrieve custom properties for vcac reservation.",e);
}

return customProperties;

Log output:

[] [D] [Action: getReservationCustomProperties] Retrieving custom properties for vcac reservation.
[] [D] [Action: getReservationCustomProperties] The following custom properties were found:
[] [D] [Action: getReservationCustomProperties] com.simplygeek.country: UK
[] [D] [Action: getReservationCustomProperties] com.simplygeek.region: EMEA
[] [D] [Action: getReservationCustomProperties] Found 2 custom properties.

Get a Specific Custom Property Value from the Set

If you would like to get a specific custom property from the reservation, then please see my previous post: vRA Developer: Part 6 – Working with vCAC Virtual Machine Custom Properties in the section ‘Get a Specific Custom Property Value from the Set‘, that provides code examples of how this can be achieved.

Get Reservation Linked Entities and Associated Properties

There are additional properties that can be retrieved which are part of other entities that the reservation has a relationship with. Here are some examples of information that can be retrieved through linked entities (the code for all of these examples is included in the package link provided at the beginning of this post).

  • Tenant Id
  • Business Group Name
  • Compute Cluster Name
  • Resource Pool Name
  • Reserved Storage Paths
  • Reserved Networks Paths
  • Reservation Policy Name
  • Virtual Machines using the reservation

The reservation entity object has a method ‘.getLink(vcacHost, “linkKey_string”)‘ that can be used to get the linked entity objects. The ‘.getProperty(“key_string”)‘ can then be used on these entities to get a specific property value, such as the business group.

Get Tenant Id

This one was interesting. The usual usage of .getLink failed to return any of the ProvisioningGroups (business groups) for the reservation (I need to do this because the tenant Id is a property of the business group). Even though when using system queries against this data, it works. No matter what I tried, the set would always return empty. I had to take a sub-optimal, long-winded approach and get all the provisioning groups, and then work backwards to the reservation. In the process I created a helper to get the business group entity and then create wrappers around this:

/*global System vcacHost reservationEntity*/

/**
 * Gets the business group entity that the reservation belongs to.
 * @author Gavin Stephens <gavin.stephens@simplygeek.co.uk>
 * @version 1.0.0
 * @function getBusinessGroupEntityForReservationEntity
 * @param {vCAC:VCACHOST} vcacHost - The vCAC Host.
 * @param {vCAC:Entity} reservationEntity - The vCAC reservation entity.
 * @returns {vCAC:Entity} Returns the business group entity.
 */

function checkParams(vcacHost, reservationEntity) {
    var inputErrors = [];
    var errorMessage;

    if (!vcacHost || System.getObjectType(vcacHost) !== "vCAC:VCACHost") {
        inputErrors.push(" - vcacHost missing or not of type 'vCAC:VCACHost'");
    }
    if (!reservationEntity || System.getObjectType(reservationEntity) !== "vCAC:Entity") {
        inputErrors.push(" - reservationEntity missing or not of type 'vCAC:Entity'");
    }
    if (inputErrors.length > 0) {
        errorMessage = "Mandatory parameters not satisfied:\n" + inputErrors.join("\n");
        log.error(errorMessage);
    }
}

var logType = "Action";
var logName = "getBusinessGroupEntityForReservationEntity"; // This must be set to the name of the action
var Logger = System.getModule("com.simplygeek.library.util").logger(logType, logName);
var log = new Logger(logType, logName);
var businessGroupEntities = [];
var reservationId = "";
var entitySetName = "ProvisioningGroups";
var reservationName = "";
var businessGroupEntity;
var businessGroupName = "";
var businessGroupId = "";

try {
    checkParams(vcacHost, reservationEntity);
    reservationName = reservationEntity.getProperty("HostReservationName");
    log.debug("Getting business group entity for vcac reservation '" + reservationName + "'");
    reservationId = reservationEntity.getProperty("HostReservationID");
    businessGroupEntities = System.getModule("com.simplygeek.library.vcac.entities").getVcacEntitiesByCustomFilter(vcacHost,
                                                                                                                   entitySetName);
    for (var i = 0; i < businessGroupEntities.length; i++) {
        var linkedBusinessGroupEntity = businessGroupEntities[i];
        var reservationEntities = linkedBusinessGroupEntity.getLink(vcacHost, "HostReservations");

        if (reservationEntities.length > 0) {
            for (var j = 0; j < reservationEntities.length; j++){
                var linkedReservationId = reservationEntities[j].getProperty("HostReservationID");

                if (linkedReservationId === reservationId) {
                    businessGroupEntity = linkedBusinessGroupEntity;
                    break;
                }
            }
        }
    }
    if (!businessGroupEntity) {
        log.error("No business group entity was found.");
    }
    businessGroupId = businessGroupEntity.getProperty("GroupID");
    businessGroupName = businessGroupEntity.getProperty("GroupName");
    log.debug("Found business group entity '" + businessGroupName + "' with id '" + businessGroupId + "'");
} catch (e) {
    log.error("Action failed to retrieve business group entity for vcac reservation.",e);
}

return businessGroupEntity;

Then the actual wrapper action that gets the tenant id:

/*global System vcacHost reservationEntity*/

/**
 * Gets the tenant id that the reservation belongs to.
 * @author Gavin Stephens <gavin.stephens@simplygeek.co.uk>
 * @version 1.0.0
 * @function getTenantIdForReservationEntity
 * @param {vCAC:VCACHOST} vcacHost - The vCAC Host.
 * @param {vCAC:Entity} reservationEntity - The vCAC reservation entity.
 * @returns {string} Returns the tenant id.
 */

function checkParams(vcacHost, reservationEntity) {
    var inputErrors = [];
    var errorMessage;

    if (!vcacHost || System.getObjectType(vcacHost) !== "vCAC:VCACHost") {
        inputErrors.push(" - vcacHost missing or not of type 'vCAC:VCACHost'");
    }
    if (!reservationEntity || System.getObjectType(reservationEntity) !== "vCAC:Entity") {
        inputErrors.push(" - reservationEntity missing or not of type 'vCAC:Entity'");
    }
    if (inputErrors.length > 0) {
        errorMessage = "Mandatory parameters not satisfied:\n" + inputErrors.join("\n");
        log.error(errorMessage);
    }
}

var logType = "Action";
var logName = "getTenantIdForReservationEntity"; // This must be set to the name of the action
var Logger = System.getModule("com.simplygeek.library.util").logger(logType, logName);
var log = new Logger(logType, logName);
var tenantId = "";
var businessGroupEntity;
var reservationName = "";

try {
    checkParams(vcacHost, reservationEntity);
    reservationName = reservationEntity.getProperty("HostReservationName");
    log.log("Getting tenant id for vcac reservation '" + reservationName + "'");
    businessGroupEntity = System.getModule("com.simplygeek.library.vcac.reservations.links").getBusinessGroupEntityForReservationEntity(vcacHost,
                                                                                                                                        reservationEntity);
    tenantId = businessGroupEntity.getProperty("TenantID");
    if (!tenantId) {
        log.error("No tenant id was found.");
    }
    log.log("Found tenant id '" + tenantId + "'");
} catch (e) {
    log.error("Action failed to retrieve tenant id for vcac reservation.",e);
}

return tenantId;

Log output:

[] [I] [Action: getTenantIdForReservationEntity] Getting tenant id for vcac reservation 'RES-SITEA-vSphere-Resource-01'
[] [I] [Action: getTenantIdForReservationEntity] Found tenant id 'sg'

Get Business Group Name

For this, I took the same approach as getting the tenant id and created a wrapper around the business group helper action to get the name.

/*global System vcacHost reservationEntity*/

/**
 * Gets the business group name that the reservation belongs to.
 * @author Gavin Stephens <gavin.stephens@simplygeek.co.uk>
 * @version 1.0.0
 * @function getBusinessGroupNameForReservationEntity
 * @param {vCAC:VCACHOST} vcacHost - The vCAC Host.
 * @param {vCAC:Entity} reservationEntity - The vCAC reservation entity.
 * @returns {string} Returns the business group name.
 */

function checkParams(vcacHost, reservationEntity) {
    var inputErrors = [];
    var errorMessage;

    if (!vcacHost || System.getObjectType(vcacHost) !== "vCAC:VCACHost") {
        inputErrors.push(" - vcacHost missing or not of type 'vCAC:VCACHost'");
    }
    if (!reservationEntity || System.getObjectType(reservationEntity) !== "vCAC:Entity") {
        inputErrors.push(" - reservationEntity missing or not of type 'vCAC:Entity'");
    }
    if (inputErrors.length > 0) {
        errorMessage = "Mandatory parameters not satisfied:\n" + inputErrors.join("\n");
        log.error(errorMessage);
    }
}

var logType = "Action";
var logName = "getBusinessGroupNameForReservationEntity"; // This must be set to the name of the action
var Logger = System.getModule("com.simplygeek.library.util").logger(logType, logName);
var log = new Logger(logType, logName);
var businessGroupName = "";
var businessGroupEntity;
var reservationName = "";

try {
    checkParams(vcacHost, reservationEntity);
    reservationName = reservationEntity.getProperty("HostReservationName");
    log.log("Getting business group name for vcac reservation '" + reservationName + "'");
    businessGroupEntity = System.getModule("com.simplygeek.library.vcac.reservations.links").getBusinessGroupEntityForReservationEntity(vcacHost,
                                                                                                                                        reservationEntity);
    businessGroupName = businessGroupEntity.getProperty("GroupName");
    if (!businessGroupName) {
        log.error("No business group was found.");
    }
    log.log("Found business group'" + businessGroupName + "'");
} catch (e) {
    log.error("Action failed to retrieve business group name for vcac reservation.",e);
}

return businessGroupName;

Log output:

[] [I] [Action: getBusinessGroupNameForReservationEntity] Getting business group name for vcac reservation 'RES-SITEA-vSphere-Resource-01'
[] [I] [Action: getBusinessGroupNameForReservationEntity] Found business group 'SG-BG-Delivery'

Get Compute Cluster Name

The following code can be used to get the compute cluster name that the reservation is assigned to.

/*global System vcacHost reservationEntity*/

/**
 * Gets the compute cluster name that the reservation is assigned to.
 * @author Gavin Stephens <gavin.stephens@simplygeek.co.uk>
 * @version 1.0.0
 * @function getComputeClusterNameForReservationEntity
 * @param {vCAC:VCACHOST} vcacHost - The vCAC Host.
 * @param {vCAC:Entity} reservationEntity - The vCAC reservation entity.
 * @returns {string} Returns the compute cluster name.
 */

function checkParams(vcacHost, reservationEntity) {
    var inputErrors = [];
    var errorMessage;

    if (!vcacHost || System.getObjectType(vcacHost) !== "vCAC:VCACHost") {
        inputErrors.push(" - vcacHost missing or not of type 'vCAC:VCACHost'");
    }
    if (!reservationEntity || System.getObjectType(reservationEntity) !== "vCAC:Entity") {
        inputErrors.push(" - reservationEntity missing or not of type 'vCAC:Entity'");
    }
    if (inputErrors.length > 0) {
        errorMessage = "Mandatory parameters not satisfied:\n" + inputErrors.join("\n");
        log.error(errorMessage);
    }
}

var logType = "Action";
var logName = "getComputeClusterNameForReservationEntity"; // This must be set to the name of the action
var Logger = System.getModule("com.simplygeek.library.util").logger(logType, logName);
var log = new Logger(logType, logName);
var computeClusterName = "";
var reservationName = "";
var hostEntity;

try {
    checkParams(vcacHost, reservationEntity);
    reservationName = reservationEntity.getProperty("HostReservationName");
    log.log("Getting compute cluster name for vcac reservation '" + reservationName + "'");
    hostEntity = reservationEntity.getLink(vcacHost, "Host")[0];
    computeClusterName = hostEntity.getProperty("HostName");
    log.log("Found compute cluster name '" + computeClusterName + "'");
} catch (e) {
    log.error("Action failed to retrieve compute cluster name for vcac reservation.",e);
}

return computeClusterName;

Log output:

[] [I] [Action: getComputeClusterNameForReservationEntity] Getting compute cluster name for vcac reservation 'RES-SITEA-vSphere-Resource-01'
[] [I] [Action: getComputeClusterNameForReservationEntity] Found compute cluster name 'SITEA-CLS-CLOUD-01'

Get Resource Pool Name

The following code can be used to get the resource pool name that the reservation is assigned to.

/*global System vcacHost reservationEntity*/

/**
 * Gets the resource pool name that the reservation is assigned to.
 * @author Gavin Stephens <gavin.stephens@simplygeek.co.uk>
 * @version 1.0.0
 * @function getResourcePoolNameForReservationEntity
 * @param {vCAC:VCACHOST} vcacHost - The vCAC Host.
 * @param {vCAC:Entity} reservationEntity - The vCAC reservation entity.
 * @returns {string} Returns the resource pool name.
 */

function checkParams(vcacHost, reservationEntity) {
    var inputErrors = [];
    var errorMessage;

    if (!vcacHost || System.getObjectType(vcacHost) !== "vCAC:VCACHost") {
        inputErrors.push(" - vcacHost missing or not of type 'vCAC:VCACHost'");
    }
    if (!reservationEntity || System.getObjectType(reservationEntity) !== "vCAC:Entity") {
        inputErrors.push(" - reservationEntity missing or not of type 'vCAC:Entity'");
    }
    if (inputErrors.length > 0) {
        errorMessage = "Mandatory parameters not satisfied:\n" + inputErrors.join("\n");
        log.error(errorMessage);
    }
}

var logType = "Action";
var logName = "getResourcePoolNameForReservationEntity"; // This must be set to the name of the action
var Logger = System.getModule("com.simplygeek.library.util").logger(logType, logName);
var log = new Logger(logType, logName);
var resourcePoolName = "";
var reservationName = "";
var hostEntity;

try {
    checkParams(vcacHost, reservationEntity);
    reservationName = reservationEntity.getProperty("HostReservationName");
    log.log("Getting resource pool name for vcac reservation '" + reservationName + "'");
    hostEntity = reservationEntity.getLink(vcacHost, "ResourcePool")[0];
    resourcePoolName = hostEntity.getProperty("ResourcePoolName");
    log.log("Found resource pool name '" + resourcePoolName + "'");
} catch (e) {
    log.error("Action failed to retrieve resource pool name for vcac reservation.",e);
}

return resourcePoolName;

Log output:

[] [I] [Action: getResourcePoolNameForReservationEntity] Getting resource pool name for vcac reservation 'RES-SITEA-vSphere-Resource-01'
[] [I] [Action: getResourcePoolNameForReservationEntity] Found resource pool name 'Resources'

Get Reserved Storage Paths

The following code will get a list of storage paths that have been configured on the reservation.

/*global System vcacHost reservationEntity*/

/**
 * Gets a list of storage paths that are enabled in the reservation.
 * @author Gavin Stephens <gavin.stephens@simplygeek.co.uk>
 * @version 1.0.0
 * @function getStoragePathsForReservationEntity
 * @param {vCAC:VCACHOST} vcacHost - The vCAC Host.
 * @param {vCAC:Entity} reservationEntity - The vCAC reservation entity.
 * @returns {string[]} Returns the list of storage paths.
 */

function checkParams(vcacHost, reservationEntity) {
    var inputErrors = [];
    var errorMessage;

    if (!vcacHost || System.getObjectType(vcacHost) !== "vCAC:VCACHost") {
        inputErrors.push(" - vcacHost missing or not of type 'vCAC:VCACHost'");
    }
    if (!reservationEntity || System.getObjectType(reservationEntity) !== "vCAC:Entity") {
        inputErrors.push(" - reservationEntity missing or not of type 'vCAC:Entity'");
    }
    if (inputErrors.length > 0) {
        errorMessage = "Mandatory parameters not satisfied:\n" + inputErrors.join("\n");
        log.error(errorMessage);
    }
}

var logType = "Action";
var logName = "getStoragePathsForReservationEntity"; // This must be set to the name of the action
var Logger = System.getModule("com.simplygeek.library.util").logger(logType, logName);
var log = new Logger(logType, logName);
var storagePaths = [];
var hostReservationStorages = [];
var reservationName = "";
var numStoragePaths = 0;

try {
    checkParams(vcacHost, reservationEntity);
    reservationName = reservationEntity.getProperty("HostReservationName");
    log.log("Getting a list of storage paths enabled on vcac reservation '" + reservationName + "'");
    hostReservationStorages = reservationEntity.getLink(vcacHost, "HostReservationToStorages");
    storagePaths = hostReservationStorages.map(function(x){return x.getLink(vcacHost, "HostToStorage")[0].getProperty("StoragePath");});
    numStoragePaths = storagePaths.length;
    for (var i = 0; i < numStoragePaths; i++) {
        log.log("Found storage path '" + storagePaths[i] + "'");
    }
    log.log("Found " + numStoragePaths + " storage path(s).");
} catch (e) {
    log.error("Action failed to get a list of storage paths enabled on vcac reservation.",e);
}

return storagePaths;

Log output:

[] [I] [Action: getStoragePathsForReservationEntity] Getting a list of storage paths enabled on vcac reservation 'RES-SITEA-vSphere-Resource-01'
[] [I] [Action: getStoragePathsForReservationEntity] Found storage path 'DSC-SITEA-BRONZE-01'
[] [I] [Action: getStoragePathsForReservationEntity] Found storage path 'DSC-SITEA-SILVER-01'
[] [I] [Action: getStoragePathsForReservationEntity] Found storage path 'DSC-SITEA-GOLD-01'
[] [I] [Action: getStoragePathsForReservationEntity] Found 3 storage path(s).

Get Reserved Networks Paths

The following code will get a list of network paths that have been configured on the reservation.

/*global System vcacHost reservationEntity*/

/**
 * Gets a list of network paths that are enabled in the reservation.
 * @author Gavin Stephens <gavin.stephens@simplygeek.co.uk>
 * @version 1.0.0
 * @function getNetworkPathsForReservationEntity
 * @param {vCAC:VCACHOST} vcacHost - The vCAC Host.
 * @param {vCAC:Entity} reservationEntity - The vCAC reservation entity.
 * @returns {string[]} Returns the list of network paths.
 */

function checkParams(vcacHost, reservationEntity) {
    var inputErrors = [];
    var errorMessage;

    if (!vcacHost || System.getObjectType(vcacHost) !== "vCAC:VCACHost") {
        inputErrors.push(" - vcacHost missing or not of type 'vCAC:VCACHost'");
    }
    if (!reservationEntity || System.getObjectType(reservationEntity) !== "vCAC:Entity") {
        inputErrors.push(" - reservationEntity missing or not of type 'vCAC:Entity'");
    }
    if (inputErrors.length > 0) {
        errorMessage = "Mandatory parameters not satisfied:\n" + inputErrors.join("\n");
        log.error(errorMessage);
    }
}

var logType = "Action";
var logName = "getNetworkPathsForReservationEntity"; // This must be set to the name of the action
var Logger = System.getModule("com.simplygeek.library.util").logger(logType, logName);
var log = new Logger(logType, logName);
var networkPaths = [];
var hostNicReservations = [];
var reservationName = "";
var numNetworkPaths = 0;

try {
    checkParams(vcacHost, reservationEntity);
    reservationName = reservationEntity.getProperty("HostReservationName");
    log.log("Getting a list of network paths enabled on vcac reservation '" + reservationName + "'");
    hostNicReservations = reservationEntity.getLink(vcacHost, "HostNicToReservations");
    networkPaths = hostNicReservations.map(function(x){return x.getLink(vcacHost, "HostNic")[0].getProperty("HostNicName");});
    numNetworkPaths = networkPaths.length;
    for (var i = 0; i < numNetworkPaths; i++) {
        log.log("Found network path '" + networkPaths[i] + "'");
    }
    log.log("Found " + numNetworkPaths + " network path(s).");
} catch (e) {
    log.error("Action failed to get a list of network paths enabled on vcac reservation.",e);
}

return networkPaths;

Log Output:

[] [I] [Action: getNetworkPathsForReservationEntity] Getting a list of network paths enabled on vcac reservation 'RES-SITEA-vSphere-Resource-01'
[] [I] [Action: getNetworkPathsForReservationEntity] Found network path 'vxw-dvs-314-virtualwire-8-sid-5005-SiteA-Transit-South'
[] [I] [Action: getNetworkPathsForReservationEntity] Found 1 network path(s).

Get Reservation Policy Name

The following code gets the reservation policy name that has been assigned to the reservation.

/*global System vcacHost reservationEntity*/

/**
 * Gets the reservation policy name assigned to the reservation.
 * @author Gavin Stephens <gavin.stephens@simplygeek.co.uk>
 * @version 1.0.0
 * @function getReservationPolicyNameForReservationEntity
 * @param {vCAC:VCACHOST} vcacHost - The vCAC Host.
 * @param {vCAC:Entity} reservationEntity - The vCAC reservation entity.
 * @returns {string} Returns the reservation policy name.
 */

function checkParams(vcacHost, reservationEntity) {
    var inputErrors = [];
    var errorMessage;

    if (!vcacHost || System.getObjectType(vcacHost) !== "vCAC:VCACHost") {
        inputErrors.push(" - vcacHost missing or not of type 'vCAC:VCACHost'");
    }
    if (!reservationEntity || System.getObjectType(reservationEntity) !== "vCAC:Entity") {
        inputErrors.push(" - reservationEntity missing or not of type 'vCAC:Entity'");
    }
    if (inputErrors.length > 0) {
        errorMessage = "Mandatory parameters not satisfied:\n" + inputErrors.join("\n");
        log.error(errorMessage);
    }
}

var logType = "Action";
var logName = "getReservationPolicyNameForReservationEntity"; // This must be set to the name of the action
var Logger = System.getModule("com.simplygeek.library.util").logger(logType, logName);
var log = new Logger(logType, logName);
var reservationPolicyName = "";
var reservationPolicyEntity;
var reservationName = "";

try {
    checkParams(vcacHost, reservationEntity);
    reservationName = reservationEntity.getProperty("HostReservationName");
    log.log("Getting reservation policy name for vcac reservation '" + reservationName + "'");
    reservationPolicyEntity = reservationEntity.getLink(vcacHost, "HostReservationPolicy")[0];
    reservationPolicyName = reservationPolicyEntity.getProperty("name");
    log.log("Found reservation policy name '" + reservationPolicyName + "'");
} catch (e) {
    log.error("Action failed to get reservation policy name for vcac reservation.",e);
}

return reservationPolicyName;

Log output:

[] [I] [Action: getReservationPolicyNameForReservationEntity] Getting reservation policy name for vcac reservation 'RES-SITEA-vSphere-Resource-01'
[] [I] [Action: getReservationPolicyNameForReservationEntity] Found reservation policy name 'RP-vSphere-Resources'

Get A list of Virtual Machines using the Reservation

The following code will get a list of virtual machines that have been provisioned using this reservation. Unlike my other actions, this will not output the name of each virtual machine to the console. The list will only be returned as an array, which can be output with a follow on script if required. The list could be large and I didn’t want to flood the console too much.

/*global System vcacHost reservationEntity*/

/**
 * Gets a list of virtual machines that have been provisioned using the reservation.
 * @author Gavin Stephens <gavin.stephens@simplygeek.co.uk>
 * @version 1.0.0
 * @function getListOfVirtualMachinesForReservationEntity
 * @param {vCAC:VCACHOST} vcacHost - The vCAC Host.
 * @param {vCAC:Entity} reservationEntity - The vCAC reservation entity.
 * @returns {string[]} Returns a list of virtual machine names.
 */

function checkParams(vcacHost, reservationEntity) {
    var inputErrors = [];
    var errorMessage;

    if (!vcacHost || System.getObjectType(vcacHost) !== "vCAC:VCACHost") {
        inputErrors.push(" - vcacHost missing or not of type 'vCAC:VCACHost'");
    }
    if (!reservationEntity || System.getObjectType(reservationEntity) !== "vCAC:Entity") {
        inputErrors.push(" - reservationEntity missing or not of type 'vCAC:Entity'");
    }
    if (inputErrors.length > 0) {
        errorMessage = "Mandatory parameters not satisfied:\n" + inputErrors.join("\n");
        log.error(errorMessage);
    }
}

var logType = "Action";
var logName = "getListOfVirtualMachinesForReservationEntity"; // This must be set to the name of the action
var Logger = System.getModule("com.simplygeek.library.util").logger(logType, logName);
var log = new Logger(logType, logName);
var vmEntities = [];
var vmNames = [];
var reservationName = "";
var numVms = 0;

try {
    checkParams(vcacHost, reservationEntity);
    reservationName = reservationEntity.getProperty("HostReservationName");
    log.log("Getting a list of virtual machines for vcac reservation '" + reservationName + "'");
    vmEntities = reservationEntity.getLink(vcacHost, "VirtualMachines");
    vmNames = vmEntities.map(function(x){return x.getProperty("VirtualMachineName");});
    numVms = vmNames.length;
    log.log("Found " + numVms + " virtual machines.");
} catch (e) {
    log.error("Action failed to get a list of virtual machines for vcac reservation.",e);
}

return vmNames;

Log output:

[] [I] [Action: getListOfVirtualMachinesForReservationEntity] Getting a list of virtual machines for vcac reservation 'RES-SITEA-vSphere-Resource-01'
[] [I] [Action: getListOfVirtualMachinesForReservationEntity] Found 5 virtual machines.

I still want to cover more ground on reserved storage for a reservation, but as that content was ever-growing, I decided to split them over 2 posts. So I’ll conclude this and provide a follow on post, which will exclusively cover reservation storage.

I hope this has been useful. If you discover bugs with any of my code, require some help or simply need an ad-hoc solution, then please drop me a message via the Drift app.

0 0 votes
Article Rating

Related Posts

Subscribe
Notify of
guest

2 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Luke Lloyd
4 years ago

I always use your blog when I need to recap on vCAC Entities :)

I don’t know what version you were/are using when trying to get the ProvisioningGroups (business groups) link from the reservation but it works for me (currently on v7.5).

If I have the reservation entity in variable reservationEntity and vCAC Host in variable vcacHost; I can then run the below to return the tenant:

var bgEntity = reservationEntity.getLink(vcacHost, “ProvisioningGroup”)[0];
var bgTenant = bgEntity.getProperty(“TenantID”);