New HomeLab!

I’ve been working on my homelab for the last few months and I finally have it at a point where I am content with how it’s behaving.

I opted to use the Intel NUC i7 model for several reasons, not the least is the high wife approval factor of low energy, low heat and quiet running. My old lab was a 2u Dell R710 that sounded like an airplane taking off, needless to say the wife did not approve.

I chose the NUC5i7RYH model and threw in a 250GB SSD along with 16GB of RAM and this SSHD

Now one major drawback of the NUC is of course the low amount of supported RAM which has recently been addressed with the new skylake chipsets from intel (now supports 32GB) but I can live with 16GB. I went ahead and purchase 3 of the nodes along with 3x 32GB low profile USB drives that I could install ESXi onto.

If you’re following closely you can see that I went ahead and decided to go with a vSAN setup for my shared storage which has worked out nicely for myself. In case you haven’t signed up yet, the VMUG advantage program is fantastic for the licenses you get so head on over and sign up asap.

I do not have a 10GB switch at home but I do have a dedicated 1GB switch I use on my lab and so far the performance has been just fine, I’m not building a production level lab so having resyncs and vMotions max out at 1GB is just fine for me.

I’ve installed vSphere6 and NSX within the environment. This has allowed me to dive into my nesting experience and setup multiple versions of vSphere all running on the host parent lab. Currently I am running vSphere5 and vSphere6 in a nested environment with 3 nested ESXi hypervisors and “shared” storage in each lab. I tend to keep the nested labs powered down unless they are in active use since memory is at a premium in my lab.

I’ll post more in following posts regarding powercli automation used to deploy, configure and manage these nested labs. In the meantime reach out if you have any questions.

New Beginnings

It’s been awhile since I updated the blog but things have been quite busy for myself. My family and I will be welcoming our third child in 2 months and I’ve left my previous job of over 9 years to join VMware. I’ll be taking on the role of NSX Technical Account Manager, something I am really looking forward to.

Now that things have somewhat calmed down I plan to get back to updating the blog on a semi-regular basis. Feel free to hit me up with any topics or ideas you’d like to see.

NSX DNS resolution lockdown

Been a bit since my last post but starting to catch up on things around here. Recently we got a notification from our security teams that one of our labs participated in a DNS DDOS attack on a third party. Upon investigation it appears that the Edge appliance that was being used for VPN access and DNS resolution was the source of the problem.

A bit baffled I checked into how this could be and discovered that the DNS resolvers of a standard edge are listening on ALL interfaces. Well considering that one of the interfaces has a public IP on that, that essentially means the Edge DNS server is resolving DNS requests to anyone on the internet.

If you pull up the config of an Edge using the API you get the following:

<dns>
<version>4</version>
<enabled>false</enabled>
<cacheSize>16</cacheSize>
<listeners>
<vnic>any</vnic>
</listeners>

Notice that the listeners are listening on ‘any’ interface, which leaves a lot to be desired. In order to fix this we need to specify what vmnic interfaces the DNS server will listen on. By editing the Rest API call and specifying the vmnic interfaces then we can limit what interfaces we’re listening on:

<dns>
<version>4</version>
<enabled>false</enabled>
<cacheSize>16</cacheSize>
<listeners>
<vnic>vnic0</vnic>
<vnic>vnic1</vnic>
</listeners>

Perform a put operation using the API at the https:///api/4.0/edges//dns/config location and you’ll reconfigure the DNS server.

Be warned however, that vCloud will not like this modification at all, doing this will in effect break your edge preventing you from making any further modifications.

NSX Undocumented Requirement…..Maybe???

Ran into an interesting issue in one of our labs today. While preparing a cluster to install the NSX vib one of our techs noticed the install kept failing. Logs indicated the problem was due to a callback to VMware Update Manager failing which seemed odd.

The NSX manager is what is actually pushing out the NSX vib so why is VUM involved? After checking the virtual center I noticed the tech had disabled the VUM plugin in the virtual center. After enabling it, the install process for NSX proceeded without issue.

To further test this I deployed another lab and 10 minutes later uninstalled VUM. Same result, NSX would not prepare a cluster of new hosts. Once I installed VUM I was once again able to prepare the cluster.

So moral of the story is, make sure your VUM instance is installed and functioning properly before trying to prepare a NSX cluster.

Create Random Password

Not taking credit for this function but it’s something I’ve used quite a bit lately. For the life of me I cannot track down who originally wrote it but it’s very handy to have. If someone knows the original author please let me know so I can properly credit them. Fairly simple code that will randomly generate a password of $length including Letters, numbers and Characters.

function random-password {
    $punc = 46..46
    $digits = 48..57
    $letters = 65..90 + 97..122
    $length = 15
    $password = get-random -count $length -input ($punc + $digits + $letters) | % -begin { $aa = $null } -process {$aa += [char]$_} -end {$aa}
    return $password
}

