In our environment we have a PowerCLI script that generates various dashboards. One dashboard reports on org vDC usage and we needed to list the used / total IPs for org networks. This information is easy to get with external networks:
connect-ciserver cloud
$externalNetwork = Get-ExternalNetwork “external network”
$externalNetwork.UsedIpCount
$externalNetwork.TotalIpCount
Unfortunately, the objects returned by Get-OrgNetwork don’t have these properties, and I wasn’t able to find a way to get them via PowerCLI. I also didn’t see how to get them using the vCloud API, but didn’t look too hard so it may be there. Fortunately, vCO org vDC network objects have a method named getAllocatedAddresses(). So I could get the information from vCO, but how would I get the data into the report that’s ran on the reporting server?
Creating a scheduled task
The current PowerCLI scripts are ran as scheduled tasks on the reporting server. I decided to add another scheduled task on the reporting server that called the vCO workflow (Org Network IP Allocation Report). I call the workflow using curl, which isn’t included with Windows so the first step was to download and install it from http://curl.haxx.se/download.html. The scheduled tasks properties are:
Program/script: C:\Program Files (x86)\curl\curl.exe
Add arguments: -i -k -H “accept:application/xml” -H “content-type:application/xml;charset=UTF-8” -u vcoadmin:password -X POST https://vco.example.com:8281/api/workflows/e2e9b56a-7867-44a6-9b9f-3b3e69fe1175/executions/ -d “<execution-context xmlns=’http://www.vmware.com/vco’><parameters></parameters></execution-context>”
The workflow id is e2e9b56a-7867-44a6-9b9f-3b3e69fe1175. You can get the workflow id by pressing ctrl-c while the workflow is highlighted in the vCO client or using the method in https://kickingwaterbottles.wordpress.com/2013/06/05/scheduling-vco-workflows-with-curl-and-the-rest-api/
The quoted value after -d is the data that you’re sending with the POST request. The workflow takes no input so there are no parameters.
Workflow schema
Workfow details
The main work is done in the “Build network list” scripted task. The results of this scripted task are inserted via the built-in workflow “Run program in guest” to insert a series of cvs values into a file on the reporting server. This file is then read via PowerCLI’s Import-Csv cmdlet and the values are used to build the dashboard.
The contents of “Build network list” are:
A couple of notes
- The information reported works for us, but may not be exactly what you’d expect. The IP allocation is off by one because I actually wanted to report the available IPs in the IP pools. When using a network that creates a vSE gateway, the gateway will consume an internal IP and count as an allocated IP, but I wasn’t interested in that so I removed it.
- This workflow should probably be broken up to be more modular, but like a lot of things once I got the workflow done it was time to move on to something else. I’ll try to fix it up at a later time, which of course won’t happen 🙂
- The for loop in getAvailableIps contains two values (startAddress and endAddress) that calculate the total number IPs based off a range. This was the solution I came up with and probably terrible but it works.
- Just looking at the code makes me want to go and change a lot of things but if I waited for everything to be perfect, I’d never make a post. I hope what I have will help someone, and I hope PowerCLI gets UsedIpCount and TotalIpCount properties for org networks so this isn’t necessary.
- I’m not a programmer so please forgive the code.
I thought this was an example of how vCO can be used. Often times you run into a road block while trying to implement something and vCO is great at bypassing those roadblocks due to all the functionality it contains. Here is the code for the Build network list scripted task.
networks = [] for each(var org in vcdHost.getOrganizations()) { for each(var orgVdc in org.getVdcs()) { for each (var orgVdcNetwork in orgVdc.getOrgVdcNetworks()) { ipUsage = getAvailableIps(orgVdcNetwork) fenceMode = orgVdcNetwork.configuration.fenceMode parentNetwork = "n/a" if (orgVdcNetwork.configuration.parentNetwork) { parentNetwork = getParentNetworkName(orgVdcNetwork.configuration.parentNetwork) } networks.push(org.name + "," + orgVdcNetwork.name + "," + fenceMode + "," + parentNetwork + "," + ipUsage[0] + "," + ipUsage[1]) } } } function getAvailableIps(orgVdcNetwork) { network = null totalIps = 0 usedIps = 0 if (orgVdcNetwork.configuration.fenceMode == "bridged") { usedIps = orgVdcNetwork.getAllocatedAddresses().length } else { // Substract one for networks that require a vSE since getAllocatedAddresses counts the vSE. // The vSE's IP doesn't count towards the IP pool. usedIps = orgVdcNetwork.getAllocatedAddresses().length -1 } for each(var ipScope in orgVdcNetwork.configuration.ipScopes.ipScope.enumerate()) { for each (var ipRange in ipScope.ipRanges.ipRange.enumerate()) { startOctets = ipRange.startAddress.split('.') endOctets = ipRange.endAddress.split('.') startAddress = (16777216 * startOctets[0])/1 + (65536 * startOctets[1])/1 + (256 * startOctets[2])/1 + startOctets[3]/1 endAddress = (16777216 * endOctets[0])/1 + (65536 * endOctets[1])/1 + (256 * endOctets[2])/1 + endOctets[3]/1 totalIps += (endAddress - startAddress) + 1 } } return ([usedIps, totalIps]) } function getParentNetworkName(parentNetworkReference) { parentNetwork = vcdHost.getEntityByReference(VclFinderType.EXTERNAL_NETWORK, parentNetworkReference) return (parentNetwork.name) }