Blog Feed

NSX-T Rest PowerShell Module

I needed to develop a solution to work with NSX-T that didn’t make use of the Binary Files included with the default NSX-T Power Shell Modules.

PowerShell is a fairly effective way to deal with Rest API’s, but can use some around the construction of the Header and Authentication Details.

To get myself started I put together a short Powershell module that contained

  • Connect-NsxtRestServer
  • Disconnect-NsxtRestServer
  • Invoke-NsxtRestMethod

https://github.com/greenscript-net/NsxtRest

And can be downloaded from the PowerShell Gallery

Depending on tasks I have on the ground, I will likely add functions in time to simplify working with NSX-T

Advertisements

VRSLCM Multi Deploy

Multi Deploy is now available in LCM & usually pretty reliable… but it isn’t immediately obvious how to start it.

By default when you select 2 or more items from the content page, the deploy button is greyed out.

You need to make use of the filters to do a multi select, then be able to do a multi deploy.

VRO Literal Map Viewer

The following snippet of code – I did not write, This will not become a theme… But it has become so useful to me, I wanted to have my own beautified jsdoc reference to it.

https://communities.vmware.com/thread/609702

thanks qc4vmware

/**
* converts literal map to a JSON string
* @param {string} literalMap - literal map in text
* @id 6ecaebc1-c70b-46b2-a2e1-2ce57ef03802
* @version 0.0.1
* @allowedoperations 
* @return {string}
*/
function literalMapViewer(literalMap) {
	var literalMap = extensionData;
	var jsonObj = convertLiteralMapToJson(literalMap);
	var json = JSON.stringify(jsonObj);
	System.debug(json);
	
	return json
	
	function convertLiteralMapToJson(literalMap) {
	    var mapObj = {};
	    for each(var key in literalMap.keySet()) {
	        var obj = literalMap.get(key);
	        var className = System.getObjectClassName(obj);
	
	        if (className == "vCACCAFEStringLiteral" || "vCACCAFEDateTimeLiteral" || "vCACCAFEIntegerLiteral" ||
	            "vCACCAFEBooleanLiteral" || "vCACCAFEDecimalLiteral" || "vCACCAFESecureStringLiteral") mapObj[key] = obj.getValue();
	
	        if (className == "vCACCAFEComplexLiteral") mapObj[key] = convertComplexLiteralToJson(obj);
	
	        if (className == "vCACCAFEMultipleLiteral") {
	            multClassName = System.getObjectClassName(obj.getValue());
	            mapObj[key] = [];
	            for each(var item in obj.getValue()) {
	                var itemClassName = System.getObjectClassName(item);
	                if (itemClassName == "vCACCAFEComplexLiteral") {y
	                    mapObj[key].push(convertComplexLiteralToJson(item));
	                }
	                else {
	                    System.debug("unhandled itemClassName::" + itemClassName);
	                }
	            }
	        }
	
	        if (className == "vCACCAFEEntityReference") {
	            mapObj[key] = {};
	            mapObj[key].referenceType = "vCACCAFEEntityReference";
	            mapObj[key].classId = obj.getClassId();
	            mapObj[key].componentId = obj.getComponentId();
	            mapObj[key].id = obj.getId();
	            mapObj[key].label = obj.getLabel();
	            mapObj[key].typeId = obj.getTypeId();
	            mapObj[key].label = obj.getLabel();
	        }
	
	        if (mapObj[key] == undefined) {
	            System.log(key + " unhandled className::" + className);
	            mapObj[key] = "QCconvertLiteralMapToJson: This mapping has an unhandled class for key:" + key + ", class: " + classname;
	        }
	    };
	    return mapObj;
	};
	
	function convertComplexLiteralToJson(complexLiteral) {
	    var complexClass = System.getObjectClassName(complexLiteral.getValue());
	    if (complexClass == "vCACCAFELiteralMap") {
	        return convertLiteralMapToJson(complexLiteral.getValue());
	    }
	    else {
	        System.log("not sure what to do with complexClass::" + complexClass);
	        return "QCconvertComplexLiteralToJson: This complex literal has an unhandled class:" + complexClass;
	    }
	}
};

NSX-T with Postman

After following the fantastic blog entry

To try and get the NSX-T postman collection running in my Postman…

I hit the Postman Import failure that seems to occur post version 7.2.0

Mine was at 7.3.6 but the issue was still in place

from the following blog

