Obtaining a VMware Cloud Services API token via vRO & ABX

If you are working with VMware cloud services such as VMware on AWS (VMC) or vRA Cloud, you will likely hit the point where you need to authenticate into cloud services before enacting the relevant REST API call.

This post quickly covers creating a vRO workflow (which will also work as an action) and a python ABX call. Both the workflow and ABX action return an access token which subsequent calls can utilise.

This post assumes a good working knowledge of vRealize Orchestrator

vRO Worflow

Step 1 – Create REST Host & Operation

a. Create a new REST host with the below parameters

vRO host configuration
REST Host configuration

b. Create a new REST Operation against the above host with the below parameters. Note the Content-Type is application/x-www-form-urlencoded, which is a little unexpected as everything these days is application/json. This caught me out for ages and I had to go back and RTFM!

vRO REST operation
REST Operation

Step 2 – Setup constants file

I like to use vRO constants as a way of holding global variables, configurations and credentials in a secure manner which can be programatically called rather than having multiple inputs on workflows. It also speeds up the transformation from workflow > action when needed.

In this example, I have a tg-test100Constants file with my VMware Cloud API key and the REST:Operation configured as vars cloudApiKey & restLogin respectively.

vRO Constants file
vRO Constants

Step 3 – Create workflow schema

Create a very basic workflow with a single script, no inputs and a single output of accessToken/string. I always add a default error handler to workflows as a centralised error handling mechanism, but here it is probably overkill!

vRO workflow schema
Basic vRO Schema

Step 4 – Code

Below is the code within the Obtain Token step.

General Flow.

  • Grabs the variables from the constants file, as described above.
  • Creates content var, which is the urlencoded payload which is passed in the body of the HTTP request.
  • Sets the request header to accept application/json, allowing for simple parsing of the returned data.
  • Executes the request to VMware in a while loop, which will try 3 times before failing.
  • If statuscode 200 is found, the returned content is parsed as JSON and the relevant access token is obtained and set as the workflow output variable.
var categoryPath = "Library/Testing"
var category = Server.getConfigurationElementCategoryWithPath(categoryPath)
//die in a fire if non-existent
if (category == null) {
    throw "Configuration element category '" + categoryPath + "' not found or empty!";
}
//get _all_ the elements
var elementName = "tg-test100Constants"
var attributeName_cloudAPIKey = "cloudApiKey"
var attributeName_restlogin = "restLogin"
var elements = category.configurationElements;
var result = [];

for (i = 0; i < elements.length; i++) {
    if (elements[i].name == elementName) {
        var apikey_attribute = elements[i].getAttributeWithKey(attributeName_cloudAPIKey);
        var restlogin_attribute = elements[i].getAttributeWithKey(attributeName_restlogin);
        var refresh_token = apikey_attribute.value
        var restLogin = restlogin_attribute.value
    } else {
        throw "Attribute '" + attributeName + "' not found!";
    }

}

var content = "refresh_token=" + refresh_token
param = [""]
var request = restLogin.createRequest(param, content);
request.setHeader("accept", "application/json");
System.log(request.fullUrl)
//System.debug("Executing content: " + content);

var response = {
    statusCode: 0,
    contentAsString: ""
};


var count = 3
var sleepMs = 10000
while (count > 0) {
    --count; 3;
    try {
        response = request.execute();;
        System.debug("Response status code: " + response.statusCode);
        System.debug("Response content: " + response.contentAsString);
    } catch (e) {
        System.error("REST Execution failed with URL: " + request.fullUrl + " Error Details: " + e);
    }

    if (response.statusCode === 200) {
        var content = JSON.parse(response.contentAsString);
        if (content !== null) {
            var accessToken = content.access_token;
            System.debug("Access Token Obtained")
            count = 0
        }
    }
    else { 
		if (count > 0) {
			System.sleep(sleepMs) 
		} else {
			errorCode = "Unable to retrieve access token"
			throw (errorCode)
		}
	}

}