API Gotcha Deploying NSX Edge

Was beating my head against a wall over several days to track down why I could Inject a fully configured Edge into the NSX Manager but had no way to actually Deploy it via API. This was requiring me to log into the WebClient UI and right click the undeployed edge and click deploy, annoying to say the least.

After opening a support ticket with VMware and digging into the API a bit more we tracked down the mistake I was making. When injecting the Edge into the NSX manager you needed to specify the Edge to be deployed in 3 locations, not just the 2 I was thinking.

Initially I was specifying that each appliance was in a ‘Deployed’ state by setting the deployed variable to true. But it turns out theres another entry just below the Appliances section of API that’s required in order for deployment to actually occur when you create the Edge.

<deployAppliances>true</deployAppliances>

If you leave that statement as false, you’ll get an error every time you attempt to run this code against the NSX manager. To deploy the Edge at the time of creation, set all 3 entries to ‘true’

<appliances>
		<applianceSize>compact</applianceSize>
		<appliance>
			<highAvailabilityIndex>0</highAvailabilityIndex>
			<resourcePoolId>resgroup-8546</resourcePoolId>
			<resourcePoolName>System vDC (6a53b23b-8b07-47b2-9947-d7d53e399ec1)</resourcePoolName>
			<datastoreId>datastore-74</datastoreId>
			<datastoreName>584442-san-fc-hlu0-Silver</datastoreName>
			<hostId>host-2031</hostId>
			<hostName>354985-hyp28.ord1.rvi.local</hostName>
            <vmFolderId>group-v4168</vmFolderId>
			<vmFolderName>Service VMs</vmFolderName>
			<vmHostname>$EdgeName-0</vmHostname>
			<vmName>$EdgeName-0</vmName>
			<deployed>true</deployed>
			<edgeId>edge-100</edgeId>
		</appliance>
		<appliance>
			<highAvailabilityIndex>1</highAvailabilityIndex>
			<resourcePoolId>resgroup-8546</resourcePoolId>
			<resourcePoolName>System vDC (6a53b23b-8b07-47b2-9947-d7d53e399ec1)</resourcePoolName>
			<datastoreId>datastore-74</datastoreId>
			<datastoreName>584442-san-fc-hlu0-Silver</datastoreName>
			<hostId>host-4128</hostId>
			<hostName>354984-hyp27.ord1.rvi.local</hostName>
            <vmFolderId>group-v4168</vmFolderId>
			<vmFolderName>Service VMs</vmFolderName>
			<vmHostname>$EdgeName-1</vmHostname>
			<vmName>$EdgeName-1</vmName>
			<deployed>true</deployed>
			<edgeId>edge-100</edgeId>
		</appliance>
		<deployAppliances>true</deployAppliances>
	</appliances>

Create NSX One-Arm Load Balancer

As part of our lab automation we needed a way to load balance a pair of nested vCloud Director Cells. Given the way Edges work, we would have to have the IP’s of the Nested vCD instance sub-allocated to an Edge to handle the load balancing but this wasn’t going to be possible due to the way vCD works. The way to solve this, while unorthodox was to deploy a One-arm Load Balancing Edge outside the scope of vCD using NSX. Taking a cue from this great blog: Tom Fojta I was able to piece together the steps needed to create a one-arm load balancer via PowerCLI. Now what made this a little complex is I needed to deploy the Edge Load Balancer to a vxlan virtual wire after it had been created earlier in a deployment script.

The way I solved this was to query for the connected vxlan networks our nested vApp was connected to, once I had that it was simple to modify the body of a Rest call to have the proper configuration for our one-Arm Load Balancer. Be warned, the code for the body is very long as I fully configured the Edge prior to deployment. This included Load Balancer, Firewall, Nat and routing setup.

$NSXManager = Read-Host "Please provide the URL of the NSX Manager"
$NSXUserName = "administrator@vsphere.local"
$NSXPassword = Read-Host "Provide SSO Password" -AsSecureString
$NSXPassword = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($NSXPassword))
$EdgeName = "$OrgName-One-Arm-LB"

### Ignore TLS/SSL errors
add-type @"
    using System.Net;
    using System.Security.Cryptography.X509Certificates;
    public class TrustAllCertsPolicy : ICertificatePolicy {
        public bool CheckValidationResult(
            ServicePoint srvPoint, X509Certificate certificate,
            WebRequest request, int certificateProblem) {
            return true;
        }
    }
"@

[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
  
$auth = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($NSXUserName + ":" + $NSXPassword))
$head = @{"Authorization"="Basic $auth"}
$Request = "https://$NSXManager/api/4.0/edges"