https://community.getpostman.com/t/cannot-import-swagger-2-0-file-anymore-it-was-working-before-updating-to-7-2-2/6545

I was able to follow the steps to

  • Downgrade my Postman
  • Import the Collection
  • Export the Collection
  • Upgrade my Postman
  • Import the Collection
  • Happy Days!

Temporary Lower Certificate security to connect VRA VRO

PowerVRA and PowerVRO do a fantastic job at assisting with connecting to VRO and VRA. When working with Self Signed certificates, using the switch “–IgnoreCertRequirements” will usually allow connection to proceed. Occasionally a more drastic approach is required. 

I often use the following bit of code to enable the connection. I do apologise for not being state the source of this, I have had it save in my library for quite a while and usually use it as is.

if (-not ([System.Management.Automation.PSTypeName]'ServerCertificateValidationCallback').Type)
{
$certCallback = @"
    using System;
    using System.Net;
    using System.Net.Security;
    using System.Security.Cryptography.X509Certificates;
    public class ServerCertificateValidationCallback
    {
        public static void Ignore()
        {
            if(ServicePointManager.ServerCertificateValidationCallback ==null)
            {
                ServicePointManager.ServerCertificateValidationCallback += 
                    delegate
                    (
                        Object obj, 
                        X509Certificate certificate, 
                        X509Chain chain, 
                        SslPolicyErrors errors
                    )
                    {
                        return true;
                    };
            }
        }
    }
"@
    Add-Type $certCallback
 }
[ServerCertificateValidationCallback]::Ignore()

$SecurityProtocols = @(
        [System.Net.SecurityProtocolType]::Ssl3,
        [System.Net.SecurityProtocolType]::Tls,
        [System.Net.SecurityProtocolType]::Tls12
    )
    [System.Net.ServicePointManager]::SecurityProtocol = $SecurityProtocols -join ","


API Creation of VRA Network profiles with Infoblox Endpoint

PowerVRA cmdlets for creating external network profiles don’t directly allow for creation of Infoblox connected network profiles. You can still make use of the Invoke-VraRestMethod, but you will need to source some of the required information yourself.

Firstly you will need to get the provider ID for the IPAM endpoint. An easy way to do this is to look at an example network profile that has been connected to the target Infoblox.

$sampleNetworkName = "testnetwork"
$EndpointId = (Get-vRAExternalNetworkProfile -Name $sampleNetworkName).IPAMEndpointId

Now you need to draw back a list of all the Possible ranges from Infoblox

$ranges = Invoke-vRARestMethod -Method GET -URI "/ipam-service/api/providers/$EndpointId/ip-ranges?limit=1000"
$ranges = $ranges.content | select-object name, description,externalId

Personally I then filter the list for only what is needed

You can obviously filter the list to whatever is required, but for this scenario, just going to create a new network profile for each range.

The entire code base together is as follow

$URI = "/iaas-proxy-provider/api/network/profiles"

$sampleNetworkName = "testnetwork"

$EndpointId = (Get-vRAExternalNetworkProfile -Name $sampleNetworkName).IPAMEndpointId

$ranges = Invoke-vRARestMethod -Method GET -URI "/ipam-service/api/providers/$EndpointId/ip-ranges?limit=1000"
$ranges = $ranges.content | select-object name, description,externalId


$Template = @"
    {
        "profileType" : "EXTERNAL",
        "id" : null,
        "@type" : "ExternalNetworkProfile",
        "name" : "External IPAM",
        "IPAMEndpointId" : "f55e372a-0b6e-46a7-9243-4fd8526e3566",
        "addressSpaceExternalId" : "",
        "description" : "my description",
        "definedRanges" : [{
			"externalId" : "network-1",
			"name" : "192.168.1.0/24",
			"description" : "Created by vRO package stub workflow",
			"state" : "UNALLOCATED",
			"beginIPv4Address" : null,
			"endIPv4Address" : null
		}
	]
    }
"@

$Template = $Template | ConvertFrom-Json

$Template.IPAMEndpointId = $EndpointId

foreach ($range in $ranges){
    $Template.name = $range.name
    $Template.description = $range.description
    $Template.definedRanges[0].externalId = $range.externalId
    $Template.definedRanges[0].name = $range.name
    $Template.definedRanges[0].description = $range.description
    
    Invoke-vRARestMethod -Method POST -URI $URI -Body ($Template | ConvertTo-Json)
}

This creates a network profile for every available range in Infoblox