ABX Action

The equivilant code in ABX is much smaller and simplier.

ABX Dependancy: requests

refresh_token – This is an ABX input with your API key included. I don’t recommend this as its held in clear text using vRA Cloud.

import ldap3
import json
import requests
import time
def handler(context, inputs):

    #Login to VMware API and obtain access token
    refresh_token = inputs['refresh_token']
    vmware_api_url = 'https://console.cloud.vmware.com/csp/gateway/am/api/auth/api-tokens/authorize'
    full_url = vmware_api_url
    session = requests.Session()
    session.headers.update({"accept" : "application/json"})
    response = session.post(full_url, data = {'refresh_token':refresh_token})
    if response.status_code == 200:
        json_response = json.loads(response.content)
        access_token = json_response['access_token']
    else:
        raise NameError("Error Obtaining API Access Code. Status Code " + response.status_code)
        
    #Setup response headers
    session.headers.update({"content-type" : "application/json"})
    basic_auth_header = "Bearer " + access_token
    session.headers.update({"authorization" : basic_auth_header})
    session.headers.update({"csp-auth-token": access_token})
    

References

Creating an API key:

https://docs.vmware.com/en/VMware-Cloud-services/services/Using-VMware-Cloud-Services/GUID-E2A3B1C1-E9AD-4B00-A6B6-88D31FCDDF7C.html

Using vRA 8.2 Terraform cloud templates to deploy AWS resources
AWSDevOpsTerraformvRealize Automation

Using vRA 8.2 Terraform cloud templates to deploy AWS resources

VMware have jumped on the Terraform bandwagon and it is now fully integrated into vRA 8.2 onwards. In this blog...
Read More
vRA Cloud ABX – Manage Action Secrets
ABXPythonvRealize Automation

vRA Cloud ABX – Manage Action Secrets

Not a moment too soon into 2021 and vRA Cloud has been updated with some essential functionality, the ability to...
Read More
Manual Sync of VMware Identity Manager (vIDM) via API
Identity ManagerPythonvRealize Automation

Manual Sync of VMware Identity Manager (vIDM) via API

VMware's Identity Manager. 🙁 A product which causes me more hassle than it's worth (in my opinion!). I get why...
Read More
Managing AWS S3 objects via Python & boto3
AWSDevOpsPythonS3

Managing AWS S3 objects via Python & boto3

I recently had a task which required updating a large number of JSON manifest files housed within S3 folders, so...
Read More
vRA 8.x Orchestrator validation in custom forms
DevOpsJavascriptvRealize AutomationvRealize Orchestrator

vRA 8.x Orchestrator validation in custom forms

When configuring vRA service broker custom forms, it is often useful to validate user values prior to the data being...
Read More
Creating Hashicorp Vault Records with Ansible
AnsibleDevOpsHashicorp Vault

Creating Hashicorp Vault Records with Ansible

Hasicorp Vault is a more and more popular choice for securing credentials / keys / certificates. The API is clear...
Read More
Using ldap3 python module to manage Active Directory
Active DirectoryDevOpsPython

Using ldap3 python module to manage Active Directory

I have found myself in situations where I have needed to manage Active Directory objects programatically, but have not been...
Read More
Obtaining a VMware Cloud Services API token via vRO & ABX
ABXVMwareVMware Cloud ServicesvRealize AutomationvRealize Orchestrator

Obtaining a VMware Cloud Services API token via vRO & ABX

If you are working with VMware cloud services such as VMware on AWS (VMC) or vRA Cloud, you will likely...
Read More
Using vRA ABX actions to execute and monitor Jenkins jobs
ABXvRealize Automation

Using vRA ABX actions to execute and monitor Jenkins jobs

I hit the requirement recently to execute a Jenkins job as part of a VM build within vRA. I wanted...
Read More

Leave a Reply