$Response = Invoke-WebRequest -Uri $Request -Method 'Get' -Headers $head -ContentType "application/xml"
if ($Response.StatusCode -eq "200")
{
    $rxml = $Response.Content
    foreach ($edgeSummary in $rxml.pagedEdgeList.edgePage.edgeSummary) {
        $edge = @{} | select Name,id
        if ($edgeSummary.Name -like "*$OrgName*") {
            $edge.Name = $edgeSummary.Name
            $edge.ID = $edgeSummary.ID
            $requestedID = $edge.ID
            $Request = "https://$NSXManager/api/4.0/edges/$requestedID"
            $Response = Invoke-WebRequest -Uri $Request -Method 'Get' -Headers $head -ContentType "application/xml"
                if ($Response.StatusCode -eq "200") {
                    $rxml = $Response.Content
                    foreach ($vnic in $rxml.edge.vnics.vnic) {
                        $interface =  @{} | select portgroupId,portgroupName
                        if ($vnic.portgroupName -like '*ExNet-Inside*') {
                        $interface.portgroupId = $vnic.portgroupId
                        $portgroupID = $interface.portgroupId
                        $interface.portgroupName = $vnic.portgroupName
                        $portgroupname = $interface.portgroupName
                        }
                    }
                }
            
            }
        
        }
}

