Cloud Provider Pod - Get-PodFirewall PowerShell cmdlet


Cloud Provider Pod - Get-PodFirewall PowerShell cmdlet

The VMware Cloud Provider Pod Designer produces a bunch of documentation which is really useful (even if you don’t use the Deployer to actually, err… deploy). One of the options in the Designer is to forgo having NSX deployed in the management stack. Instead, we leave a load of dangling VLANs and let you connect them together with your own external network/security stack. The “icing on the cake” would be if you could not only find the network topology in the Designer downloads (which you can), but also the firewall policies necessary to make the whole shebang work (which you can’t).

Fortunately, all the information we need is inside the configData.cfg file in the Designer bundle, but not in a very friendly format. What we need is a slick tool to extract the firewall policy data and present it in a neat way. Sadly, we don’t have that, but what we do have is a PowerShell script/cmdlet that I wrote to do the job instead…

If you’re the sort who thinks RTFM is for wimps, you can jump straight to the code here.

Background

This post has been sitting in Drafts for a while now. My VMware colleagues who needed to extract copies of the Pod Designer firewall had access to the PowerShell script and tested it in the real world. However, the world has moved on, and the Cloud Provider Pod is destined for bigger and better things now, so the useful shelf-life of this particular script is already past its sell-by date. However, partly as there are some useful bits of PowerShell which I’m sure will come in handy at some point, and partly in case anyone should actually need it, I decided to quietly release the post. If I can get github to work, I’ll make the code available from there too.

I started to write this in rusty Python and PowerShell at the same time. I wanted to use the challenge to learn a little PowerShell but fully expected to complete the tool in Python which I had much more experience with. However, along the journey I discovered some typically MicroSoft style capabilities which made the PowerShell version far more useful with much less effort. I find that if you want to do what Microsoft intended, their tools can be brilliant. But, if you want to go your own way and Microsoft didn’t think that likely, their tools often put up a great deal of resistance. I liked PowerShell so I guess I fell into line with its developers, or they had a broad enough set of use cases that my tiny one was covered.

The cmdlet

The Cmdlet needs PowerShell Core 6.23 or later to run it. It won’t work on the version of PowerShell which comes with Windows Desktop/Server. I used a couple of features from PS Core as I thought I’d get shouted at if I used the Windows-only version of PS anyway, and they made some of the importing much easier.

The code

You can grab the code from GitHub using the usual methods, but if you want to browse the code first, here it is.

  1  <#
  2
  3   .Notes
  4   ==============================================================================
  5      Written by:    Steve Dockar
  6      Organization:  VMware 
  7      Twitter:       @SteveDockar
  8      Blog:          notthe.blog
  9      Version:       20191119 - Pretty PortList on PS Object, -strict switch
 10                                and PortsFile.json to override port desc text
 11      Version:       20191112 - Default output now PowerShell objects
 12   ==============================================================================
 13
 14   .Synopsis
 15   Produces firewall policy output from VMware Cloud Provider Pod Designer "configData.cfg" file
 16
 17   .Description
 18   Extracts IP addresses, netmasks and other sundry variables and outputs PSCustomObject for each rule or a text-based firewall policy (using -AsText) for use when deploying non-SDN based Pods.
 19
 20   .Parameter ConfigFile
 21   Absolute or relative path to configData.cfg from Designer Zip file.
 22   .Parameter PortsFile
 23   Absolute or relative path to json file containing port description output overrides.
 24   .Parameter PxeRangeRp00
 25   PXE/TFTP Range for ESXi boot/config
 26   .Parameter North
 27   Output North Edge/Firewall policy
 28   .Parameter South
 29   Output South Edge/Firewall policy
 30   .Parameter AsText
 31   Change output from PowerShell objects to simple (slightly) formatted text.
 32   .Parameter Strict
 33   Change output ports from default Deployer "Any" to Application specific ones.
 34   .Example 
 35   # Default full text-based output
 36   Get-PodFirewall /path/to/configData.cfg "192.168.1.1-192.168.1.99" -AsText
 37   .Example
 38   # Pass Pxe range as subnet
 39   Get-PodFirewall /path/to/configData.cfg "192.168.1.0/24"
 40   .Example
 41   # Output only North Edge/Firewall policy as text.
 42   Get-PodFirewall /path/to/configData.cfg "192.168.1.1-192.168.1.99" -North -AsText
 43   .Example
 44   # Output entire policy as CSV
 45   Get-PodFirewall /path/to/configData.cfg "192.168.1.1-192.168.1.99" | Export-CSV /path/to/output.csv
 46   .Example
 47   # Output entire policy as JSON ( and redirect to file)
 48   Get-PodFirewall /path/to/configData.cfg "192.168.1.1-192.168.1.99" | ConvertTo-JSON >/path/to/output.json
 49   .Example
 50   # Override port descriptions with external ports.json file
 51   Get-PodFirewall /path/to/configData.cfg [-PortsFile] /path/to/ports.json [-PxeRangerp00] "192.168.1.1-192.168.1.99"
 52  #>
 53
 54  <#
 55      ===================================================================================================================
 56      If you want to replace the text in the Port descriptions, copy the JSON/text below, from "{" to "}" inclusive, into a ports.json file. Edit the "<SVC> (nnn/xxx)" on the right hand side of each line to suit your requirements, and then add -PortsFile '/path/to/ports.json' when you call the script. Your descriptions will then override the built in ones. Don't change the left hand side or the script won't match them. You can also edit $AppIDs in this script directly of course, but you'll lose those changes if you update the script to a newer version.
 57
 58      The examples below have the extra ">" so that you can see -PortsFile has worked before you edit it yourself.
 59
 60      -----8<-----
 61
 62      { 
 63          "dnsudp": ">DNS (53/UDP)",
 64          "http": ">HTTP (80/TCP)",
 65          "https": ">HTTPS (443/TCP)",
 66          "ntp": ">NTP (123/UDP)",
 67          "icmpecho": ">ICMP (Echo/Reply)",
 68          "smtp": ">SMTP (25/TCP)",
 69          "ssh": ">SSH (22/TCP)",
 70          "ftp": ">FTP (20/TCP, 21/TCP)",
 71          "rmq1": ">RMQ (5671/TCP)",
 72          "rmq2": ">RMQ (5672/TCP, 5672/UDP)",
 73          "psql": ">PSQL (5432/TCP)",
 74          "nfs": ">NFS (111/TCP, 111/UDP)",
 75          "cas": ">CAS (9042/TCP)",
 76          "syslog": ">Syslog (514/UDP, 514/TCP, 1514/TCP, 6514/TCP)",
 77          "esx": ">ESX (623/UDP, 5988/TCP, 5989/TCP, 6500/TCP, 8000/TCP, 8001/TCP)",
 78          "902": ">(902/TCP, 902/UDP",
 79          "902T": ">902/TCP",
 80          "903T": ">903/TCP",
 81          "920": ">(920/TCP, 920/UDP",
 82          "8443": "8443/TCP"
 83          "61611T": ">61611/TCP",
 84          "61616T": ">61616/TCP",
 85          "tftp": ">Any(tftp)"
 86          "any": ">Any"
 87      }
 88
 89      ----->8-----
 90      ==================================================================================================================
 91  #>
 92
 93  Param  (
 94      # Path to Config File
 95      [Parameter(Mandatory=$true)] [string] $ConfigFile,
 96      # Path to Port override file
 97      [Parameter(Mandatory=$false)] [string] $PortsFile,
 98      # PXE Ports (subnet/range)
 99      [Parameter(Mandatory=$false)] [string] $PxeRangeRp00 = "'pxe/tftp range'",
100      # Optional Switches
101      [Parameter(Mandatory=$false)] [switch] $North = $false,
102      [Parameter(Mandatory=$false)] [switch] $South = $false,
103      [Parameter(Mandatory=$false)] [switch] $AsText = $false,
104      [Parameter(Mandatory=$false)] [switch] $Strict = $false
105  )
106
107  $Config = Get-Content -Path $ConfigFile | ConvertFrom-Json -AsHashtable
108  $DhcpRangeRp00 = @( $PxeRangeRp00 ) # Turn param string into array for $Rule(src|dst)
109
110  $PSObject = (-not $AsText) 
111
112  $In = "    " # Centralise indent for write-rule
113  $InSize= $In.Length # Save checking on every Send-Rule
114
115  $Firewall = ""
116
117  $VcdCellsIp = @( $Config.vcdCellRp0001Ip, $Config.vcdCellRp0002Ip)
118
119  # Lookup table to convert AppId to more descriptive text
120  if ($PortsFile) {
121      # Write-Host "Importing Port Descriptions"
122      $AppIds = Get-Content -Path $PortsFile | ConvertFrom-Json -AsHashtable  
123  } else {
124      $AppIds = @{ 
125          "dnsudp" = "DNS (53/UDP)";
126          "http" = "HTTP (80/TCP)";
127          "https" = "HTTPS (443/TCP)";
128          "ntp" = "NTP (123/UDP)";
129          "icmpecho" = "ICMP (Echo/Reply)";
130          "smtp" = "SMTP (25/TCP)";
131          "ssh" = "SSH (22/TCP)";
132          "ftp" = "FTP (20/TCP, (21/TCP)";
133          "rmq1" = "RMQ (5671/TCP)";
134          "rmq2" = "RMQ (5672/TCP, 5672/UDP)";
135          "psql" = "PSQL (5432/TCP)";   # PostgreSQL
136          "nfs" = "NFS (111/TCP, 111/UDP)";
137          "cas" = "CAS (9042/TCP)";  # Cassandra DB
138          "syslog" = "Syslog (514/UDP, 514/TCP, 1514/TCP, 6514/TCP)";
139          "esx" = "ESX (623/UDP, 5988/TCP, 5989/TCP, 6500/TCP, 8000/TCP, 8001/TCP)";
140          "902" = "(902/TCP, 902/UDP)";
141          "902T" = "902/TCP";
142          "903T" = "903/TCP";
143          "920" = "(920/TCP, 920/UDP)";
144          "8443" = "8443/TCP";
145          "61611T" = "61611/TCP";
146          "61616T" = "61616/TCP";
147          "tftp" = "Any";
148          "any" = "Any"
149      }
150  }
151
152  function Get-CidrMask {
153      # Pass in "Dotted Quad" mask and get back CIDR length
154      param (
155          [string]$dotMask
156      )
157      
158      $mask = ([ipaddress] $dotMask).Address
159      for ($ml = 0; $mask -ne 0; $ml++) {
160          $mask = $mask -band ($mask -1)
161      }
162      return $ml
163  }
164
165  function Get-ClusterCount {
166      param (
167          $rpNo = 0
168      )
169      return $Config.$("rp"+ ([string]$rpNo).PadLeft(2, "0") + "ClusterCount")    
170  }
171
172  function Get-HostCount {
173      param (
174          [string]$clNo = 1
175      )
176
177      return $Config.$("rp00Rc"+ ([string]$clNo).PadLeft(2, "0") + "HostCount")
178      
179  }
180
181  function Get-HostInfo {
182      param (
183          [Int32]$rp = 0,
184          [Int32]$rc = 0,
185          [Int32]$hostNo = 1,
186          # Valid infoType(s) are: Ip, VsanIp, Mac, VmotionIp, Name, Password, VxlanIp, IpStorageIp
187          [String]$infoType = "Ip"
188      )
189      
190      return $Config.("esxiRp" + ([string]$rp).PadLeft(2,"0") + "Rc" + ([string]$rc).PadLeft(2,"0") + ([string]$hostNo).PadLeft(2,"0") + $infoType) 
191  }
192
193  function Get-ResourceEsxiRanges {
194      $hostRanges = @()
195      for ( $rc=0; $rc -lt (Get-ClusterCount); $rc++) {
196          $hostRanges += ( $(Get-HostInfo 0 $rc 1 "Ip") + "-" + $(Get-HostInfo 0 $rc (Get-HostCount "1") "Ip") )
197      }
198      return $hostRanges
199  }
200
201  $ResourceEsxiHosts = Get-ResourceEsxiRanges
202
203  # Output related functions
204
205  function Get-PrettyPorts {
206      param (
207          [array]$ports
208      )
209      
210      # Build "pretty" ports list
211      $portList = @()
212      foreach ($id in $ports) {
213          if ( $AppIds.ContainsKey($id) ) {
214              $portList += $AppIds.$id
215          } else {
216              $portList += $id
217          }
218      }
219      return $portList
220  }
221
222  function Write-Rule {
223      param (
224          [string]$description,
225          [array]$srcIps,
226          [array]$dstIps,
227          [array]$ports
228      )
229
230      $portList = Get-PrettyPorts $ports
231          
232      Write-Host -Object ($description)
233      Write-Host -Object ($In + "Source      [" + ( $srcIps -join ", ") + "]" )
234      Write-Host -Object ($In + "Destination [" + ( $dstIps -join ", ") + "]" )
235      Write-Host -Object ($In + "Ports       [" + ( $portList -join ", ") + "]" )
236  }
237
238  function New-RuleObject {
239      param (
240          # For now each RuleObject holds which fw N/S and the rule number as well as the rule data.
241          [string] $fwNS,
242          [int32] $ruleNo,
243          [string] $description,
244          [array] $srcIps,
245          [array] $dstIps,
246          [array] $ports
247      )
248      
249      $portList = Get-PrettyPorts $ports
250      
251      # Create a custom object
252      $ruleObject = [PSCustomObject]@{
253          RuleId = ($fwNS + "-" + [string]$ruleNo);
254          Firewall = $fwNS;
255          RuleNo = $ruleNo;
256          Description = $description;
257          Source = ( $srcIps -join ", " );
258          Destination = ($dstIps -join ", " );
259          Ports = ($portList -join ", " )
260      }
261      return $ruleObject
262  }
263
264  function Send-Rule {
265      if ($PSObject) {
266          # Create a FWRule custom object and add to RuleArray
267          New-RuleObject $Firewall $RuleCount $RuleDesc $RuleSrc $RuleDst $RulePorts     
268      } else {
269          # Convenience wrapper as we're using global variables. 'Send' rule vars to 'Write-Rule'
270          $ruleNo = ([string]$script:RuleCount + ".").PadRight($InSize)
271          Write-Rule ($ruleNo + $RuleDesc) $RuleSrc $RuleDst $RulePorts
272      }
273      $Script:RuleCount += 1
274  }
275
276  # --------------------------------------------- Rules -------------------------------------------
277  # For each rule populate Desc, Src, Dst and Ports the call Send-Rule
278
279  function Get-NorthFirewall {
280      # Rule 1
281      $RuleDesc = "Outgoing traffic common for all machines in the network"
282      $RuleSrc = @( ($Config.mgmtVcdDmzNetwork + "/" + $(Get-CidrMask $Config.mgmtVcdDmzSubnet)), 
283          ($Config.mgmtVcdNetwork +"/" + $(Get-CidrMask  $Config.mgmtVcdSubnet)),
284          ($Config.mgmtInternalNetwork +"/" + $(Get-CidrMask  $Config.mgmtInternalSubnet)),
285          ($Config.rp00Rc00MgiNetwork +"/" + $(Get-CidrMask  $Config.rp00Rc00MgiSubnet)) )
286      $RuleDst = @( "any" )
287      $RulePorts = @( "dnsudp", "http", "https", "ntp", "icmpecho", "smtp")
288      Send-Rule
289
290      # Rule 2
291      $RuleDesc = "vCD cell server to cassandra database nodes"
292      $RuleSrc = @( $Config.vcdCellRp0001Ip , $Config.vcdCellRp0002Ip )
293      $RuleDst = @( ($Config.vcdPfdbRp0001Ip + "-" + $Config.vcdPfdbRp0004Ip) )
294      $RulePorts = @( "any" ) # Deployer
295      if ($Strict) { $RulePorts = @( "cas" ) } # Actual Ports
296      Send-Rule
297
298      # Rule 3
299      $RuleDesc = "vCD cell server to postgreSQL database"
300      $RuleSrc = $VcdCellsIp
301      $RuleDst = @( $Config.vcdDbRp0001Ip)
302      $RulePorts = @( "any" )
303      if ($Strict) { $RulePorts = @( "psql" ) }
304      Send-Rule
305
306      # Rule 4
307      $RuleDesc = "vCD cell server to Rabbit MQ loadbalancer"
308      $RuleSrc = $VcdCellsIp
309      $RuleDst = @( $Config.vcdRabbLbsRp00Ip )
310      $RulePorts = @( "any" )
311      if ($Strict) { $RulePorts = @( "61611T", "61616T", "rmq2" ) }
312      Send-Rule
313
314      # Rule 5
315      $RuleDesc = "vCD cell server to VCSA Resource Pod"
316      $RuleSrc = $VcdCellsIp
317      $RuleDst = @( $Config.vcsaRp0001Ip )
318      $RulePorts = @( "any" )
319      if ($Strict) { $RulePorts = @( "https", "902T", "903T" ) }
320      Send-Rule
321
322      # Rule 6 - Need to calculate ESXi cluster numbers and sizes for this - See Get-ClusterCound & Get-HostCount!
323      $RuleDesc = "vCD cell server to ESXi hosts Resource Pod"
324      $RuleSrc = $VcdCellsIp
325      $RuleDst = $ResourceEsxiHosts
326      $RulePorts = @( "any" )
327      if ($Strict) { $RulePorts = @( "https", "902T", "903T" ) }
328      Send-Rule
329
330      # Rule 7
331      $RuleDesc = "vCD cell server to NSX Manager Resource Pod"
332      $RuleSrc = $VcdCellsIp
333      $RuleDst = @( $Config.nsxMgrRp0001Ip )
334      $RulePorts = @( "any" )
335      if ($Strict) { $RulePorts = @( "https" ) }
336      Send-Rule
337
338      # Rule 8
339      $RuleDesc = "vRealize Operations Tenant App to vRealize Operations Manager"
340      $RuleSrc = @( $Config.vropsMg0101TenantIp )
341      $RuleDst = @( $Config.vropsMg0101Ip )
342      $RulePorts = @( "any" )
343      if ($Strict) { $RulePorts = @( "https" ) }
344      Send-Rule
345
346      # Rule 9
347      $RuleDesc = "Rabbit MQ nodes to vRealize Orchestrator"
348      $RuleSrc = @( ($Config.vcdRabbRp0001Ip + "-" + $Config.vcdRabbRp0002Ip) )
349      $RuleDst = @( $Config.vroMg0101Ip )
350      $RulePorts = @( "any" )
351      if ($Strict) { $RulePorts = @( "rmq2" ) }
352      Send-Rule
353
354      # Rule 10
355      $RuleDesc = "Rabbit MQ nodes to vCloud Director"
356      $RuleSrc = @( ($Config.vcdRabbRp0001Ip + "-" + $Config.vcdRabbRp0002Ip) )
357      $RuleDst = $VcdCellsIp
358      $RulePorts = @( "any" )
359      if ($Strict) { $RulePorts = @( "rmq2" ) }
360      Send-Rule
361
362      # Rule 11
363      $RuleDesc = "vRealize Orchestrator to virtual machines and appliances"
364      $RuleSrc = @( $Config.vroMg0101Ip )
365      $RuleDst = $VcdCellsIp
366      $RulePorts = @( "any" )
367      if ($Strict) { $RulePorts = @( "https" ) }
368      Send-Rule
369
370      # Rule 12
371      $RuleDesc = "CPOD install server to vCD cell server and NFS transfer"
372      $RuleSrc = @( $Config.vcppInstallIp )
373      $RuleDst = $VcdCellsIp + $Config.vcdNfsRp0001Ip
374      $RulePorts = @( "any" )
375      if ($Strict) { $RulePorts = @( "https", "nfs", "920" ) }
376      Send-Rule
377
378      # Rule 13
379      $RuleDesc = "CPOD vRealize Orchestrator to vCD cell server and NFS transfer"
380      $RuleSrc = @( $Config.vroMg0101Ip )
381      $RuleDst = $VcdCellsIp + $Config.vcdNfsRp0001Ip
382      $RulePorts = @( "any" )
383      if ($Strict) { $RulePorts = @( "https", "nfs", "920" ) }
384      Send-Rule
385
386      # Rule 14
387      $RuleDesc = "vCD cell server to cpod install"
388      $RuleSrc = $VcdCellsIp
389      $RuleDst = @( $Config.vcppInstallIp )
390      $RulePorts = @( "any" )
391      if ($Strict) { $RulePorts = @( "https" ) }
392      Send-Rule
393          
394      # Rule 15
395      $RuleDesc = "Incoming to vCD LBS UI"
396      $RuleSrc = @( "any" )
397      $RuleDst = @( $Config.mgmtDmzVcdUiIp )
398      $RulePorts = @( "https" )
399      Send-Rule
400
401      # Rule 16
402      $RuleDesc = "Incoming to vCD LBS Console"
403      $RuleSrc = @( "any" )
404      $RuleDst = @( $Config.mgmtDmzVcdConsoleIp )
405      $RulePorts = @( "8443" )
406      Send-Rule
407
408      # Rule 17
409      $RuleDesc = "Incoming to vCD tenant App"
410      $RuleSrc = @( "any" )
411      $RuleDst = @( $Config.mgmtDmzVropsTenantIp )
412      $RulePorts = @( "https" )
413      if ($Strict) { $RulePorts = @( "http", "https" ) }
414      Send-Rule
415
416      # Rule 18
417      $RuleDesc = "vCD cell server to cpod install"
418      $RuleSrc = $VcdCellsIp
419      $RuleDst = @( $Config.vrliMg0101Ip )
420      $RulePorts = @( "any" )
421      if ($Strict) { $RulePorts = @( "https" ) }
422      Send-Rule
423
424      # [Rule 19] 
425      if ($Config.vropsMg0101Deploy -eq "true") {
426          $RuleDesc = "vROPS tenant app to RabbitMQ"
427          $RuleSrc = @( $Config.vropsMg0101TenantIp )
428          $RuleDst = @( $Config.vcdRabbLbsRp00Ip )
429          $RulePorts = @( "any" )
430          if ($Strict) { $RulePorts = @( "rmq2" ) }
431          Send-Rule
432      }
433  }
434
435  function Get-SouthFirewall {
436      # Rule 1
437      $RuleDesc = "Outgoing traffic common for all machines in the network"
438  	$RuleSrc = @( ($Config.mgmtVcdDmzNetwork + "/" + $(Get-CidrMask $Config.mgmtVcdDmzSubnet)) , 
439          ($Config.mgmtVcdNetwork +"/" + $(Get-CidrMask  $Config.mgmtVcdSubnet)) ,
440          ($Config.mgmtInternalNetwork +"/" + $(Get-CidrMask  $Config.mgmtInternalSubnet)) ,
441          ($Config.rp00Rc00MgiNetwork +"/" + $(Get-CidrMask  $Config.rp00Rc00MgiSubnet)) )
442      $RuleDst = @( "any" )
443      $RulePorts = @( "dnsudp", "http", "https", "ntp", "icmpecho", "smtp")
444      Send-Rule
445
446      # Rule 2
447      $RuleDesc = "FTP traffic for Centos machines to CPOD deployer"
448      $RuleSrc = @( ($Config.vcdPfdbRp0001Ip + "-" + $Config.vcdPfdbRp0004Ip),
449  		($Config.vcdRabbRp0001Ip + "-" + $Config.vcdRabbRp0002Ip),
450  		($Config.vcdCellRp0001Ip + "-" + $Config.vcdCellRp0002Ip),
451  		$Config.vcdNfsRp0001Ip,
452  		$Config.vcdDbRp0001Ip ) 
453  	$RuleDst = @( $Config.vcppInstallIp )
454  	$RulePorts = @( "ftp" )
455      Send-Rule
456      
457      # Rule 3
458      $RuleDesc = "vCD cell server to cassandra database nodes"
459      $RuleSrc = $VcdCellsIp
460      $RuleDst = @( $Config.vcdPfdbRp0001Ip + "-" + $Config.vcdPfdbRp0004Ip )
461      $RulePorts = @( "any" )
462      if ($Strict) { $RulePorts = @( "cas" ) }
463      Send-Rule
464
465      # Rule 4
466      $RuleDesc = "vCD cell server to postgreSQL database"
467      $RuleSrc = $VcdCellsIp
468      $RuleDst = @( $Config.vcdDbRp0001Ip)
469      $RulePorts = @( "any" )
470      if ($Strict) { $RulePorts = @( "psql" ) }
471      Send-Rule
472
473      # Rule 5
474      $RuleDesc = "vCD cell server to Rabbit MQ loadbalancer"
475      $RuleSrc = $VcdCellsIp
476      $RuleDst = @( $Config.vcdRabbLbsRp00Ip )
477      $RulePorts = @( "any" )
478      if ($Strict) { $RulePorts = @( "61611T", "61616T", "rmq2" ) }
479      Send-Rule
480
481      # Rule 6
482      $RuleDesc = "vCD cell server to VCSA Resource Pod"
483      $RuleSrc = $VcdCellsIp
484      $RuleDst = @( $Config.vcsaRp0001Ip)
485      $RulePorts = @( "any" )
486      if ($Strict) { $RulePorts = @( "https", "902T", "903T" ) }
487      Send-Rule
488
489      # Rule 7
490      $RuleDesc = "vCD cell server to ESXi hosts Resource Pod"
491      $RuleSrc = $VcdCellsIp
492      $RuleDst = $ResourceEsxiHosts
493      $RulePorts = @( "any" )
494      if ($Strict) { $RulePorts = @( "https", "902T", "903T" ) }
495      Send-Rule
496
497      # Rule 8
498      $RuleDesc = "vCD cell server to NSX Manager Resource Pod"
499      $RuleSrc = $VcdCellsIp
500      $RuleDst = @( $Config.nsxMgrRp0001Ip )
501      $RulePorts = @( "any" )
502      if ($Strict) { $RulePorts = @( "https" ) }
503      Send-Rule
504
505      # Rule 9
506      $RuleDesc = "vRealize Operations Tenant App to vRealize Operations Manager"
507      $RuleSrc = @( $Config.vropsMg0101TenantIp )
508      $RuleDst = @( $Config.vropsMg0101Ip )
509      $RulePorts = @( "any" )
510      if ($Strict) { $RulePorts = @( "https" ) }
511      Send-Rule
512
513      # Rule 10
514      $RuleDesc = "Rabbit MQ nodes to vRealize Orchestrator"
515      $RuleSrc = @( ($Config.vcdRabbRp0001Ip + "-" + $Config.vcdRabbRp0002Ip) )
516      $RuleDst = @( $Config.vroMg0101Ip )
517      $RulePorts = @( "any" )
518      if ($Strict) { $RulePorts = @( "rmq2" ) }
519      Send-Rule
520
521      # Rule 11
522      $RuleDesc = "Rabbit MQ nodes to vCloud Director"
523      $RuleSrc = @( ($Config.vcdRabbRp0001Ip + "-" + $Config.vcdRabbRp0002Ip) )
524      $RuleDst = $VcdCellsIp
525      $RulePorts = @( "any" )
526      if ($Strict) { $RulePorts = @( "rmq2" ) }
527      Send-Rule
528
529      # Rule 12
530      $RuleDesc = "vRealize Orchestrator to virtual machines and appliances"
531      $RuleSrc = @( $Config.vroMg0101Ip )
532      $RuleDst = $VcdCellsIp
533      $RulePorts = @( "any" )
534      if ($Strict) { $RulePorts = @( "https" ) }
535      Send-Rule
536
537      # Rule 13
538      $RuleDesc = "CPOD install server to vCD cell server and NFS transfer"
539      $RuleSrc = @( $Config.vcppInstallIp )
540      $RuleDst = $VcdCellsIp + $Config.vcdNfsRp0001Ip
541      $RulePorts = @( "any" )
542      if ($Strict) { $RulePorts = @( "https", "nfs", "920" ) }
543      Send-Rule
544
545      # Rule 14
546      $RuleDesc = "CPOD vRealize Orchestrator to vCD cell server and NFS transfer"
547      $RuleSrc = @( $Config.vroMg0101Ip )
548      $RuleDst = $VcdCellsIp + $Config.vcdNfsRp0001Ip
549      $RulePorts = @( "any" )
550      if ($Strict) { $RulePorts = @( "https", "nfs", "920" ) }
551      Send-Rule
552
553      # Rule 15
554      $RuleDesc = "vCenter resource pod to ESXi hosts Resource Pod"
555      $RuleSrc = @( $Config.vcsaRp0001Ip)
556      $RuleDst = $ResourceEsxiHosts
557      $RulePorts = @( "any" )
558      if ($Strict) { $RulePorts = @( "http", "https", "902", "esx" ) }
559      Send-Rule
560
561      # Rule 16
562      $RuleDesc = "NSX Manager resource pod to ESXi hosts Resource Pod"
563      $RuleSrc = @( $Config.nsxMgrRp0001Ip)
564      $RuleDst = $ResourceEsxiHosts
565      $RulePorts = @( "any" )
566      if ($Strict) { $RulePorts = @( "https", "902T" ) }
567      Send-Rule
568
569      # Rule 17
570      $RuleDesc = "Cpod vRO to ESXi hosts Resource Pod"
571      $RuleSrc = @( $Config.vroMg0101Ip)
572      $RuleDst = $ResourceEsxiHosts
573      $RulePorts = @( "any" )
574      if ($Strict) { $RulePorts = @( "ssh", "https" ) }
575      Send-Rule
576
577      # Rule 18
578      $RuleDesc = "CPOD install server to linux VMs mgmtVcdNetwork and new CPOD install server"
579      $RuleSrc = @( $Config.vcppInstallIp)
580      $RuleDst = @( ($Config.vcdRabbRp0001Ip + "-" + $Config.vcdRabbRp0002Ip),
581   		($Config.vcdPfdbRp0001Ip + "-" + $Config.vcdPfdbRp0004Ip),
582           $Config.vcppInstallRp00Rc00Ip )
583      $RulePorts = @( "any" )
584      if ($Strict) { $RulePorts = @( "ssh" ) }
585      Send-Rule
586
587      # Rule 19
588      $RuleDesc = "CPOD vRO to virtual machines and appliances and new CPOD install server"
589      $RuleSrc = @( $Config.vroMg0101Ip)
590      $RuleDst = @( ($Config.vcdRabbRp0001Ip + "-" + $Config.vcdRabbRp0002Ip),
591   		($Config.vcdPfdbRp0001Ip + "-" + $Config.vcdPfdbRp0004Ip),
592   		$Config.vcppInstallRp00Rc00Ip,
593           $Config.vcdDbRp0001Ip )
594      $RulePorts = @( "any" )
595      if ($Strict) { $RulePorts = @( "https" ) }
596      Send-Rule
597
598      # Rule 20
599      $RuleDesc = "NSX controller cluster rp00 to NSX manager rp00"
600      $RuleSrc = @( ($Config.nsxCtrlRp0001Ip + "-" + $Config.nsxCtrlRp0003Ip) )
601      $RuleDst = @( $Config.nsxMgrRp0001Ip) 
602      $RulePorts = @( "any" )
603      if ($Strict) { $RulePorts = @( "https" ) }
604      Send-Rule
605
606      # Rule 21 
607      $RuleDesc = "ESXi hosts resource pod to vRNI proxy"
608      $RuleSrc = $ResourceEsxiHosts
609      $RuleDst = @( $Config.vrniMg0101ProxyIp)
610      $RulePorts = @( "any" )
611      if ($Strict) { $RulePorts = @( "https" ) }
612      Send-Rule
613
614      # Rule 22
615      $RuleDesc = "RP00 Hosts to cpod-install for TFTP"
616      $RuleSrc = $ResourceEsxiHosts
617      $RuleDst = @( $Config.vcppInstallIp )
618      $RulePorts = @( "any" )
619      if ($Strict) { $RulePorts = @( "tftp" ) }
620      Send-Rule
621
622      # Rule 23
623      $RuleDesc = "RP00 ip range to cpod-install for TFTP"
624      $RuleSrc = $DhcpRangeRp00 # dhcp range used for TFTP/PXE boot
625      $RuleDst = @( $Config.vcppInstallIp )
626      $RulePorts = @( "any" )
627      if ($Strict) { $RulePorts = @( "tftp" ) }
628      Send-Rule
629
630      # Rule 24
631      $RuleDesc = "vCD cell server to cpod install"
632      $RuleSrc = $VcdCellsIp
633      $RuleDst = @( $Config.vcppInstallIp )
634      $RulePorts = @( "any" )
635      if ($Strict) { $RulePorts = @( "https" ) }
636      Send-Rule
637
638      # Rule 25
639      $RuleDesc = "RP00 Hosts to RP00 NSX Manager"
640      $RuleSrc = $ResourceEsxiHosts
641      $RuleDst = @( $Config.nsxMgrRp0001Ip)
642      $RulePorts = @( "any" )
643      if ($Strict) { $RulePorts = @( "rmq1" ) }
644      Send-Rule
645
646      # Rule 26
647      $RuleDesc = "RP00 Hosts to rp00 VCSA"
648      $RuleSrc = $ResourceEsxiHosts
649      $RuleDst = @( $Config.vcsaRp0001Ip )
650      $RulePorts = @( "any" )
651      if ($Strict) { $RulePorts = @( "http", "https", "902", "esx" ) }
652      Send-Rule
653
654      # Rule 27
655      $RuleDesc = "RP00 Hosts to vRealize Log Insight"
656      $RuleSrc = $ResourceEsxiHosts
657      $RuleDst = @( $Config.vrliMg0101Ip )
658      $RulePorts = @( "any" )
659      if ($Strict) { $RulePorts = @( "syslog" ) }
660      Send-Rule
661
662      # Rule 28
663      $RuleDesc = "vRNI Proxy to RP00 NSX Controller"
664      $RuleSrc = @( $Config.vrniMg0101ProxyIp )
665      $RuleDst = @( ($Config.nsxCtrlRp0001Ip + "-" + $Config.nsxCtrlRp0003Ip) )
666      $RulePorts = @( "any" )
667      if ($Strict) { $RulePorts = @( "https" ) }
668      Send-Rule
669
670      # Rule 29
671      $RuleDesc = "vCD cell server to vRealize Log Insight"
672      $RuleSrc = $VcdCellsIp
673      $RuleDst = @( $Config.vrliMg0101Ip )
674      $RulePorts = @( "any" )
675      if ($Strict) { $RulePorts = @( "syslog" ) }
676      Send-Rule
677
678      # Rule 30
679      if ($Config.vropsMg0101Deploy -eq "true") {
680          $RuleDesc = "vROPS tenant app to RabbitMQ"
681          $RuleSrc = @( $Config.vropsMg0101TenantIp )
682          $RuleDst = @( $Config.vcdRabbLbsRp00Ip )
683          $RulePorts = @( "any" )
684          if ($Strict) { $RulePorts = @( "rmq2" ) }
685          Send-Rule
686      }
687  }
688
689  # Switch Logic
690  # When N/S both still false (no switch) print both.
691  # If N -xor S print the true one
692  # If both are true print both.
693
694  # If xor returns false print both (-xor has precedence over -not)
695  if ( -not $North -xor $South ) {
696      $North = $true
697      $South = $true
698  }
699  if ($North) {
700      $RuleCount = 1
701      $Firewall = "North"
702      if (-not $PSObject) { Write-Host -Object ("`nNorth Firewall Rulebase`n") }
703      Get-NorthFirewall
704  }
705  if ($South) {
706      $RuleCount = 1
707      $Firewall = "South"
708      if (-not $PSObject) { Write-Host -Object ("`nSouth Firewall Rulebase`n") }
709      Get-SouthFirewall
710  }
711  

The cmdlet holds a sanitized version of the production code which configures the NSX environment, in particular the two Edge firewall policies. I converted the original into a more readable format and hacked together some code to extract the variables from the configData file and output it either to screen, or as a PowerShell object. That latter is quite handy if you want to pipe the result into another cmdlet to do something even more useful with the data.

There are two firewalls in the ProviderPod topology, and we have cmdlet switches (and some embedded logic) to decide which of them you want to output. There’s also an option to swap the terms used in the descriptions of the flows. You can copy the example out of the code, save and edit it, and then have the cmdlet read it in and replace the descriptions with your own.

Caveat Emptor

This is in no way a PowerShell tutorial. There may be better, more PowerShelly was of doing things, and even I could have made the code more compact and less verbose. But, I thought I might have to come and revisit it every time we changed the policy in ProviderPod. So, following PEP20 I went with the ‘readability counts’ philosophy otherwise I’d have no chance of remembering how it all worked!

Feel free to share this post...

comments powered by Disqus