VRA Cloud -Add the users in Projects and Change the owner of deployment dynamically using Python abx action

Recently i came across the used case , Where daily 100+ deployments are getting submitted via Service Account with CI/CD tool Jenkins or Code stream. Later VRA admin has to change the owner of the deployment to end user manually and To change the Owner of deployment currently VRA support only for those user who are explicitly part of project . VRA Admin first add the user in project and assign the permission then he does the change owner task.

Although it is 3-5 click Job but If we have to do for 100+ user , this can become very tedious task . To ease the Job I have created the Python ABX action and Yaml which will take the input who shall we be the owner of the deployment and Will add that user in Project and assign the ownership of deployment to specified user. Below shows the flow of operation.

As we see First we need Catalog Item which accepts the above items . For that below is the Yaml reference.

formatVersion: 1
inputs:
  email:
    type: string
    title: Owner Email
    pattern: "^[a-zA-Z0-9+_.-]+@[a-zA-Z0-9]+.[a-zA-Z0-9]+$"
    description: 'Enter valid email Address exam: support@vmwarecode.com'
  role:
    type: string
    title: User Role
    enum:
      - administrator
      - member
      - viewer
  type:
    type: string
    title: User Type
    enum:
      - user
resources:
  Cloud_vSphere_Machine_1:
    type: Cloud.vSphere.Machine
    properties:
      image: Linux
      flavor: Small
      constraints:
        - tag: 'vCenter155:Cluster'
      networks:
        - network: '${resource.Cloud_vSphere_Network_1.id}'
  Cloud_vSphere_Network_1:
    type: Cloud.vSphere.Network
    properties:
      networkType: existing
      constraints:
        - tag: 'vCenter155:network'

Save the Blueprint and release it , Catalog Item will look like below.

Next step is create the Python ABX action, To do that we have some prerequisites
1. Save the VRA cloud api url in secrets by name VRAURL
2. Save CSP token with full role permission in secrets by name token.

Here is the screenshot for reference.

Once we have created above 2 secrets , we are good to go for creating Python ABX action.
Here is the code , Only thing I have hardcoded in Project ID in code in line number 11 . you may provide your project ID in code.

import requests
import json
from requests.packages.urllib3.exceptions import InsecureRequestWarning

requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

def handler(context, inputs):
    vraurl = context.getSecret(inputs['VRAURL'])
    token = context.getSecret(inputs['token'])
    deploymentid = inputs['deploymentId']
    id = '4d0f75d5-8855-481b-a78d-2e5957fd8cc4'
    email = inputs['requestInputs']['email']
    role = inputs['requestInputs']['role']
    type = inputs['requestInputs']['type']
    api_version_url = f'{vraurl}/iaas/api/about'
    headers = {
        'accept': "application/json",
        'content-type': "application/json"
    }
    output = requests.get(url=api_version_url, headers=headers, verify=False)
    if output.status_code == 200:
        latest_api_version = output.json()['latestApiVersion']
        apiversion = latest_api_version
        # Getting the Bearer token

        # Getting the bearer token
        iaasUrl = f"{vraurl}/iaas/api/login?apiVersion={apiversion}"
        refreshtoken = token
        iaasPayload = f'{{"refreshToken": "{refreshtoken}"}}'
        iaasApiOutput = requests.post(iaasUrl, data=iaasPayload, headers=headers, verify=False)
        if iaasApiOutput.status_code == 200:
            print('Authentication completed with VRA Cloud')
            jsondata = iaasApiOutput.json()['token']
            bearerToken = "Bearer " + jsondata
            bearertoken = bearerToken
            headers = {
                'accept': "application/json",
                'content-type': "application/json",
                'authorization': bearertoken
            }

            # adding the New User to Project
            url = f'{vraurl}/project-service/api/projects/{id}/principals'
            payload_schema = {
                "modify": [
                    {
                        "email": "",
                        "type": "",
                        "role": ""
                    }
                ],
                "remove": [
                    {
                        "email": "",
                        "type": ""
                    }
                ]
            }
            user_inputs = {
                "email": email,
                "type": type,
                "role": role
            }
            payload_schema['modify'][0].update(user_inputs)
            apioutput2 = requests.patch(url, headers=headers, data=json.dumps(payload_schema), verify=False)
            if apioutput2.status_code == 200:
                # Changing the owner
                print(f'User {email} has been added to Project')
                url2 = f'{vraurl}/deployment/api/deployments/{deploymentid}/requests'
                data = {
                    "actionId": "Deployment.ChangeOwner",
                    "inputs": {
                        'New Owner': email
                    }
                }
                apioutput3 = requests.post(url2, headers=headers, data=json.dumps(data), verify=False)
                print(apioutput3)
            else:
                print(apioutput2)
                print(apioutput2.json())
        else:
            print(iaasApiOutput.status_code)
            print(iaasApiOutput.json())
    else:
        print(output.status_code)
        print(output.json())

Below is the Reference screenshot of Python ABX action.

Once we have created the Python Action , Last step is create the subscription.

We are using Deployment completed event here and Here is the screenshot.

All configuration is sorted , Now Once you submit the build via CI/CD or self Service , It will add the user in project with specified permission and change the deployment owner.