VMware Aria Automation Blog

from Stefan Schnell

In this post is a way described how to get detailed information about all actions. For this an action is used that collects all the desired information and saves it in XML format.

Get Detailed Information about all Actions


First we take a look at what information are provided and where it can be found in the UI of Aria Automation. Here a look at the General and Script tab of an Action.

General Tab

In the General Tab we can find information about the module, name and the unique ID of the script. Also we have a description and a version here.

vmware aria orchestrator action general tab

Script Tab

In the Script tab we can find the script code, the return type of the script and the input parameters.

vmware aria orchestrator action script tab

XML Mapping

In XML format the same information can be mapped as follows. The chosen tag or attribute names correspond exactly to the descriptions in the UI, to avoid confusion.

<?xml version="1.0"?>
<actions>
  <action module="de.stschnell" name="testStefan">
    <id>aa347d8e-1a8d-4a9b-8737-cf5dbbba7b23</id>
    <description>This is a test</description>
    <version>0.1.0</version>
    <inputs>
      <input>
        <name>in_HelloWho</name>
        <type>string</type>
        <description>Say Hello</description>
      </input>
    </inputs>
    <returnType>string</returnType>
    <script>
System.log(&quot;Hello World from &quot; + in_HelloWho);
return &quot;Hello Stefan&quot;;
    </script>
  </action>
</actions>

Action

To get these information an action which detects all actions is used, then the detailed information are detected in a loop, with the help of the Action object and its methods. This information are stored in the XML structure presented above.

/**
 * This action creates an XML file with all details of all existing
 * actions and its script code.
 *
 * @name getActions
 * @param {string} in_moduleFilter - Search for substring in module, optional
 * @param {string} in_nameFilter - Search for substring in name, optional
 *
 * @author Stefan Schnell
 * @version 1.3.1
 *
 * Checked with release 8.12.0, 8.14.1 and 8.16.2
 */

var _getActionsNS = {

  /**
   * _escapeXML
   *
   * Escapes characters in a string, which could be misinterpreted as
   * markup in XML.
   *
   * @name escapeXML
   * @param {string} strXML - XML which characters to convert
   * @returns {string} Converted XML
   */
  _escapeXML : function(strXML) {
    if (strXML) {
      return strXML.replace(/&/g, "&amp;")
                   .replace(/</g, "&lt;")
                   .replace(/>/g, "&gt;")
                   .replace(/"/g, "&quot;")
                   .replace(/'/g, "&apos;");
/*
                   .replace(/\u00e4/g, "ae")
                   .replace(/\u00c4/g, "Ae")
                   .replace(/\u00f6/g, "oe")
                   .replace(/\u00d6/g, "Oe")
                   .replace(/\u00fc/g, "ue")
                   .replace(/\u00dc/g, "Ue")
                   .replace(/\u00df/g, "ss");
*/
    }
  },

  Main : function() {

    var output = "<?xml version=\"1.0\"?>";
    output += "<actions>";

    try {

      var actions =
        System.getModule("com.vmware.library.action").getAllActions();
      /* getAllActions
      var actions = new Array();
      var modules = System.getAllModules();
      for (i in modules) {
        var actionDescriptions = modules[i].actionDescriptions;
        for (j in actionDescriptions) {
          actions.push(actionDescriptions[j]);
        }
      }
      return actions;
      */

      // Search for substring in module
      if (in_moduleFilter) {
        // Reverse search in actions array to ...
        for (var i = actions.length - 1; i >= 0; i--) {
          if (actions[i].module.name.indexOf(in_moduleFilter) === -1) {
            // delete element if in_moduleFilter not found in module name
            actions.splice(i, 1);
          }
        }
      }

      // Search for substring in script name
      if (in_nameFilter) {
        // Reverse search in actions array to ...
        for (var i = actions.length - 1; i >= 0; i--) {
          if (actions[i].name.indexOf(in_nameFilter) === -1) {
            // delete element if in_nameFilter not found in script name
            actions.splice(i, 1);
          }
        }
      }

      actions.forEach( function(action) {

        output += "<action module=\"" + action.module.name +
          "\" name=\"" + _getActionsNS._escapeXML(action.name) + "\">";
        // General
        output += "<id>" + action.id + "</id>";
        if (action.description) {
          var actionDescription = action.description.replace(/[\r\n]/gm, '');
          output += "<description>" +
            _getActionsNS._escapeXML(actionDescription) + "</description>";
        } else {
          output += "<description/>";
        }
        output += "<version>" + action.version + "</version>";

        // Script > Properties > Inputs
        var parameters = action.parameters;
        output += "<inputs>";
        parameters.forEach( function(parameter) {
          output += "<input>";
          output += "<name>" +
            _getActionsNS._escapeXML(parameter.name) + "</name>";
          output += "<type>" + parameter.type + "</type>";
          if (parameter.description) {
            output += "<description>" +
              _getActionsNS._escapeXML(parameter.description) +
              "</description>";
          } else {
            output += "<description/>";
          }
          output += "</input>";
        });
        output += "</inputs>";

        // Script > Properties > Return type
        output += "<returnType>" + action.returnType +
          "</returnType>";

        // Script > Code
        output += "<script>";
        if (action.script) {
          output += _getActionsNS._escapeXML(action.script);
        }
        output += "</script>";

        output += "</action>";

      });

      output += "</actions>";

    } catch(e) {
      System.log(e);
      System.log(e.stack);
    } finally {
      System.log(output);
    }

  }

}

// Main
_getActionsNS.Main();

The code is really easy to understand. First a file is created in which the XML data is stored. Then all actions are detected and possible selections are made over the inputs, by module or script names. Now, action by action, the details are detected, with certain characters having to be converted to conform to XML conventions. If this action is now executed, we get an XML file with the desired information.

Conclusion

The generated XML information can be used for analysis purposes, e.g. via XPath. Here, for example, would be the finding of code duplicates or deviations from specifications. The advantage of fully local provision of these XML data brings independence and performance improvements.