$body = "
<edge>
	<version>16</version>
	<status>undeployed</status>
	<datacenterMoid>datacenter-21</datacenterMoid>
	<datacenterName>1000112</datacenterName>
	<tenant>default</tenant>
	<name>$EdgeName</name>
	<fqdn>$EdgeName</fqdn>
	<enableAesni>true</enableAesni>
	<enableFips>false</enableFips>
	<vseLogLevel>emergency</vseLogLevel>
	<vnics>
		<vnic>
			<label>vNic_0</label>
			<name>vCloud-Https</name>
			<addressGroups>
				<addressGroup>
					<primaryAddress>192.168.100.119</primaryAddress>
					<secondaryAddresses>
						<ipAddress>192.168.100.120</ipAddress>
					</secondaryAddresses>
					<subnetMask>255.255.255.0</subnetMask>
					<subnetPrefixLength>24</subnetPrefixLength>
				</addressGroup>
			</addressGroups>
			<mtu>1500</mtu>
			<type>uplink</type>
			<isConnected>true</isConnected>
			<index>0</index>
            <portgroupId>$portgroupID</portgroupId>
            <portgroupName>
                $portgroupname
            </portgroupName>
			<enableProxyArp>false</enableProxyArp>
			<enableSendRedirects>true</enableSendRedirects>
		</vnic>
		<vnic>
			<label>vNic_1</label>
			<name>vnic1</name>
			<addressGroups/>
			<mtu>1500</mtu>
			<type>internal</type>
			<isConnected>false</isConnected>
			<index>1</index>
			<enableProxyArp>false</enableProxyArp>
			<enableSendRedirects>true</enableSendRedirects>
		</vnic>
		<vnic>
			<label>vNic_2</label>
			<name>vnic2</name>
			<addressGroups/>
			<mtu>1500</mtu>
			<type>internal</type>
			<isConnected>false</isConnected>
			<index>2</index>
			<enableProxyArp>false</enableProxyArp>
			<enableSendRedirects>true</enableSendRedirects>
		</vnic>
		<vnic>
			<label>vNic_3</label>
			<name>vnic3</name>
			<addressGroups/>
			<mtu>1500</mtu>
			<type>internal</type>
			<isConnected>false</isConnected>
			<index>3</index>
			<enableProxyArp>false</enableProxyArp>
			<enableSendRedirects>true</enableSendRedirects>
		</vnic>
		<vnic>
			<label>vNic_4</label>
			<name>vnic4</name>
			<addressGroups/>
			<mtu>1500</mtu>
			<type>internal</type>
			<isConnected>false</isConnected>
			<index>4</index>
			<enableProxyArp>false</enableProxyArp>
			<enableSendRedirects>true</enableSendRedirects>
		</vnic>
		<vnic>
			<label>vNic_5</label>
			<name>vnic5</name>
			<addressGroups/>
			<mtu>1500</mtu>
			<type>internal</type>
			<isConnected>false</isConnected>
			<index>5</index>
			<enableProxyArp>false</enableProxyArp>
			<enableSendRedirects>true</enableSendRedirects>
		</vnic>
		<vnic>
			<label>vNic_6</label>
			<name>vnic6</name>
			<addressGroups/>
			<mtu>1500</mtu>
			<type>internal</type>
			<isConnected>false</isConnected>
			<index>6</index>
			<enableProxyArp>false</enableProxyArp>
			<enableSendRedirects>true</enableSendRedirects>
		</vnic>
		<vnic>
			<label>vNic_7</label>
			<name>vnic7</name>
			<addressGroups/>
			<mtu>1500</mtu>
			<type>internal</type>
			<isConnected>false</isConnected>
			<index>7</index>
			<enableProxyArp>false</enableProxyArp>
			<enableSendRedirects>true</enableSendRedirects>
		</vnic>
		<vnic>
			<label>vNic_8</label>
			<name>vnic8</name>
			<addressGroups/>
			<mtu>1500</mtu>
			<type>internal</type>
			<isConnected>false</isConnected>
			<index>8</index>
			<enableProxyArp>false</enableProxyArp>
			<enableSendRedirects>true</enableSendRedirects>
		</vnic>
		<vnic>
			<label>vNic_9</label>
			<name>vnic9</name>
			<addressGroups/>
			<mtu>1500</mtu>
			<type>internal</type>
			<isConnected>false</isConnected>
			<index>9</index>
			<enableProxyArp>false</enableProxyArp>
			<enableSendRedirects>true</enableSendRedirects>
		</vnic>
	</vnics>
	<appliances>
		<applianceSize>compact</applianceSize>
		<appliance>
			<highAvailabilityIndex>0</highAvailabilityIndex>
			<resourcePoolId>resgroup-8546</resourcePoolId>
			<resourcePoolName>System vDC (6a53b23b-8b07-47b2-9947-d7d53e399ec1)</resourcePoolName>
			<datastoreId>datastore-74</datastoreId>
			<datastoreName>584442-san-fc-hlu0-Silver</datastoreName>
			<hostId>host-2031</hostId>
			<hostName>354985-hyp28.ord1.rvi.local</hostName>
            <vmFolderId>group-v4168</vmFolderId>
			<vmFolderName>Service VMs</vmFolderName>
			<vmHostname>$EdgeName-0</vmHostname>
			<vmName>$EdgeName-0</vmName>
			<deployed>true</deployed>
			<edgeId>edge-100</edgeId>
		</appliance>
		<appliance>
			<highAvailabilityIndex>1</highAvailabilityIndex>
			<resourcePoolId>resgroup-8546</resourcePoolId>
			<resourcePoolName>System vDC (6a53b23b-8b07-47b2-9947-d7d53e399ec1)</resourcePoolName>
			<datastoreId>datastore-74</datastoreId>
			<datastoreName>584442-san-fc-hlu0-Silver</datastoreName>
			<hostId>host-4128</hostId>
			<hostName>354984-hyp27.ord1.rvi.local</hostName>
            <vmFolderId>group-v4168</vmFolderId>
			<vmFolderName>Service VMs</vmFolderName>
			<vmHostname>$EdgeName-1</vmHostname>
			<vmName>$EdgeName-1</vmName>
			<deployed>true</deployed>
			<edgeId>edge-100</edgeId>
		</appliance>
		<deployAppliances>true</deployAppliances>
	</appliances>
	<features>
		<l2Vpn>
			<version>6</version>
			<enabled>false</enabled>
			<logging>
				<enable>false</enable>
				<logLevel>info</logLevel>
			</logging>
		</l2Vpn>
		<featureConfig/>
		<firewall>
			<version>2</version>
			<enabled>true</enabled>
			<globalConfig>
				<tcpPickOngoingConnections>false</tcpPickOngoingConnections>
				<tcpAllowOutOfWindowPackets>false</tcpAllowOutOfWindowPackets>
				<tcpSendResetForClosedVsePorts>true</tcpSendResetForClosedVsePorts>
				<dropInvalidTraffic>true</dropInvalidTraffic>
				<logInvalidTraffic>false</logInvalidTraffic>
				<tcpTimeoutOpen>30</tcpTimeoutOpen>
				<tcpTimeoutEstablished>3600</tcpTimeoutEstablished>
				<tcpTimeoutClose>30</tcpTimeoutClose>
				<udpTimeout>60</udpTimeout>
				<icmpTimeout>10</icmpTimeout>
				<icmp6Timeout>10</icmp6Timeout>
				<ipGenericTimeout>120</ipGenericTimeout>
			</globalConfig>
			<defaultPolicy>
				<action>accept</action>
				<loggingEnabled>false</loggingEnabled>
			</defaultPolicy>
			<firewallRules>
				<firewallRule>
					<id>131074</id>
					<ruleTag>131074</ruleTag>
					<name>firewall</name>
					<ruleType>internal_high</ruleType>
					<enabled>true</enabled>
					<loggingEnabled>false</loggingEnabled>
					<description>firewall</description>
					<action>accept</action>
					<source>
						<exclude>false</exclude>
						<vnicGroupId>vse</vnicGroupId>
					</source>
				</firewallRule>
				<firewallRule>
					<id>131073</id>
					<ruleTag>131073</ruleTag>
					<name>default rule for ingress traffic</name>
					<ruleType>default_policy</ruleType>
					<enabled>true</enabled>
					<loggingEnabled>false</loggingEnabled>
					<description>default rule for ingress traffic</description>
					<action>accept</action>
				</firewallRule>
			</firewallRules>
		</firewall>
		<sslvpnConfig>
			<version>6</version>
			<enabled>false</enabled>
			<logging>
				<enable>false</enable>
				<logLevel>info</logLevel>
			</logging>
			<advancedConfig>
				<enableCompression>false</enableCompression>
				<forceVirtualKeyboard>false</forceVirtualKeyboard>
				<randomizeVirtualkeys>false</randomizeVirtualkeys>
				<preventMultipleLogon>false</preventMultipleLogon>
				<clientNotification/>
				<enablePublicUrlAccess>false</enablePublicUrlAccess>
				<timeout>
					<forcedTimeout>0</forcedTimeout>
					<sessionIdleTimeout>10</sessionIdleTimeout>
				</timeout>
			</advancedConfig>
			<clientConfiguration>
				<autoReconnect>true</autoReconnect>
				<upgradeNotification>false</upgradeNotification>
			</clientConfiguration>
			<layoutConfiguration>
				<portalTitle>VMware</portalTitle>
				<companyName>VMware</companyName>
				<logoExtention>jpg</logoExtention>
				<logoUri>/api/4.0/edges/edge-100/sslvpn/config/layout/images/portallogo</logoUri>
				<logoBackgroundColor>FFFFFF</logoBackgroundColor>
				<titleColor>996600</titleColor>
				<topFrameColor>000000</topFrameColor>
				<menuBarColor>999999</menuBarColor>
				<rowAlternativeColor>FFFFFF</rowAlternativeColor>
				<bodyColor>FFFFFF</bodyColor>
				<rowColor>F5F5F5</rowColor>
			</layoutConfiguration>
			<authenticationConfiguration>
				<passwordAuthentication>
					<authenticationTimeout>1</authenticationTimeout>
					<primaryAuthServers/>
					<secondaryAuthServer/>
				</passwordAuthentication>
			</authenticationConfiguration>
		</sslvpnConfig>
		<dns>
			<version>6</version>
			<enabled>false</enabled>
			<cacheSize>16</cacheSize>
			<listeners>
				<vnic>any</vnic>
			</listeners>
			<dnsViews>
				<dnsView>
					<viewId>view-0</viewId>
					<name>vsm-default-view</name>
					<enabled>true</enabled>
					<viewMatch>
						<ipAddress>any</ipAddress>
						<vnic>any</vnic>
					</viewMatch>
					<recursion>false</recursion>
				</dnsView>
			</dnsViews>
			<logging>
				<enable>false</enable>
				<logLevel>info</logLevel>
			</logging>
		</dns>
		<routing>
			<version>6</version>
			<enabled>true</enabled>
			<routingGlobalConfig>
				<ecmp>false</ecmp>
				<logging>
					<enable>false</enable>
					<logLevel>info</logLevel>
				</logging>
			</routingGlobalConfig>
			<staticRouting>
				<defaultRoute>
					<vnic>0</vnic>
					<mtu>1500</mtu>
					<gatewayAddress>192.168.100.1</gatewayAddress>
				</defaultRoute>
				<staticRoutes/>
			</staticRouting>
			<ospf>
				<enabled>false</enabled>
				<ospfAreas>
					<ospfArea>
						<areaId>51</areaId>
						<type>nssa</type>
						<authentication>
							<type>none</type>
						</authentication>
					</ospfArea>
					<ospfArea>
						<areaId>0</areaId>
						<type>normal</type>
						<authentication>
							<type>none</type>
						</authentication>
					</ospfArea>
				</ospfAreas>
				<ospfInterfaces/>
				<redistribution>
					<enabled>false</enabled>
					<rules/>
				</redistribution>
				<gracefulRestart>true</gracefulRestart>
				<defaultOriginate>false</defaultOriginate>
			</ospf>
		</routing>
		<highAvailability>
			<version>6</version>
			<enabled>true</enabled>
			<vnic>any</vnic>
			<ipAddresses>
				<ipAddress>169.254.10.1/30</ipAddress>
				<ipAddress>169.254.10.2/30</ipAddress>
			</ipAddresses>
			<declareDeadTime>15</declareDeadTime>
			<logging>
				<enable>false</enable>
				<logLevel>info</logLevel>
			</logging>
			<security>
				<enabled>false</enabled>
			</security>
		</highAvailability>
		<syslog>
			<version>1</version>
			<enabled>false</enabled>
		</syslog>
		<featureConfig/>
		<loadBalancer>
			<version>10</version>
			<enabled>true</enabled>
			<enableServiceInsertion>false</enableServiceInsertion>
			<accelerationEnabled>false</accelerationEnabled>
			<virtualServer>
				<virtualServerId>virtualServer-1</virtualServerId>
				<name>vCloud-HTTPS-VIP</name>
				<enabled>true</enabled>
				<ipAddress>192.168.100.119</ipAddress>
				<protocol>https</protocol>
				<port>443</port>
				<connectionLimit>0</connectionLimit>
				<connectionRateLimit>0</connectionRateLimit>
				<defaultPoolId>pool-1</defaultPoolId>
				<applicationProfileId>applicationProfile-1</applicationProfileId>
				<enableServiceInsertion>false</enableServiceInsertion>
				<accelerationEnabled>false</accelerationEnabled>
			</virtualServer>
			<virtualServer>
				<virtualServerId>virtualServer-2</virtualServerId>
				<name>vCloud-Console-VIP</name>
				<enabled>true</enabled>
				<ipAddress>192.168.100.120</ipAddress>
				<protocol>https</protocol>
				<port>443</port>
				<connectionLimit>0</connectionLimit>
				<connectionRateLimit>0</connectionRateLimit>
				<defaultPoolId>pool-2</defaultPoolId>
				<applicationProfileId>applicationProfile-1</applicationProfileId>
				<enableServiceInsertion>false</enableServiceInsertion>
				<accelerationEnabled>false</accelerationEnabled>
			</virtualServer>
			<pool>
				<poolId>pool-1</poolId>
				<name>vCloud-HTTPS-Pool</name>
				<algorithm>leastconn</algorithm>
				<transparent>false</transparent>
				<monitorId>monitor-4</monitorId>
				<member>
					<memberId>member-1</memberId>
					<ipAddress>192.168.100.101</ipAddress>
					<weight>1</weight>
					<monitorPort>443</monitorPort>
					<port>443</port>
					<maxConn>0</maxConn>
					<minConn>0</minConn>
					<condition>enabled</condition>
					<name>vCloud-CellA-Https</name>
				</member>
				<member>
					<memberId>member-2</memberId>
					<ipAddress>192.168.100.104</ipAddress>
					<weight>1</weight>
					<monitorPort>443</monitorPort>
					<port>443</port>
					<maxConn>0</maxConn>
					<minConn>0</minConn>
					<condition>enabled</condition>
					<name>vCloud-CellB-Https</name>
				</member>
			</pool>
			<pool>
				<poolId>pool-2</poolId>
				<name>vCloud-Console-Pool</name>
				<algorithm>leastconn</algorithm>
				<transparent>false</transparent>
				<monitorId>monitor-3</monitorId>
				<member>
					<memberId>member-3</memberId>
					<ipAddress>192.168.100.103</ipAddress>
					<weight>1</weight>
					<monitorPort>443</monitorPort>
					<port>443</port>
					<maxConn>0</maxConn>
					<minConn>0</minConn>
					<condition>enabled</condition>
					<name>vCloud-Console-CellA</name>
				</member>
				<member>
					<memberId>member-4</memberId>
					<ipAddress>192.168.100.107</ipAddress>
					<weight>1</weight>
					<monitorPort>443</monitorPort>
					<port>443</port>
					<maxConn>0</maxConn>
					<minConn>0</minConn>
					<condition>enabled</condition>
					<name>vCloud-CellB-Console</name>
				</member>
			</pool>
			<applicationProfile>
				<applicationProfileId>applicationProfile-1</applicationProfileId>
				<name>vCloud-Https</name>
				<insertXForwardedFor>false</insertXForwardedFor>
				<sslPassthrough>true</sslPassthrough>
				<template>HTTPS</template>
				<serverSslEnabled>false</serverSslEnabled>
			</applicationProfile>
			<monitor>
				<monitorId>monitor-1</monitorId>
				<type>tcp</type>
				<interval>5</interval>
				<timeout>15</timeout>
				<maxRetries>3</maxRetries>
				<name>default_tcp_monitor</name>
			</monitor>
			<monitor>
				<monitorId>monitor-2</monitorId>
				<type>http</type>
				<interval>5</interval>
				<timeout>15</timeout>
				<maxRetries>3</maxRetries>
				<method>GET</method>
				<url>/</url>
				<name>default_http_monitor</name>
			</monitor>
			<monitor>
				<monitorId>monitor-3</monitorId>
				<type>https</type>
				<interval>5</interval>
				<timeout>15</timeout>
				<maxRetries>3</maxRetries>
				<method>GET</method>
				<url>/</url>
				<name>default_https_monitor</name>
			</monitor>
			<monitor>
				<monitorId>monitor-4</monitorId>
				<type>http</type>
				<interval>10</interval>
				<timeout>15</timeout>
				<maxRetries>3</maxRetries>
				<method>GET</method>
				<url>/cloud/server_status</url>
				<name>vCloud HTTPS Monitor</name>
			</monitor>
			<logging>
				<enable>false</enable>
				<logLevel>info</logLevel>
			</logging>
		</loadBalancer>
		<gslb>
			<version>1</version>
			<enabled>false</enabled>
			<logging>
				<enable>false</enable>
				<logLevel>info</logLevel>
			</logging>
		</gslb>
		<ipsec>
			<version>1</version>
			<enabled>false</enabled>
			<logging>
				<enable>false</enable>
				<logLevel>info</logLevel>
			</logging>
			<sites/>
			<global>
				<psk>******</psk>
				<caCertificates/>
				<crlCertificates/>
			</global>
		</ipsec>
		<dhcp>
			<version>6</version>
			<enabled>false</enabled>
			<staticBindings/>
			<ipPools/>
			<logging>
				<enable>false</enable>
				<logLevel>info</logLevel>
			</logging>
		</dhcp>
		<bridges>
			<version>6</version>
			<enabled>false</enabled>
		</bridges>
		<nat>
			<version>7</version>
			<enabled>true</enabled>
			<natRules>
				<natRule>
					<ruleId>196611</ruleId>
					<ruleTag>196611</ruleTag>
					<ruleType>internal_high</ruleType>
					<action>dnat</action>
					<vnic>0</vnic>
					<originalAddress>192.168.100.120</originalAddress>
					<translatedAddress>192.168.100.120</translatedAddress>
					<loggingEnabled>false</loggingEnabled>
					<enabled>true</enabled>
					<description>loadBalancer</description>
					<protocol>tcp</protocol>
					<originalPort>443</originalPort>
					<translatedPort>443</translatedPort>
				</natRule>
				<natRule>
					<ruleId>196610</ruleId>
					<ruleTag>196610</ruleTag>
					<ruleType>internal_high</ruleType>
					<action>dnat</action>
					<vnic>0</vnic>
					<originalAddress>192.168.100.119</originalAddress>
					<translatedAddress>192.168.100.119</translatedAddress>
					<loggingEnabled>false</loggingEnabled>
					<enabled>true</enabled>
					<description>loadBalancer</description>
					<protocol>tcp</protocol>
					<originalPort>443</originalPort>
					<translatedPort>443</translatedPort>
				</natRule>
			</natRules>
		</nat>
		<featureConfig/>
		<featureConfig/>
	</features>
	<autoConfiguration>
		<enabled>true</enabled>
		<rulePriority>high</rulePriority>
	</autoConfiguration>
	<type>gatewayServices</type>
	<hypervisorAssist>false</hypervisorAssist>
	<edgeAssistId>0</edgeAssistId>
	<queryDaemon>
		<enabled>false</enabled>
		<port>5666</port>
	</queryDaemon>
