Using Node.js in Aria Automation Orchestrator 8.10

Reading time: 9 minutes

Aria Automation Orchestrator + Node.js

Introduction

With the release of VMware vRealize Orchestrator 8.1 in April 2020, VMware added the ability to utilize new languages within your workflows and actions. These new languages included PowerShell, Node.js, and Python. Since then, I have seen very few documents detailing the use of this capability.

Recently though, while attempting to migrate some legacy scripts from a vRealize Orchestrator 7.6 deployment to vRealize Orchestrator 8.8, I found a need to implement DNS lookup capabilities within a workflow that previously utilized nslookup commands within the Orchestrator appliance. Due to the containerized nature of vRealize Orchestrator 8.8, the nslookup command no longer functioned. After digging within the Node.js documentation for a possible solution, I ran across the Node.js DNS library. This library allows for several types of DNS queries, including utilizing operating system methods or specifying specific DNS servers.

In this post, I provide a walkthrough of what I learned during my journey to utilize Node.js and examples of how to implement DNS querying functionality using Node.js within Aria Orchestrator 8.10.

Why Not Use the Built-in Orchestrator System.resolveHostName () Function

While Aria Automation Orchestrator does include a function to resolve DNS queries utilizing the Orchestrator server’s built-in DNS, this method did not provide me with the ability to specify specific DNS resolvers. In my particular use case, I needed the ability to set a specific DNS resolver not utilized by the Orchestrator appliance.

Why Node.js Over Python or PowerShell?

I don’t have a concrete reason for this outside of the following:

  • I’m more familiar with JavaScript than I am with Python
  • When I tested the workflow in my home lab on Aria Automation Orchestrator 8.10, the Node.js DNS library worked out-of-the-box without importing the library (not the case in my 8.8 environments).
  • The PowerShell DnsClient module didn’t appear to be included in Aria Automation Orchestrator

Based on these reasons, the best path forward would be to explore implementing the solution using Node.js. My next task was to determine how exactly I’d do that.

Adding Node.js to an Aria Automation Orchestrator Workflow

The first step to learning and testing Node.js in Aria Automation Orchestrator is creating a new workflow containing a single Scriptable task object. To do this, we create a new workflow with no inputs or outputs and add the Scriptable task object. Next, under the Scripting tab for the Scriptable task, the default Runtime Environment will be listed as “JavaScript”. We change this to “Node.js 14”. After making this change, notice that content has been added to the scripting object’s script block.

VMware Aria Automation Orchestrator Workflow with new Scriptable Task block Set to Node.js Runtime Environment

The newly added text is an example script that includes the minimum required content to utilize Node.js in Aria Automation Orchestrator. The script provided is as follows:

exports.handler = (context, inputs, callback) => {
    console.log('Inputs were ' + JSON.stringify(inputs));
    callback(undefined, {status: "done"});
}

If you are unfamiliar with JavaScript, I will explain the above code. The first line of the code defines a new function called handler. This function is passed three inputs contained within the parentheses that Aria Automation Orchestrator provides:

  • context (required) – contains the Aria Automation Orchestrator workflow execution context object
  • inputs (required) – contains the inputs provided into the Scriptable task object
  • callback (optional) – a reference to a function utilized to indicate completion of asynchronous work, which includes a result and any return data

Finally, the contents of the handler function are indicated by the “=>” and are contained within the curly brackets. The second line of the code logs to the console the string “Inputs were ” and concatenates the inputs object that has been converted to a string. The third line calls the callback function that was passed into our function with a return object that contains a variable called status with a value of “done”.

If we save the workflow as is and execute it, we see that the workflow log will show the string “Inputs were {}” which matches our Node.js function’s intention.

VMware Aria Automation Orchestrator Workflow execution showing the output logged from the Node.js function

Adding Inputs and Outputs to our Node.js Scriptable Task

Now that we have the basics let’s define the workflow input values that our scriptable task will use to complete a DNS lookup of a hostname using one or more defined DNS servers. To do this, we define a hostname input of type string, a dnsServers input array of type string, and a results output array of type string. Again, we save the workflow and execute it. This time we are prompted to provide values for our new inputs. In this case, we set the hostname value to “google.com” and then add a value to the dnsServers input of “8.8.8.8”. We haven’t yet added any code to complete a DNS lookup, but the workflow log will now show our input values in the log as a set of name/value pairs in JSON.

VMware Aria Automation Orchestrator Workflow execution showing our input values in the output logged from the Node.js function

Making Use of Our Input Values

Now that we have verified that our Node.js scriptable task inputs are available to use in our script, let’s add our DNS lookup logic into the script and output our results to the console. The new code is the following:

