Using vCAC 6.X REST APIs – Part 2

Previously on the using vCAC API blog series, we learned how capture and analyze the JSON code going from the VCAC Web UI, to the appliance.  In this post we’ll learn how to modify the request in order to generate a brand new request that can easily requested using vCO REST APIs abstraction.

Lets get to it!

First, make sure you have a vCAC 6 vCO plugin installed, and that you’ve configured it to work with your vCAC Appliance by running the ‘add a vCAC Host’ workflow.

After we have that sorted out, i’ll explain the basics of the vCO workflow required to submit the request:

Rest Request Workflow

 

Breaking it down, what I do in the first scriptable is get the catalog item object by it’s name, in order to get some of its details like id and such, the second scriptable task basically just submits the JSON code we’ve captured, with a few changes in it for the different field modification’s i’d like to perform.

As inputs, I take:
– Catalog Item Name: <Debian / RHEL 6.4 / whatever else I have in my IaaS catalog>
– Memory Size <1024/2048 whatever you want to put in>
– Cpu Size <1/2/3/4 etc.>
– User Name <any user in the Business Group to request on behalf of>

Get Catalog Item

In the general post i’ve made about the vCAC 6 plugin for VCO i’ve mentioned an object worth getting to know – the vCACCAFEEntitiesFinder in the scriptable Javascript code:

[code lang=”js”]
var founditems = vCACCAFEEntitiesFinder.findCatalogItems(vcacHost, itemName);
if (founditems != null)
{
for (var i in founditems)
{
if (founditems[i].name == itemName)
{
var catalogItem = founditems[i];
}
}
}
[/code]

get item

After I’ve found the item and made sure it exists, i’ll submit the JSON request for that item.

Request Item via REST

I’ve actually modified the formatting so it would be simpler to understand the different key:values that are submitted. I’ll point out all of the changes i’ve made to the JSON in the section below it.

[code lang=”js” collapse=”true” title=”Click to see full REST scriptable task code”]
var item = {
"@type":"CatalogItemRequest",
"catalogItemRef":{"id":catalogItem.id},
"organization":{"tenantRef":"vmdemo", "subtenantRef":"ce43f3ed-a3f0-42d0-b8e6-897239f52dbc"},
"requestedFor":UserName,
"state":"SUBMITTED",
"requestNumber":0,
"requestData":
{"entries":[
//{"key":"provider-blueprintId", "value":{"type":"string", "value":"ab5f5a5c-281b-49bf-a549-595789c07957"}},
{"key":"provider-provisioningGroupId", "value":{"type":"string", "value":"ce43f3ed-a3f0-42d0-b8e6-897239f52dbc"}},
{"key":"requestedFor", "value":{"type":"string", "value":UserName}},
{"key":"provider-VirtualMachine.CPU.Count", "value":{"type":"integer", "value":CPUs}},
{"key":"provider-VirtualMachine.Memory.Size", "value":{"type":"integer", "value":MemorySize}},
{"key":"provider-VirtualMachine.Disk0.Size", "value":{"type":"string", "value":"1"}},
{"key":"provider-VirtualMachine.LeaseDays", "value":{"type":"integer", "value":0}},
{"key":"provider-__Notes", "value":{"type":"string", "value":""}},
{"key":"provider-Vrm.DataCenter.Location", "value":{"type":"string", "value":"Lab"}},
{"key":"provider-Cafe.Shim.VirtualMachine.TotalStorageSize", "value":{"type":"decimal", "value":0}},
{"key":"provider-Cafe.Shim.VirtualMachine.Description", "value":{"type":"string", "value":""}},
{"key":"provider-Cafe.Shim.VirtualMachine.NumberOfInstances", "value":{"type":"integer", "value":1}},
{"key":"provider-Cafe.Shim.VirtualMachine.Reason", "value":{"type":"string", "value":""}},
{"key":"provider-Cafe.Shim.VirtualMachine.AssignToUser", "value":{"type":"string", "value":UserName}},
{"key":"provider-Cafe.Shim.VirtualMachine.MinCost", "value":{"type":"string", "value":"0"}},
{"key":"provider-Cafe.Shim.VirtualMachine.MaxCost", "value":{"type":"string", "value":"0"}},
{"key":"description", "value":{"type":"string", "value":""}},
{"key":"reasons", "value":{"type":"string", "value":""}
}]}
}

var catalogRest = vcacHost.createRestClient(vCACCAFEServicesEnum.CATALOG_SERVICE);
var response = catalogRest.post("consumer/requests",item);
System.log(response);
[/code]

~UPDATE~
For this to work with vCAC 6.1, you’ll need to serialize the request prior to submitting it, with the following code:

[code]item = System.getModule("org.dojotoolkit.dojo.json").serialize(item);[/code]

So be sure to add this line in your scriptable with vCAC 6.1
~UPDATE~

Screen Shot 2014-06-10 at 12.14.30 PM

Running through the code, you can notice some replacements i’ve done to the JSON text strings with my own variables, like:

[code lang=”js”]
"@type":"CatalogItemRequest",
"catalogItemRef":{"id":catalogItem.id},
[/code]

I’ve used the catalog item object to get it’s id so the proper item would be requested.
Also I’ve modified the memory and cpu parameters to fit the users input values:

[code lang=”js”]
{"key":"requestedFor", "value":{"type":"string", "value":UserName}},
{"key":"provider-VirtualMachine.CPU.Count", "value":{"type":"integer", "value":CPUs}},
{"key":"provider-VirtualMachine.Memory.Size", "value":{"type":"integer", "value":MemorySize}},
[/code]

Last part of the scriptable task code actually creates an internal , pre authenticated REST Client in vCO , to actually submit the request itself:

[code lang=”js”]
var catalogRest = vcacHost.createRestClient(vCACCAFEServicesEnum.CATALOG_SERVICE);
var response = catalogRest.post("consumer/requests",item);
System.log(response);
[/code]

the response variable will hold the servers response to our request, which will usually consist of a request item we can follow on to get progress updates with the request’s ‘Phase’ field.

To summarize the workflow, you can opt to change any one of the JSON parameters to expose less or more properties for user input, it all depends what is your use case and who are you giving this capability to. Of course your organization could have other custom properties needed to provision a vm, these appear as just another key:value in the JSON request.
Keep in mind that in more complicated environments you will probably have to add error checks, and might need to change the ‘subtenantidref ‘ value which is the value for the Business Group that the item is being provisioned by.

Day 2 operations via REST API

To allow for a day 2 action of a catalog VM with vCAC , we will repeat the process depicted in this two part series, grab the JSON code for a ‘destroy’ operation for example, and we will get the same kind of workflow. This time we will use a different vCACCAFEEnititiesFinder function called ‘

[code lang=”js”]
var founditems = vCACCAFEEntitiesFinder.findCatalogResources(vcacHost, resourceName);
[/code]

After that, we’ll get the resource object id, and post a ‘destroy action’ JSON request, for that specific VM. The code below is for posting the ‘destroy action’ after we’ve found the catalog resource item (our provisioned VM)

[code lang=”js”]
var resourceAction = {
"@type":"ResourceActionRequest",
"resourceRef":{"id":resourceItem.id},
"resourceActionRef":{"id":"a7eb7daf-de73-4cf9-b2c7-0c8aeded3b01"},
"organization":{"tenantRef":"vmdemo", "tenantLabel":"vmdemo.local", "subtenantRef":"ce43f3ed-a3f0-42d0-b8e6-897239f52dbc", "subtenantLabel":"Lab-BG"},
"state":"SUBMITTED", "requestNumber":0,
"requestData":{"entries":[]}
}
var catalogRest = vcacHost.createRestClient(vCACCAFEServicesEnum.CATALOG_SERVICE);
var response = catalogRest.post("consumer/requests",resourceAction);
System.log(response);
[/code]

Rest operations

Calling a vCO workflow with REST API

The main thing after we built this workflow, is to wrap it all up by simply letting users access this vCO workflow with vCO’s REST API! Now, users or any 3rd party system , can simply call vCO’s REST interface to run this specific workflow, and get a VM of choice with a quick API call.
You can read about calling vCO via REST in this article by our awesome vCOTeam @ VMware.

Attached below is a very simple example of calling a vCO Worflow with python code (remember to change to py instead of txt)
and REST APIs
If you have any questions, feel free to drop them in the comment section!


Comments
Harvey Specter
Posted at 9:09 pm August 19, 2014
Artur
Reply
Author

Hi Omer, thank a lot for this tutorial. Would you know how to use HTTP response in json format as an input for vCO workflow ? Let’s say, GET cluster name from vCenter and use it as input into next WF which will eventually add nodes into this cluster – or something similar

thanks
Artur

    Harvey Specter
    Posted at 5:55 pm August 24, 2014
    Kushmaro
    Reply
    Author

    Umm, if I understand correctly what you mean, I think it should be just a regular string variable, if that doesn’t work (since some JSON formats parsed by VCO parsed as an object, thus start with ‘{‘) you can always use the ‘Any’ vCO type

Harvey Specter
Posted at 3:52 pm September 15, 2014
Marty
Reply
Author

In the full REST scriptable task code, you comment out the “provider-blueprintId” entry – why is that? Thanks.

    Harvey Specter
    Posted at 4:57 pm September 15, 2014
    Kushmaro
    Reply
    Author

    Hi,
    It’s another key / value that specifies the blueprint id inside the full REST request, i’ve noticed in some testing that it’s not a ‘MUST’ meaning if its missing from the request, vCAC will autocomplete this key / value

      Harvey Specter
      Posted at 8:46 pm September 15, 2014
      Marty
      Reply
      Author

      So, vCAC can auto-complete it because it you’re telling it the catalogItem.id – is that correct? Thanks.

        Harvey Specter
        Posted at 9:14 am September 16, 2014
        Kushmaro
        Reply
        Author

        Should be able to, but i’d re-test it if I were you just to be sure :)

