sanderkl/PSMeraki

Update-MrkNetworkMXL3FwRule removes existing rules and does not place added rule to top of the list

Closed this issue · 1 comments

Expected behaviour:

  • Retrieves all Meraki L3 Firewall for a given Meraki network/ssid.
  • Adds the newly provided rule to the top of the list.

Problem noticed:

  • After using the function (action=add), the new rule was added and all other rules were deleted.
  1. Found that the existing rules are not retrieved (and re-added accordingly) unless the following code is changed:

from:

$ruleset = @()
    if (-not $reset){
        $ruleSource = Get-MrkNetworkMXL3FwRule -networkId $networkId
        #the non-default rules are in the array above the default
        $ruleset = $ruleSource[0..$(($ruleSource.Count) -2)]
    }

to:

$ruleset = @()
    if (-not $reset){
        $ruleSource = (Get-MrkNetworkMXL3FwRule -networkId $networkId).rules
        #the non-default rules are in the array above the default
        $ruleset = $ruleSource[0..$(($ruleSource.Count) -2)]
    }
  1. After fixing the above, found that the new rule (when action=add) is not added to the top of the list unless the following code is changed:

from:

#populate the to-be ruleset first with the existing rules (will be none in case of reset)
    $applyRules = @()
    ForEach ($rule in $ruleset){

        #if the action is delete and either the current rule comment matches the given comment, or the rule specifications protocol/destPort/destCidr are equal keep the entry in the ruleset.
        if ($action -eq 'remove' -and `
          (($rule.protocol -eq $protocol -and `
            $rule.destPort -eq $destPort -and `
            $rule.destCidr -eq $destCidr) -or `
            ($rule.comment -eq $comment))){
                "No longer adding this rule: $comment";
                continue
            }

        if ($action -eq 'add' -and `
            (($rule.protocol -eq $protocol -and `
              $rule.srcPort -eq $srcPort -and `
              $rule.srcCidr -eq $srcCidr -and `
              $rule.destPort -eq $destPort -and `
              $rule.destCidr -eq $destCidr) -or `
              ($rule.comment -eq $comment))){
                  "Not adding this rule as it is already present: $comment";
                  $rulePresent = $true
              }

        #add this exising rule to the $ruleset object
        $ruleEntry = New-Object -TypeName PSObject -Property @{
            comment  = $rule.comment
            policy   = $rule.policy
            protocol = $rule.protocol
            srcPort  = $rule.srcPort
            srcCidr  = $rule.srcCidr
            destPort = $rule.destPort
            destCidr = $rule.destCidr
        }

        $applyRules += $ruleEntry

    }

    #append the new ruleobject to the applyRules
    if ($action -eq 'add' -and $true -ne $rulePresent){
        $ruleEntry = New-Object -TypeName PSObject -Property @{
            comment  = $comment
            policy   = $policy
            protocol = $protocol
            srcPort  = $srcPort
            srcCidr  = $srcCidr
            destPort = $destPort
            destCidr = $destCidr
        }

        $applyRules += $ruleEntry
    };

to:

#populate the to-be ruleset first with the existing rules (will be none in case of reset)
    $applyRules = @()
    $applyRulesToBe = @()
    ForEach ($rule in $ruleset){

        #if the action is delete and either the current rule comment matches the given comment, or the rule specifications protocol/destPort/destCidr are equal keep the entry in the ruleset.
        if ($action -eq 'remove' -and `
          (($rule.protocol -eq $protocol -and `
            $rule.destPort -eq $destPort -and `
            $rule.destCidr -eq $destCidr) -or `
            ($rule.comment -eq $comment))){
                "No longer adding this rule: $comment";
                continue
            }

        if ($action -eq 'add' -and `
            (($rule.protocol -eq $protocol -and `
              $rule.srcPort -eq $srcPort -and `
              $rule.srcCidr -eq $srcCidr -and `
              $rule.destPort -eq $destPort -and `
              $rule.destCidr -eq $destCidr) -or `
              ($rule.comment -eq $comment))){
                  "Not adding this rule as it is already present: $comment";
                  $rulePresent = $true
              }

        #add this exising rule to the $ruleset object
        $ruleEntry = New-Object -TypeName PSObject -Property @{
            comment  = $rule.comment
            policy   = $rule.policy
            protocol = $rule.protocol
            srcPort  = $rule.srcPort
            srcCidr  = $rule.srcCidr
            destPort = $rule.destPort
            destCidr = $rule.destCidr
        }

        $applyRulesToBe += $ruleEntry

    }

    #append the new ruleobject to the applyRules
    if ($action -eq 'add' -and $true -ne $rulePresent){
        $ruleEntry = New-Object -TypeName PSObject -Property @{
            comment  = $comment
            policy   = $policy
            protocol = $protocol
            srcPort  = $srcPort
            srcCidr  = $srcCidr
            destPort = $destPort
            destCidr = $destCidr
        }

        $applyRules += $ruleEntry
    };
    #append the to-be ruleobjects to the applyRules
    if ($applyRulesToBe) {
        $applyRules += $applyRulesToBe
    }

Good catch, Thanks jmisty!
I'll include your fix in the next version,