Using HTTP REST to Process or Review Requests using API with vRA/vRO

Mindwatering Incorporated

Author: Tripp W Black

Created: 12/15/2020 at 05:10 PM

 

Category:
VMWare
vRA, vRO - VCAC

Retrieve Request Info for a Request Already Submitted:
- If you know your request ID, you can get past request runs details of what your submitted.

Documentation:
The api documentation for vCO:
myvrao.mindwatering.net:8281/vco/api/docs
or, with vRA/vRO 7.6:
myvrao.mindwatering.net/component-registry/services/docs#!apis

Get Authentication Token:
Authenticate and get the authentication token for subsequent requests.
- To use JSON, add a custom header to the request:
Name: Accept
Value: application/json

$ curl --insecure -H "Accept: application/json" -H 'Content-Type: application/json' --data '{"username":"myadminid@vsphere.local","password":"myadminpassword","tenant":"vsphere.local"}' https://myvrao.mindwatering.net/identity/api/token

Notes:
- Update the admin id, the password, the tenant, and the name of your vRA server.
- The return will be in JSON, parse out the "id" value returned. We re-use the token until its expiration. Set it to a variable and a a prefix "Bearer ".
- vRA supports Bearer token in 7.6, vRO supports Basic username and password. The login endpoint would get a token, but we could not use the Bearer token the second workflow GET call; we'd get an Error 500.
- The JSON support for syntax is frustrating, any syntax errors or tags outside the expected order create an Error 400 as a response.

e.g.
export AUTHTOKEN = "Bearer ABCD1234...1234=="
- Use the token and add to the header of each response afterwords.



Get a workflow by it's UUID:
URL: myvrao.mindwatering.net:8281/vco/api/workflows/abc1234a-a123-b123-abcd-123654321abc
or, in vRA/vRO 7.6
myvrao.mindwatering.net/vco/api/workflows/abc1234a-a123-b123-abcd-123654321abc


Get a workflow by name:
URL: myvrao.mindwatering.net:8281/vco/api/workflows/?conditions=name=worfklow%20name
or, in vRA/vRO 7.6
myvrao.mindwatering.net/vco/api/workflows/?conditions=name=worfklow%20name

Notes:
- In the above workflow, workflow name, the space was converted to %20.

- Add the authorization token:
Name: Authorization
Value: $AUTHTOKEN

- To use JSON, add a custom header to the request:
Name: Accept
Value: application/json

- The itemHref attribute contains the URL to retrieve (GET) the workflow executions. Locate the itemHref attribute:
...
{
"value": "https://myvrao.mindwatering.net:8281/vco/api/workflows/abc1234a-a123-b123-abcd-123654321abc",
"name" : "itemHref"
},
...

- We use the ID to view the past executions or to execute a new one. Locate the attribute: "id":
...
{
"value": "abc1234a-a123-b123-abcd-987654321abc",
"name" : "id"
},
...

