diff --git a/module/Include.ps1 b/module/Include.ps1 index 97d33e9f..bec7d940 100644 --- a/module/Include.ps1 +++ b/module/Include.ps1 @@ -209,6 +209,7 @@ $FunctionsToExport = @( 'Remove-NsxFirewallSection', 'Get-NsxFirewallRule', 'New-NsxFirewallRule', + 'Set-NsxFirewallRule', 'Remove-NsxFirewallRule', 'Get-NsxLoadBalancer', 'Set-NsxLoadBalancer', diff --git a/module/PowerNSX.psm1 b/module/PowerNSX.psm1 index c4eb8e7a..d0419339 100644 --- a/module/PowerNSX.psm1 +++ b/module/PowerNSX.psm1 @@ -27865,6 +27865,106 @@ function New-NsxFirewallRule { end {} } +function Set-NsxFirewallRule { + + <# + .SYNOPSIS + Set configuration for a NSX Distributed Firewall Rule. + + .DESCRIPTION + An NSX Distributed Firewall Rule defines a typical 5 tuple rule and is + enforced on each hypervisor at the point where the VMs NIC connects to the + portgroup or logical switch. + + This cmdlet accepts a firewall rule object returned from Get-NsxFirewallRule + and set configuration (disabled, name, action...) + + .EXAMPLE + Get-NsxFirewallRule -Ruleid 1007 | Set-NsxFirewallRule -disabled:$true + + Disabled the RuleId 1007 + + .EXAMPLE + Get-NsxFirewallRule -Ruleid 1007 | Set-NsxFirewallRule -logged:$true + + Enable logging on the RuleId 1007 + + .EXAMPLE + Get-NsxFirewallRule -Ruleid 1007 | Set-NsxFirewallRule -name "My Distributed Firewall Rule" + + Set/Update the description of the RuleId 1007 + + .EXAMPLE + Get-NsxFirewallRule -Ruleid 1007 | Set-NsxFirewallRule -action deny + + Change action to deny to RuleId 1007 + #> + + param ( + + [Parameter (Mandatory=$true,ValueFromPipeline=$true)] + # DFW rule as returned by Get-NsxFirewallRule / New-NsxFirewallRule + [ValidateScript({ ValidateFirewallRule $_ })] + [System.Xml.XmlElement]$FirewallRule, + [Parameter (Mandatory=$false)] + [boolean]$disabled, + [Parameter (Mandatory=$false)] + [boolean]$logged, + [Parameter (Mandatory=$false)] + [ValidateNotNullOrEmpty()] + [string]$name, + [Parameter (Mandatory=$false)] + [ValidateSet("Allow","Deny", "Reject")] + [string]$action, + [Parameter (Mandatory=$false)] + #PowerNSX Connection object. + [ValidateNotNullOrEmpty()] + [PSCustomObject]$Connection=$defaultNSXConnection + ) + + begin {} + + process { + + $sectionId = $FirewallRule.ParentNode.Id + $RuleId = $FirewallRule.id + $generationNumber = $FirewallRule.ParentNode.generationnumber + + #Clone the xml so we dont modify source... + $_FirewallRule = $FirewallRule.CloneNode($true) + + if ( $PsBoundParameters.ContainsKey('disabled') ) { + $_FirewallRule.disabled = $disabled.ToString().ToLower() + } + + if ( $PsBoundParameters.ContainsKey('logged') ) { + $_FirewallRule.logged = $logged.ToString().ToLower() + } + + if ( $PsBoundParameters.ContainsKey('name') ) { + $_FirewallRule.name = $name + } + + if ( $PsBoundParameters.ContainsKey('action') ) { + $_FirewallRule.action = $action + } + + $uri = "/api/4.0/firewall/globalroot-0/config/layer3sections/$sectionId/rules/$Ruleid" + #Need the IfMatch header to specify the current section generation id + $IfMatchHeader = @{"If-Match"=$generationNumber} + try { + $response = Invoke-NsxWebRequest -method put -Uri $uri -body $_FirewallRule.OuterXml -extraheader $IfMatchHeader -connection $connection + [xml]$ruleElem = $response.Content + Get-NsxFirewallRule -RuleId $ruleElem.rule.id + } + catch { + throw "Failed to modify the specified rule. $_" + } + } + + end {} +} + function Remove-NsxFirewallRule { <# diff --git a/tests/integration/05.Dfw.Tests.ps1 b/tests/integration/05.Dfw.Tests.ps1 index f86333e0..107dc1e8 100644 --- a/tests/integration/05.Dfw.Tests.ps1 +++ b/tests/integration/05.Dfw.Tests.ps1 @@ -20,7 +20,7 @@ Describe "DFW" { $script:DefaultNsxConnection = Connect-NsxServer -vCenterServer $PNSXTestVC -NsxServerHint $PNSXTestNSX -Credential $PNSXTestDefViCred -ViWarningAction "Ignore" $script:cl = get-cluster | select -first 1 write-warning "Using cluster $cl for edge appliance deployment" - $script:ds = $cl | get-datastore | select -first 1 + $script:ds = $cl | get-datastore | select -first 1 write-warning "Using datastore $ds for edge appliance deployment" $script:dc = Get-Datacenter | select -first 1 write-warning "Using Datacenter $dc for object identifier" @@ -1938,6 +1938,21 @@ Describe "DFW" { {$section | New-NsxFirewallRule -Name "pester_dfw_bottom" -action allow -position bottom } | should throw } + it "Can modified an l3 rule" { + $rule = $l3sec | New-NsxFirewallRule -Name "pester_dfw_rule1" -action deny -EnableLogging + $rule | should not be $null + $rule.name | should be "pester_dfw_rule1" + $rule.action | should be deny + $rule.disabled | should be "false" + $rule.logged | should be "true" + $rule = Get-NsxFirewallSection -Name $l3sectionname | Get-NsxFirewallRule -Name "pester_dfw_rule1" | Set-NsxFirewallRule -name "modified_pester_dfw_rule1" -action allow -disabled:$true -logged:$false + $rule | should not be $null + $rule.name | should be "modified_pester_dfw_rule1" + $rule.action | should be allow + $rule.disabled | should be "true" + $rule.logged | should be "false" + } + BeforeEach { #create new sections for each test.