Calling the NSX REST API with vRO and Navigating The XML Response

Share on:

While the NSX for vSphere plugin for vRealize Orchestrator is useful, occasionally there are limitations. For example when creating an NSX Edge Services Gateway we use this method.

NSXEdgeTrinityBasicController.createEdgeV4

That method returns void, so next you need to make a second method call using filter by name to get the object and obtain object ID which is typically the input to other methods.

NSXEdgeTrinityBasicController.getAllEdgeSummariesV4

When creating NSX Distributed Logical Router it is the same method to create. However the second method to get the object fails as it cannot handle the additional property LogicalRouterScope which DLRs have, so throws an error.

java.lang.NoSuchMethodException:com.vmware.vshield.edge.dto.trinity.LogicalRouterScope.<init>()

After trying various other NSX plugin methods all have same issue so I changed approach. NSX offers all its capabilities via REST API. vRealize Orchestrator comes with a HTTP-REST plugin, so in theory we can add NSX Managers as HTTP-REST endpoint and call everything direct.

If you have multiple REST HTTP hosts added you would want to bring back a list of these.

restHosts = RESTHostManager.getHosts();

This returns an array of UUIDs of each REST host, we can use these UUIDs to get the REST host objects. We could normally loop to find the specific RESThost object we are looking for, but for ease here we would use the first item from array.

host = RESTHostManager.getHost(restHosts[0]);

So we have the target RESThost object look at forming the request using the createRequest method.

request = host.createRequest('GET','/api/4.0/edges','');

Once we have our request formed we can look to make the call using the executeRequestWithCredentials method. Here I store username and password as Secure String variables.

responseStr = request.executeWithCredentials(username,password);

This returns a RESTResponse object, this has attribute contentAsString to navigate this XML we first convert this string to a XML DOM Document Object. vRealize Orchestrator comes with a XML plugin we can use the XMLManager.fromString method to perform this converstion.

responseXml = XMLManager.fromString(responseStr.contentAsString);

If we look inside of the XML which is returned from /api/4.0/edges we can see each the hierachy that each NSX Edge is a XML Node called edgeSummary and within that Node are child nodes for all of its attributes.

<pagedEdgeList>
    <edgePage>
        <edgeSummary>
            <objectId>
            <objectTypeName>
            <vsmUuid>
            <nodeId>
            <Revision>
            <type>
            <name>
            ...
        <edgeSummary>
            <objectId>
            <objectTypeName>
            <vsmUuid>
            <nodeId>
            <Revision>
            <type>
            <name>
            ...

So we need to bring back all the edgeSummary Nodes and create a XMLNodeList object containing all of out Edges.

edgeNodeList = responseXml.getElementsByTagName("edgeSummary");

Once we have this we can loop around the children of this and find the correct Edge entry and then get the objectId. We know the child order is always the same so we can choose data from positon in list and output the text content of Node.

for (var i = 0 ; i < edgeNodeList.length ; i++) {
    var node = edgeNodeList.item(i) ;
    edgeChildNodeList = node.getChildNodes();
    if (edgeChildNodeList.item(6).textContent == edgeName) {
        var objectId = edgeChildNodeList.item(0).textContent ;
        System.log("Edge named " + edgeName + " has objectId " + objectId) ;
    }
}

With this technique we should be able to get around any vRealize Orchestrator NSX Plugin limitation. This would also be useful for calling other RESTful APIs in absence of a specific vRealize Orchestrator plugin.