- The parameters of the workflow are included within the JSON input-parameters array:
...
"input-parameters": [
{
"value": {
"string": {
"value": "parametervalue"
}
},
...

In vRO, 7.6, we seem to have a more rigorous format; we have to include the local scope. We use the GET input-parameter as the format for the POST.
...
"input-parameters": [
{
"value": {
"string": {
"value": "parametervalue"
}
},
"type": "string",
"name": "parametername"
"scope": "local"
}
],
...



Perform a GET request for a Specific Workflow Execution:
URL: myvrao.mindwatering.net:8281/vco/api/workflows/1234abcd...abcd123/executions/ff12345123a123123a1234a123456/
Note:
- Replace the workflow ID 1234abcd...abcd123 with a real request ID above.
- Replace the execution ID ff123...456 with a real execution/run ID.

This will return the status, such as Complete, Running, etc.



Submit a New Workflow Run (POST):
- Use the executions path.
e.g. myvrao.mindwatering.net:8281/vco/api/workflows/1234abcd...abcd123/executions/

- Reuse the JSON of the previous run's GET request.

- Change input-parameters to just parameters when doing a POST. Within the renamed parameters JSON array, re-use the same individual fields and values for the post.

- To send a SecureString parameter:
...
{
"name":"fldSecure",
"type":"SecureString",
"scope":"local",
"value":{ "string":{"value":"securetext"}
},
...

- To use JSON, add two custom headers to the request:
Name: Accept
Value: application/json

Name: Content-Type
Value: application/json


Note: Below is the JSON for one or more parameters. To avoid the Error 400 error, we can either
{
"parameters": [
{
"value": {
"string": {
"value": "parametervalue"
}
},
"type": "string",
"name": "parametername",
"scope": "local"
}
]
}

or

{
"parameters": [
{
"type": "string",
"name": "parametername",
"scope": "local",
"value":
{
"string":
{ "value": "parametervalue" }
}
}
]
}

The response from the vCO server should be:
Status Code: 202 (Accepted)
Content-Length: 0
Date: <the current date in GMT>
Location: <the full URL of the post e.g. myvrao.mindwatering.net:8281/vco/api/workflows/1234abcd...abcd123/executions/ff54345123abc3123a1234a123123/ >


Get Run Status:
Use the workflow execution/run ID with a /state to GET the status of the run. So for the above POST, the corresponding status GET would be:
myvrao.mindwatering.net:8281/vco/api/workflows/1234abcd...abcd123/executions/ff54345123abc3123a1234a123123/state

Successful run:
Status: 200 (OK)
Body:
{"value":"completed"}

Failed run:
{"value":"failed"}

Running run:
{"value":"running"}

Waiting run:
{"value":"waiting"}

Cancelled run:
{"value":"canceled"}




___________________

vRA Deployment

___________________

v7.6 - Get Actions for Deployment ID:
Retrieve the actions for a vRA deployment ID from vRA (vRA runs on port 443). Use the Deployment ID, not the Request ID for this REST API call.
GET: myvrao.mindwatering.net/catalog-service/api/consumer/resources/12ab3c456-abc1-1234-1ab2-a123b4c5678d9/actions
{
"links": [],
"content" : [
{
"@type": "ConsumerResourceOperation",
"name": "Destroy",
...
"type": "ACTION",
"id": "1ab2c3de-a123-b456-c123-d123abc12345",
...
}
]
}

Using the id above, a repeat call using the id, can initiate a destroy on the VM.

Perform a Destroy for the vRA deployment. We need the resource ID/ deployment ID, the action ID, and body (reason of the destroy).
e.g.
Deployment ID: 12ab3c456-abc1-1234-1ab2-a123b4c5678d9
Action ID: 1ab2c3de-a123-b456-c123-d123abc12345
Body: "Destroy requested by customer. Req# ABCDE-AB123EF."

POST: myvrao.mindwatering.net/catalog-service/api/consumer/resources/12ab3c456-abc1-1234-1ab2-a123b4c5678d9/actions



vRO / vRA8.x - Get All Deployments:
Retrieve the actions for a vRA deployment ID from vRA (vRA runs on port 443). Use the Deployment ID, not the Request ID for this REST API call.
GET: myvrao.mindwatering.net/deployment/api/deployments/

restPathURI = "/deployments/api/deployments/";
restMethod = "GET";
restInputHdrs = new Properties();
restInputHdrs.put("Content-Type", "application/json");

var restPayloadJSON = "";
restPayload = JSON.stringify(restPayloadJSON);

Notes:
Pass the rest* variables above into your vRA (Host) REST action. Assign the response from the action into a restResponse/restResp string variable.

To loop through results write something like:
try {
var jsonDetails = JSON.parse(respResp);
var jsonArr = jsonDetails["content"];
for (var tmpObj in jsonArr) {
var depID = jsonArr[tmpObj].id;
var depNm = jsonArr[tmpObj].name;
// ... do something ...

} catch(e) {
System.error("ScriptTask-An unhandled exception was caught: " + e);
throw e;
}


v8.x - Set/Extend a Lease:
Retrieve the actions for a vRA deployment ID from vRA (vRA runs on port 443). Use the Deployment ID, not the Request ID for this REST API call.
POST: myvrao.mindwatering.net/deployment/api/deployments/<id>/requests

Incoming Variables:
depID as string
leaseDays as number
leaseReasonTxt as string

try {
var leaseDt = new Date(Date.now());
leaseDt.setDate(leaseDt.getDate() + leaseDays);
leaseDtStr = leaseDt.toISOString();
System.debug("leaseDtStr: " + leaseDtStr);

restPathURI = "/deployments/api/deployments/" + depID + "/requests";
restMethod = "POST";
restInputHdrs = new Properties();
restInputHdrs.put("Content-Type", "application/json");

var restPayloadInputs = '{"Lease Expiration Date" : "' + leaseDtStr + '"}';
var restPayloadJSON = '{ "actionId": "Deployment.ChangeLease", "inputs": ' + restPayloadInputs + ', "reason": "' + leaseReasonTxt + '" }';

// restPayload = JSON.stringify(restPayloadJSON);
restPayload = restPayloadJSON;
} catch(e) {
System.error("ScriptTask-An unhandled exception was caught: " + e);
throw e;
}

Notes:
Pass the rest* variables above into the REST action. Assign the response from the action into a restResponse/restResp string variable.
If you get an error with the REST call saying that the first character should be a { and you find the payload wrapped in double quotes, leave off the stringify.


___________________

vRA Deployment
VM Properties

___________________

vRA8.x - Add or If Existing, Update a VM's Custom Properties:
Update/apply a custom property to the an existing vRA 8.x VM. Use the VM UUID for this REST API call.
e.g. POST: myvrao.mindwatering.net/iaas/api/machines/1abc23d4-abcd-1234-1234a5b6cdef

vmID = '1abc23d4-abcd-1234-1234a5b6cdef';
// build request and its header
restPathURI = "myvrao.mindwatering.net/iaas/api/machines/";
restMethod = "PATCH";
restInputHdrs = new Properties();
restInputHdrs.put("Content-Type", "application/json");

// create new properties array, and add value(s)
var newProps = new Properties();
newProps.put(propName, propVal);

// add the new props to the customProperties properties object/array as the PATCH payload:
//var object = new Object();
var customPropsObj = {"customProperties" : newProps};
// attach to payload
restPayload = JSON.stringify(customPropsObj);


Notes:
Pass the rest* variables above into the REST action. Assign the response from the action into a restResponse/restResp string variable.

var restResp = System.getModule("net.mindwatering.utils").MWvRAREST(restMethod, restPathURI, restPayload);

To loop through results write something like:
try {
var jsonDetails = JSON.parse(respResp);
var jsonArr = jsonDetails["content"];
for (var tmpObj in jsonArr) {
var depID = jsonArr[tmpObj].id;
var depNm = jsonArr[tmpObj].name;
// ... do something ...

} catch(e) {
System.error("ScriptTask-An unhandled exception was caught: " + e);
throw e;
}




___________________

Client RESTHost
Action Example

___________________

Input:
restMethod: string
restPathURI: string
restPayload: string

Output:
string

// quick verification of inputs
if ( restMethod =='' || restPathURI == '') {
System.debug('MWvRAREST-restMethod: ' + restMethod + ', restPathURI: ' + restPathURI );
throw "REST Method, Path URI, or Input Headers string is missing. Cannot perform lookup";
}
// get host by configuration item
var vRAHost = System.getModule("net.mindwatering.utils").getConfigValue('MW/vRA', 'vraHost', false);
if (vRAHost) {
// have vRA Host with its authentication account already configured
System.debug('RESTHostAction-vRAHost: ' + vRAHost);
} else {
throw "vRA Host missing. Cannot perform lookup";
}

// create the REST client and perform request:
var restClient = vRAHost.createRestClient();
var request = restClient.createRequest(restMethod, restPathURI, restPayload);
try {
var restResp = restClient.execute(request);
System.debug(''MWvRAREST-statusCode: ' + restResp.statusCode );
System.debug(''MWvRAREST-contentAsString: ' + restResp.contentAsString );
return restResp.contentAsString;
} catch(e) {
System.error("MWvRAREST-An unhandled exception was caught: " + e);
throw e;
}




previous page