14 Jun 2016

Two Methods to Select a vRA Reservation Policy at Request Time with vRO Featured

In the last 6 months, I've done quite a bit of vRA6, 7 and vRO. During this time, I've had to learn quite a bit about both products, and how they interact with each other and with other REST based APIs, such as ServiceNow. Having been set in my ways in vRA 6 of using workflow stubs to break out to vRO in order to extend vRA functionality, I was concious of the fact that VMware will be removing .NET workflow stubs in future releases of vRA 7, and that the preferred method of extending out to vRO in vRA7 is to make use of the event broker service. Also, vRA7 makes use of converged blueprints, which from an extensibility point of view, actually means that we have to do things slightly differently in code than what we got used in in vRA/vRO6.

 

In this blog post, I'd like to show how we can make reservation policy selections at request time from vRO, when using vRA 7.0.1 and it's converged blueprints. Basically there are two methods that I use to make a reservation policy selection in vRA7 at request time. The option we use will depend on the blueprint configuration. Basically, using the Request Calatog Item with Provisioning Request method(method not in a programming sense, but rather a way of doing things ;)), you can set the reservation policy properties as outlined further down this post.

Please note, this post is not meant to explain how you go about getting the provisioning request data, setting new values and then making the provisioning request to vRA, but rather to show the properties to update and how to access those properties, and when those properties are available and when they are not. If you'd like to know how to actually go about making the provisioning request, refer to this blog post where I explain it in more detail.

Option 1: If a reservation policy has been specified within the vRA blueprint, the Catalog Provisioning Request JSON data will contain the following element keys within the reservation_policy element:

{
	...
	"os_arch" : "x86_64",
	"os_distribution" : null,
	"os_type" : "Linux",
	"os_version" : null,
	"property_groups" : [ null ],
	"reservation_policy" : {
		"componentId" : null,
		"classId" : "Infrastructure.Reservation.Policy.ComputeResource",
		"id" : "Blueprint-Specified Reservation Policy",
		"label" : "Blueprint-Specified Reservation Policy"
		},
	"security_groups" : [ ],
	"security_tags" : [ ],
	"source_machine_external_snapshot" : null,
	"source_machine_vmsnapshot" : null,
	"storage" : 56
	...
}

Because the reservation_policy.id and reservation_policy.label element keys now exist in the JSON data object, we are able to override them as part of the provisioning request:

JSON.vSphere_Machine_1.data.reservation_policy.id = "Target Reservation Policy Name";
JSON.vSphere_Machine_1.data.reservation_policy.label = "Target Reservation Policy Name";

NOTE: The above method will fail with "Type error, cannot set property of "id" of null", if the Reservation Policy field in the blueprint was left blank.

Option 2 (my preferred option): If a reservation policy has not been specified in the vRA blueprint (Reservation Policy field was left blank), the keys in option 1 won't exist, so you can't simply reference them as was done in option 1:

 

{
    ...
    "os_arch" : "x86_64",
    "os_distribution" : null,
    "os_type" : "Linux",
    "os_version" : null,
    "property_groups" : [ null ],
    "reservation_policy" : null,
    "security_groups" : [ ],
    "security_tags" : [ ],
    "source_machine_external_snapshot" : null,
    "source_machine_vmsnapshot" : null,
    "storage" : 56
    ...
}

Sure, you can probably do some funky stuff in JavaScript and generate the JSON key value pairs yourself and update the provisioning request data object with it, but a simpler way is to simply pass the reservation ID to the JSON request, using the hidden property __reservationPolicyID:

JSON.vSphere_Machine_1.data.__reservationPolicyID = "eb7c987a-6565-530f-ac15-682a5652f91c";

or for those of you who really need to be spoon fed ;), this is how you get the policy id:

var myReservationName = "Target Reservation Policy Name";

var reservationEntity = System.getModule("com.vmware.library.vcac").getReservationEntityByName(inVCACHost, myReservationName)

var reservationPolicy = reservationEntity.getLink(inVCACHost, "HostReservationPolicy");

var reservationPolicyId = reservationPolicy[0].getProperty('id');

JSON.vSphere_Machine_1.data.__reservationPolicyID = reservationPolicyId;

To avoid hard coding stuff into your workflows in Javascript, a sackable offence in my opinion, configure vSphere_Machine_1 as a value to a string attribute in a configuration element within vRO, then link a new local attribute (say for instance something like attBlueprintComponentName) in your vRO workflow to that configuration element. Then reference the local attribute as an input to a scriptable item. Then code it like this:

JSON[attBlueprintComponentName].data.__reservationPolicyID = reservationPolicyId;

Here's a tip, if you're a tad OCD like I am, then you'll make sure your code catches exceptions and at least handles them correctly through the default exception handler. Don't just assume the myReservationName exists in vRA. It's sloppy and there's no excuse and no place for code like that in a production environment. You can use try/catch blocks, but I'd just test if the myReservationName variable matches one of the reservations returned from vRA and if not, throw and exception and let the workflow's default exception handler take care of it. I'm therefore also assuming you're using the default exception handler properly, right? 

I'm not going to share all my production code, but here's my advice:

  1. Get all reservation policies in vRA and assign them to a variable. Use System.getModule("com.vmware.library.vcac").getReservationNames(inVCACHost). It will return an array of reservation policy names.
  2. In a "for each()" loop, check that the value of myReservationName matches one of the reservations in the new reservations array variable. If it does, go ahead and get the reservation entity like above. If nothing matches, throw an exception. Something like this will do nicely:
throw "No reservation policies match input of: " + myReservationName + ". Cannot get reservation name. Exiting...";

NOTE: This method will fail with an error within vRA if a reservation policy has been specified in the vRA blueprint. You will get an error like: [IaaS property already exists. Key: __reservationPolicyID]

Disclaimer: I've typed this post out by hand without actually running the code through an interpreter, so check for typos if you're going to copy and paste.

Happy coding!

 

Written by  0 comment
Last modified on Tuesday, 14 June 2016 17:39
Rate this item
(0 votes)

Comments (0)

There are no comments posted here yet

Leave your comments

Posting comment as a guest. Sign up or login to your account.
0 Characters
Attachments (0 / 3)
Share Your Location

@evankirstel I know what they are for. It just feels wrong to throw a good cable out, even if it seems obsolete
Follow Rynardt Spies on Twitter