</edge>"

$Request = "https://$NSXManager/api/4.0/edges"
$Response = Invoke-WebRequest -Uri $Request -Method 'Post' -Headers $head -ContentType "application/xml" -Body $body
if ($Response.StatusCode -eq "201")
{
    Write-Host "One Armed LB $EdgeName was properly created"
}


Create Third Party Catalog for vCloud Director

Was browsing some blogs today and ran across this entry by William Lam: virtuallyghetto.com. Ironically I had written something similar to this back in early May for us in our own internal vCloud Director lab. We’re currently hosting it on a Netapp for customers to subscribe to and manual creation of the catalog was a serious time sink. Quick PowerCLI script and we were off to the races.

We have a staging vCloud Director instance that we do all our Image testing on. Once the catalog there has been verified and shown to be working, we run this script to export and create the proper file structure for upload to the Netapp.

# Add vcloud cmdlets
if( -not (Get-PSSnapin VMware.VimAutomation.Core) )
{
    Add-PSSnapin VMware.VimAutomation.Core
}
if( -not (Get-PSSnapin VMware.VimAutomation.Cloud) )
{
    Add-PSSnapin VMware.VimAutomation.Cloud
}
try {
    Connect-CIServer "vcd01-2848638.mv.rackspace.com"
     
    } Catch {
        throw "Unable to connect to VCD Server"
    }
