VCF Automation Blog

from Stefan Schnell

Actions are standard or individual functions which can be used in workflows. VCF Automation provides libraries of predefined actions. Actions are important elements for structuring and reusing code. That is why their use is very important, also in other runtime environments e.g. like Python. This post presents a class that simplifies the calling of actions in Python.

Action Class for Python Runtime Environment

This class contains two external methods, getActionId and invoke. The invoke method executes an action, by specifying the module of the action, its name and parameters, as well as the orchestrator URL and token.

"""
@author Stefan Schnell <mail@stefan-schnell.de>
@license MIT
@version 1.0
"""

import json
import time

from util.http import Http

class Action:
    """ Handles VCF Automation actions
    """

    def __init__(self):
        self.__http = Http()

    def getActionId(
        self,
        vcoUrl: str,
        bearerToken: str,
        actionModule: str,
        actionName: str
    ) -> str:
        """ Gets the ID of an action.

        @param {string} vcoUrl - URL of Aria orchestrator
        @param {string} bearerToken
        @param {string} actionModule - Module of the action
        @param {string} actionName - Name of the action
        @returns {string}
        """

        returnValue: str = ""

        try:

            actions = self.__http.request(
                url = vcoUrl + "/api/actions",
                bearerToken = bearerToken
            )

            found: bool = False
            for action in actions["link"]:
                for attribute in action["attributes"]:
                    if attribute["name"] == "fqn" and \
                    attribute["value"] == actionModule + "/" + actionName:
                        for attribute in action["attributes"]:
                            if attribute["name"] == "id":
                                returnValue = attribute["value"]
                                found = True
                if found:
                    break

        except Exception as err:
            raise ValueError(
                f"An error occurred at get Action ID - {err}"
            ) from err

        return returnValue

    def __executeAction(
        self,
        vcoUrl: str,
        bearerToken: str,
        actionId: str,
        parameters: dict = {}
    ) -> dict:
        """ Executes an action.

        @param {string} vcoUrl - URL of Aria orchestrator
        @param {string} bearerToken
        @param {string} actionId - ID of the action
        @param {dictionary} parameters - Parameters of the action
        @returns {dictionary}
        """

        returnValue: dict = {}

        try:

            returnValue = self.__http.request(
                url = vcoUrl + "/api/actions/" + actionId + "/executions",
                bearerToken = bearerToken,
                method = "POST",
                body = parameters
            )

        except Exception as err:
            raise ValueError(
                f"An error occurred at action executing - {err}"
            ) from err

        return returnValue

    def __getActionLog(
        self,
        vcoUrl: str,
        bearerToken: str,
        executionId: str
    ) -> dict:
        """ Delivers the action log.

        @param {string} vcoUrl - URL of Aria orchestrator
        @param {string} bearerToken
        @param {string} executionId - ID of the execution, from executeAction
        @returns {dictionary}
        """
        returnValue: dict = {}

        try:

            returnValue = self.__http.request(
                url = vcoUrl + "/api/actions/" + executionId + \
                "/logs?maxResult=2147483647",
                bearerToken = bearerToken
            )

        except Exception as err:
            raise ValueError(
                f"An error occurred at get action log - {err}"
            ) from err

        return returnValue

    def invoke(
        self,
        vcoUrl: str,
        bearerToken: str,
        actionModule: str,
        actionName: str,
        parameters: dict
    ) -> dict:
        """ Calls an action

        @param {string} vcoUrl - URL of Aria orchestrator
        @param {string} bearerToken
        @param {string} actionModule - Module of the action
        @param {string} actionName - Name of the action
        @param {dictionary} parameters - Parameters of the action
        @returns {dictionary}
        """

        returnValue: dict = {}

        try:

            actionID: str = self.getActionId(
                vcoUrl,
                bearerToken,
                actionModule,
                actionName
            )

            _parameters: dict = {
                "async-execution": False,
                "parameters": parameters
            }

            executionResult: dict = self.__executeAction(
                vcoUrl,
                bearerToken,
                actionID,
                _parameters
            )

            returnValue["executionResult"] = executionResult

            executionId: str = executionResult["execution-id"]

            time.sleep(2.5)

            actionLog: dict = self.__getActionLog(
                vcoUrl,
                bearerToken,
                executionId
            )

            returnValue["actionLog"] = actionLog

        except Exception as err:
            raise ValueError(
                f"An error occurred at call action - {err}"
            ) from err

        return returnValue

Conclusion

This Python class greatly simplifies the invoking of actions and it can be used as an integration basis in VCF Automation. It can also be used in other environments that support Python.

References