exports.handler = (context, inputs, callback) => {
    const { Resolver } = require('dns');
    const resolver = new Resolver();
    console.log('Querying DNS results for: %j', inputs.hostname);
    resolver.setServers(inputs.dnsServers);
    resolver.resolve(inputs.hostname, (err, addresses) => {
        console.log('Results: %j', addresses);
        callback(undefined, {status: "done", results: addresses});
    });
}

There’s a lot more happening in our script, so I will explain. We already discussed the first line of the script, so we’ll move on.

The second line of the script is importing the Node.js module called dns. This module contains the functions necessary to complete our DNS lookups.

The third line defines a new constant variable containing an instance of the Node.js dns resolver class.

The fourth line logs our first input, which is the hostname input. Notice that this value is referenced utilizing the inputs variable in the format of inputs.{input name}.

The fifth line relates to the Node.js dns module, and it assigns our list of DNS servers as the servers that should be used by the resolver object when looking up our hostname. The setServers function takes an array of type string as its only parameter.

The sixth line calls the resolve function of the resolver. This function takes our hostname as the first parameter and defines a new callback function with two parameters that will be executed when the result is obtained from the network. The first parameter err contains error information if the function execution encounters an error. The second parameter addresses will contain the IP addresses resolved for the hostname. This new callback function contains two lines of code. The first logs the results obtained to the console, while the second calls our scriptable task’s callback function with no error state and two outputs. The outputs are status with a value of “done” and addresses that contain the array results of our DNS lookup. Let’s execute this workflow again using the same inputs of “google.com” and “8.8.8.8” to see our results. Notice that our workflow log now displays two log entries showing the hostname we are looking up and an array of IP addresses resolved for the hostname.

VMware Aria Automation Orchestrator Workflow execution showing the output logged from the Node.js DNS lookup function

Additionally, if we review our workflow variables, we see that the results variable has been assigned an array of outputs that contains the IP addresses returned by our Node.js script.

VMware Aria Automation Orchestrator Workflow execution showing the output from the Node.js DNS lookup function assigned to our output variable

What are These Callback Functions You Keep Mentioning?

One thing to understand when working for Node.js/JavaScript is the concept around asynchronous execution. In the case of our DNS query, the results take time to come back. Instead, the resolver is provided a set of code (a function) to execute on the results once they are received back from the network. This allows us to control what happens with the results and controls the execution flow of the function. In the case of our Node.js scriptable task, we are passed a callback function from Aria Automation Orchestrator that we call from our code to indicate that we are done executing our code and providing the results.

Moving our Node.js Script to a Reusable Aria Automation Orchestrator Action

Our DNS code works great in our workflow, but the capability provided is something we would like to use repeatedly in several workflows. This makes it a great use case for defining an Aria Automation Orchestrator action. Moving our code over to a new action would look like the following:

VMware Aria Automation Orchestrator action definition using our Node.js lookup code

Notice that we have a couple of fields labeled Memory limit and Timeout. While these values can be left as is in most cases, there may be times when you import multiple dependency modules where 64 MB of memory may not be enough. In those situations, defining your code in an action will allow you to fine-tune these values to enable the successful execution of your code.

Now that we have defined our action let’s go back to our workflow and swap out our scriptable task with our new action. We assign the same inputs and outputs to the action and test executing our workflow. Whoops! It seems that things are now broken! If you look through the workflow log, you will see that our output is assigned a value of null, which is not an array of type string.

VMware Aria Automation Orchestrator Workflow execution showing an error generated by our Node.js DNS lookup action

Why would this be happening? If you think about it, an Aria Automation Orchestrator action does not allow the return of multiple values as an object. Aria Automation Orchestrator actions only allow for a single returned value. In our code, we are attempting to return a string and an array. Let’s revisit our action and change it to only return our addresses array. Our action’s code is now defined as the following:

exports.handler = (context, inputs, callback) => {
    const { Resolver } = require('dns');
    const resolver = new Resolver();
    console.log('Querying DNS results for: %j', inputs.hostname);
    resolver.setServers(inputs.dnsServers);
    resolver.resolve(inputs.hostname, (err, addresses) => {
    console.log('Results: %j', addresses);
    callback(undefined, addresses);   
    });     
}

Now, when our workflow executes, we receive our DNS lookup results, which are assigned to our results output variable.

VMware Aria Automation Orchestrator Workflow execution showing the output from the Node.js DNS lookup action assigned to our output variable

Conclusion

While not as straightforward as working with JavaScript code native to Aria Automation Orchestrator, utilizing Node.js scripts within our workflows and actions isn’t too difficult. The main difference is the additional supporting code encapsulating our functions and handling input/output variables.

See Also


Search

Get Notified of Future Posts

Follow Me

LinkedIn Icon
Twitter/X Icon
Threads Icon
RSS Icon

Recent Posts