Harvey Specter
Posted at 12:36 pm September 22, 2014
PB
Reply
Author

Hi,
Can you please tell me how can I delete a vCAC virtual machine using the standard vCO plugin. (6.1)? I am trying to do it using ASD but not able to figure out a way to trigger the VM decommissioning process through vCO.

    Harvey Specter
    Posted at 7:57 pm September 22, 2014
    Kushmaro
    Reply
    Author

    I’m trying to understand exactly what your trying to do. Are you trying to initiate a vCAC ‘Destroy’ Action on a specific machine?

      Harvey Specter
      Posted at 11:57 am September 23, 2014
      PB
      Reply
      Author

      Yes I am trying to do it using the vCO workflow provided by the vCAC plugin – “Request a resource action”.
      When I trigger this workflow and select the “Destroy” machine operation, the workflow exits with an error. The message is as follows –
      [2014-09-23 17:16:35.569] [I] Getting resource action ‘Change Lease’ request form…
      [2014-09-23 17:16:38.260] [I] Expected inputs:
      [2014-09-23 17:16:38.261] [I] – provider-ExpirationDate
      [2014-09-23 17:16:38.261] [I] Filling in resource action request…
      [2014-09-23 17:16:38.262] [I] Sending resource action request…
      [2014-09-23 17:16:40.775] [I] 400 BAD_REQUEST – Unknown field: VM (Dynamic Script Module name : requestResourceAction#13)

      I am selecting the “Destroy” action, yet in the logs it mentions “Change Lease” action. Please let me know what am I doing wrong? Or is there an other way of doing this?

      Harvey Specter
      Posted at 10:37 am October 16, 2014
      PB
      Reply
      Author

      Hi Kushmaro,
      Any updates on how can I “Destroy” an Iaas virtual machine from vCAC custom resource action? Just a heads up though, i have disabled the standard ‘destroy’ operation from the entitlements and looking for a customized way through ASD to destroy the machine from vCAC.

        Harvey Specter
        Posted at 12:34 pm November 20, 2014
        virtualsabi
        Reply
        Author

        The plug-in Finder of the vCAC plug-in you are using isn’t working correctly with the Type ConsumerResourceOperation. It will always find only the Change Lease operation instead of the provided operation in your input parameter. So the workaround is to get the correct ResourceOperation inside your own script without providing it by attribute or input parameter.

        Harvey Specter
        Posted at 2:57 pm December 2, 2014
        Kushmaro
        Reply
        Author

        So as I said before, I don’t think its possible to destroy without the Iaas action, or , not possible in a simple manner…
        the destroy operation takes care of DB records in IaaS as well as in Cafe…
        you may be able to build something custom, but it wouldn’t be straightforward.

Harvey Specter
Posted at 10:00 pm October 7, 2014
Sides
Reply
Author

This is good stuff. Would you mind sharing a little more on the {“id”:catalogItem.id}, you are using? If put the ID from my catalog in I can deploy fine. I would like it to be dynamic but when I use the .id I get cannot read property “id”.

    Harvey Specter
    Posted at 2:55 pm December 2, 2014
    Kushmaro
    Reply
    Author

    you should be able to make it dynamic, if you can’t read the id property, i’d debug the workflow by getting the item in a separate task and trying to parse its properties

Harvey Specter
Posted at 6:10 pm November 26, 2014
Luke
Reply
Author

Kushmaro,
Can you explain how you find the provisioningGroupID from vCO for a particular blueprint?

Thanks.
-Luke

    Harvey Specter
    Posted at 2:54 pm December 2, 2014
    Kushmaro
    Reply
    Author

    ProvisioningGroupID results from the IaaS Business group ID if I recall correctly,
    sorry for the big delay in responses

Harvey Specter
Posted at 7:28 pm December 4, 2014
Sean
Reply
Author

Omer,
I was able to duplicate your results here. Have you actually successfully run any Resource Actions with this method? (power operations, lease extension, etc) It seems to be protected as I get a 403 error.

https://communities.vmware.com/message/2454875#2454875

Harvey Specter
Posted at 4:20 pm March 15, 2015
Satish
Reply
Author

Hi Omer, How to monitor the request status. The response header has location property set to the url — https://<>/catalog-service/api/consumer/requests/56428808-f9a0-4bac-b83d-ce75ddc86b78. How to use this to get request status? I tried crestclient.get(“consumer/requests/56428808-f9a0-4bac-b83d-ce75ddc86b78”) which did not work. Let me know.

    Harvey Specter
    Posted at 8:54 pm March 15, 2015
    Kushmaro
    Reply
    Author

    Satish, you can grab the request Id from that url, and get the request object using native vCO code rather rest api’s
    using : vCACENTITESFinder object , and method getCatalogRequests(vcachost,requestId)
    The resulting request object will contain ints status.

Leave a Reply

Navigation