New-Item -ItemType directory -Path 's:/vcsp/lib/1cf1823b-4321-4e66-b49d-16e2d78b744f/items' -Force
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}
 
#downloading and creating descriptor.json file
$url = 'https://vcd01-2848638.mv.rackspace.com/vcsp/lib/1cf1823b-4321-4e66-b49d-16e2d78b744f/'
$descriptor = (Invoke-RestMethod $url)
$descriptor.itemsHref = 'items.json'
$descriptor | Add-Member -PassThru NoteProperty maintenanceMessage "This catalog is currently in maintenance mode"
$descriptor | ConvertTo-Json -depth 999 | Out-File 's:/vcsp/lib/1cf1823b-4321-4e66-b49d-16e2d78b744f/descriptor.json'
#downloading and creating items.json file
$url = 'https://vcd01-2848638.mv.rackspace.com/vcsp/lib/1cf1823b-4321-4e66-b49d-16e2d78b744f/items'
$items = (Invoke-RestMethod $url)
 
#Creating Folder Structure and Downloading files
for ($i=0;$i -lt $Items.items.count; $i++) {
    $Items.items[$i].selfHref = $Items.items[$i].selfHref + 'item.json'
    $ovfPath = 'https://vcd01-2848638.mv.rackspace.com' + $Items.items[$i].files[0].hrefs
    $mfPath =  'https://vcd01-2848638.mv.rackspace.com' + $Items.items[$i].files[1].hrefs
    $vmdkPath = 'https://vcd01-2848638.mv.rackspace.com' + $Items.items[$i].files[2].hrefs
    $path = 's:/vcsp/lib/1cf1823b-4321-4e66-b49d-16e2d78b744f/items/' + $Items.items[$i].selfHref.Split("/")[5] + '/file/'
    $url = 'https://vcd01-2848638.mv.rackspace.com/vcsp/lib/1cf1823b-4321-4e66-b49d-16e2d78b744f/item/' + $Items.items[$i].selfHref.Split("/")[5]
    New-Item -ItemType directory -Path $path -Force
    $item = (Invoke-RestMethod $url)
    $outputURL = 's:/vcsp/lib/1cf1823b-4321-4e66-b49d-16e2d78b744f/items/' + $Items.items[$i].selfHref.Split("/")[5] + '/item.json'
    $item | ConvertTo-Json -depth 999 | Out-File "$outputURL"
    #downloading .ovf .mf and .vmdk files
    $webclient = New-Object System.Net.WebClient
    $ovfFile = $item.files[0].name
    $mfFile = $item.files[1].name
    $vmdkFile = $item.files[2].name
    $webclient.DownloadFile($ovfPath,$path+$ovfFile)
    $webclient.DownloadFile($mfPath,$path+$mfFile)
    $webclient.DownloadFile($vmdkPath,$Path+$vmdkFile)
     
}
$items | ConvertTo-Json -depth 999 | Out-File 's:/vcsp/lib/1cf1823b-4321-4e66-b49d-16e2d78b744f/items.json'
#Disconnect-CIServer -server * -Force:$true -confirm:$false

