Introduction:
I’ve been experimenting with NSX-T deployment automation, working on a method to quickly deploy typical network topologies for repro and testing.
A typical lab topology consists of Tier-0 and Tier-1 gateways and segments, where one or more object IDs uniquely identify each construct.
NSX-T Universally Unique IDentifiers (UUID)
NSX-T identifies objects using Universally Unique IDentifiers (UUID), 128 bits in length, represented as 32 hexadecimal characters separated by four hyphens. Here is an example of an NSX-T UUID from my lab, the edge cluster UUID: ae01ac0a-57de-4c25-978a-643472c81efb.
The parameters required in creating new objects include references to existing UUIDs. Using automation, we need a reliable method to collect specific UUIDs from the NSX-T environment. For example, to create an external segment, the VXLAN Overlay UUID is required. To instantiate a Tier-0 gateway on an Edge Cluster, the Edge Cluster UUID is required.
Using cURL to interact with the NSX-T API
cURL is a command-line tool for transferring data specified with URL syntax. Sample cURL expressions for NSX-T can be found here: https://spillthensxt.com/nsx-t-disable-dfw/
cURL is a logical way to interact with the NSX-T API for scripting purposes. Here is an example of a curl request to get edge cluster details, run from a Photon OS Guest VM:
root@photon-machine [ ~ ]# curl --silent -k -u admin:VMware1\!VMware1\! -X GET "https://nsxtmgr.core.hypervizor.com/api/v1/edge-clusters" { "results" : [ { "deployment_type" : "VIRTUAL_MACHINE", "members" : [ { "member_index" : 0, "transport_node_id" : "d1e99a0e-23af-11ea-9efe-005056960985" <--- Edge1 UUID }, { "member_index" : 1, "transport_node_id" : "8dba7128-23af-11ea-a05e-00505696ef14" <--- Edge2 UUID } ], "cluster_profile_bindings" : [ { "resource_type" : "EdgeHighAvailabilityProfile", "profile_id" : "91bcaa06-47a1-11e4-8316-17ffc770799b" } ], "member_node_type" : "EDGE_NODE", "allocation_rules" : [ ], "resource_type" : "EdgeCluster", "id" : "ae01ac0a-57de-4c25-978a-643472c81efb", <--- edge cluster UUID "display_name" : "EdgeCluster", "description" : "Edge Cluster for Cairo Site", "_create_user" : "admin", "_create_time" : 1576927246237, "_last_modified_user" : "admin", "_last_modified_time" : 1576927246237, "_system_owned" : false, "_protection" : "NOT_PROTECTED", "_revision" : 0 } ], "result_count" : 1 }
JQ is a lightweight and flexible command-line JSON processor
As part of NSX-T deployment automation, the goal is to collect the edge cluster UUID, in this case, ae01ac0a-57de-4c25-978a-643472c81efb. JQ is a lightweight and flexible command-line JSON processor. JQ can extract a UUID from JavaScript Object Notation (JSON) encoded cURL results. A JQ tutorial can be found here: https://stedolan.github.io/jq/tutorial/.
jq is like sed for JSON data – you can use it to slice and filter and map and transform structured data with the same ease that sed , awk , grep and friends let you play with text. jq is written in portable C, and it has zero runtime dependencies.Since jq by default pretty-prints all output, it can be a useful way of formatting JSON output from cURL.
Installing JQ on Photon OS
Since JQ is a Photon OS package, installing it is straight forward.
root@photon-machine [ ~ ]# cat /etc/os-release NAME="VMware Photon OS" VERSION="3.0" ID=photon VERSION_ID=3.0 PRETTY_NAME="VMware Photon OS/Linux" ANSI_COLOR="1;34" HOME_URL="https://vmware.github.io/photon/" BUG_REPORT_URL="https://github.com/vmware/photon/issues" root@photon-machine [ ~ ]# tdnf install jq Installing: jq x86_64 1.5-4.ph3 photon 338.37k 346489 Total installed size: 338.37k 346489 Is this ok [y/N]:y Downloading: jq 168790 100% Testing transaction Running transaction Installing/Updating: jq-1.5-4.ph3.x86_64 Complete! root@photon-machine [ ~ ]# jq --version jq-1.5
The simplest JQ filter
Here is the edge cluster cURL result for:
curl –silent -k -u admin:VMware1\!VMware1\! -X GET “https://nsxtmgr.core.hypervizor.com/api/v1/edge-clusters”
The simplest JQ program is the expression ‘.’ which takes the input and produces it unchanged as output. Here is the same edge cluster cURL result piped to JQ. Notice that JQ interprets and color formats the command line output:
curl –silent -k -u admin:VMware1!VMware1! -X GET “https://nsxtmgr.core.hypervizor.com/api/v1/edge-clusters” | jq “.”
Other JQ filters
Other examples of JQ filters are shown with the edge cluster cURL result:
root@photon-machine [ ~ ]# curl --silent -k -u admin:VMware1\!VMware1\! -X GET "https://nsxtmgr.core.hypervizor.com/api/v1/edge-clusters" { <- | jq '.' "results" : [ { <- | jq '.results[]' "deployment_type" : "VIRTUAL_MACHINE", <- | jq '.results[].deployment_type' "members" : [ { <- | jq '.results[].members' "member_index" : 0, "transport_node_id" : "d1e99a0e-23af-11ea-9efe-005056960985" <- | jq '.results[].members[0].transport_node_id' }, { "member_index" : 1, "transport_node_id" : "8dba7128-23af-11ea-a05e-00505696ef14" <- | jq '.results[].members[1].transport_node_id' } ], "cluster_profile_bindings" : [ { <- | jq '.results[].cluster_profile_bindings' "resource_type" : "EdgeHighAvailabilityProfile", "profile_id" : "91bcaa06-47a1-11e4-8316-17ffc770799b" <- | jq '.results[].cluster_profile_bindings[].profile_id' } ], "member_node_type" : "EDGE_NODE", "allocation_rules" : [ ], "resource_type" : "EdgeCluster", "id" : "ae01ac0a-57de-4c25-978a-643472c81efb", <- | jq '.results[].id' (this is the one we need) "display_name" : "EdgeCluster", "description" : "Edge Cluster for Cairo Site", "_create_user" : "admin", "_create_time" : 1576927246237, "_last_modified_user" : "admin", "_last_modified_time" : 1576927246237, "_system_owned" : false, "_protection" : "NOT_PROTECTED", "_revision" : 0 } ], "result_count" : 1 } To clarify, here are the results for some of these filters: root@photon-machine [ ~ ]# curl --silent -k -u admin:VMware1!VMware1! -X GET "https://nsxtmgr.core.hypervizor.com/api/v1/edge-clusters" | jq '.results[].deployment_type' "VIRTUAL_MACHINE" root@photon-machine [ ~ ]# curl --silent -k -u admin:VMware1!VMware1! -X GET "https://nsxtmgr.core.hypervizor.com/api/v1/edge-clusters" | jq '.results[].members' [ { "member_index": 0, "transport_node_id": "d1e99a0e-23af-11ea-9efe-005056960985" }, { "member_index": 1, "transport_node_id": "8dba7128-23af-11ea-a05e-00505696ef14" } root@photon-machine [ ~ ]# curl --silent -k -u admin:VMware1!VMware1! -X GET "https://nsxtmgr.core.hypervizor.com/api/v1/edge-clusters" | jq '.results[].members[0].transport_node_id' "d1e99a0e-23af-11ea-9efe-005056960985" root@photon-machine [ ~ ]# curl --silent -k -u admin:VMware1!VMware1! -X GET "https://nsxtmgr.core.hypervizor.com/api/v1/edge-clusters" | jq '.results[].members[1].transport_node_id' "8dba7128-23af-11ea-a05e-00505696ef14" root@photon-machine [ ~ ]# curl --silent -k -u admin:VMware1!VMware1! -X GET "https://nsxtmgr.core.hypervizor.com/api/v1/edge-clusters" | jq '.results[].cluster_profile_bindings' [ { "resource_type": "EdgeHighAvailabilityProfile", "profile_id": "91bcaa06-47a1-11e4-8316-17ffc770799b" } ] root@photon-machine [ ~ ]# curl --silent -k -u admin:VMware1!VMware1! -X GET "https://nsxtmgr.core.hypervizor.com/api/v1/edge-clusters" | jq '.results[].cluster_profile_bindings[].profile_id' "91bcaa06-47a1-11e4-8316-17ffc770799b"
Collecting the edge cluster UUID:
We have it, for NSX-T Deployment Automation the ability to collect the edge cluster UUID, ae01ac0a-57de-4c25-978a-643472c81efb, with the following cURL command and JQ filter:
root@photon-machine [ ~ ]# curl --silent -k -u admin:VMware1!VMware1! -X GET "https://nsxtmgr.core.hypervizor.com/api/v1/edge-clusters" | jq '.results[].id' "ae01ac0a-57de-4c25-978a-643472c81efb"
Storing the UUID
To instantiate a Tier-0 gateway on an Edge Cluster, the Edge Cluster UUID is required. In automating the NSX-T lab deployment, edge cluster UUID needs to be stored for the Tier-0 gateway configuration.
nsxtpasswd='VMware1!VMware1!' nsxtvip="nsxtmgr.core.hypervizor.com" edge_cluster_id=$(curl --silent -k -u admin:$nsxtpasswd -X GET "https://$nsxtvip/api/v1/edge-clusters" | jq -r '.results[].id') echo "Edge Cluster ID: $edge_cluster_id"
Keep in mind that a more logical method of collecting the Edge Cluster UUID is during edge cluster creation.
Create a Tier-0 Gateway, using the Edge Cluster UUID
Create a Tier-0 Gateway:
curl --silent -k -u admin:$nsxtpasswd -H "Content-Type: application/json" -d '{"transit_subnets": ["100.64.0.0/16"],"internal_transit_subnets": ["169.254.0.0/24"]}' -X PATCH "https://$nsxtvip/policy/api/v1/infra/tier-0s/lab-tier-0"
Instantiate the Tier-0 Gateway on the Edge Cluster, and configure route redistribution:
curl --silent -k -u admin:$nsxtpasswd -H "Content-Type: application/json" -d '{"route_redistribution_types": [ "TIER1_CONNECTED", "TIER0_CONNECTED" ],"edge_cluster_path": "/infra/sites/default/enforcement-points/default/edge-clusters/'"$edge_cluster_id"'"}' -X PATCH "https://$nsxtvip/policy/api/v1/infra/tier-0s/lab-tier-0/locale-services/default"
Upcoming in NSX-T Deployment Automation – Part 2
This completes Part 1 of NSX-T Deployment Automation, using cURL and JQ to collect NSX-T UUIDs and deploy a new Tier-0 gateway.
In Part 2, we will look a the steps required to implement a fully functional lab configuration consisting of Tier-0, Tier-1, Segments, DNS, and BGP.