Month: August 2016

vRealize Orchestrator – Working with XML and the NSX API

I’ve found that it’s a must to know how to work with XML in vRealize Orchestrator, especially when using the NSX API, and the good news is that it is very simple, once you know a few key commands.

First off, the XML plugin is based on E4X, so searching for help on this XML library is a good start.

Take this XML structure for example, which is for NSX load balance configuration that shows the configuration for pool members:

<loadBalancer>
  <pool>
    <poolId>pool-1</poolId>
    <name>pool-one</name>
    <algorithm>round-robin</algorithm>
    <transparent>false</transparent>
    <member>
      <memberId>member-1</memberId>
      <ipAddress>192.168.0.1</ipAddress>
      <weight>1</weight>
      <monitorPort>80</monitorPort>
      <port>80</port>
      <maxConn>0</maxConn>
      <minConn>0</minConn>
      <condition>enabled</condition>
      <name>member-one</name>
    </member>
    <member>
      <memberId>member-2</memberId>
      <ipAddress>192.168.0.2</ipAddress>
      <weight>1</weight>
      <monitorPort>80</monitorPort>
      <port>80</port>
      <maxConn>0</maxConn>
      <minConn>0</minConn>
      <condition>enabled</condition>
      <name>member-two</name>
    </member>
  </pool>
</loadBalancer>

Notice there are multiple member XML nodes, one for each pool member. That makes sense as you would have mor ethan one pool member in a NSX load balancer.

You can delete nodes by converting the XML into an object and using the delete command in Javascript. So something like this:

var xmlObj = new XML(xml);
delete xmlObj.pool.member[0];

So this would delete the first member node and all the child nodes but what happens if you need to delete a specific node, say the 192.168.0.2 pool member, or any member for that matter.

In order to do this, you need to find the index. Note that E4X is zero based, so the first member node is index 0 , the second member node is at index 1 etc..

So you need to find the index number for 192.168.0.2. Here’s a script to do this.

// Convert the XML to a XML document object
var document = XMLManager.fromString(xml);

//Search for member element by tag name
var members = document.getElementsByTagName("member");

// Set a marker so we can break in the loop
var memberFound = false;
// Now iterate using i and starting from 0 (remember E4X is zero based.
for (i = 0; i < members.length; i++){

// Now get all the child nodes for the first member.
var childNodes = members.item(i).getChildNodes();

// Iterate through the child node.
for (j = 0; j < childNodes.length; j++){

// Search for your IP address.
if (childNodes.item(j).textContent == "192.168.0.2"){

// Now take the value of the iterator for the member iteration, not the member nodes.
// In this case, it is 1.

System.log(childNodes.item(j).textContent + " found at index " + i);

// Set you flag as you've found the IP and do not want to iterate further.
memberFound = true;
break;
}
}
if (memberFound) {break;}
}

Now you can delete the member using the iterator value. Note that E4X is zero based, so the member-one node is at index 0, member-two is at index 1 etc..

// Create the xmlObj, although we did set this up above.
var xmlObj = new XML(xml);

// note, you need to have the value for i, which is 1 in this case
delete xmlObj.pool.member[i];

But what happens if you what to append an element with child nodes? Say you want to add this XML to the main xmlObj.

var newMemberXml = "<member>
      <memberId>member-3</memberId>
      <ipAddress>192.168.0.3</ipAddress>
      <weight>1</weight>
      <monitorPort>80</monitorPort>
      <port>80</port>
      <maxConn>0</maxConn>
      <minConn>0</minConn>
      <condition>enabled</condition>
      <name>member-three</name>
    </member>"

We can use the new XMLList() object type. An XML List is a linear sequence of XML nodes.

var xmlNewObj = new XMLList(newMemberXml);

// Create the xmlObj, although we did set this up above.
var xmlObj = new XML(xml);

// create the new xml object you wish to append
var xmlNewObj = new XMLList(newMemberXml);

// Append the xmlNeObj to the xmlObj.pool node
System.log(xmlObj.pool.appendChild(xmlNewObj));

This will add the new member node and its child elements to the main xmlObj.
So using delete and childApend(obj) can get you a long way.

Tip:

I use resource elements to hold XML structure in vRealize Orchestrator. Most structures, say to configure a load balancer or to add a node, have static element nodes.

So in order to change the resource element, you can set placeholders in your XML resource element. For example:

<monitor>
   <monitorId>monitor-1</monitorId>
   <type>http</type>
   <interval>10</interval>
   <timeout>15</timeout>
   <maxRetries>3</maxRetries>
   <method>GET</method>
   <url>{monitor_url}</url>
   <expected>{monitor_expected}</expected>
   <name>http_service_monitor</name>
   <send>{monitor_send}</send>
   <receive>{monitor_receive}</receive>
</monitor>

You can then use the following code to replace the placeholders in the curly brackets with values from vRO attributes or input parameters (addHTTPMonitor is the resource element)

var content = addHTTPMonitor.getContentAsMimeAttachment().content;

var monitorContent = content.replace("{monitor_url}", monitorUrl)
	.replace("{monitor_expected}", monitorExpected)
	.replace("{monitor_send}", monitorSend)
	.replace("{monitor_receive}", monitorReceive)

So once you have your XML structure from the resource element, append this using the childApend(obj) method to add the XML element and node to the main XML structure.