VRA Cloud -Python ABX action to send the VM provisioning status alerts to Slack & Microsoft teams

Recently I have written Blog for Automatic deletion and I have received multiple queries how can we notified before the deletion happens or what is the reason of failure. Previously i thought I will update failure reason in Python action.
Later I thought what if we get notification on common communicator like Slack, Teams, It would make job lot easier to keep track how many deployments were got failed or Success with Slack/Teams Notification, Also It would allow us to choose whether we want to send notification to Slack/ teams or not , If yes In which Channel we want to send the notification .


To get started we have some prerequisites ….

  1. VRA Cloud CSP token with all access to run the ABX action (How to generate CSP token)
  2. Slack Web-hook
  3. Teams Web-hook
  4. Channel name where we want to send notification (Slack allows single web-hook to multiple channels, Teams It is 1:1)
  5. VRA Cloud url (url)
  6. Yaml Inputs for Notification and Channel name



Once we have All these prerequisites completed , Jump to VRA Cloud => Cloud Assembly => Infrastructure => Secrets.

Here is the screenshot will look like.

Slack_webhook holds slack webhook information
Teams_Code_channel holds Teams webhook for channel name code
token holds information of CSP token
VmwareCode_Demo holds Teams webhook for channel name vmwarecode-demo
VRAURL— holds information related to Cloud api

It is not mandatory fo your to have 2 channels webhook for teams , Since i am allowing my user to choose channel i have created 2 webhook.
Once we have created the secrets , next part is adding the input value to any blueprint with below Yaml Code.

inputs:
  Notification:
    type: string
  NotificationChanel:
    type: string

Note: Do not change the name of the inputs variable as it is being used at Python ABX action and subscription.

Once prerequisites are done lets jump to Extensibility and create Python Actions., here is the code for Slack

import requests
import json


def handler(context, inputs):
    if inputs['eventType'] == 'CREATE_DEPLOYMENT' and inputs['requestInputs']['Notification'] == 'Slack':
        # Taking the value from secret into local Variable
        vraurl = context.getSecret(inputs['VRAURL'])
        token = context.getSecret(inputs['token'])
        slackwebhook = context.getSecret(inputs['slack_webhook'])
        deploymentid = inputs['deploymentId']
        eventType = inputs['eventType']
        channelname = inputs['requestInputs']['NotificationChanel']
        if inputs['status'] == 'FAILED':
            failuremessage = inputs['failureMessage']
        else:
            failuremessage = 'No Errors'
        # Taking the value from secret into local Variable

        # getting the latest version of API
        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)
        # getting the latest version of API

        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
                # Getting the deployment details.

                depurl = f'{vraurl}/deployment/api/deployments/{deploymentid}?apiVersion={apiversion}'
                headers = {
                    'accept': "application/json",
                    'content-type': "application/json",
                    'authorization': bearertoken
                }
                deployment_apioutput = requests.get(depurl, headers=headers, verify=False)
                if deployment_apioutput.status_code == 200:
                    jdata = deployment_apioutput.json()
                    deployment_name = jdata['name']
                    deployment_description = jdata['description']
                    deployment_id = jdata['id']
                    created_at = jdata['createdAt']
                    createdBy = jdata['createdBy']
                    ownedBy = jdata['ownedBy']
                    lastUpdatedAt = jdata['lastUpdatedAt']
                    lastUpdatedBy = jdata['lastUpdatedBy']
                    deployment_status = inputs['status']
                    projectname = inputs['projectName']

                    # Sending the data to notification to slack
                    payload = {
                        "username": "VMwareCodeBot",
                        "channel": f"#{channelname}",
                        "icon_emoji": ":ironman-7316:",
                        "color": "Blue",
                        "type": "home",
                        "blocks": [
                            {
                                "type": "header",
                                "text": {
                                    "type": "plain_text",
                                    "text": f"Triggered  {eventType.capitalize()} {deployment_name}  request is {deployment_status.capitalize()} :python3: :vrac: :vmware_logo:"
                                }
                            },
                            {
                                "type": "divider"
                            },
                            {
                                "type": "section",
                                "fields": [
                                    {
                                        "type": "mrkdwn",
                                        "text": f"*Deployment Name:*\n{deployment_name}"
                                    },
                                    {
                                        "type": "mrkdwn",
                                        "text": f"*Deployment Description:*\n{deployment_description}"
                                    }
                                ]
                            },
                            {
                                "type": "section",
                                "fields": [
                                    {
                                        "type": "mrkdwn",
                                        "text": f"*Creation Date: *\n{created_at}"
                                    },
                                    {
                                        "type": "mrkdwn",
                                        "text": f"*CreatedBy:*\n{createdBy}"
                                    }
                                ]
                            },
                            {
                                "type": "section",
                                "fields": [
                                    {
                                        "type": "mrkdwn",
                                        "text": f"*Deployment Owner:*\n{ownedBy}"
                                    },
                                    {
                                        "type": "mrkdwn",
                                        "text": f"*Deployment Status:*\n{deployment_status}"
                                    }
                                ]
                            },
                            {
                                "type": "section",
                                "fields": [
                                    {
                                        "type": "mrkdwn",
                                        "text": f"*Last Updated By :*\n{lastUpdatedBy}"
                                    },
                                    {
                                        "type": "mrkdwn",
                                        "text": f"*Last Updated At:*\n{lastUpdatedAt}"
                                    }
                                ]

                            },
                            {
                                "type": "section",
                                "fields": [
                                    {
                                        "type": "mrkdwn",
                                        "text": f"*Project Name :*\n{projectname}"
                                    },
                                    {
                                        "type": "mrkdwn",
                                        "text": f"*Deployment ID:*\n{deployment_id}"
                                    }
                                ]
                            },
                            {
                                "type": "section",
                                "text": {
                                    "type": "mrkdwn",
                                    "text": f"*Failure Message*\n{failuremessage}"
                                }
                            },
                            {
                                "type": "divider"
                            }
                        ]

                    }
                    slackheaders = {
                        'content-type': "application/json",
                        'accept': "application/json"
                    }

                    result = requests.post(url=slackwebhook, data=json.dumps(payload), headers=slackheaders)
                    if result.status_code == 200:
                        print('Please check the slack for notification')
                    else:
                        print(result.status_code)
                        print(result.json())



                else:
                    print(deployment_apioutput.status_code)



            else:
                print(iaasApiOutput)
        else:
            print(output.status_code)
            print(output.json())

    else:
        print(inputs['eventType'])