PowerCLI Create Routed OrgVDC Networks

Creating Routed OrgVDC networks is fairly painless and straight forward when working with vCloud Director. But it does take some time, especially if you need to create 50-60 of them a day for customers. Luckily we can easily script this with PowerCLI

$edgeGateway = Search-Cloud -QueryType EdgeGateway -Name $orgName | Get-CIView | where {$_.name -like "$orgName*"}
$ExNetnetwork = New-Object VMware.VimAutomation.Cloud.Views.OrgVdcNetwork
$ExNetnetwork.EdgeGateway = $edgeGateway.Id
$ExNetnetwork.isShared = $false
$ExNetnetwork.Configuration = New-Object VMware.VimAutomation.Cloud.Views.NetworkConfiguration
$ExNetnetwork.Name = "ExNet-Inside"
$ExNetnetwork.Configuration.IpScopes = New-Object VMware.VimAutomation.Cloud.Views.IpScopes
$ExNetnetwork.Configuration.FenceMode = "natRouted"

$IpScope = New-Object VMware.VimAutomation.Cloud.Views.IpScope
$IpScope.Gateway = $ExNetinternalGateway
$IpScope.Netmask = $ExNetinternalNetmask
$IpScope.Dns1 = $ExNetinternalGateway
$IpScope.IpRanges = New-Object VMware.VimAutomation.Cloud.Views.IpRanges
$IpScope.IpRanges.IpRange = New-Object VMware.VimAutomation.Cloud.Views.IpRange
$IpScope.IpRanges.IpRange[0].StartAddress = $ExNetfirstInternalIP
$IpScope.IpRanges.IpRange[0].EndAddress = $ExNetlastInternalIP

