Leave us your email address and be the first to receive a notification when Robin posts a new blog.
About a year ago while working on a NSX-T implementation I needed to automate the creation of Firewall Sections, Firewall rules, Groups and Services in the Policy Manager of NSX-T. Because the PowerCli module wasn’t available at that time, I scripted the creation of objects directly against the API. This meant building an XML using Powershell and posting it against the Policy API. Although this worked, I ended up with a lot of code that was difficult to manage, especially if you are not that familiar with Powershell and JSON.
As a little sidestep; part of JSON Based Powershell script to create a service:
$Service = @{
"resource_type" = "Service";
"id" = $Svc_name -replace " ","_";
"display_name" = $Svc_name;
"description" = $Svc_desc;
}
$Service.Add("service_entries",$ServiceEntries)
$ChildService = @{
"resource_type" = "ChildService"
"marked_for_delete" = $false;
}
$ChildService.Add("Service",$Service)
$baseService = New-Object System.Collections.ArrayList
$baseService.Add($ChildService)
$jsonBase = @{
"resource_type" = "Infra";
"children" = $baseService
This could be posted to the NSX-T Manager with:
$jsonBase | ConvertTo-Json -Depth 10 | Out-File "$(Get-Location)\Create-MultiService-$Svc_name.json"
$body = $jsonBase | ConvertTo-Json -Depth 10
$patchServicesURL = "https://$nsxtmanager/policy/api/v1/infra/"
$responseData = Invoke-WebRequest -Uri $patchServicesURL -Method Patch -Body $body -Headers $global:headers -ContentType application/json -UseBasicParsing
Even though this worked at the time, for a new project I wanted to see if there was an easier way. Or if any new PowerCli modules were now available for the NSX-T Policy API. After a few minutes I found that since November the Get-NsxtPolicyService was made available. The other 3 modules: Connect-NsxtServer, Disconnect-NsxtServer and Get-NsxtService, were already available but they didn’t talk to the Policy API.
After another few minutes of searching for some documentation, I found some older blog posts that explained how to use the Get-NsxtService module in PowerCli:
And a great post on how to use the Get-NsxtPolicyService:
But as I stated in the introduction, they all use the ‘Any’ service. Since I’m not a programmer or professional scripter it took me some time to find the correct settings and methods to be able to create a custom service. But the previous mentioned posts gave me a good starting point and I found that the service can be created using:
$ServiceData = Get-NsxtPolicyService -Name com.vmware.nsx_policy.infra.services
With the Get-Member function you can see that options like delete, get, list and patch are available. For the Policy Manager we are going to use the patch method, which needs a service_id (name for the service) and com.vmware.nsx_policy.model.service service (description of the service).
I will not go into the details on how to find these NSX-T Policy services, they are explained into great detail in the before mentioned blog posts.
Creating a NSX-T custom service
When you create a custom service using the NSX-T GUI you need to give it a Name and optionally you can add a Description or a Tag.
These settings or specifications can be set using:
$ServiceSpec = $ServiceData.help.patch.service.Create()
$ServiceSpec.id = $Serviceid
$ServiceSpec.description = "Created for the Blog"
And a service needs Service Entries, that describe which ports are referenced in the service. This is where it gets a little more complicated, because there are several different Service Entries available. You can view them in the GUI or use:
$ServiceData.help.patch.service.service_entries.Element
For this example I’m going to add a TCP and a UDP port which requires l4_port_set_service_entry, so my Service Entry specification will look somewhat like:
ServiceEntL4Spec = $ServiceData.help.patch.service.service_entries.Element.l4_port_set_service_entry.Create()
Since I’m going to add two different service entries, I made things a bit easier for myself in this blog, but you’ll get the point. The Service Entries added a $ServiceEntries array, this array then needs to be added to the service specification using $ServiceSpec.service_entries. This is how the Service Entries look:
$ServiceEntries = @()
$ServiceEntL4Spec1 = $ServiceData.help.patch.service.service_entries.Element.l4_port_set_service_entry.Create()
$ServiceEntL4Spec1.id = "TCP-Port"
$ServiceEntL4Spec1.destination_ports=@(1234)
$ServiceEntL4Spec1.l4_protocol = "TCP"
$ServiceEntL4Spec1.source_ports = @()
$ServiceEntL4Spec1.resource_type = "L4PortSetServiceEntry"
$ServiceEntries += $ServiceEntL4Spec1
$ServiceEntL4Spec2 = $ServiceData.help.patch.service.service_entries.Element.l4_port_set_service_entry.Create()
$ServiceEntL4Spec2.id = "UDP-Port"
$ServiceEntL4Spec2.destination_ports=@(4321)
$ServiceEntL4Spec2.l4_protocol = "UDP"
$ServiceEntL4Spec2.source_ports = @()
$ServiceEntL4Spec2.resource_type = "L4PortSetServiceEntry"
$ServiceEntries += $ServiceEntL4Spec2
When it’s all combined it looks like:
#Retrieve Service Information
$ServiceData = Get-NsxtPolicyService -Name com.vmware.nsx_policy.infra.services
$Serviceid = "Blog-Service"
$ServiceEntries = @()
$ServiceEntL4Spec1 = $ServiceData.help.patch.service.service_entries.Element.l4_port_set_service_entry.Create()
$ServiceEntL4Spec1.id = "TCP-Port"
$ServiceEntL4Spec1.destination_ports=@(1234)
$ServiceEntL4Spec1.l4_protocol = "TCP"
$ServiceEntL4Spec1.source_ports = @()
$ServiceEntL4Spec1.resource_type = "L4PortSetServiceEntry"
$ServiceEntries += $ServiceEntL4Spec1
$ServiceEntL4Spec2 = $ServiceData.help.patch.service.service_entries.Element.l4_port_set_service_entry.Create()
$ServiceEntL4Spec2.id = "UDP-Port"
$ServiceEntL4Spec2.destination_ports=@(4321)
$ServiceEntL4Spec2.l4_protocol = "UDP"
$ServiceEntL4Spec2.source_ports = @()
$ServiceEntL4Spec2.resource_type = "L4PortSetServiceEntry"
$ServiceEntries += $ServiceEntL4Spec2
$ServiceSpec = $ServiceData.help.patch.service.Create()
$ServiceSpec.id = $Serviceid
$ServiceSpec.description = "Created for the Blog"
$ServiceSpec.service_entries = $ServiceEntries
$ServiceSpec.service_entries = @($ServiceEntL4Spec1,$ServiceEntL4Spec2)
$ServiceData.patch($serviceid,$ServiceSpec)
I know people are working on functions and modules to make this a lot easier, but in the meantime hopefully the mentioned blogs and this blog post can help you get started.
Questions, Remarks & Comments
If you have any questions and need more clarification, we are more than happy to dig deeper. Any comments are also appreciated. You can either post it online or send it directly to the author, it’s your choice.