Here is the screenshot of my lab.

Here is the Python Code for Teams

import requests
import json


def handler(context, inputs):
    if inputs['eventType'] == 'CREATE_DEPLOYMENT' and inputs['requestInputs']['Notification'] == 'Teams':
        # Taking the value from secret into local Variable
        vraurl = context.getSecret(inputs['VRAURL'])
        token = context.getSecret(inputs['token'])
        Teams_Code_channel = context.getSecret(inputs['Teams_Code_channel'])
        VmwareCode_Demo = context.getSecret(inputs['VmwareCode-Demo'])
        deploymentid = inputs['deploymentId']
        eventType = inputs['eventType']
        channelname = inputs['requestInputs']['NotificationChanel']
        if inputs['status'] == 'FAILED':
            failuremessage = inputs['failureMessage']
        else:
            failuremessage = 'No Errors'
        # Taking the value from secret into local Variable

        # getting the latest version of API
        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)
        # getting the latest version of API

        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
                # Getting the deployment details.

                depurl = f'{vraurl}/deployment/api/deployments/{deploymentid}?apiVersion={apiversion}'
                headers = {
                    'accept': "application/json",
                    'content-type': "application/json",
                    'authorization': bearertoken
                }
                deployment_apioutput = requests.get(depurl, headers=headers, verify=False)
                if deployment_apioutput.status_code == 200:
                    jdata = deployment_apioutput.json()
                    deployment_name = jdata['name']
                    deployment_description = jdata['description']
                    deployment_id = jdata['id']
                    created_at = jdata['createdAt']
                    createdBy = jdata['createdBy']
                    ownedBy = jdata['ownedBy']
                    lastUpdatedAt = jdata['lastUpdatedAt']
                    lastUpdatedBy = jdata['lastUpdatedBy']
                    deployment_status = inputs['status']
                    projectname = inputs['projectName']

                    # Sending the data to notification to Teams
                    if channelname == 'code':
                        url = Teams_Code_channel
                    elif channelname == 'vmwarewcode-demo':
                        url = VmwareCode_Demo
                    headers = {
                        'content-type': "application/json",
                        'accept': "application/json"
                    }
                    payload = {
                        "@type": "MessageCard",
                        "themeColor": "0076D7",
                        "summary": "Create Deployments",
                        "sections": [{
                            "activityTitle": f"Task: {eventType} ",
                            "activitySubtitle": f"Project: {projectname}",
                            "facts": [{
                                "name": "Owner",
                                "value": f"{ownedBy}"
                            }, {
                                "name": "Deployment Name",
                                "value": f"{deployment_name}"
                            },
                                {
                                    "name": "Description",
                                    "value": f" {deployment_description}"
                                }, {
                                    "name": "Creation Date",
                                    "value": f"{created_at}"
                                }, {
                                    "name": "Last Updated at",
                                    "value": f"{lastUpdatedAt}"
                                }, {
                                    "name": "Last Updated By",
                                    "value": f"{lastUpdatedBy}"
                                }, {
                                    "name": "Created By",
                                    "value": f"{createdBy}"
                                }, {
                                    "name": "Deployment ID",
                                    "value": f"{deployment_id}"
                                },
                                {
                                    "name": "Status",
                                    "value": f"{deployment_status}"
                                }, {
                                    "name": "Failure Message",
                                    "value": f"{failuremessage}"
                                }],
                            "markdown": "true"
                        }]
                    }

                    teamsresult = requests.post(url=url, headers=headers, data=json.dumps(payload), verify=False)
                    if teamsresult.status_code == 200:
                        print('Notification has been sent to teams channel')
                    else:
                        teamsresult.status_code
                else:
                    print(deployment_apioutput.status_code)
            else:
                print(iaasApiOutput)
        else:
            print(output.status_code)
            print(output.json())
    else:
        print(inputs['eventType'])

Here is the screenshot will look like.

Once we have created the Python Actions , now last step is to configure the subscription . We are using Deployment Completed subscription with blocking.
Here are my Subscription look like

Here is the screenshots of subscription with all setting and Filter condition

event.data.eventType =='CREATE_DEPLOYMENT' && event.data.requestInputs.Notification=='Slack'

teams also look identical except the filter condition here is the filter for Teams.

event.data.eventType =='CREATE_DEPLOYMENT' && event.data.requestInputs.Notification=='Teams'


Job is Done ,whenever we trigger any deployment , we will get notification .
I have recorded Demo also , Here is the recorded demo , Note : All names are case sensitive like Notification Slack /Teams .

Here is the sample for notification for both Slack/ Teams.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s