$ExNetnetwork.Configuration.IpScopes.IpScope += $IpScope
 
$orgVdc.ExtensionData.CreateNetwork($ExNetnetwork)

PowerCLI Create OrgVDC Bug

I was looking over my code earlier and noticed a strange bug that kept popping up. When I deploy a lab for customers or vendors I specify the vCPU speed to match the physical CPU speed. Additionally I set the CPU and Memory guarantees at 5% as this is non-production and we don’t want folks getting greedy.

But what I was noticing was that depending on the order some code was executed, one code would effectively reverse the previous codes command.

If for example I set the CPU and Memory guarantees with the following code first…

#Set Org VDC CPU and Memory guarantees
Get-OrgVdc $orgvDCName | Set-OrgVdc -CpuGuaranteedPercent 5
Get-OrgVdc $orgvDCName | Set-OrgVdc -MemoryGuaranteedPercent 5

and follow it up by setting the vCPU Core Speed…

#Set the vCPU Core Speed
$orgVdc.ExtensionData.VCpuInMhz = '2400'
$orgVdc.ExtensionData.UpdateServerData()

Something Strange would occur. Namely the Memory guarantee would shoot up to 100% despite just setting it a few lines above to 5% (and seeing it take effect in vCloud and in the logs.)

The fix for this ultimately was to just switch the order of code execution and set the vCPU Core speed first and then set the reservation but for the life of me I cannot see why setting the vCPU code speed would affect memory reservation.