How to use and extend the workflow "Request a catalog item" from the vCAC plug-in for vCO

How to use and extend the workflow "Request a catalog item" from the vCAC plug-in for vCO

The vCAC plug-in for vCO comes with an out of the box workflow for requesting catalog items from any vCAC host configured in the plug-in. Let's see how it's used and how to extending to request specific catalog items.

How to use the default "Request a catalog item" workflow

When you run it, the workflow presentation looks like:

Request a catalog item.PNG

where the "Catalog item" field opens a tree chooser to select the catalog item that you want to request, and the "Input value" field opens a pop-up editor for an array of composite types (key/value pairs basically):

Array of composite types.PNG

One limitation of this workflow is that the list of expected parameters is not pre-populated in the array of composite types. Another limitation is that for all the inputs the type of the value is "string". These limitations come from the vCO workflow presentation itself (difficulty of creating/loading default workflow input parameters involving composite types), and the fact that when you define an array of composite types all the elements must have the same value type (i.e. it's not possible to have some parameters as string and other as integers or booleans for example).

The good thing is that this approach works just fine for simple scenarios ("simple" catalog items) and, as you'll see, it's very easy to adapt it to more complex scenarios where, for example, a fixed collection of inputs is needed or inputs of different types are required. And the same applies for similar workflows like:

  • Request a catalog item on behalf of a user
  • Request a resource action
  • Request a resource action on behalf of a user

Then, how to get the list of expected input parameters for a specific catalog item? There are few approaches:

  • You know them already. For example if you are requesting a catalog item based on some ASD service blueprint that you created and published, or if you are requesting some well-known catalog item with well-known parameters. The important thing here to take into consideration is that once the blueprints are published the input parameters names coming from them start always with the prefix "provider-", in other words, if the blueprint defines for example a parameter called "username", the expected input parameter name will be "provider-username".
  • In case you don't know them, the most straightforward way is to run the "Request a catalog item" workflow itself for the catalog item, providing some dummy input parameter, and to check the log of the workflow execution. Most probably the workflow will fail, typically with a 400 BAD REQUEST message coming from the server, but you will get the list of expected input parameters printed.

get_input_parameters.png

  • Also, if you want to get them and populate them more dynamically from a piece of scripting, you can use directly the action "getRequestFormInputsForCatalogItem" from the module "com.vmware.library.vcaccafe.request".
  • Finally, as alternative, you can access the catalog item or request the catalog item from the catalog and, for example, use a browser functionality or plug-in like FireBug to capture the specific request and its inputs parameters. You can find more details about it (and related topics) in blog posts like:

And once you have the list of input parameters you can run again the workflow and set them and their values accordingly in the "Input value" field. Now let's see how to create custom workflows based on the default one to define custom workflow inputs forms and to combine different input values types.

How to create a custom workflow for requesting service-oriented catalog items

  • The first step is to duplicate the default workflow, e.g., to "Request a catalog item (service)".
  • After that you can edit the inputs of the workflow to include the default ones (instead of using the generic "inputs" parameter):
    • description (string, mandatory)
    • reasons (string, optional)
  • And depending on the service you may expose more or less input parameters depending on the catalog item that you want actually to request (which, at the same time can be another input of the workflow or "fixed" as a workflow attribute). For the example let's say that you want to expose the following inputs:
    • aString (string)
    • anInteger (catalog item type integer, vCO type number)
    • aDecimal (catalog item type decimal, vCO type number)
    • aBoolean (boolean)
  • Then you'll get a presentation like:

2014-06-13_1527.png

  • After that you have to replace, from the workflow schema, the "compositeTypeToProperties" action call with a custom Scriptable task:

2014-06-13_1521.png2014-06-13_1521_001.png

  • With the following scripting code:
  • 2014-06-26_1439.pngAnd that's all. The previous block of scripting code will set the proper values in the scripting object "properties", and after that the next "requestCatalogItem" action will receive that "properties" object and it will uses it to prepare and send the request.

How to create a custom workflow for requesting machine-oriented catalog items

This scenario is pretty much the same like the previous one, the only difference is the list of usual parameters that are needed to request a typical machine. For example, from the machine blueprint used in the beginning, these are:

  • blueprintId (string)
  • provisioningGroupId (string)
  • Cafe.Shim.VirtualMachine.NumberOfInstances (integer)
  • Cafe.Shim.VirtualMachine.TotalStorageSize (decimal)
  • VirtualMachine.LeaseDays (integer)
  • VirtualMachine.CPU.Count (integer)
  • VirtualMachine.Memory.Size (integer)
  • VirtualMachine.Disk0.Size (decimal)
  • VirtualMachine.Disk0.IsClone (boolean)

And defining them as inputs of a vCO workflow, for example as:

  • blueprintId (string)
  • provisioningGroupId (string)
  • numberOfInstances (vCO number)
  • totalStorageSize (vCO number)
  • leaseDays (vCO number)
  • cpuCount (vCO number)
  • memorySize (vCO number)
  • disk0Size (vCO number)
  • disk0IsClone (boolean)

Then at the end the scripting code to prepare the parameters for the request should look like:

2014-06-26_1442.pngThe values for the "blueprintId" and "provisioningGroupId" could be extracted from the requested catalog item itself in case it's provided as an input parameter as well, but a bit more of scripting code is needed.

Conclusion

The out of the box workflow "Request a catalog item", because of the reasons exposed previously, won't work by default in all the possible scenarios, but as you can see it's very easy to (re-)use it as the base for customized "Request my catalog item" workflows.

Edited (06/26):

vNico let me know that the expected way of setting a boolean within the properties didn't work in his scenario:

properties.put("provider-aBoolean", vCACCAFEBooleanLiteral.fromBoolean(aBoolean).getValue());

So that I updated the example and I propose as workaround his suggestion of using a plain string:

properties.put("provider-aBoolean", aBoolean ? "true" : "false");

Edited (10/31):

After Jase Machado and other colleagues comments it looks like somehow (I'm not sure how or why for now) some Machine Blueprints are published with their parameters 'Disk0.Size' defined as of type 'string' instead of type 'decimal' as described in the post. This causes the request to fail and an error with the message "A server error was encountered. Error requesting machine. Input string was not in a correct format.". The solution in this case is just replacing the line:

properties.put("provider-VirtualMachine.Disk0.Size", new vCACCAFEDecimalLiteral(disk0Size).getValue());

with:

properties.put("provider-VirtualMachine.Disk0.Size", disk0Size);

and to be sure that the workflow variable 'disk0Size' is of type 'string' and not of type 'number'.

Comments

Very good job Sergio ! It will be very usefull for everyone in the field for sure Smiley Wink.

One last observation during my tests is that the "Cafe.Shim.VirtualMachine.TotalStorageSize" is mandatory, but don't have to be exact. It could be set to "0" in the request, the provisioning process will auto-calculate the exact right size of that paramter.

Good point and useful info! Thank Nico!

When I run this and it spits out the list of expected inputs I don't see any of my custom properties in the list.  They are all string types.  It seems to accept them as inputs however.  Is this expected behavior?  It seems like a bug.

I'd also like to call this via curl with the vCO api.  Up until now I have only done very simple calls to the vCO api and I am not exactly sure how to format the incoming json for the catalog item and the composite type list of parameters.  I don't suppose you have a sample of that as well do you?

Hi all,

Is this solution is working fine ? I am getting same problem during destroying the VM using workflow "Request a resource Action".

Thanks for reply.

Yes, the same ideas applies to the "Request a Resource Action" workflow. I could try to prepare another example at some point, but with the guidelines form this post it should be easy to adapt a copy of the "Request a Resource Action" workflow also.

Yes, unfortunately for now blueprints custom properties are not included in the list of expected inputs (we are working on being able to retrieve them), but of course if you know them you can pass them as parameters as well.

For the composite type through REST example, I have nothing right now but I'll try to find one for you.

Thanks for the document. One question remains thought: is there some default parameter I can pass so vCAC will grab the blueprint default values? E.g. the blueprint is configured to use 2 CPU, instead of calling vCAC in order to get that configuration information it would be nice to just pass  "NULL" as VirtualMachine.CPU.Count and have vCAC grab the default (2).

Is there something like that?

I think that it depends on the type of input, whether is mandatory or not.

If it's not mandatory and you don't provide it, the catalog request process should take the default value from the blueprint.

If it's mandatory and you don't provide it the request will fail, and since plug-in logic is still not so "advanced" to retrieve the default values, you have to provide the value explicitly, whether is the default value (that you know), or a different value.

For next releases we will try to extend the request submission (or request creation) process to show or use any default values if there are any and as far as is possible (this could be trivial for simple types and values, e.g. CPU = 2, but complex for other types or object references, e.g. datacenter = pointer to "Data Center A").

Hello Sergio, Thanks so much for writing up this blog! I'm surprised there are not more views as this is a situation I would imagine a lot of people would be in.

Our situation is that the vCAC API is not really easy or ready for consumption and of course we are turning to the tried and true vCO API to launch vCAC blueprints.

I followed all the steps in this guide, and the error shown in vCAC improved from " 'Entries' should not be empty" which is what you get when you just run the vanilla workflow for "Request a catalog item" to now saying "A server error was encountered Error requesting machine. Input string was not in a correct format.." It seems the array of properties is coming over in the request but some needed values are missing, incorrect, or wrong format?

Do I need to define the blueprintID or provisioningGroupdId string variables? Any ideas where or what I should be looking at?

This image shows the vCAC results using the default vCO workflow and after modifying the workflow per this blog.

This image shows the vCO workflow Variables and Logs when running the modified vCO workflow.

Any suggestions would be very appreciated! Smiley Happy

BTW - Here are the lines of code (below) in the scriptable task so that others can copy to their clipboard.

_________________________________________________________________________________

properties = new Properties();

properties.put("provider-blueprintId", blueprintId);

properties.put("provider-provisioningGroupId", provisioningGroupId);

properties.put("provider-Cafe.Shim.VirtualMachine.NumberOfInstances", new vCACCAFEIntegerLiteral(numberOfInstances).getValue());

properties.put("provider-Cafe.Shim.VirtualMachine.TotalStorageSize", new vCACCAFEDecimalLiteral(totalStorageSize).getValue());

properties.put("provider-VirtualMachine.LeaseDays", new vCACCAFEIntegerLiteral(leaseDays).getValue());

properties.put("provider-VirtualMachine.CPU.Count", new vCACCAFEIntegerLiteral(cpuCount).getValue());

properties.put("provider-VirtualMachine.Memory.Size",  new vCACCAFEIntegerLiteral(memorySize).getValue());

properties.put("provider-VirtualMachine.Disk0.Size",  new vCACCAFEDecimalLiteral(disk0Size).getValue());

properties.put("provider-VirtualMachine.Disk0.IsClone", disk0IsClone ? "true" : "false");

_________________________________________________________________________________

Thanks Jase! You are right that we have a lot of opportunities for improvement in the vCAC API areas, and I guarantee you that we are working on that Smiley Happy

About your issue, a colleague of mine had exactly the same issue recently and after some debugging together I think that we found the solution. In his case it looks like the Machine Blueprint was published (I'm not sure how or why right now) with the parameter 'Disk0.Size' being of type 'string' instead of type 'decimal' as described in the post. Then just replacing the line

     properties.put("provider-VirtualMachine.Disk0.Size", new vCACCAFEDecimalLiteral(disk0Size).getValue());

with

     properties.put("provider-VirtualMachine.Disk0.Size", disk0Size);

and changing the vCO type of your workflow variable 'disk0Size' from 'number' to 'string' should do the trick.

If that doesn't work, I'd suggest you to do a dummy request through the browser and capture the actual HTTP request body with all the parameters, where you can see for each of them its name and type (and provided value). This will allow you to compare them with the ones from your scripting element and decide whether they have the right types or not.

That fixed it! Thank you sir!

Sergio,

   Above you said "The values for the "blueprintId" and "provisioningGroupId" could be extracted from the requested catalog item itself in case it's provided as an input parameter as well, but a bit more of scripting code is needed.".  I'm having trouble figuring out how to find the provisioningGroupID for a particular blueprint.  Can you provide a little guidance.  Any help would be greatly appreciated.

-Luke

So I think if figured out how to get the provisioningGroupId, but now I'm getting an error when the workflow is sending info to vCAC.  Here's the error I'm getting...

[2014-11-26 14:35:54.247] [I] Getting catalog item 'Colo Windows Server 2012R2' request form...

[2014-11-26 14:35:58.975] [I] Expected inputs:

[2014-11-26 14:35:58.976] [I]  - provider-Cafe.Shim.VirtualMachine.TotalStorageSize

[2014-11-26 14:35:58.976] [I]  - provider-blueprintId

[2014-11-26 14:35:58.976] [I]  - provider-provisioningGroupId

[2014-11-26 14:35:58.977] [I]  - provider-VirtualMachine.LeaseDays

[2014-11-26 14:35:58.977] [I]  - provider-VirtualMachine.Memory.Size

[2014-11-26 14:35:58.977] [I]  - provider-Cafe.Shim.VirtualMachine.NumberOfInstances

[2014-11-26 14:35:58.978] [I]  - provider-VirtualMachine.CPU.Count

[2014-11-26 14:35:58.978] [I] Filling in catalog item request...

[2014-11-26 14:35:58.978] [I] Sending catalog item request...

[2014-11-26 14:35:58.979] [I] ch.dunes.vso.sdk.api.IUserToken.getPrincipalKey()Ljava/lang/String; (Dynamic Script Module name : requestCatalogItem#13)


As you can see, I’m getting the unfortunate error that doesn’t really say anything.  I pass in all of the Expected inputs and I have verified in vCAC that I am entitled to create a vm from this blueprint.

Hi Luke,

What version of the plug-in and vCAC are you using? Do you have the host configured with "shared session" credentials or it's registered in vCAC as "session per user"? I think I've seen a similar error when handling some type of credentials... but not on any final build but on some internal build of 6.1. Anyway, if you can answer my questions I'll try to find out about the issue.

Sergio

My vCO is 5.5.2, vCAC is 6.1.0 and the plugin is 6.1.0 as well.  I know there were issues in previous plugin versions with the session per user, but according to the documentation it was fixed in 6.1.0.  I found that after I posted this, and I haven't been able to get a hold of the username and password to change it to shared session.  That should happen this afternoon.  vCenter is also configured with session per user so I was going to change that to shared session as well.

-Luke

Hi Luke,

A colleague of mine answered your question in the Communities provisioning a vCAC machine from vCO error.

You will let us know whether you made it work.

Sergio

sanchezs,

      I haven't tried the technical preview of the vCAC 6.1.1 plugin.  However, changing the session mode type from session per user to shared session did resolve our issue.  Based on what your colleague said, it looks like the technical preview should work for both session mode types.

Thanks,

     Luke

We worked with the VMware PSO group to build something much like this so we can make requests against vCAC using Ruby. This was successful, the collection of provided values are used to construct a number of attributes that some machine state changes can look for and key in on.

However, I still want to use ASD to provide some GUI look and feel similar to the above. When we were coming via Ruby the requestor was providing a field value called "platform.businessunit" and an action is used to go find the proper business group that has the matching custom property. ASD already has this value, but other parts of the workflow depend on the shorter name! So now I need to perform the inverse. The business group is known, but I need to look up a custom property that belongs to it.

Sorry if thats a bit confusing.

Dear,

Thanks for the details. I am using vRO 7.0 and vRO 7.0. I am trying to execute the below steps mentioned by you to know the exact form values. But I am not getting any expected values in the error log. Can you please help me out ?

"In case you don't know them, the most straightforward way is to run the "Request a catalog item" workflow itself for the catalog item, providing some dummy input parameter, and to check the log of the workflow execution. Most probably the workflow will fail, typically with a 400 BAD REQUEST message coming from the server, but you will get the list of expected input parameters printed"

Thanks,

Koushik

You won't have the finder element in the workflow work the way it worked for vRO 6.0.3. or previous version of vRO As the vRA 7.0 has the new CBP (Composite Blueprint )added to the machine ,but the changes in vRO for the same to fetch the properties are not added.

But using same machine properties as you defined in vRO 6.0.3 you can provision the machine in vRA 7.0 ,but yes those properties will not be available at the CBP level and if you want to pass the value at CBp level you need to pass the properties as

provider-BaseTemplate-VirtualMachine.Network0.Name

where BaseTemple is nothing but CBP or in vRA its default  value is vSphere_Machine_1

So you can provision machine with

provider-VirtualMachine.LeaseDays
provider-VirtualMachine.CPU.Count
provider-VirtualMachine.Memory.Size
provider-VirtualMachine.Disk0.IsClone
provider-VirtualMachine.Disk0.Size
provider-VirtualMachine.Disk1.IsClone
provider-VirtualMachine.Disk1.Size
provider-Cafe.Shim.VirtualMachine.TotalStorageSize
provider-HostName
provider-VirtualMachine.Network0.Address
provider-VirtualMachine.Network0.Gateway
provider-VirtualMachine.Network0.SubnetMask
provider-VirtualMachine.Network0.PrimaryDns
provider-VirtualMachine.Network0.SecondaryDns
provider-VMware.VirtualCenter.Folder

Or

provider-vSphere_Machine_1-VirtualMachine.LeaseDays

along with about machine properties

In my experience with 7.0.1 the properties VirtualMachine.Memory.Size and VirtualMachine.CPU.Count need to be specified with the blueprint object name like "provider-vSphere_Machine_1-VirtualMachine.CPU.Count". I ended up converting them directly to the blueprint object they referenced and all is well with the world.

Use as below

Memory = json.memory * 1024;

inputs.put("provider-VirtualMachine.Memory.Size",new vCACCAFEIntegerLiteral(Memory).getValue());

None of these work they all result in a 400 BAD_REQUEST error:

inputs.put("provider-VirtualMachine.Memory.Size", json.memory * 1024); -- NUMBER 1024

inputs.put("provider-VirtualMachine.Memory.Size", (json.memory * 1024).toString()); -- STRING "1024"

inputs.put("provider-VirtualMachine.Memory.Size", new vCACCAFEIntegerLiteral(json.memory * 1024).getValue()); -- INTEGER 1024

inputs.put("provider-VirtualMachine.Memory.Size", new vCACCAFEDecimalLiteral(json.memory * 1024).getValue()); -- DECIMAL1024


var memory = json.memory * 1024;

inputs.put("provider-VirtualMachine.Memory.Size", new vCACCAFEIntegerLiteral(memory).getValue()); INTEGER 1024


using "provider-vSphere_Machine_1-VirtualMachine.Memory.Size" just creates a property with that name but does not affect the memory allocated to the VM.


Basic blueprint with a single vCenter VM object.

For anyone else trying to duplicate this process in vRA 7.

Request vRA 7.0.1 Catalog Item from vRO

Version history
Revision #:
1 of 1
Last update:
‎06-13-2014 07:21 AM
Updated by: