Next step of my journey was to activate dhcp in the newly created OrgNetwork. With all my knowledge I had till now, this was a really heavy part.
(To save you some time, you had to leave PowerShell and PowerCLI and make as step further and use REST API calls.)
As I did it always, I searched for a method in some of the PowerCLI objects which help me achieve my goal. But this time I failed very hard.
The only PowerCLI commandlet I have was Get-EdgeGateway
. (https://code.vmware.com/docs/11794/cmdlet-reference/doc/Get-EdgeGateway.html) Sadly there is no Set-EdgeGateway
. This didn’t afraid me at all, because I learned from my former steps that PowerCLI objects have methods I could use to write data back to Cloud Director. (Like the UpdateServerData()
method I used in the past.)
Therefore I searched the edge object I got from Get-EdgeGateway
if I could find something useful in there. Quickly I found the right part in the sub-object ExtensionData.Configuration.EdgeGatewayServiceConfiguration
. But I was really confused because this sub-object was empty. Looking in the API documentation (https://code.vmware.com/apis/912/vmware-cloud-director/doc/doc/types/GatewayFeaturesType.html) I should find there the dhcp, firewall, … configuration objects.
After hours of fruitless searching I tried to access the REST API directly to see if I can see more there.
Since I never accessed the Cloud Director API with PowerShell my first problem was to learn how. Normally you use a REST API by authenticating and creating a session first and then making the call to get the data. After another hours of searching I learned that I don’t need to authenticate, because PowerCLI already did this for me!
When you start PowerCLI and connect to Cloud Director with the Connect-CIServer
commandlet, your session data is stored in the $global:defaultciservers
array. When you have only one session, it is in the first entry $global:defaultciservers[0]
. In this session object you find a parameter called SessionSecret
which is the access token for using the REST API of Cloud Director. (Because PowerCLI modules are also using the API.) So authentication is simply not necessary thanks to PowerCLI.
The next step was to create the right header for the REST API request. I learned that I had to describe what return value I expect and which version of the API I want to use. Additionally I had to add the access token to prove my identity. Therefore I had to create the following variable construct as header information for the REST API call.
$header = @{
Accept='application/vnd.vmware.admin.edgeGateway+xml;version=33.0'
"x-vcloud-authorization"=$global:defaultciservers[0].SessionSecret
}
Next step was the url which I had to query. A look into the documentation (https://code.vmware.com/apis/912/vmware-cloud-director/doc/doc/operations/GET-EdgeGateway.html) shows me that I can use /admin/edgeGateway/{id}
to get informations about my edge. I found out that it could get the {id}
portion of the url simply from the edge PowerCLI object. The id
field contains the needed object identifier, but also contains other parts which I don’t need. So i had to split that id
field to extract only the object identifier. (The id
field of the PowerCLI edge object contains some more informations separated with the “:” .)
$myedgeid = $myedge.id.Split(":")[-1] # extract the guid from the object id
Now I could construct the url and make the REST API call.
$result = Invoke-RestMethod -Uri "https://[DNS-NAME-OF-CLOUD-DIRECTOR] /api/admin/edgeGateway/$myedgeid" -Method get -Headers $header
Now I had the edgeGateway object directly from the REST API and could analyze it. Shortly I saw that using the REST API, I could get informations about the the service configuration of the edge gateway.
$result.EdgeGateway.Configuration.EdgeGatewayServiceConfiguration
GatewayDhcpService : GatewayDhcpService
FirewallService : FirewallService
NatService : NatService
GatewayIpsecVpnService : GatewayIpsecVpnService
StaticRoutingService : StaticRoutingService
LoadBalancerService : LoadBalancerService
These sub objects contains all the informations I could also see in the UI. But what I desperately missed here was a way to change this configuration and write it back to Cloud Director. The documentation mentions an old API call (https://code.vmware.com/apis/912/vmware-cloud-director/doc/doc/operations/POST-ConfigureEdgeGatewayServices.html) which is depreciated since Cloud Director version 10.0. Besides that I found no other way in the documentation.
Finally I started to use the developer tools of my chrome browser while working in the Cloud Director UI. I wanted to see what my browser does when I configure dhcp on an edge gateway.
With activated developer tools I could see that my browser was making API calls to the /network
namespace. This is something I did not find in the Cloud Director API documentation (yet). But what I found while searching was that there is a /network
namespace in the NSX Manager API. I learned that Cloud Director presents the /network
namespace only as a proxy and forwards calls to the NSX Manager. This has the advantage that Cloud Director takes care of the authentication part and you don’t have to authenticate again to the NSX Manager. So I understand that for configuring dhcp on an edge gateway I had to read the NSX Manager API.
With that knowledge found my way to the NSX API documentation about configuring dhcp on an edge gateway. (https://vdc-repo.vmware.com/raw.githubusercontent.com/vmware/nsxraml/6.4/html-version/nsxvapi.html#4_0_edges)
With all what I learned in this step I extended my script with this steps:
- Extract the object identifier from the id field of the PowerCLI edge gateway object
- Build the correct url for the REST API call to the NSX Manager by using the /network proxy namespace of Cloud Director
- Create the correct REST API call header which defines the format of my request body as xml and add the access token I already have from my PowerCLI session.
- Create the correct REST API call body with the desired dhcp settings.
(I just wanted dhcp to be enabled and defined a small dhcp scope.) - Execute the REST API call
The script:
##############################################
# activate dhcp for that network on the edge #
##############################################
# get a fresh copy of the edge object
$myedge = Get-EdgeGateway -Name $edgename
# build the url for the nsx rest api call
$myedgeid = $myedge.id.Split(":")[-1] # extract the guid from the object id
$url = "https://[DNS-NAME-OF-CLOUD-DIRECTOR]/network/edges/$myedgeid/dhcp/config"
# build the header for the api call
$header = @{
Accept='application/xml'
"content-type"='application/xml'
"x-vcloud-authorization"=$global:defaultciservers[0].SessionSecret
}
# build the body for the api call
# this enabled dhcp and set a default ip scope
$body = "<dhcp><enabled>true</enabled><staticBindings/><ipPools>
<ipPool>
<autoConfigureDNS>true</autoConfigureDNS>
<defaultGateway>192.168.0.1</defaultGateway>
<leaseTime>86400</leaseTime>
<poolId>pool-1</poolId>
<ipRange>192.168.0.30-192.168.0.39</ipRange>
<allowHugeRange>false</allowHugeRange>
</ipPool>
</ipPools>
<logging>
<enable>false</enable>
<logLevel>info</logLevel>
</logging>
</dhcp>"
# execute call to the nsx api
$result = Invoke-RestMethod -Uri $url -Method put -Headers $header -Body $body
Next article in this series: