VMware Cloud Community
AdamRushUK
Enthusiast
Enthusiast
Jump to solution

Adding vShield Edge NAT rules from a CSV file using PowerCLI

I recently read Alan's great post on adding NAT rules here: http://www.virtu-al.net/2014/07/24/working-vcd-edge-gateway-rules-powercli/

I have used this successfully for single rules in a lab environment, but have hundreds of rules I need to do in Production.

Although I managed to hack together an Excel spreadsheet which concatenated all these parameters to create each command, I wondered if there was a quicker way to do this.

My plan was to modify Alan's script to import a CSV file, then loop through every row and build the XML file in one pass.

However, I'm very rusty on my scripting skills, so I thought I'd ask first if this has already been done by someone else.

Does anybody know if there's a way to update the vShield Edge NAT rules from a CSV file?

VCP-Cloud | VCP5-DCV | MCITP:EA | MCSE | CCNA | CCAA LinkedIn: https://www.linkedin.com/in/adamrushuk | Twitter : @adamrushuk
Reply
0 Kudos
1 Solution

Accepted Solutions
SBooker
Contributor
Contributor
Jump to solution

Adam,

I was a involved with the original request for this functionality. Alan got us most of the way there with a function to create a single rule, but as in your use case, we also had a lot of rules to build all at once.

Our solution was some rather minor tweaks and the creation of 3 functions rather than 2.

* Function: New-DNATRuleXML and New-SNATRuleXML.  We created these two functions to build the XML string (one for SNAT and one for DNAT), the results of these are stored in a global variable.

* Function: New-NATXMLExecute. This is an execute function to execute the creation of the large XML string created in the functions above.

You should be able to modify/use the XML rule creation functions to interface to a spreadsheet, and then you should be away. Hope it helps.

Code example is below:

===============================================

Function New-NATXMLExecute (

  $EdgeGateway,

  $NATXML,

  $FirewallEnable) {

  Write-Host "`n`nExecuting the add NAT Function" -ForegroundColor Cyan

  Write-Host "-----------------------------------------------------"

  Write-Host "EdgeGateway: `t`t$EdgeGateway"

  #Write-Host "`tNATXML:`t`t$NATXML"

  Write-Host "Enable the Firewall?:`t`t$FirewallEnable"

  Write-Host "-----------------------------------------------------"

  $Edgeview = Search-Cloud -QueryType EdgeGateway -name $EdgeGateway | Get-CIView

  if (!$Edgeview) {

  Write-Warning "Edge Gateway with name $Edgeview not found"

  Exit

  }

  $URI = ($edgeview.Href + "/action/configureServices")

  $wc = New-Object System.Net.WebClient

  # Add Authorization headers

  $wc.Headers.Add("x-vcloud-authorization", $Edgeview.Client.SessionKey)

  $wc.Headers.Add("Content-Type", "application/vnd.vmware.admin.edgeGatewayServiceConfiguration+xml")

  $wc.Headers.Add("Accept", "application/*+xml;version=5.1")

  $webclient = New-Object system.net.webclient

    $webclient.Headers.Add("x-vcloud-authorization",$Edgeview.Client.SessionKey)

    $webclient.Headers.Add("accept",$EdgeView.Type + ";version=5.1")

    [xml]$EGWConfXML = $webclient.DownloadString($EdgeView.href)

  [xml]$OriginalXML = $EGWConfXML.EdgeGateway.Configuration.EdgegatewayServiceConfiguration.NatService.outerxml

  #Check if the firewall is enabled

  $FirewallStatus = $EGWConfXML.EdgeGateway.Configuration.EdgegatewayServiceConfiguration.FirewallService.IsEnabled

  Write-Host "Current Firewall Enabled Status: $FirewallStatus. This will be changed to: $FirewallEnable"

  LogWrite "Current Firewall Enabled Status: $FirewallStatus. This will be changed to: $FirewallEnable"

  if (($NATXML) -or ($FirewallStatus -ne $FirewallEnable)){

  $GoXML = '<?xml version="1.0" encoding="UTF-8"?>

  <EdgeGatewayServiceConfiguration xmlns="http://www.vmware.com/vcloud/v1.5" >

     <FirewallService>

  <IsEnabled>' + $FirewallEnable + '</IsEnabled>

  <DefaultAction>drop</DefaultAction>

  <LogDefaultAction>false</LogDefaultAction>

  </FirewallService>

  <NatService>

         <IsEnabled>true</IsEnabled>'

  $OriginalXML.NatService.NatRule | Foreach {

  $GoXML += $_.OuterXML

  }

  $GoXML += $NATXML

  $GoXML += '</NatService>

  </EdgeGatewayServiceConfiguration>'

  $script:NATXMLExecute = $GoXML

  [byte[]]$byteArray = [System.Text.Encoding]::ASCII.GetBytes($GoXML)

  $UploadData = $wc.Uploaddata($URI, "POST", $bytearray)

  $EdGWStatus = EdgeGatewayStatus -EdgeGateway $EdgeGateway

  Write-Host -NoNewline "Waiting for EdgeGateway to Configure..."

  LogWrite "Waiting for EdgeGateway to Configure..."

  while($EdGWStatus -ne "Ready")

  {

  Start-Sleep -Seconds 3

  Write-Host -NoNewline "."

  $EdGWStatus = EdgeGatewayStatus -EdgeGateway $EdgeGateway

  if ($EdGWStatus -eq "Error"){

  Write-Host "Error Has Occured.... Check the EdgeGateway" -ForegroundColor Red

  LogWrite "Error Has Occured.... Check the EdgeGateway"

  break

  }

  }

  Write-Host -NoNewline ".EdgeGateway Ready"

  Write-Host "`nNAT Building Complete."  -ForegroundColor Green

  LogWrite "NAT Building Complete."

  }

  else{

  Write-Host "No Changes Required... No changes have been made to the EdgeGateway"  -ForegroundColor Yellow

  LogWrite "No Changes Required... No changes have been made"

  }

}

Function New-DNATRuleXML (

  $EdgeGateway,

  $ExternalNetwork,

  $OriginalIP,

  $OriginalPort,

  $TranslatedIP,

  $TranslatedPort,

  $Protocol) {

  Write-Host "Building DNAT Rule XML" -ForegroundColor Yellow

  Write-Host "`tEdgeGateway: `t`t$EdgeGateway"

  Write-Host "`tExternalNetwork: `t$ExternalNetwork"

  Write-Host "`tOriginal IP:`t`t$OriginalIP"

  Write-Host "`tOriginalPort:`t`t$OriginalPort"

  Write-Host "`tTranslatedIP: `t`t$TranslatedIP"

  Write-Host "`tTranslatedPort:`t`t$TranslatedPort"

  Write-Host "`tProtocol:`t`t$Protocol"

  $Edgeview = Search-Cloud -QueryType EdgeGateway -name $EdgeGateway | Get-CIView

  if (!$Edgeview) {

  Write-Warning "Edge Gateway with name $Edgeview not found"

  Exit

  }

  $URI = ($edgeview.Href + "/action/configureServices")

  $wc = New-Object System.Net.WebClient

  # Add Authorization headers

  $wc.Headers.Add("x-vcloud-authorization", $Edgeview.Client.SessionKey)

  $wc.Headers.Add("Content-Type", "application/vnd.vmware.admin.edgeGatewayServiceConfiguration+xml")

  $wc.Headers.Add("Accept", "application/*+xml;version=5.1")

  $webclient = New-Object system.net.webclient

    $webclient.Headers.Add("x-vcloud-authorization",$Edgeview.Client.SessionKey)

    $webclient.Headers.Add("accept",$EdgeView.Type + ";version=5.1")

    [xml]$EGWConfXML = $webclient.DownloadString($EdgeView.href)

  [xml]$OriginalXML = $EGWConfXML.EdgeGateway.Configuration.EdgegatewayServiceConfiguration.NatService.outerxml

  if ($Script:NewID){

  $Script:NewID += 1

  $NewID = $Script:NewID

  }

  else{

  $NewID = [int]($OriginalXML.NatService.natrule | Sort id | Select Id -Last 1).id + 1

  If($NewID -eq 1){

  #If NoID has been found, set the correct starting ID

  $NewID = 65537

  }

  $Script:NewID = $NewID

  }

  $strXML = '<NatRule>

             <RuleType>DNAT</RuleType>

             <IsEnabled>true</IsEnabled>

             <Id>' + $NewID + '</Id>

             <GatewayNatRule>

                 <Interface type="application/vnd.vmware.admin.network+xml" name="' + $ExternalNetwork.Name + '" href="' + $ExternalNetwork.Href + '"/>

                 <OriginalIp>' + $OriginalIP + '</OriginalIp>

                 <OriginalPort>' + $OriginalPort + '</OriginalPort>

                 <TranslatedIp>' + $TranslatedIP + '</TranslatedIp>

                 <TranslatedPort>' + $TranslatedPort + '</TranslatedPort>

                 <Protocol>' + $Protocol + '</Protocol>

             </GatewayNatRule>

         </NatRule>'

  $script:DNATXML = $StrXML

}

Function New-SNATRuleXML (

  $EdgeGateway,

  $ExternalNetwork,

  $OriginalIP,

  $TranslatedIP

  ) {

  Write-Host "Building SNAT Rule XML" -ForegroundColor Yellow

  Write-Host "`tEdgeGateway: `t`t$EdgeGateway"

  Write-Host "`tExternalNetwork: `t$ExternalNetwork"

  Write-Host "`tOriginal IP:`t`t$OriginalIP"

  Write-Host "`tTranslatedIP: `t`t$TranslatedIP"

  $Edgeview = Search-Cloud -QueryType EdgeGateway -name $EdgeGateway | Get-CIView

  if (!$Edgeview) {

  Write-Warning "Edge Gateway with name $Edgeview not found"

  Exit

  }

  $URI = ($edgeview.Href + "/action/configureServices")

  $wc = New-Object System.Net.WebClient

  # Add Authorization headers

  $wc.Headers.Add("x-vcloud-authorization", $Edgeview.Client.SessionKey)

  $wc.Headers.Add("Content-Type", "application/vnd.vmware.admin.edgeGatewayServiceConfiguration+xml")

  $wc.Headers.Add("Accept", "application/*+xml;version=5.1")

  $webclient = New-Object system.net.webclient

    $webclient.Headers.Add("x-vcloud-authorization",$Edgeview.Client.SessionKey)

    $webclient.Headers.Add("accept",$EdgeView.Type + ";version=5.1")

    [xml]$EGWConfXML = $webclient.DownloadString($EdgeView.href)

  [xml]$OriginalXML = $EGWConfXML.EdgeGateway.Configuration.EdgegatewayServiceConfiguration.NatService.outerxml

  if ($Script:NewID){

  $Script:NewID += 1

  $NewID = $Script:NewID

  }

  else{

  $NewID = [int]($OriginalXML.NatService.natrule | Sort id | Select Id -Last 1).id + 1

  If($NewID -eq 1){

  #If NoID has been found, set the correct starting ID

  $NewID = 65537

  }

  $Script:NewID = $NewID

  }

  $strXML = '<NatRule>

  <RuleType>SNAT</RuleType>

  <IsEnabled>true</IsEnabled>

  <Id>' + $NewID + '</Id>

  <GatewayNatRule>

  <Interface type="application/vnd.vmware.admin.network+xml" name="' + $ExternalNetwork.Name + '" href="' + $ExternalNetwork.Href + '"/>

  <OriginalIp>' + $OriginalIP + '</OriginalIp>

  <TranslatedIp>' + $TranslatedIP + '</TranslatedIp>

  </GatewayNatRule>

  </NatRule>'

  $script:SNATXML = $StrXML

}

===============================================

View solution in original post

Reply
0 Kudos
1 Reply
SBooker
Contributor
Contributor
Jump to solution

Adam,

I was a involved with the original request for this functionality. Alan got us most of the way there with a function to create a single rule, but as in your use case, we also had a lot of rules to build all at once.

Our solution was some rather minor tweaks and the creation of 3 functions rather than 2.

* Function: New-DNATRuleXML and New-SNATRuleXML.  We created these two functions to build the XML string (one for SNAT and one for DNAT), the results of these are stored in a global variable.

* Function: New-NATXMLExecute. This is an execute function to execute the creation of the large XML string created in the functions above.

You should be able to modify/use the XML rule creation functions to interface to a spreadsheet, and then you should be away. Hope it helps.

Code example is below:

===============================================

Function New-NATXMLExecute (

  $EdgeGateway,

  $NATXML,

  $FirewallEnable) {

  Write-Host "`n`nExecuting the add NAT Function" -ForegroundColor Cyan

  Write-Host "-----------------------------------------------------"

  Write-Host "EdgeGateway: `t`t$EdgeGateway"

  #Write-Host "`tNATXML:`t`t$NATXML"

  Write-Host "Enable the Firewall?:`t`t$FirewallEnable"

  Write-Host "-----------------------------------------------------"

  $Edgeview = Search-Cloud -QueryType EdgeGateway -name $EdgeGateway | Get-CIView

  if (!$Edgeview) {

  Write-Warning "Edge Gateway with name $Edgeview not found"

  Exit

  }

  $URI = ($edgeview.Href + "/action/configureServices")

  $wc = New-Object System.Net.WebClient

  # Add Authorization headers

  $wc.Headers.Add("x-vcloud-authorization", $Edgeview.Client.SessionKey)

  $wc.Headers.Add("Content-Type", "application/vnd.vmware.admin.edgeGatewayServiceConfiguration+xml")

  $wc.Headers.Add("Accept", "application/*+xml;version=5.1")

  $webclient = New-Object system.net.webclient

    $webclient.Headers.Add("x-vcloud-authorization",$Edgeview.Client.SessionKey)

    $webclient.Headers.Add("accept",$EdgeView.Type + ";version=5.1")

    [xml]$EGWConfXML = $webclient.DownloadString($EdgeView.href)

  [xml]$OriginalXML = $EGWConfXML.EdgeGateway.Configuration.EdgegatewayServiceConfiguration.NatService.outerxml

  #Check if the firewall is enabled

  $FirewallStatus = $EGWConfXML.EdgeGateway.Configuration.EdgegatewayServiceConfiguration.FirewallService.IsEnabled

  Write-Host "Current Firewall Enabled Status: $FirewallStatus. This will be changed to: $FirewallEnable"

  LogWrite "Current Firewall Enabled Status: $FirewallStatus. This will be changed to: $FirewallEnable"

  if (($NATXML) -or ($FirewallStatus -ne $FirewallEnable)){

  $GoXML = '<?xml version="1.0" encoding="UTF-8"?>

  <EdgeGatewayServiceConfiguration xmlns="http://www.vmware.com/vcloud/v1.5" >

     <FirewallService>

  <IsEnabled>' + $FirewallEnable + '</IsEnabled>

  <DefaultAction>drop</DefaultAction>

  <LogDefaultAction>false</LogDefaultAction>

  </FirewallService>

  <NatService>

         <IsEnabled>true</IsEnabled>'

  $OriginalXML.NatService.NatRule | Foreach {

  $GoXML += $_.OuterXML

  }

  $GoXML += $NATXML

  $GoXML += '</NatService>

  </EdgeGatewayServiceConfiguration>'

  $script:NATXMLExecute = $GoXML

  [byte[]]$byteArray = [System.Text.Encoding]::ASCII.GetBytes($GoXML)

  $UploadData = $wc.Uploaddata($URI, "POST", $bytearray)

  $EdGWStatus = EdgeGatewayStatus -EdgeGateway $EdgeGateway

  Write-Host -NoNewline "Waiting for EdgeGateway to Configure..."

  LogWrite "Waiting for EdgeGateway to Configure..."

  while($EdGWStatus -ne "Ready")

  {

  Start-Sleep -Seconds 3

  Write-Host -NoNewline "."

  $EdGWStatus = EdgeGatewayStatus -EdgeGateway $EdgeGateway

  if ($EdGWStatus -eq "Error"){

  Write-Host "Error Has Occured.... Check the EdgeGateway" -ForegroundColor Red

  LogWrite "Error Has Occured.... Check the EdgeGateway"

  break

  }

  }

  Write-Host -NoNewline ".EdgeGateway Ready"

  Write-Host "`nNAT Building Complete."  -ForegroundColor Green

  LogWrite "NAT Building Complete."

  }

  else{

  Write-Host "No Changes Required... No changes have been made to the EdgeGateway"  -ForegroundColor Yellow

  LogWrite "No Changes Required... No changes have been made"

  }

}

