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

Linux – How to increase LVMs by extending existing virtual disks
CentOS / RHEL Operating Systems

Linux – How to increase LVMs by extending existing virtual disks

Use Case: Logical Volume (LVM) on a Linux server requires expansion. Pre-Req: Increase the virtual disk size to the required...
Read More
Synchronising VMware SDDC Manager Credentials to Hashicorp Vault with Python
Hashicorp Vault Python VCF

Synchronising VMware SDDC Manager Credentials to Hashicorp Vault with Python

VMware's SDDC has a great feature whereby it can manage credentials for all the applications and appliances within its scope,...
Read More
Configuring iDRAC using RedFish API via Ansible.
Ansible Hardware IDRAC

Configuring iDRAC using RedFish API via Ansible.

Having a large number of iDRAC out of band (OOB) interfaces to configure on Dell hardware can seem like a...
Read More
VMware VCF on Dell VxRail 4.2 to 4.3 – Tips & Tricks
VCF

VMware VCF on Dell VxRail 4.2 to 4.3 – Tips & Tricks

VMware VCF 4.3 is GA and not a moment too soon! The release of 4.3 brings the vRealize product set...
Read More
Using the vRA Plugin for vRO – Enabling Actions in custom forms which call the vRA API
Javascript vRealize Automation vRealize Orchestrator

Using the vRA Plugin for vRO – Enabling Actions in custom forms which call the vRA API

I haven't done a blog for a while due to an overload of work, but I'm getting back on the...
Read More
SDDC Manager – ‘SSO Ring Topology’ Error when rebuilding additional VCF 4.x Workload Domains
PSC / SSO VCF

SDDC Manager – ‘SSO Ring Topology’ Error when rebuilding additional VCF 4.x Workload Domains

I've recently been working on a large VCF rollout with Dell which comprised of a management cluster and multiple workload...
Read More
vRA 8.3 – Saltstack Config – Getting started. Part 1
DevOps Salt vRealize Automation

vRA 8.3 – Saltstack Config – Getting started. Part 1

Like many others, Ansible is my tool of choice for configuring endpoints once the VM is provisioned. With the introduction...
Read More
Using vRA 8.2 Terraform cloud templates to deploy AWS resources
AWS DevOps Terraform vRealize 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
ABX Python vRealize 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 Manager Python vRealize 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
AWS DevOps Python S3

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
DevOps Javascript vRealize Automation vRealize 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
Ansible DevOps Hashicorp 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 Directory DevOps Python

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
ABX VMware VMware Cloud Services vRealize Automation vRealize 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
ABX vRealize 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