Thursday, July 9, 2015

Searching within vRealize Automation – Part 2 – REST API

In Part 1 of this article series, I wrote about using some of the more interesting queries possible through the vRealize Automation IaaS component.  Specifically, using the Model Manager calls from vRealize Orchestrator.  Here in Part 2, I will demonstrate yet another approach to searching – but this time from the new vRA REST API.

Getting into the API session

There are already a number of articles about getting into the REST API.  But in short, I used the Firefox plug-in “REST Client”.  See the screenshot below for the example of how to initiate the authenticated session in the REST Client.


URI: https://{vrahost}/identity/api/tokens

Notice the credentials being passed in the POST body?  This indicates the tenant as well, so the authentication URI is consistent across all tenants.

Another good step to complete is to validate your session.  See the screenshot below for the example of this being performed.


URI: https://{vrahost}/vcac/org/{tenant}/tokens/{tokenID}

Note that the “id” returned from the authentication call is now attached as an appendix to the URI call.  The successful validation is merely the HTTP 200 response code, to say that everything is OK.

Getting unfiltered content

The REST API is surprisingly easy to use, once you’ve done a little reading and poking around.  I was able to pickup some basic skills with just the regular documentation and playing with the running product.  I didn’t end up breaking anything, so I guess I did OK!

To get the entire list of currently provisioned items, those that I am entitled to see, it a simple API call as shown below.


URI: https://{vrahost}/catalog-service/api/consumer/resources

Note that the “id” token form the initial authentication is now being passed in a request header called “Authorization”.  This represents the current session, and seem to be valid for 24 hours (by default).

This API call will return ALL my items, and/or my group’s item.  However, my recent dealings with a customer were needing a way to efficiently lookup a specific item in vRA, if it existed at all.

Filtering by VM name – OData queries again!

As it turns out, the vRA REST API also supports some of the OData query syntax that was introduced in Part 1 of this blog.  In particular, you can use the $filter parameter to submit a query to the API call above.  See the below example for searching for a specific item (VM) by name.


URI: https://{vrahost}/catalog-service/api/consumer/resources?$filter=name eq ‘win042’

Pay attention!  In this query, I am actually passing spaces in my URI!  I presume this is being encoded for me by the REST Client plug-in, otherwise I assume planes would start falling out of the sky!  According to the Programming Guide, the query is happy to take encoded or non-encoded form.  The proper encoded call equivalent would look like one of the below.
URI: https://{vrahost}/catalog-service/api/consumer/resources?$filter=name+eq+%27win042%27
URI: https://{vrahost}/catalog-service/api/consumer/resources?$filter=name%20eq%20%27win042%27

As you can check for yourself, if the query succeeds, it will return only the items matching the query – success!  Please see below for an example of the query returning no matches.


As you might notice, the API call still succeeds and returns content – it just returns a JSON document with no members in the content section.

Other query parameters

As per the previous article, the vRA REST API supports a few more of the OData parameter types.  One parameter type - $select – is missing from the API, presumably because the structured JSON data returned is easier to navigate in full, rather than if it were teased apart into flat fields.

The table below is replicated from the in-built documentation within each vRealize Automation appliance, which is a copy of the online documentation.  Go ahead, check it out on your own appliance!

Appliance Source:  https://{vrahost}/catalog-service/api/docs/resource_Resource.html


name
description
type
default
managedOnly if true, the returned requests are from User's managed subtenants. query
page Page Number query
1
limit Number of entries per page query
20
$orderby Multiple comma-separated properties sorted in ascending or descending order query
$top Sets the number of returned entries from the top of the response (total number per page in relation to skip) query
$skip Sets how many entries you would like to skip query
$filter Boolean expression for whether a particular entry should be included in the response query



That concludes this series of articles on searching with vRealize Automation using both Orchestrator and the REST API.  Please let me know any feedback or comments below!

Monday, July 6, 2015

Searching within vRealize Automation – Part 1 - Orchestrator

I was recently engaged with a customer needing to execute some very particular manipulations of their provisioned virtual machines in their nascent vRealize Automation environment.  I learned a few things about using search functions in both vRealize Orchestrator and the vRealize Automation REST API, and I figured it was worth sharing here.

vRealize Orchestrator

The requirement for this part was to use vRealize Orchestrator to change properties of a specific type of vRA-provisioned machine.  This entailed finding all managed virtual machines that lived on a certain cluster within vCenter, and then filtering those machines by a further custom property that was being used.

It tuned out to be a bad idea to use vRealize Orchestrator to do all the grabbing and manual sorting, iterating over scripts and actions to gradually reduce all machines down to the required subset.  It was taking ages, and it was REALLY annoying to have to wait for so long before finding out I hadn’t quite nailed the search anyway!  So I turned to the Model Manager function within the vRA IaaS component.  This is one of the services that runs on Windows servers in the solution, and manages the data model quite directly.

Cluster search

I used a little bit of cheeky searching to discover the right “entity sets” and fields I needed to utilize for the search.  I needed to find the UUID of the target cluster first, taking the “cluster path” that was derived from vCenter’s API structure.  I handled the search as per the below code snippet.
var modelName = 'ManagementModelEntities.svc';
var entitySetName = 'Hosts';
var filter = "HostUniqueID eq '" + clusterPath + "'";
var orderBy = null;
var top = 1;
var skip = 0;
var headers = null;
var select = null;
var entities = vCACEntityManager.readModelEntitiesBySystemQuery(host.id,     modelName, entitySetName, filter, orderBy, select, top, skip, headers);
The important parts to point out are:

  • modelName is indicating the standard entity model.  There is a special one for AWS, for example, if I wanted to search on that instead.
  • entitySetName is “Hosts” in the first search, which is the host or cluster running a given virtual machine.  If you are running clusters, then the cluster is stored as the “host”, rather than a specific runtime host.
  • filter is the magic part.  It turns out that this complies with OData syntax, which you can read about here ().  In my case, the query was for a cluster path, but this is where you need to engage your brain to determine was to search for.
  • orderBy, top, skip, headers and select are all modifiers for what gets returned from the search result set and how.  I will come back to these in the follow up blog article where I search in the vRA REST API.
  • vCACEntityManager is the object that executes the search, and this invocation method is the same across all my queries – just varying a couple of parameters.

Virtual Machine search
In my use case, I then wanted to find the virtual machines within the matching cluster, which was similar to above, but I used a new entitySet and filter.
var entitySetName = 'VirtualMachineProperties';
var filter = "PropertyName eq '" + propertyName + "' and PropertyValue eq     '" + propertyValue + "'";

Properties search

And the final search was to find all virtual machines with a given property – a custom property in my case.
var entitySetName = 'VirtualMachineProperties';
var filter = "PropertyName eq '" + propertyName + "' and PropertyValue eq     '" + propertyValue + "'";
End result
At the end of these searches, I had two arrays of virtual machine objects.  Merging these arrays in vRO was a piece of regular Javascript, looping over the data set looking for common elements.

See below for the visual representation of the two searches and final merge.
(Download the vRO actions here, if you like.)

In the next article, I will show a different search use case, where I needed to filter a specific VM from the vRA API.