Function New-DNATRuleXML (

  $EdgeGateway,

  $ExternalNetwork,

  $OriginalIP,

  $OriginalPort,

  $TranslatedIP,

  $TranslatedPort,

  $Protocol) {

  Write-Host "Building DNAT Rule XML" -ForegroundColor Yellow

  Write-Host "`tEdgeGateway: `t`t$EdgeGateway"

  Write-Host "`tExternalNetwork: `t$ExternalNetwork"

  Write-Host "`tOriginal IP:`t`t$OriginalIP"

  Write-Host "`tOriginalPort:`t`t$OriginalPort"

  Write-Host "`tTranslatedIP: `t`t$TranslatedIP"

  Write-Host "`tTranslatedPort:`t`t$TranslatedPort"

  Write-Host "`tProtocol:`t`t$Protocol"

  $Edgeview = Search-Cloud -QueryType EdgeGateway -name $EdgeGateway | Get-CIView

  if (!$Edgeview) {

  Write-Warning "Edge Gateway with name $Edgeview not found"

  Exit

  }

  $URI = ($edgeview.Href + "/action/configureServices")

  $wc = New-Object System.Net.WebClient

  # Add Authorization headers

  $wc.Headers.Add("x-vcloud-authorization", $Edgeview.Client.SessionKey)

  $wc.Headers.Add("Content-Type", "application/vnd.vmware.admin.edgeGatewayServiceConfiguration+xml")

  $wc.Headers.Add("Accept", "application/*+xml;version=5.1")

  $webclient = New-Object system.net.webclient

    $webclient.Headers.Add("x-vcloud-authorization",$Edgeview.Client.SessionKey)

    $webclient.Headers.Add("accept",$EdgeView.Type + ";version=5.1")

    [xml]$EGWConfXML = $webclient.DownloadString($EdgeView.href)

  [xml]$OriginalXML = $EGWConfXML.EdgeGateway.Configuration.EdgegatewayServiceConfiguration.NatService.outerxml

  if ($Script:NewID){

  $Script:NewID += 1

  $NewID = $Script:NewID

  }

  else{

  $NewID = [int]($OriginalXML.NatService.natrule | Sort id | Select Id -Last 1).id + 1

  If($NewID -eq 1){

  #If NoID has been found, set the correct starting ID

  $NewID = 65537

  }

  $Script:NewID = $NewID

  }

  $strXML = '<NatRule>

             <RuleType>DNAT</RuleType>

             <IsEnabled>true</IsEnabled>

             <Id>' + $NewID + '</Id>

             <GatewayNatRule>

                 <Interface type="application/vnd.vmware.admin.network+xml" name="' + $ExternalNetwork.Name + '" href="' + $ExternalNetwork.Href + '"/>

                 <OriginalIp>' + $OriginalIP + '</OriginalIp>

                 <OriginalPort>' + $OriginalPort + '</OriginalPort>

                 <TranslatedIp>' + $TranslatedIP + '</TranslatedIp>

                 <TranslatedPort>' + $TranslatedPort + '</TranslatedPort>

                 <Protocol>' + $Protocol + '</Protocol>

             </GatewayNatRule>

         </NatRule>'

  $script:DNATXML = $StrXML

}

Function New-SNATRuleXML (

  $EdgeGateway,

  $ExternalNetwork,

  $OriginalIP,

  $TranslatedIP

  ) {

  Write-Host "Building SNAT Rule XML" -ForegroundColor Yellow

  Write-Host "`tEdgeGateway: `t`t$EdgeGateway"

  Write-Host "`tExternalNetwork: `t$ExternalNetwork"

  Write-Host "`tOriginal IP:`t`t$OriginalIP"

  Write-Host "`tTranslatedIP: `t`t$TranslatedIP"

  $Edgeview = Search-Cloud -QueryType EdgeGateway -name $EdgeGateway | Get-CIView

  if (!$Edgeview) {

  Write-Warning "Edge Gateway with name $Edgeview not found"

  Exit

  }

  $URI = ($edgeview.Href + "/action/configureServices")

  $wc = New-Object System.Net.WebClient

  # Add Authorization headers

  $wc.Headers.Add("x-vcloud-authorization", $Edgeview.Client.SessionKey)

  $wc.Headers.Add("Content-Type", "application/vnd.vmware.admin.edgeGatewayServiceConfiguration+xml")

  $wc.Headers.Add("Accept", "application/*+xml;version=5.1")

  $webclient = New-Object system.net.webclient

    $webclient.Headers.Add("x-vcloud-authorization",$Edgeview.Client.SessionKey)

    $webclient.Headers.Add("accept",$EdgeView.Type + ";version=5.1")

    [xml]$EGWConfXML = $webclient.DownloadString($EdgeView.href)

  [xml]$OriginalXML = $EGWConfXML.EdgeGateway.Configuration.EdgegatewayServiceConfiguration.NatService.outerxml

  if ($Script:NewID){

  $Script:NewID += 1

  $NewID = $Script:NewID

  }

  else{

  $NewID = [int]($OriginalXML.NatService.natrule | Sort id | Select Id -Last 1).id + 1

  If($NewID -eq 1){

  #If NoID has been found, set the correct starting ID

  $NewID = 65537

  }

  $Script:NewID = $NewID

  }

  $strXML = '<NatRule>

  <RuleType>SNAT</RuleType>

  <IsEnabled>true</IsEnabled>

  <Id>' + $NewID + '</Id>

  <GatewayNatRule>

  <Interface type="application/vnd.vmware.admin.network+xml" name="' + $ExternalNetwork.Name + '" href="' + $ExternalNetwork.Href + '"/>

  <OriginalIp>' + $OriginalIP + '</OriginalIp>

  <TranslatedIp>' + $TranslatedIP + '</TranslatedIp>

  </GatewayNatRule>

  </NatRule>'

  $script:SNATXML = $StrXML

}

===============================================

Reply
0 Kudos