VMware Cloud Community
StefanSchnell
Enthusiast
Enthusiast

Tip: How to get Detailed Information About all Actions

In this post I describe a way how to get detailed information about all actions in vRealize Automation. For this I also use an action that collects all the desired information and saves it in XML format. First we take a look at what information are provided and where it can be found in the UI of the vRA. 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.

actionsGeneral.jpg

Script Tab

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

actionsScript.jpg

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.

 

/* Begin----------------------------------------------------------------
 *
 * 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.2.0
 *
 **/

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;");
    }
  },

  // Main---------------------------------------------------------------
  Main : function() {

    var fileName = "/var/run/vco/actions.xml";

    try {

      var file = new File(fileName);
      if (file.exists) {
        file.deleteFile();
      }

      var fileWriter = new FileWriter(fileName);
      fileWriter.open();

      fileWriter.writeLine("<?xml version=\"1.0\"?>");
      fileWriter.writeLine("<actions>");

      var actions = System.getModule("com.vmware.library.action").getAllActions();

      // 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) {

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

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

        // Script > Properties > Return type----------------------------
        fileWriter.writeLine("    <returnType>" + action.returnType +
          "</returnType>");

        // Script > Code------------------------------------------------
        fileWriter.writeLine("    <script>");
        if (action.script) {
          fileWriter.writeLine(_getActionsNS.escapeXML(action.script));
        }
        fileWriter.writeLine("    </script>");

        fileWriter.writeLine("  </action>");

      });

      fileWriter.writeLine("</actions>");

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

  }

}

// Main-----------------------------------------------------------------
_getActionsNS.Main();

// End------------------------------------------------------------------

 

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, by module or script names, are made over the inputs. 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. However, also the fact that with many code changes a new XML file must be created again and again.


More interesting information at blog.stschnell.de

0 Kudos
0 Replies