New Upstream Release - puppet-module-puppetlabs-firewall

Ready changes

Summary

Merged new upstream version: 5.0.0 (was: 3.4.0).

Resulting package

Built on 2023-06-21T02:45 (took 4m31s)

The resulting binary packages can be installed (if you have the apt repository enabled) by running one of:

apt install -t fresh-releases puppet-module-puppetlabs-firewall

Lintian Result

Diff

diff --git a/.github/workflows/auto_release.yml b/.github/workflows/auto_release.yml
index c25a80d..ca67718 100644
--- a/.github/workflows/auto_release.yml
+++ b/.github/workflows/auto_release.yml
@@ -3,88 +3,8 @@ name: "Auto release"
 on:
   workflow_dispatch:
 
-env:
-  HONEYCOMB_WRITEKEY: 7f3c63a70eecc61d635917de46bea4e6 
-  HONEYCOMB_DATASET: litmus tests
-  CHANGELOG_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-
 jobs:
-  auto_release:
-    name: "Automatic release prep"
-    runs-on: ubuntu-20.04
-
-    steps:
-    - name: "Honeycomb: Start recording"
-      uses: puppetlabs/kvrhdn-gha-buildevents@pdk-templates-v1
-      with:
-        apikey: ${{ env.HONEYCOMB_WRITEKEY }}
-        dataset: ${{ env.HONEYCOMB_DATASET }}
-        job-status: ${{ job.status }}
-
-    - name: "Honeycomb: start first step"
-      run: |
-        echo STEP_ID="auto-release" >> $GITHUB_ENV
-        echo STEP_START=$(date +%s) >> $GITHUB_ENV
-
-    - name: "Checkout Source"
-      if: ${{ github.repository_owner == 'puppetlabs' }}
-      uses: actions/checkout@v2
-      with:
-        fetch-depth: 0
-        persist-credentials: false
-
-    - name: "PDK Release prep"
-      uses: docker://puppet/iac_release:ci
-      with:
-        args: 'release prep --force'
-      env:
-        CHANGELOG_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-
-    - name: "Get Version"
-      if: ${{ github.repository_owner == 'puppetlabs' }}
-      id: gv
-      run: |
-        echo "::set-output name=ver::$(jq --raw-output .version metadata.json)"
-
-    - name: "Check if a release is necessary"
-      if: ${{ github.repository_owner == 'puppetlabs' }}
-      id: check
-      run: |
-        git diff --quiet CHANGELOG.md && echo "::set-output name=release::false" || echo "::set-output name=release::true"
-
-    - name: "Commit changes"
-      if: ${{ github.repository_owner == 'puppetlabs' && steps.check.outputs.release == 'true' }}
-      run: |
-        git config --local user.email "${{ github.repository_owner }}@users.noreply.github.com"
-        git config --local user.name "GitHub Action"
-        git add .
-        git commit -m "Release prep v${{ steps.gv.outputs.ver }}"
-
-    - name: Create Pull Request
-      id: cpr
-      uses: puppetlabs/peter-evans-create-pull-request@v3
-      if: ${{ github.repository_owner == 'puppetlabs' && steps.check.outputs.release == 'true' }}
-      with:
-        token: ${{ secrets.GITHUB_TOKEN }}
-        commit-message: "Release prep v${{ steps.gv.outputs.ver }}"
-        branch: "release-prep"
-        delete-branch: true
-        title: "Release prep v${{ steps.gv.outputs.ver }}"
-        body: |
-          Automated release-prep through [pdk-templates](https://github.com/puppetlabs/pdk-templates/blob/main/moduleroot/.github/workflows/auto_release.yml.erb) from commit ${{ github.sha }}. 
-          Please verify before merging:
-          - [ ] last [nightly](https://github.com/${{ github.repository }}/actions/workflows/nightly.yml) run is green
-          - [ ] [Changelog](https://github.com/${{ github.repository }}/blob/release-prep/CHANGELOG.md) is readable and has no unlabeled pull requests
-          - [ ] Ensure the [changelog](https://github.com/${{ github.repository }}/blob/release-prep/CHANGELOG.md) version and [metadata](https://github.com/${{ github.repository }}/blob/release-prep/metadata.json) version match
-        labels: "maintenance"
-
-    - name: PR outputs
-      if: ${{ github.repository_owner == 'puppetlabs' && steps.check.outputs.release == 'true' }}
-      run: |
-        echo "Pull Request Number - ${{ steps.cpr.outputs.pull-request-number }}"
-        echo "Pull Request URL - ${{ steps.cpr.outputs.pull-request-url }}"
-
-    - name: "Honeycomb: Record finish step"
-      if: ${{ always() }}
-      run: |
-        buildevents step $TRACE_ID $STEP_ID $STEP_START 'Finished auto release workflow'
+  release_prep:
+    name: "Release Prep"
+    uses: "puppetlabs/cat-github-actions/.github/workflows/module_release_prep.yml@main"
+    secrets: "inherit"
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..e6dd8d7
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,21 @@
+name: "ci"
+
+on:
+  pull_request:
+    branches:
+      - "main"
+  workflow_dispatch:
+    
+jobs:
+  Spec:
+    uses: "puppetlabs/cat-github-actions/.github/workflows/module_ci.yml@main"
+    with:
+      runs_on: "ubuntu-20.04"
+    secrets: "inherit"
+
+  Acceptance:
+    needs: Spec
+    uses: "puppetlabs/cat-github-actions/.github/workflows/module_acceptance.yml@main"
+    with:
+      runs_on: "ubuntu-20.04"
+    secrets: "inherit"
diff --git a/.github/workflows/labeller.yml b/.github/workflows/labeller.yml
new file mode 100644
index 0000000..5434d3f
--- /dev/null
+++ b/.github/workflows/labeller.yml
@@ -0,0 +1,22 @@
+name: community-labeller
+
+on:
+  issues:
+    types:
+      - opened
+  pull_request_target:
+    types:
+      - opened
+
+jobs:
+  label:
+    runs-on: ubuntu-latest
+    steps:
+
+      - uses: puppetlabs/community-labeller@v0
+        name: Label issues or pull requests
+        with:
+          label_name: community
+          label_color: '5319e7'
+          org_membership: puppetlabs
+          token: ${{ secrets.IAC_COMMUNITY_LABELER }}
diff --git a/.github/workflows/mend.yml b/.github/workflows/mend.yml
new file mode 100644
index 0000000..b4100a5
--- /dev/null
+++ b/.github/workflows/mend.yml
@@ -0,0 +1,15 @@
+name: "mend"
+
+on:
+  pull_request:
+    branches:
+      - "main"
+  schedule:
+    - cron: "0 0 * * *"
+  workflow_dispatch:
+
+jobs:
+
+  mend:
+    uses: "puppetlabs/cat-github-actions/.github/workflows/mend_ruby.yml@main"
+    secrets: "inherit"
diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml
index e85b4a9..8ea551f 100644
--- a/.github/workflows/nightly.yml
+++ b/.github/workflows/nightly.yml
@@ -2,208 +2,20 @@ name: "nightly"
 
 on:
   schedule:
-    - cron: '0 0 * * *'
-
-env:
-  HONEYCOMB_WRITEKEY: 7f3c63a70eecc61d635917de46bea4e6
-  HONEYCOMB_DATASET: litmus tests
+    - cron: "0 0 * * *"
+  workflow_dispatch:
 
 jobs:
-  setup_matrix:
-    name: "Setup Test Matrix"
-    runs-on: ubuntu-20.04
-    outputs:
-      matrix: ${{ steps.get-matrix.outputs.matrix }}
-
-    steps:
-    - name: "Honeycomb: Start recording"
-      uses: puppetlabs/kvrhdn-gha-buildevents@pdk-templates-v1
-      with:
-        apikey: ${{ env.HONEYCOMB_WRITEKEY }}
-        dataset: ${{ env.HONEYCOMB_DATASET }}
-        job-status: ${{ job.status }}
-
-    - name: "Honeycomb: Start first step"
-      run: |
-        echo STEP_ID=setup-environment >> $GITHUB_ENV
-        echo STEP_START=$(date +%s) >> $GITHUB_ENV
-
-    - name: Checkout Source
-      uses: actions/checkout@v2
-      if: ${{ github.repository_owner == 'puppetlabs' }}
-
-    - name: Activate Ruby 2.7
-      uses: ruby/setup-ruby@v1
-      if: ${{ github.repository_owner == 'puppetlabs' }}
-      with:
-        ruby-version: "2.7"
-        bundler-cache: true
-
-    - name: Print bundle environment
-      if: ${{ github.repository_owner == 'puppetlabs' }}
-      run: |
-        echo ::group::bundler environment
-        buildevents cmd $TRACE_ID $STEP_ID 'bundle env' -- bundle env
-        echo ::endgroup::
-
-    - name: "Honeycomb: Record Setup Environment time"
-      if: ${{ github.repository_owner == 'puppetlabs' }}
-      run: |
-        buildevents step $TRACE_ID $STEP_ID $STEP_START 'Setup Environment'
-        echo STEP_ID=Setup-Acceptance-Test-Matrix >> $GITHUB_ENV
-        echo STEP_START=$(date +%s) >> $GITHUB_ENV
-
-    - name: Setup Acceptance Test Matrix
-      id: get-matrix
-      if: ${{ github.repository_owner == 'puppetlabs' }}
-      run: |
-        if [ '${{ github.repository_owner }}' == 'puppetlabs' ]; then
-          buildevents cmd $TRACE_ID $STEP_ID matrix_from_metadata -- bundle exec matrix_from_metadata_v2
-        else
-          echo  "::set-output name=matrix::{}"
-        fi
-
-    - name: "Honeycomb: Record Setup Test Matrix time"
-      if: ${{ always() }}
-      run: |
-        buildevents step $TRACE_ID $STEP_ID $STEP_START 'Setup Test Matrix'
+  Spec:
+    uses: "puppetlabs/cat-github-actions/.github/workflows/module_ci.yml@main"
+    with:
+      runs_on: "ubuntu-20.04"
+    secrets: "inherit"
 
   Acceptance:
-    name: "${{matrix.platforms.label}}, ${{matrix.collection}}"
-    needs:
-      - setup_matrix
-
-    runs-on: ubuntu-20.04
-    strategy:
-      fail-fast: false
-      matrix: ${{fromJson(needs.setup_matrix.outputs.matrix)}}
-
-    env:
-      BUILDEVENT_FILE: '../buildevents.txt'
-
-    steps:
-    - run: |
-        echo 'platform=${{ matrix.platforms.image }}' >> $BUILDEVENT_FILE
-        echo 'collection=${{ matrix.collection }}' >> $BUILDEVENT_FILE
-        echo 'label=${{ matrix.platforms.label }}' >> $BUILDEVENT_FILE
-
-
-    - name: "Honeycomb: Start recording"
-      uses: puppetlabs/kvrhdn-gha-buildevents@pdk-templates-v1
-      with:
-        apikey: ${{ env.HONEYCOMB_WRITEKEY }}
-        dataset: ${{ env.HONEYCOMB_DATASET }}
-        job-status: ${{ job.status }}
-        matrix-key: ${{ matrix.platforms.label }}-${{ matrix.collection }}
-
-    - name: "Honeycomb: start first step"
-      run: |
-        echo STEP_ID=${{ matrix.platforms.image }}-${{ matrix.collection }}-1 >> $GITHUB_ENV
-        echo STEP_START=$(date +%s) >> $GITHUB_ENV
-
-    - name: Checkout Source
-      uses: actions/checkout@v2
-
-    - name: Activate Ruby 2.7
-      uses: ruby/setup-ruby@v1
-      with:
-        ruby-version: "2.7"
-        bundler-cache: true
-
-    - name: Print bundle environment
-      run: |
-        echo ::group::bundler environment
-        buildevents cmd $TRACE_ID $STEP_ID 'bundle env' -- bundle env
-        echo ::endgroup::
-
-    - name: "Honeycomb: Record Setup Environment time"
-      if: ${{ always() }}
-      run: |
-        buildevents step $TRACE_ID $STEP_ID $STEP_START 'Setup Environment'
-        echo STEP_ID=${{ matrix.platforms.image }}-${{ matrix.collection }}-2 >> $GITHUB_ENV
-        echo STEP_START=$(date +%s) >> $GITHUB_ENV
-
-    - name: Provision test environment
-      run: |
-        if [[ "${{matrix.platforms.provider}}" == "provision::docker" ]]; then
-          DOCKER_RUN_OPTS="docker_run_opts: {'--volume': '/lib/modules/$(uname -r):/lib/modules/$(uname -r)'}"
-        else
-          DOCKER_RUN_OPTS=''
-        fi
-        buildevents cmd $TRACE_ID $STEP_ID 'rake litmus:provision ${{ matrix.platforms.image }}' -- bundle exec rake "litmus:provision[${{matrix.platforms.provider}},${{ matrix.platforms.image }},$DOCKER_RUN_OPTS]"
-        echo ::group::=== REQUEST ===
-        cat request.json || true
-        echo
-        echo ::endgroup::
-        echo ::group::=== INVENTORY ===
-        if [ -f 'spec/fixtures/litmus_inventory.yaml' ];
-        then
-          FILE='spec/fixtures/litmus_inventory.yaml'
-        elif [ -f 'inventory.yaml' ];
-        then
-          FILE='inventory.yaml'
-        fi
-        sed -e 's/password: .*/password: "[redacted]"/' < $FILE || true
-        echo ::endgroup::
-
-    - name: Install agent
-      run: |
-        buildevents cmd $TRACE_ID $STEP_ID 'rake litmus:install_agent ${{ matrix.collection }}' -- bundle exec rake 'litmus:install_agent[${{ matrix.collection }}]'
-
-    - name: Install module
-      run: |
-        buildevents cmd $TRACE_ID $STEP_ID 'rake litmus:install_module' -- bundle exec rake 'litmus:install_module'
-
-    - name: "Honeycomb: Record deployment times"
-      if: ${{ always() }}
-      run: |
-        echo ::group::honeycomb step
-        buildevents step $TRACE_ID $STEP_ID $STEP_START 'Deploy test system'
-        echo STEP_ID=${{ matrix.platforms.image }}-${{ matrix.collection }}-3 >> $GITHUB_ENV
-        echo STEP_START=$(date +%s) >> $GITHUB_ENV
-        echo ::endgroup::
-
-    - name: Run acceptance tests
-      run: |
-        buildevents cmd $TRACE_ID $STEP_ID 'rake litmus:acceptance:parallel' -- bundle exec rake 'litmus:acceptance:parallel'
-
-    - name: "Honeycomb: Record acceptance testing times"
-      if: ${{ always() }}
-      run: |
-        buildevents step $TRACE_ID $STEP_ID $STEP_START 'Run acceptance tests'
-        echo STEP_ID=${{ matrix.platforms.image }}-${{ matrix.collection }}-4 >> $GITHUB_ENV
-        echo STEP_START=$(date +%s) >> $GITHUB_ENV
-
-    - name: Remove test environment
-      if: ${{ always() }}
-      continue-on-error: true
-      run: |
-        if [[ -f inventory.yaml || -f spec/fixtures/litmus_inventory.yaml ]]; then
-          buildevents cmd $TRACE_ID $STEP_ID 'rake litmus:tear_down' -- bundle exec rake 'litmus:tear_down'
-          echo ::group::=== REQUEST ===
-          cat request.json || true
-          echo
-          echo ::endgroup::
-        fi
-
-    - name: "Honeycomb: Record removal times"
-      if: ${{ always() }}
-      run: |
-        buildevents step $TRACE_ID $STEP_ID $STEP_START 'Remove test environment'
+    needs: Spec
+    uses: "puppetlabs/cat-github-actions/.github/workflows/module_acceptance.yml@main"
+    with:
+      runs_on: "ubuntu-20.04"
+    secrets: "inherit"
 
-  slack-workflow-status:
-    if: always()
-    name: Post Workflow Status To Slack
-    needs:
-      - Acceptance
-    runs-on: ubuntu-20.04
-    steps:
-      - name: Slack Workflow Notification
-        uses: puppetlabs/Gamesight-slack-workflow-status@pdk-templates-v1
-        with:
-          # Required Input
-          repo_token: ${{ secrets.GITHUB_TOKEN }}
-          slack_webhook_url: ${{ secrets.SLACK_WEBHOOK }}
-          # Optional Input
-          channel: '#team-ia-bots'
-          name: 'GABot'
diff --git a/.github/workflows/pr_test.yml b/.github/workflows/pr_test.yml
deleted file mode 100644
index e2ba9f4..0000000
--- a/.github/workflows/pr_test.yml
+++ /dev/null
@@ -1,189 +0,0 @@
-name: "PR Testing"
-
-on: [pull_request]
-
-env:
-  HONEYCOMB_WRITEKEY: 7f3c63a70eecc61d635917de46bea4e6
-  HONEYCOMB_DATASET: litmus tests
-
-jobs:
-  setup_matrix:
-    name: "Setup Test Matrix"
-    runs-on: ubuntu-20.04
-    outputs:
-      matrix: ${{ steps.get-matrix.outputs.matrix }}
-
-    steps:
-    - name: "Honeycomb: Start recording"
-      uses: puppetlabs/kvrhdn-gha-buildevents@pdk-templates-v1
-      with:
-        apikey: ${{ env.HONEYCOMB_WRITEKEY }}
-        dataset: ${{ env.HONEYCOMB_DATASET }}
-        job-status: ${{ job.status }}
-
-    - name: "Honeycomb: Start first step"
-      run: |
-        echo STEP_ID=setup-environment >> $GITHUB_ENV
-        echo STEP_START=$(date +%s) >> $GITHUB_ENV
-
-    - name: Checkout Source
-      uses: actions/checkout@v2
-      if: ${{ github.repository_owner == 'puppetlabs' }}
-
-    - name: Activate Ruby 2.7
-      uses: ruby/setup-ruby@v1
-      if: ${{ github.repository_owner == 'puppetlabs' }}
-      with:
-        ruby-version: "2.7"
-        bundler-cache: true
-
-    - name: Print bundle environment
-      if: ${{ github.repository_owner == 'puppetlabs' }}
-      run: |
-        echo ::group::bundler environment
-        buildevents cmd $TRACE_ID $STEP_ID 'bundle env' -- bundle env
-        echo ::endgroup::
-
-    - name: "Honeycomb: Record Setup Environment time"
-      if: ${{ github.repository_owner == 'puppetlabs' }}
-      run: |
-        buildevents step $TRACE_ID $STEP_ID $STEP_START 'Setup Environment'
-        echo STEP_ID=Setup-Acceptance-Test-Matrix >> $GITHUB_ENV
-        echo STEP_START=$(date +%s) >> $GITHUB_ENV
-
-    - name: Setup Acceptance Test Matrix
-      id: get-matrix
-      run: |
-        if [ '${{ github.repository_owner }}' == 'puppetlabs' ]; then
-          buildevents cmd $TRACE_ID $STEP_ID matrix_from_metadata -- bundle exec matrix_from_metadata_v2
-        else
-          echo  "::set-output name=matrix::{}"
-        fi
-
-    - name: "Honeycomb: Record Setup Test Matrix time"
-      if: ${{ always() }}
-      run: |
-        buildevents step $TRACE_ID $STEP_ID $STEP_START 'Setup Test Matrix'
-
-  Acceptance:
-    name: "${{matrix.platforms.label}}, ${{matrix.collection}}"
-    needs:
-      - setup_matrix
-    if: ${{ needs.setup_matrix.outputs.matrix != '{}' }}
-
-    runs-on: ubuntu-20.04
-    strategy:
-      fail-fast: false
-      matrix: ${{fromJson(needs.setup_matrix.outputs.matrix)}}
-
-    env:
-      BUILDEVENT_FILE: '../buildevents.txt'
-
-    steps:
-    - run: |
-        echo 'platform=${{ matrix.platforms.image }}' >> $BUILDEVENT_FILE
-        echo 'collection=${{ matrix.collection }}' >> $BUILDEVENT_FILE
-        echo 'label=${{ matrix.platforms.label }}' >> $BUILDEVENT_FILE
-
-    - name: "Honeycomb: Start recording"
-      uses: puppetlabs/kvrhdn-gha-buildevents@pdk-templates-v1
-      with:
-        apikey: ${{ env.HONEYCOMB_WRITEKEY }}
-        dataset: ${{ env.HONEYCOMB_DATASET }}
-        job-status: ${{ job.status }}
-        matrix-key: ${{ matrix.platforms.label }}-${{ matrix.collection }}
-
-    - name: "Honeycomb: start first step"
-      run: |
-        echo STEP_ID=${{ matrix.platforms.image }}-${{ matrix.collection }}-1 >> $GITHUB_ENV
-        echo STEP_START=$(date +%s) >> $GITHUB_ENV
-
-    - name: Checkout Source
-      uses: actions/checkout@v2
-
-    - name: Activate Ruby 2.7
-      uses: ruby/setup-ruby@v1
-      with:
-        ruby-version: "2.7"
-        bundler-cache: true
-
-    - name: Print bundle environment
-      run: |
-        echo ::group::bundler environment
-        buildevents cmd $TRACE_ID $STEP_ID 'bundle env' -- bundle env
-        echo ::endgroup::
-
-    - name: "Honeycomb: Record Setup Environment time"
-      if: ${{ always() }}
-      run: |
-        buildevents step $TRACE_ID $STEP_ID $STEP_START 'Setup Environment'
-        echo STEP_ID=${{ matrix.platforms.image }}-${{ matrix.collection }}-2 >> $GITHUB_ENV
-        echo STEP_START=$(date +%s) >> $GITHUB_ENV
-
-    - name: Provision test environment
-      run: |
-        if [[ "${{matrix.platforms.provider}}" == "provision::docker" ]]; then
-          DOCKER_RUN_OPTS="docker_run_opts: {'--volume': '/lib/modules/$(uname -r):/lib/modules/$(uname -r)'}"
-        else
-          DOCKER_RUN_OPTS=''
-        fi
-        buildevents cmd $TRACE_ID $STEP_ID 'rake litmus:provision ${{ matrix.platforms.image }}' -- bundle exec rake "litmus:provision[${{matrix.platforms.provider}},${{ matrix.platforms.image }},$DOCKER_RUN_OPTS]"
-        echo ::group::=== REQUEST ===
-        cat request.json || true
-        echo
-        echo ::endgroup::
-        echo ::group::=== INVENTORY ===
-        if [ -f 'spec/fixtures/litmus_inventory.yaml' ];
-        then
-          FILE='spec/fixtures/litmus_inventory.yaml'
-        elif [ -f 'inventory.yaml' ];
-        then
-          FILE='inventory.yaml'
-        fi
-        sed -e 's/password: .*/password: "[redacted]"/' < $FILE || true
-        echo ::endgroup::
-
-    - name: Install agent
-      run: |
-        buildevents cmd $TRACE_ID $STEP_ID 'rake litmus:install_agent ${{ matrix.collection }}' -- bundle exec rake 'litmus:install_agent[${{ matrix.collection }}]'
-
-    - name: Install module
-      run: |
-        buildevents cmd $TRACE_ID $STEP_ID 'rake litmus:install_module' -- bundle exec rake 'litmus:install_module'
-
-    - name: "Honeycomb: Record deployment times"
-      if: ${{ always() }}
-      run: |
-        echo ::group::honeycomb step
-        buildevents step $TRACE_ID $STEP_ID $STEP_START 'Deploy test system'
-        echo STEP_ID=${{ matrix.platforms.image }}-${{ matrix.collection }}-3 >> $GITHUB_ENV
-        echo STEP_START=$(date +%s) >> $GITHUB_ENV
-        echo ::endgroup::
-
-    - name: Run acceptance tests
-      run: |
-        buildevents cmd $TRACE_ID $STEP_ID 'rake litmus:acceptance:parallel' -- bundle exec rake 'litmus:acceptance:parallel'
-
-    - name: "Honeycomb: Record acceptance testing times"
-      if: ${{ always() }}
-      run: |
-        buildevents step $TRACE_ID $STEP_ID $STEP_START 'Run acceptance tests'
-        echo STEP_ID=${{ matrix.platforms.image }}-${{ matrix.collection }}-4 >> $GITHUB_ENV
-        echo STEP_START=$(date +%s) >> $GITHUB_ENV
-
-    - name: Remove test environment
-      if: ${{ always() }}
-      continue-on-error: true
-      run: |
-        if [[ -f inventory.yaml || -f spec/fixtures/litmus_inventory.yaml ]]; then
-          buildevents cmd $TRACE_ID $STEP_ID 'rake litmus:tear_down' -- bundle exec rake 'litmus:tear_down'
-          echo ::group::=== REQUEST ===
-          cat request.json || true
-          echo
-          echo ::endgroup::
-        fi
-
-    - name: "Honeycomb: Record removal times"
-      if: ${{ always() }}
-      run: |
-        buildevents step $TRACE_ID $STEP_ID $STEP_START 'Remove test environment'
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 1509f6e..82caec7 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -4,44 +4,7 @@ on:
   workflow_dispatch:
   
 jobs:
-  create-github-release:
-    name: Deploy GitHub Release
-    runs-on: ubuntu-20.04
-    steps:
-      - name: Checkout code
-        uses: actions/checkout@v2
-        with:
-          ref: ${{ github.ref }}
-          clean: true
-          fetch-depth: 0
-      - name: Get Version
-        id: gv
-        run: |
-          echo "::set-output name=ver::$(jq --raw-output .version metadata.json)"
-      - name: Create Release
-        uses: actions/create-release@v1
-        id: create_release
-        env:
-          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-        with:
-          tag_name: "v${{ steps.gv.outputs.ver }}"
-          draft: false
-          prerelease: false
-
-  deploy-forge:
-    name: Deploy to Forge
-    runs-on: ubuntu-20.04
-    steps:
-      - name: Checkout code
-        uses: actions/checkout@v2
-        with:
-          ref: ${{ github.ref }}
-          clean: true
-      - name: "PDK Build"
-        uses: docker://puppet/pdk:nightly
-        with:
-          args: 'build'
-      - name: "Push to Forge"
-        uses: docker://puppet/pdk:nightly
-        with:
-          args: 'release publish --forge-token ${{ secrets.FORGE_API_KEY }} --force'
+  release:
+    name: "Release"
+    uses: "puppetlabs/cat-github-actions/.github/workflows/module_release.yml@main"
+    secrets: "inherit"
diff --git a/.github/workflows/spec.yml b/.github/workflows/spec.yml
deleted file mode 100644
index 7da4f3d..0000000
--- a/.github/workflows/spec.yml
+++ /dev/null
@@ -1,130 +0,0 @@
-name: "Spec Tests"
-
-on:
-  schedule:
-    - cron: '0 0 * * *'
-  workflow_dispatch:
-  pull_request:
-
-env:
-  HONEYCOMB_WRITEKEY: 7f3c63a70eecc61d635917de46bea4e6
-  HONEYCOMB_DATASET: litmus tests
-
-jobs:
-  setup_matrix:
-    name: "Setup Test Matrix"
-    runs-on: ubuntu-20.04
-    outputs:
-      spec_matrix: ${{ steps.get-matrix.outputs.spec_matrix }}
-
-    steps:
-      - name: "Honeycomb: Start recording"
-        uses: puppetlabs/kvrhdn-gha-buildevents@pdk-templates-v1
-        with:
-          apikey: ${{ env.HONEYCOMB_WRITEKEY }}
-          dataset: ${{ env.HONEYCOMB_DATASET }}
-          job-status: ${{ job.status }}
-
-      - name: "Honeycomb: Start first step"
-        run: |
-          echo STEP_ID=setup-environment >> $GITHUB_ENV
-          echo STEP_START=$(date +%s) >> $GITHUB_ENV
-
-      - name: Checkout Source
-        uses: actions/checkout@v2
-        if: ${{ github.repository_owner == 'puppetlabs' }}
-
-      - name: Activate Ruby 2.7
-        uses: ruby/setup-ruby@v1
-        if: ${{ github.repository_owner == 'puppetlabs' }}
-        with:
-          ruby-version: "2.7"
-          bundler-cache: true
-
-      - name: Print bundle environment
-        if: ${{ github.repository_owner == 'puppetlabs' }}
-        run: |
-          echo ::group::bundler environment
-          buildevents cmd $TRACE_ID $STEP_ID 'bundle env' -- bundle env
-          echo ::endgroup::
-
-      - name: "Honeycomb: Record Setup Environment time"
-        if: ${{ github.repository_owner == 'puppetlabs' }}
-        run: |
-          buildevents step $TRACE_ID $STEP_ID $STEP_START 'Setup Environment'
-          echo STEP_ID=Setup-Acceptance-Test-Matrix >> $GITHUB_ENV
-          echo STEP_START=$(date +%s) >> $GITHUB_ENV
-
-      - name: Run Static & Syntax Tests
-        if: ${{ github.repository_owner == 'puppetlabs' }}
-        run: |
-          buildevents cmd $TRACE_ID $STEP_ID 'static_syntax_checks' -- bundle exec rake syntax lint metadata_lint check:symlinks check:git_ignore check:dot_underscore check:test_file rubocop
-
-      - name: Setup Spec Test Matrix
-        id: get-matrix
-        run: |
-          if [ '${{ github.repository_owner }}' == 'puppetlabs' ]; then
-            buildevents cmd $TRACE_ID $STEP_ID matrix_from_metadata -- bundle exec matrix_from_metadata_v2
-          else
-            echo  "::set-output name=spec_matrix::{}"
-          fi
-
-      - name: "Honeycomb: Record Setup Test Matrix time"
-        if: ${{ always() }}
-        run: |
-          buildevents step $TRACE_ID $STEP_ID $STEP_START 'Setup Test Matrix'
-
-  Spec:
-    name: "Spec Tests (Puppet: ${{matrix.puppet_version}}, Ruby Ver: ${{matrix.ruby_version}})"
-    needs:
-      - setup_matrix
-    if: ${{ needs.setup_matrix.outputs.spec_matrix != '{}' }}
-
-    runs-on: ubuntu-20.04
-    strategy:
-      fail-fast: false
-      matrix: ${{fromJson(needs.setup_matrix.outputs.spec_matrix)}}
-
-    env:
-      BUILDEVENT_FILE: '../buildevents.txt'
-      PUPPET_GEM_VERSION: ${{ matrix.puppet_version }}
-      FACTER_GEM_VERSION: 'https://github.com/puppetlabs/facter#main'
-
-    steps:
-      - run: |
-          echo "SANITIZED_PUPPET_VERSION=$(echo '${{ matrix.puppet_version }}' | sed 's/~> //g')" >> $GITHUB_ENV
-
-      - run: |
-          echo 'puppet_version=${{ env.SANITIZED_PUPPET_VERSION }}' >> $BUILDEVENT_FILE
-
-      - name: "Honeycomb: Start first step"
-        run: |
-          echo "STEP_ID=${{ env.SANITIZED_PUPPET_VERSION }}-spec" >> $GITHUB_ENV
-          echo STEP_START=$(date +%s) >> $GITHUB_ENV
-
-      - name: "Honeycomb: Start recording"
-        uses: puppetlabs/kvrhdn-gha-buildevents@pdk-templates-v1
-        with:
-          apikey: ${{ env.HONEYCOMB_WRITEKEY }}
-          dataset: ${{ env.HONEYCOMB_DATASET }}
-          job-status: ${{ job.status }}
-          matrix-key: ${{ env.SANITIZED_PUPPET_VERSION }}
-
-      - name: Checkout Source
-        uses: actions/checkout@v2
-
-      - name: "Activate Ruby ${{ matrix.ruby_version }}"
-        uses: ruby/setup-ruby@v1
-        with:
-          ruby-version: ${{matrix.ruby_version}}
-          bundler-cache: true
-
-      - name: Print bundle environment
-        run: |
-          echo ::group::bundler environment
-          buildevents cmd $TRACE_ID $STEP_ID 'bundle env' -- bundle env
-          echo ::endgroup::
-
-      - name: Run parallel_spec tests
-        run: |
-          buildevents cmd $TRACE_ID $STEP_ID 'rake parallel_spec Puppet ${{ matrix.puppet_version }}, Ruby ${{ matrix.ruby_version }}' -- bundle exec rake parallel_spec
diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml
new file mode 100644
index 0000000..266218c
--- /dev/null
+++ b/.rubocop_todo.yml
@@ -0,0 +1,510 @@
+# This configuration was generated by
+# `rubocop --auto-gen-config`
+# on 2023-03-29 09:22:12 UTC using RuboCop version 1.48.1.
+# The point is for the user to remove these configuration records
+# one by one as the offenses are removed from the code base.
+# Note that changes in the inspected code, or installation of new
+# versions of RuboCop, may require this file to be generated again.
+
+# Offense count: 13
+# This cop supports safe autocorrection (--autocorrect).
+Layout/ClosingHeredocIndentation:
+  Exclude:
+    - 'spec/acceptance/firewall_attributes_exceptions_spec.rb'
+    - 'spec/acceptance/firewall_attributes_ipv6_exceptions_spec.rb'
+    - 'spec/acceptance/firewall_duplicate_comment_spec.rb'
+    - 'spec/spec_helper_acceptance_local.rb'
+
+# Offense count: 26
+# This cop supports safe autocorrection (--autocorrect).
+Layout/EmptyLineAfterGuardClause:
+  Exclude:
+    - 'lib/puppet/provider/firewall/ip6tables.rb'
+    - 'lib/puppet/provider/firewall/iptables.rb'
+    - 'lib/puppet/provider/firewallchain/iptables_chain.rb'
+    - 'lib/puppet/type/firewall.rb'
+    - 'lib/puppet/util/firewall.rb'
+    - 'lib/puppet/util/ipcidr.rb'
+
+# Offense count: 3
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: AllowMultipleStyles, EnforcedHashRocketStyle, EnforcedColonStyle, EnforcedLastArgumentHashStyle.
+# SupportedHashRocketStyles: key, separator, table
+# SupportedColonStyles: key, separator, table
+# SupportedLastArgumentHashStyles: always_inspect, always_ignore, ignore_implicit, ignore_explicit
+Layout/HashAlignment:
+  Exclude:
+    - 'spec/unit/puppet/type/firewall_spec.rb'
+
+# Offense count: 1
+# This cop supports safe autocorrection (--autocorrect).
+Layout/HeredocIndentation:
+  Exclude:
+    - 'spec/unit/puppet/type/firewallchain_spec.rb'
+
+# Offense count: 3
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle.
+# SupportedStyles: leading, trailing
+Layout/LineContinuationLeadingSpace:
+  Exclude:
+    - 'lib/puppet/type/firewallchain.rb'
+
+# Offense count: 7
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle, IndentationWidth.
+# SupportedStyles: aligned, indented
+Layout/LineEndStringConcatenationIndentation:
+  Exclude:
+    - 'lib/puppet/provider/firewall/iptables.rb'
+    - 'lib/puppet/type/firewall.rb'
+    - 'lib/puppet/type/firewallchain.rb'
+    - 'spec/unit/puppet/type/firewall_spec.rb'
+
+# Offense count: 59
+# This cop supports unsafe autocorrection (--autocorrect-all).
+Lint/BooleanSymbol:
+  Exclude:
+    - 'lib/puppet/provider/firewall/ip6tables.rb'
+    - 'lib/puppet/provider/firewall/iptables.rb'
+    - 'lib/puppet/type/firewall.rb'
+    - 'lib/puppet/type/firewallchain.rb'
+
+# Offense count: 4
+# Configuration parameters: AllowedMethods.
+# AllowedMethods: enums
+Lint/ConstantDefinitionInBlock:
+  Exclude:
+    - 'lib/puppet/provider/firewallchain/iptables_chain.rb'
+
+# Offense count: 6
+# Configuration parameters: IgnoreLiteralBranches, IgnoreConstantBranches.
+Lint/DuplicateBranch:
+  Exclude:
+    - 'lib/puppet/provider/firewall/iptables.rb'
+    - 'lib/puppet/util/firewall.rb'
+    - 'spec/acceptance/firewall_attributes_exceptions_spec.rb'
+    - 'spec/unit/puppet/type/firewallchain_spec.rb'
+
+# Offense count: 1
+# Configuration parameters: AllowComments, AllowEmptyLambdas.
+Lint/EmptyBlock:
+  Exclude:
+    - 'spec/unit/puppet/provider/ip6tables_spec.rb'
+
+# Offense count: 8
+# This cop supports safe autocorrection (--autocorrect).
+Lint/RedundantCopEnableDirective:
+  Exclude:
+    - 'lib/puppet/provider/firewall/iptables.rb'
+    - 'spec/acceptance/firewall_attributes_exceptions_spec.rb'
+    - 'spec/unit/classes/firewall_spec.rb'
+    - 'spec/unit/puppet/type/firewall_spec.rb'
+
+# Offense count: 1
+# This cop supports unsafe autocorrection (--autocorrect-all).
+# Configuration parameters: AllowedMethods.
+# AllowedMethods: instance_of?, kind_of?, is_a?, eql?, respond_to?, equal?
+Lint/RedundantSafeNavigation:
+  Exclude:
+    - 'lib/puppet/provider/firewall/iptables.rb'
+
+# Offense count: 13
+# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes.
+Metrics/AbcSize:
+  Max: 235
+
+# Offense count: 23
+# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns, inherit_mode.
+# AllowedMethods: refine
+Metrics/BlockLength:
+  Max: 1961
+
+# Offense count: 2
+# Configuration parameters: CountBlocks.
+Metrics/BlockNesting:
+  Max: 4
+
+# Offense count: 8
+# Configuration parameters: AllowedMethods, AllowedPatterns.
+Metrics/CyclomaticComplexity:
+  Max: 60
+
+# Offense count: 19
+# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
+Metrics/MethodLength:
+  Max: 233
+
+# Offense count: 1
+# Configuration parameters: CountComments, CountAsOne.
+Metrics/ModuleLength:
+  Max: 193
+
+# Offense count: 6
+# Configuration parameters: AllowedMethods, AllowedPatterns.
+Metrics/PerceivedComplexity:
+  Max: 65
+
+# Offense count: 1
+# Configuration parameters: EnforcedStyleForLeadingUnderscores.
+# SupportedStylesForLeadingUnderscores: disallowed, required, optional
+Naming/MemoizedInstanceVariableName:
+  Exclude:
+    - 'spec/spec_helper_acceptance_local.rb'
+
+# Offense count: 3
+# Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames.
+# AllowedNames: as, at, by, cc, db, id, if, in, io, ip, of, on, os, pp, to
+Naming/MethodParameterName:
+  Exclude:
+    - 'lib/puppet/type/firewall.rb'
+
+# Offense count: 1
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: PreferredName.
+Naming/RescuedExceptionsVariableName:
+  Exclude:
+    - 'lib/puppet/util/firewall.rb'
+
+# Offense count: 12
+# Configuration parameters: MinSize.
+Performance/CollectionLiteralInLoop:
+  Exclude:
+    - 'lib/puppet/provider/firewall/iptables.rb'
+    - 'spec/unit/puppet/type/firewall_spec.rb'
+    - 'spec/unit/puppet/type/firewallchain_spec.rb'
+
+# Offense count: 4
+# This cop supports safe autocorrection (--autocorrect).
+Performance/StringIdentifierArgument:
+  Exclude:
+    - 'lib/puppet/provider/firewall/iptables.rb'
+
+# Offense count: 7
+# This cop supports unsafe autocorrection (--autocorrect-all).
+Performance/StringInclude:
+  Exclude:
+    - 'lib/puppet/provider/firewall/iptables.rb'
+    - 'lib/puppet/type/firewall.rb'
+    - 'lib/puppet/util/ipcidr.rb'
+
+# Offense count: 15
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle.
+# SupportedStyles: be, be_nil
+RSpec/BeNil:
+  Exclude:
+    - 'spec/unit/puppet/type/firewall_spec.rb'
+    - 'spec/unit/puppet/util/firewall_spec.rb'
+
+# Offense count: 7
+# Configuration parameters: Prefixes, AllowedPatterns.
+# Prefixes: when, with, without
+RSpec/ContextWording:
+  Exclude:
+    - 'spec/acceptance/firewall_attributes_exceptions_spec.rb'
+    - 'spec/unit/classes/firewall_linux_redhat_spec.rb'
+    - 'spec/unit/classes/firewall_linux_spec.rb'
+
+# Offense count: 25
+# Configuration parameters: IgnoredMetadata.
+RSpec/DescribeClass:
+  Enabled: false
+
+# Offense count: 1
+# This cop supports safe autocorrection (--autocorrect).
+RSpec/EmptyHook:
+  Exclude:
+    - 'spec/unit/puppet/provider/ip6tables_spec.rb'
+
+# Offense count: 153
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: AllowConsecutiveOneLiners.
+RSpec/EmptyLineAfterExample:
+  Exclude:
+    - 'spec/acceptance/firewall_attributes_exceptions_spec.rb'
+    - 'spec/acceptance/firewall_attributes_happy_path_spec.rb'
+    - 'spec/acceptance/firewall_attributes_ipv6_exceptions_spec.rb'
+    - 'spec/acceptance/firewall_attributes_ipv6_happy_path_spec.rb'
+    - 'spec/acceptance/rules_spec.rb'
+    - 'spec/unit/classes/firewall_linux_archlinux_spec.rb'
+    - 'spec/unit/classes/firewall_linux_debian_spec.rb'
+    - 'spec/unit/classes/firewall_linux_redhat_spec.rb'
+    - 'spec/unit/puppet/provider/iptables_spec.rb'
+    - 'spec/unit/puppet/type/firewall_spec.rb'
+    - 'spec/unit/puppet/type/firewallchain_spec.rb'
+    - 'spec/unit/puppet/util/firewall_spec.rb'
+
+# Offense count: 16
+# This cop supports safe autocorrection (--autocorrect).
+RSpec/EmptyLineAfterExampleGroup:
+  Exclude:
+    - 'spec/acceptance/firewall_attributes_exceptions_spec.rb'
+    - 'spec/acceptance/firewall_attributes_ipv6_exceptions_spec.rb'
+    - 'spec/unit/classes/firewall_spec.rb'
+    - 'spec/unit/puppet/provider/ip6tables_spec.rb'
+    - 'spec/unit/puppet/type/firewall_spec.rb'
+    - 'spec/unit/puppet/type/firewallchain_spec.rb'
+
+# Offense count: 22
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: AllowConsecutiveOneLiners.
+RSpec/EmptyLineAfterHook:
+  Exclude:
+    - 'spec/acceptance/firewall_attributes_exceptions_spec.rb'
+    - 'spec/acceptance/firewall_attributes_ipv6_exceptions_spec.rb'
+    - 'spec/acceptance/firewall_attributes_ipv6_happy_path_spec.rb'
+    - 'spec/unit/facter/iptables_persistent_version_spec.rb'
+    - 'spec/unit/facter/iptables_spec.rb'
+    - 'spec/unit/puppet/type/firewallchain_spec.rb'
+
+# Offense count: 22
+# Configuration parameters: CountAsOne.
+RSpec/ExampleLength:
+  Max: 16
+
+# Offense count: 41
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle.
+# SupportedStyles: single_line_only, single_statement_only, disallow, require_implicit
+RSpec/ImplicitSubject:
+  Exclude:
+    - 'spec/unit/classes/firewall_linux_archlinux_spec.rb'
+    - 'spec/unit/classes/firewall_linux_debian_spec.rb'
+    - 'spec/unit/classes/firewall_linux_redhat_spec.rb'
+
+# Offense count: 44
+RSpec/MultipleExpectations:
+  Max: 6
+
+# Offense count: 16
+# Configuration parameters: AllowedGroups.
+RSpec/NestedGroups:
+  Max: 5
+
+# Offense count: 66
+# Configuration parameters: AllowedPatterns.
+# AllowedPatterns: ^expect_, ^assert_
+RSpec/NoExpectationExample:
+  Exclude:
+    - 'spec/acceptance/class_spec.rb'
+    - 'spec/acceptance/firewall_attributes_exceptions_spec.rb'
+    - 'spec/acceptance/firewall_attributes_ipv6_exceptions_spec.rb'
+    - 'spec/acceptance/firewallchain_spec.rb'
+    - 'spec/acceptance/rules_spec.rb'
+    - 'spec/acceptance/standard_usage_spec.rb'
+    - 'spec/unit/puppet/provider/ip6tables_spec.rb'
+    - 'spec/unit/puppet/provider/iptables_chain_spec.rb'
+    - 'spec/unit/puppet/provider/iptables_spec.rb'
+    - 'spec/unit/puppet/type/firewall_spec.rb'
+    - 'spec/unit/puppet/type/firewallchain_spec.rb'
+    - 'spec/unit/puppet/util/firewall_spec.rb'
+    - 'spec/unit/puppet/util/ipcidr_spec.rb'
+
+# Offense count: 2
+# This cop supports safe autocorrection (--autocorrect).
+RSpec/ReceiveNever:
+  Exclude:
+    - 'spec/unit/puppet/util/firewall_spec.rb'
+
+# Offense count: 3
+RSpec/RepeatedExampleGroupBody:
+  Exclude:
+    - 'spec/unit/classes/firewall_linux_debian_spec.rb'
+
+# Offense count: 8
+RSpec/RepeatedExampleGroupDescription:
+  Exclude:
+    - 'spec/acceptance/firewall_attributes_exceptions_spec.rb'
+    - 'spec/acceptance/resource_cmd_spec.rb'
+
+# Offense count: 3
+# This cop supports unsafe autocorrection (--autocorrect-all).
+# Configuration parameters: .
+# SupportedStyles: constant, string
+RSpec/VerifiedDoubleReference:
+  EnforcedStyle: string
+
+# Offense count: 1
+# This cop supports unsafe autocorrection (--autocorrect-all).
+# Configuration parameters: EnforcedStyle.
+# SupportedStyles: nested, compact
+Style/ClassAndModuleChildren:
+  Exclude:
+    - 'lib/puppet/util/ipcidr.rb'
+
+# Offense count: 1
+# This cop supports unsafe autocorrection (--autocorrect-all).
+Style/CollectionCompact:
+  Exclude:
+    - 'lib/puppet/provider/firewall/iptables.rb'
+
+# Offense count: 1
+Style/CombinableLoops:
+  Exclude:
+    - 'spec/unit/puppet/type/firewall_spec.rb'
+
+# Offense count: 1
+# This cop supports unsafe autocorrection (--autocorrect-all).
+Style/ConcatArrayLiterals:
+  Exclude:
+    - 'lib/puppet/provider/firewall/iptables.rb'
+
+# Offense count: 90
+# This cop supports safe autocorrection (--autocorrect).
+Style/IfUnlessModifier:
+  Exclude:
+    - 'lib/puppet/provider/firewall.rb'
+    - 'lib/puppet/provider/firewall/ip6tables.rb'
+    - 'lib/puppet/provider/firewall/iptables.rb'
+    - 'lib/puppet/provider/firewallchain/iptables_chain.rb'
+    - 'lib/puppet/type/firewall.rb'
+    - 'lib/puppet/type/firewallchain.rb'
+    - 'lib/puppet/util/firewall.rb'
+    - 'spec/acceptance/class_spec.rb'
+    - 'spec/acceptance/firewall_attributes_happy_path_spec.rb'
+    - 'spec/acceptance/firewall_duplicate_comment_spec.rb'
+    - 'spec/acceptance/rules_spec.rb'
+    - 'spec/spec_helper_acceptance_local.rb'
+
+# Offense count: 1
+# This cop supports unsafe autocorrection (--autocorrect-all).
+# Configuration parameters: AllowedMethods.
+# AllowedMethods: nonzero?
+Style/IfWithBooleanLiteralBranches:
+  Exclude:
+    - 'spec/acceptance/firewall_attributes_exceptions_spec.rb'
+
+# Offense count: 1
+Style/MixinUsage:
+  Exclude:
+    - 'spec/spec_helper.rb'
+
+# Offense count: 1
+# This cop supports safe autocorrection (--autocorrect).
+Style/NegatedIfElseCondition:
+  Exclude:
+    - 'lib/puppet/type/firewallchain.rb'
+
+# Offense count: 9
+# This cop supports unsafe autocorrection (--autocorrect-all).
+# Configuration parameters: EnforcedStyle, AllowedMethods, AllowedPatterns.
+# SupportedStyles: predicate, comparison
+Style/NumericPredicate:
+  Exclude:
+    - 'spec/**/*'
+    - 'lib/puppet/provider/firewall/ip6tables.rb'
+    - 'lib/puppet/provider/firewall/iptables.rb'
+    - 'lib/puppet/type/firewall.rb'
+    - 'lib/puppet/util/firewall.rb'
+
+# Offense count: 1
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle.
+# SupportedStyles: same_as_string_literals, single_quotes, double_quotes
+Style/QuotedSymbols:
+  Exclude:
+    - 'lib/puppet/type/firewall.rb'
+
+# Offense count: 5
+# This cop supports unsafe autocorrection (--autocorrect-all).
+# Configuration parameters: Methods.
+Style/RedundantArgument:
+  Exclude:
+    - 'lib/puppet/provider/firewall/iptables.rb'
+    - 'spec/spec_helper_acceptance_local.rb'
+
+# Offense count: 1
+# This cop supports safe autocorrection (--autocorrect).
+Style/RedundantAssignment:
+  Exclude:
+    - 'spec/acceptance/firewall_duplicate_comment_spec.rb'
+
+# Offense count: 2
+# This cop supports safe autocorrection (--autocorrect).
+Style/RedundantRegexpCharacterClass:
+  Exclude:
+    - 'lib/puppet/type/firewall.rb'
+
+# Offense count: 113
+# This cop supports safe autocorrection (--autocorrect).
+Style/RedundantRegexpEscape:
+  Exclude:
+    - 'lib/puppet/provider/firewall/iptables.rb'
+    - 'lib/puppet/type/firewall.rb'
+    - 'spec/acceptance/firewall_attributes_exceptions_spec.rb'
+    - 'spec/acceptance/firewall_attributes_happy_path_spec.rb'
+    - 'spec/acceptance/firewall_attributes_ipv6_exceptions_spec.rb'
+    - 'spec/acceptance/firewall_attributes_ipv6_happy_path_spec.rb'
+    - 'spec/acceptance/rules_spec.rb'
+    - 'spec/unit/puppet/provider/iptables_spec.rb'
+    - 'spec/unit/puppet/type/firewall_spec.rb'
+
+# Offense count: 8
+# This cop supports safe autocorrection (--autocorrect).
+Style/RedundantStringEscape:
+  Exclude:
+    - 'spec/acceptance/firewall_attributes_exceptions_spec.rb'
+    - 'spec/acceptance/resource_cmd_spec.rb'
+
+# Offense count: 4
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle.
+# SupportedStyles: implicit, explicit
+Style/RescueStandardError:
+  Exclude:
+    - 'lib/puppet/util/firewall.rb'
+    - 'spec/spec_helper.rb'
+    - 'spec/spec_helper_acceptance_local.rb'
+
+# Offense count: 2
+# This cop supports unsafe autocorrection (--autocorrect-all).
+Style/SlicingWithRange:
+  Exclude:
+    - 'lib/puppet/provider/firewall/iptables.rb'
+    - 'spec/spec_helper_acceptance_local.rb'
+
+# Offense count: 16
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: AllowModifier.
+Style/SoleNestedConditional:
+  Exclude:
+    - 'lib/puppet/type/firewall.rb'
+
+# Offense count: 6
+# This cop supports unsafe autocorrection (--autocorrect-all).
+# Configuration parameters: Mode.
+Style/StringConcatenation:
+  Exclude:
+    - 'lib/puppet/provider/firewall/iptables.rb'
+    - 'lib/puppet/provider/firewallchain/iptables_chain.rb'
+    - 'lib/puppet/type/firewall.rb'
+    - 'lib/puppet/util/firewall.rb'
+    - 'spec/unit/puppet/type/firewallchain_spec.rb'
+
+# Offense count: 4
+# This cop supports unsafe autocorrection (--autocorrect-all).
+# Configuration parameters: AllowMethodsWithArguments, AllowedMethods, AllowedPatterns, AllowComments.
+# AllowedMethods: define_method
+Style/SymbolProc:
+  Exclude:
+    - 'lib/puppet/provider/firewall/iptables.rb'
+    - 'lib/puppet/type/firewall.rb'
+
+# Offense count: 46
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyleForMultiline.
+# SupportedStylesForMultiline: comma, consistent_comma, no_comma
+Style/TrailingCommaInHashLiteral:
+  Exclude:
+    - 'lib/puppet/provider/firewall/ip6tables.rb'
+    - 'lib/puppet/provider/firewall/iptables.rb'
+    - 'lib/puppet/provider/firewallchain/iptables_chain.rb'
+    - 'spec/spec_helper.rb'
+    - 'spec/spec_helper_local.rb'
+    - 'spec/unit/classes/firewall_linux_archlinux_spec.rb'
+    - 'spec/unit/classes/firewall_linux_debian_spec.rb'
+    - 'spec/unit/classes/firewall_linux_redhat_spec.rb'
+    - 'spec/unit/classes/firewall_linux_spec.rb'
+    - 'spec/unit/facter/iptables_persistent_version_spec.rb'
+    - 'spec/unit/puppet/type/firewall_spec.rb'
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 600aa10..9dda3ef 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,85 @@
 
 All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org).
 
+## [v5.0.0](https://github.com/puppetlabs/puppetlabs-firewall/tree/v5.0.0) (2023-03-31)
+
+[Full Changelog](https://github.com/puppetlabs/puppetlabs-firewall/compare/v4.1.0...v5.0.0)
+
+### Changed
+
+- \(Cont 779\) Add Support for Puppet 8 / Drop Support for Puppet 6 [\#1118](https://github.com/puppetlabs/puppetlabs-firewall/pull/1118) ([david22swan](https://github.com/david22swan))
+
+## [v4.1.0](https://github.com/puppetlabs/puppetlabs-firewall/tree/v4.1.0) (2023-03-31)
+
+[Full Changelog](https://github.com/puppetlabs/puppetlabs-firewall/compare/v4.0.1...v4.1.0)
+
+### Added
+
+- \(CONT-352\) Syntax update [\#1110](https://github.com/puppetlabs/puppetlabs-firewall/pull/1110) ([LukasAud](https://github.com/LukasAud))
+
+### UNCATEGORIZED PRS; LABEL THEM ON GITHUB
+
+- Ignore OpenBSD, similarly to FreeBSD [\#1107](https://github.com/puppetlabs/puppetlabs-firewall/pull/1107) ([buzzdeee](https://github.com/buzzdeee))
+- redhat9 needs iptables service [\#1103](https://github.com/puppetlabs/puppetlabs-firewall/pull/1103) ([robertc99](https://github.com/robertc99))
+- debian: service: fix `ensure` parameter usage [\#1095](https://github.com/puppetlabs/puppetlabs-firewall/pull/1095) ([damonbreeden](https://github.com/damonbreeden))
+
+## [v4.0.1](https://github.com/puppetlabs/puppetlabs-firewall/tree/v4.0.1) (2022-12-07)
+
+[Full Changelog](https://github.com/puppetlabs/puppetlabs-firewall/compare/v4.0.0...v4.0.1)
+
+### Fixed
+
+- \(GH-1097\) Bumping back required puppet version [\#1098](https://github.com/puppetlabs/puppetlabs-firewall/pull/1098) ([LukasAud](https://github.com/LukasAud))
+- support --nflog-size as replacement for --nflog-range [\#1096](https://github.com/puppetlabs/puppetlabs-firewall/pull/1096) ([kjetilho](https://github.com/kjetilho))
+- \(1093\) - Fix unresolved fact error [\#1094](https://github.com/puppetlabs/puppetlabs-firewall/pull/1094) ([jordanbreen28](https://github.com/jordanbreen28))
+- package "iptables" has been replaced by "iptables-nft" on EL9 [\#1085](https://github.com/puppetlabs/puppetlabs-firewall/pull/1085) ([kjetilho](https://github.com/kjetilho))
+
+## [v4.0.0](https://github.com/puppetlabs/puppetlabs-firewall/tree/v4.0.0) (2022-11-22)
+
+[Full Changelog](https://github.com/puppetlabs/puppetlabs-firewall/compare/v3.6.0...v4.0.0)
+
+### Changed
+
+- \(CONT-256\) Removing outdated code [\#1084](https://github.com/puppetlabs/puppetlabs-firewall/pull/1084) ([LukasAud](https://github.com/LukasAud))
+
+### Added
+
+- add support for using rpfilter in rules [\#1059](https://github.com/puppetlabs/puppetlabs-firewall/pull/1059) ([cmusik](https://github.com/cmusik))
+
+### Fixed
+
+- \(CONT-173\) - Updating deprecated facter instances [\#1079](https://github.com/puppetlabs/puppetlabs-firewall/pull/1079) ([jordanbreen28](https://github.com/jordanbreen28))
+- pdksync - \(CONT-189\) Remove support for RedHat6 / OracleLinux6 / Scientific6 [\#1078](https://github.com/puppetlabs/puppetlabs-firewall/pull/1078) ([david22swan](https://github.com/david22swan))
+- pdksync - \(CONT-130\) - Dropping Support for Debian 9 [\#1075](https://github.com/puppetlabs/puppetlabs-firewall/pull/1075) ([jordanbreen28](https://github.com/jordanbreen28))
+- fix service port number lookup to use protocol [\#1023](https://github.com/puppetlabs/puppetlabs-firewall/pull/1023) ([kjetilho](https://github.com/kjetilho))
+
+## [v3.6.0](https://github.com/puppetlabs/puppetlabs-firewall/tree/v3.6.0) (2022-10-03)
+
+[Full Changelog](https://github.com/puppetlabs/puppetlabs-firewall/compare/v3.5.0...v3.6.0)
+
+### Added
+
+- pdksync - \(GH-cat-11\) Certify Support for Ubuntu 22.04 [\#1063](https://github.com/puppetlabs/puppetlabs-firewall/pull/1063) ([david22swan](https://github.com/david22swan))
+- pdksync - \(GH-cat-12\) Add Support for Redhat 9 [\#1054](https://github.com/puppetlabs/puppetlabs-firewall/pull/1054) ([david22swan](https://github.com/david22swan))
+
+### Fixed
+
+- allow persistence of firewall rules for Suse [\#1061](https://github.com/puppetlabs/puppetlabs-firewall/pull/1061) ([corporate-gadfly](https://github.com/corporate-gadfly))
+- \(GH-1055\) Fix for `--random-fully` [\#1058](https://github.com/puppetlabs/puppetlabs-firewall/pull/1058) ([david22swan](https://github.com/david22swan))
+
+## [v3.5.0](https://github.com/puppetlabs/puppetlabs-firewall/tree/v3.5.0) (2022-05-17)
+
+[Full Changelog](https://github.com/puppetlabs/puppetlabs-firewall/compare/v3.4.0...v3.5.0)
+
+### Added
+
+- CentOS Stream 9 Support \(should include RHEL9 when that releases\) [\#1028](https://github.com/puppetlabs/puppetlabs-firewall/pull/1028) ([tskirvin](https://github.com/tskirvin))
+
+### Fixed
+
+- pdksync - \(GH-iac-334\) Remove Support for Ubuntu 14.04/16.04 [\#1038](https://github.com/puppetlabs/puppetlabs-firewall/pull/1038) ([david22swan](https://github.com/david22swan))
+- Fix rpfilter parameter [\#1013](https://github.com/puppetlabs/puppetlabs-firewall/pull/1013) ([onyxmaster](https://github.com/onyxmaster))
+
 ## [v3.4.0](https://github.com/puppetlabs/puppetlabs-firewall/tree/v3.4.0) (2022-02-28)
 
 [Full Changelog](https://github.com/puppetlabs/puppetlabs-firewall/compare/v3.3.0...v3.4.0)
@@ -12,7 +91,7 @@ All notable changes to this project will be documented in this file. The format
 
 ### Fixed
 
-- pdksync - \(IAC-1787\) - Remove Support for CentOS 6 [\#1027](https://github.com/puppetlabs/puppetlabs-firewall/pull/1027) ([david22swan](https://github.com/david22swan))
+- pdksync - \(IAC-1787\) Remove Support for CentOS 6 [\#1027](https://github.com/puppetlabs/puppetlabs-firewall/pull/1027) ([david22swan](https://github.com/david22swan))
 
 ## [v3.3.0](https://github.com/puppetlabs/puppetlabs-firewall/tree/v3.3.0) (2021-12-15)
 
diff --git a/README.md b/README.md
index fc3c721..f1985e3 100644
--- a/README.md
+++ b/README.md
@@ -385,7 +385,7 @@ firewall {'666 for NFLOG':
   jump            => 'NFLOG',
   nflog_group     => 3,
   nflog_prefix    => 'nflog-test',
-  nflog_range     => 256,
+  nflog_size      => 256,
   nflog_threshold => 1,
 }
 ```
diff --git a/REFERENCE.md b/REFERENCE.md
index b7831fd..d2f8d17 100644
--- a/REFERENCE.md
+++ b/REFERENCE.md
@@ -17,7 +17,7 @@
 * `firewall::linux::debian`: Installs the `iptables-persistent` package for Debian-alike systems. This allows rules to be stored to file and restored on boot.
 * `firewall::linux::gentoo`: Manages `iptables` and `ip6tables` services, and creates files used for persistence, on Gentoo Linux systems.
 * `firewall::linux::redhat`: Manages the `iptables` service on RedHat-alike systems.
-* `firewall::params`: Provides defaults for the Apt module parameters.
+* `firewall::params`: Provides defaults for the Apt module parameters
 
 ### Resource types
 
@@ -47,69 +47,69 @@ class { 'firewall': }
 
 The following parameters are available in the `firewall` class:
 
-* [`ensure`](#ensure)
-* [`ensure_v6`](#ensure_v6)
-* [`pkg_ensure`](#pkg_ensure)
-* [`service_name`](#service_name)
-* [`service_name_v6`](#service_name_v6)
-* [`package_name`](#package_name)
-* [`ebtables_manage`](#ebtables_manage)
+* [`ensure`](#-firewall--ensure)
+* [`ensure_v6`](#-firewall--ensure_v6)
+* [`pkg_ensure`](#-firewall--pkg_ensure)
+* [`service_name`](#-firewall--service_name)
+* [`service_name_v6`](#-firewall--service_name_v6)
+* [`package_name`](#-firewall--package_name)
+* [`ebtables_manage`](#-firewall--ebtables_manage)
 
-##### <a name="ensure"></a>`ensure`
+##### <a name="-firewall--ensure"></a>`ensure`
 
-Data type: `Any`
+Data type: `Enum[running, stopped, 'running', 'stopped']`
 
 Controls the state of the ipv4 iptables service on your system. Valid options: 'running' or 'stopped'.
 
 Default value: `running`
 
-##### <a name="ensure_v6"></a>`ensure_v6`
+##### <a name="-firewall--ensure_v6"></a>`ensure_v6`
 
-Data type: `Any`
+Data type: `Optional[Enum[running, stopped, 'running', 'stopped']]`
 
 Controls the state of the ipv6 iptables service on your system. Valid options: 'running' or 'stopped'.
 
-Default value: ``undef``
+Default value: `undef`
 
-##### <a name="pkg_ensure"></a>`pkg_ensure`
+##### <a name="-firewall--pkg_ensure"></a>`pkg_ensure`
 
-Data type: `Any`
+Data type: `Enum[present, installed, latest, 'present', 'installed', 'latest']`
 
-Controls the state of the iptables package on your system. Valid options: 'present' or 'latest'.
+Controls the state of the iptables package on your system. Valid options: 'present', 'installed' or 'latest'.
 
 Default value: `present`
 
-##### <a name="service_name"></a>`service_name`
+##### <a name="-firewall--service_name"></a>`service_name`
 
-Data type: `Any`
+Data type: `Variant[String[1], Array[String[1]]]`
 
 Specify the name of the IPv4 iptables service.
 
 Default value: `$firewall::params::service_name`
 
-##### <a name="service_name_v6"></a>`service_name_v6`
+##### <a name="-firewall--service_name_v6"></a>`service_name_v6`
 
-Data type: `Any`
+Data type: `Optional[String[1]]`
 
 Specify the name of the IPv6 iptables service.
 
 Default value: `$firewall::params::service_name_v6`
 
-##### <a name="package_name"></a>`package_name`
+##### <a name="-firewall--package_name"></a>`package_name`
 
-Data type: `Any`
+Data type: `Optional[Variant[String[1], Array[String[1]]]]`
 
 Specify the platform-specific package(s) to install.
 
 Default value: `$firewall::params::package_name`
 
-##### <a name="ebtables_manage"></a>`ebtables_manage`
+##### <a name="-firewall--ebtables_manage"></a>`ebtables_manage`
 
-Data type: `Any`
+Data type: `Boolean`
 
 Controls whether puppet manages the ebtables package or not. If managed, the package will use the value of pkg_ensure.
 
-Default value: ``false``
+Default value: `false`
 
 ## Resource types
 
@@ -207,7 +207,7 @@ installed.
 
   * nflog_prefix: The ability to set a prefix for nflog messages.
 
-  * nflog_range: The ability to set nflog_range.
+  * nflog_size: Set the max size of a message to send to nflog.
 
   * nflog_threshold: The ability to set nflog_threshold.
 
@@ -295,13 +295,13 @@ Default value: `INPUT`
 
 ##### `checksum_fill`
 
-Valid values: ``true``, ``false``
+Valid values: `true`, `false`
 
 Compute and fill missing packet checksums.
 
 ##### `clamp_mss_to_pmtu`
 
-Valid values: ``true``, ``false``
+Valid values: `true`, `false`
 
 Sets the clamp mss to pmtu flag.
 
@@ -333,7 +333,7 @@ Specify the random seed used for hash initialization.
 
 ##### `clusterip_new`
 
-Valid values: ``true``, ``false``
+Valid values: `true`, `false`
 
 Used with the CLUSTERIP jump target.
 Create a new ClusterIP. You always have to set this on the first rule for a given ClusterIP.
@@ -767,32 +767,32 @@ For example: 'blacklist src,dst'
 
 ##### `ipvs`
 
-Valid values: ``true``, ``false``
+Valid values: `true`, `false`
 
 Indicates that the current packet belongs to an IPVS connection.
 
 ##### `isfirstfrag`
 
-Valid values: ``true``, ``false``
+Valid values: `true`, `false`
 
 If true, matches if the packet is the first fragment.
 Sadly cannot be negated. ipv6.
 
 ##### `isfragment`
 
-Valid values: ``true``, ``false``
+Valid values: `true`, `false`
 
 Set to true to match tcp fragments (requires type to be set to tcp)
 
 ##### `ishasmorefrags`
 
-Valid values: ``true``, ``false``
+Valid values: `true`, `false`
 
 If true, matches if the packet has it's 'more fragments' bit set. ipv6.
 
 ##### `islastfrag`
 
-Valid values: ``true``, ``false``
+Valid values: `true`, `false`
 
 If true, matches if the packet is the last fragment. ipv6.
 
@@ -822,7 +822,7 @@ only one of the options should be set.
 
 ##### `kernel_timezone`
 
-Valid values: ``true``, ``false``
+Valid values: `true`, `false`
 
 Use the kernel timezone instead of UTC to determine whether a packet meets the time regulations.
 
@@ -839,7 +839,7 @@ Example values are: '50/sec', '40/min', '30/hour', '10/day'."
 
 ##### `log_ip_options`
 
-Valid values: ``true``, ``false``
+Valid values: `true`, `false`
 
 When combined with jump => "LOG" logging of the TCP IP/IPv6
 packet header.
@@ -856,21 +856,21 @@ logging.
 
 ##### `log_tcp_options`
 
-Valid values: ``true``, ``false``
+Valid values: `true`, `false`
 
 When combined with jump => "LOG" logging of the TCP packet
 header.
 
 ##### `log_tcp_sequence`
 
-Valid values: ``true``, ``false``
+Valid values: `true`, `false`
 
 When combined with jump => "LOG" enables logging of the TCP sequence
 numbers.
 
 ##### `log_uid`
 
-Valid values: ``true``, ``false``
+Valid values: `true`, `false`
 
 When combined with jump => "LOG" specifies the uid of the process making
 the connection.
@@ -914,9 +914,14 @@ useful for distinguishing messages in the logs.
 
 ##### `nflog_range`
 
+Used with the jump target NFLOG.
+This has never worked, use nflog_size instead.
+
+##### `nflog_size`
+
 Used with the jump target NFLOG.
 The number of bytes to be copied to userspace (only applicable for nfnetlink_log).
-nfnetlink_log instances may specify their own range, this option overrides it.
+nfnetlink_log instances may specify their own size, this option overrides it.
 
 ##### `nflog_threshold`
 
@@ -927,7 +932,7 @@ per packet, but increase delay until the packets reach userspace. Defaults to 1.
 
 ##### `notrack`
 
-Valid values: ``true``, ``false``
+Valid values: `true`, `false`
 
 Invoke the disable connection tracking for this packet.
 This parameter can be used with iptables version >= 1.8.3
@@ -949,19 +954,19 @@ Match if the packet is entering a bridge from the given interface.
 
 ##### `physdev_is_bridged`
 
-Valid values: ``true``, ``false``
+Valid values: `true`, `false`
 
 Match if the packet is transversing a bridge.
 
 ##### `physdev_is_in`
 
-Valid values: ``true``, ``false``
+Valid values: `true`, `false`
 
 Matches if the packet has entered through a bridge interface.
 
 ##### `physdev_is_out`
 
-Valid values: ``true``, ``false``
+Valid values: `true`, `false`
 
 Matches if the packet will leave through a bridge interface.
 
@@ -1006,7 +1011,7 @@ Default value: `tcp`
 
 ##### `queue_bypass`
 
-Valid values: ``true``, ``false``
+Valid values: `true`, `false`
 
 Used with NFQUEUE jump target
 Allow packets to bypass :queue_num if userspace process is not listening
@@ -1018,14 +1023,14 @@ What queue number to send packets to
 
 ##### `random`
 
-Valid values: ``true``, ``false``
+Valid values: `true`, `false`
 
 When using a jump value of "MASQUERADE", "DNAT", "REDIRECT", or "SNAT"
 this boolean will enable randomized port mapping.
 
 ##### `random_fully`
 
-Valid values: ``true``, ``false``
+Valid values: `true`, `false`
 
 When using a jump value of "MASQUERADE", "DNAT", "REDIRECT", or "SNAT"
 this boolean will enable fully randomized port mapping.
@@ -1034,14 +1039,14 @@ this boolean will enable fully randomized port mapping.
 
 ##### `rdest`
 
-Valid values: ``true``, ``false``
+Valid values: `true`, `false`
 
 Recent module; add the destination IP address to the list.
 Must be boolean true.
 
 ##### `reap`
 
-Valid values: ``true``, ``false``
+Valid values: `true`, `false`
 
 Recent module; can only be used in conjunction with the `rseconds`
 attribute. When used, this will cause entries older than 'seconds' to be
@@ -1113,14 +1118,14 @@ number of seconds.
 
 ##### `rsource`
 
-Valid values: ``true``, ``false``
+Valid values: `true`, `false`
 
 Recent module; add the source IP address to the list.
 Must be boolean true.
 
 ##### `rttl`
 
-Valid values: ``true``, ``false``
+Valid values: `true`, `false`
 
 Recent module; may only be used in conjunction with one of `recent =>
 'rcheck'` or `recent => 'update'`. When used, this will narrow the match
@@ -1149,7 +1154,7 @@ Sets the TCP MSS value for packets.
 
 ##### `socket`
 
-Valid values: ``true``, ``false``
+Valid values: `true`, `false`
 
 If true, matches if an open socket can be found by doing a coket lookup
 on the packet.
@@ -1323,7 +1328,7 @@ TCP  connection initiation.
 
 ##### `time_contiguous`
 
-Valid values: ``true``, ``false``
+Valid values: `true`, `false`
 
 When time_stop is smaller than time_start value, match this as a single time period instead distinct intervals.
 
@@ -1375,15 +1380,16 @@ Assign this packet to zone id and only have lookups done in that zone.
 
 The following parameters are available in the `firewall` type.
 
-* [`line`](#line)
-* [`name`](#name)
-* [`provider`](#provider)
+* [`line`](#-firewall--line)
+* [`name`](#-firewall--name)
+* [`onduplicaterulebehaviour`](#-firewall--onduplicaterulebehaviour)
+* [`provider`](#-firewall--provider)
 
-##### <a name="line"></a>`line`
+##### <a name="-firewall--line"></a>`line`
 
 Read-only property for caching the rule line.
 
-##### <a name="name"></a>`name`
+##### <a name="-firewall--name"></a>`name`
 
 Valid values: `%r{^\d+[[:graph:][:space:]]+$}`
 
@@ -1398,7 +1404,25 @@ so make sure you prefix the rule with a number:
 Depending on the provider, the name of the rule can be stored using
 the comment feature of the underlying firewall subsystem.
 
-##### <a name="provider"></a>`provider`
+##### <a name="-firewall--onduplicaterulebehaviour"></a>`onduplicaterulebehaviour`
+
+Valid values: `ignore`, `warn`, `error`
+
+In certain situations it is possible for an unmanaged rule to exist
+on the target system that has the same comment as the rule
+specified in the manifest.
+
+This setting determines what happens when such a duplicate is found.
+
+It offers three options:
+
+  * ignore - The duplicate rule is ignored and any updates to the resource will continue unaffected.
+  * warn - The duplicate rule is logged as a warning and any updates to the resource will continue unaffected.
+  * error - The duplicate rule is logged as an error and any updates to the resource will be skipped.
+
+Default value: `warn`
+
+##### <a name="-firewall--provider"></a>`provider`
 
 The specific backend to use for this `firewall` resource. You will seldom need to specify this --- Puppet will usually
 discover the appropriate provider for your platform.
@@ -1451,13 +1475,13 @@ PREROUTING, POSTROUTING) and can be one of:
 
 The following parameters are available in the `firewallchain` type.
 
-* [`ignore`](#ignore)
-* [`ignore_foreign`](#ignore_foreign)
-* [`name`](#name)
-* [`provider`](#provider)
-* [`purge`](#purge)
+* [`ignore`](#-firewallchain--ignore)
+* [`ignore_foreign`](#-firewallchain--ignore_foreign)
+* [`name`](#-firewallchain--name)
+* [`provider`](#-firewallchain--provider)
+* [`purge`](#-firewallchain--purge)
 
-##### <a name="ignore"></a>`ignore`
+##### <a name="-firewallchain--ignore"></a>`ignore`
 
 Regex to perform on firewall rules to exempt unmanaged rules from purging (when enabled).
 This is matched against the output of `iptables-save`.
@@ -1480,9 +1504,9 @@ firewallchain { 'INPUT:filter:IPv4':
 }
 ```
 
-##### <a name="ignore_foreign"></a>`ignore_foreign`
+##### <a name="-firewallchain--ignore_foreign"></a>`ignore_foreign`
 
-Valid values: ``false``, ``true``
+Valid values: `false`, `true`
 
 Ignore rules that do not match the puppet title pattern "^\d+[[:graph:][:space:]]" when purging unmanaged firewall rules
 in this chain.
@@ -1490,9 +1514,9 @@ This can be used to ignore rules that were not put in by puppet. Beware that not
 configuring firewall rules with a comment that starts with digits, and is indistinguishable from puppet-configured
 rules.
 
-Default value: ``false``
+Default value: `false`
 
-##### <a name="name"></a>`name`
+##### <a name="-firewallchain--name"></a>`name`
 
 namevar
 
@@ -1500,16 +1524,16 @@ The canonical name of the chain.
 
 For iptables the format must be {chain}:{table}:{protocol}.
 
-##### <a name="provider"></a>`provider`
+##### <a name="-firewallchain--provider"></a>`provider`
 
 The specific backend to use for this `firewallchain` resource. You will seldom need to specify this --- Puppet will
 usually discover the appropriate provider for your platform.
 
-##### <a name="purge"></a>`purge`
+##### <a name="-firewallchain--purge"></a>`purge`
 
-Valid values: ``false``, ``true``
+Valid values: `false`, `true`
 
 Purge unmanaged firewall rules in this chain
 
-Default value: ``false``
+Default value: `false`
 
diff --git a/debian/changelog b/debian/changelog
index 62126bf..7c8bd7c 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+puppet-module-puppetlabs-firewall (5.0.0-1) UNRELEASED; urgency=low
+
+  * New upstream release.
+
+ -- Debian Janitor <janitor@jelmer.uk>  Wed, 21 Jun 2023 02:41:49 -0000
+
 puppet-module-puppetlabs-firewall (3.4.0-1) unstable; urgency=medium
 
   * New upstream release.
diff --git a/lib/facter/ip6tables_version.rb b/lib/facter/ip6tables_version.rb
index 964ae74..31b0d52 100644
--- a/lib/facter/ip6tables_version.rb
+++ b/lib/facter/ip6tables_version.rb
@@ -2,12 +2,9 @@
 
 Facter.add(:ip6tables_version) do
   confine kernel: :Linux
+  confine { Facter::Core::Execution.which('ip6tables') }
   setcode do
-    version = Facter::Util::Resolution.exec('ip6tables --version')
-    if version
-      version.match(%r{\d+\.\d+\.\d+}).to_s
-    else
-      nil
-    end
+    version = Facter::Core::Execution.execute('ip6tables --version', { on_fail: nil })
+    version.match(%r{\d+\.\d+\.\d+}).to_s if version
   end
 end
diff --git a/lib/facter/iptables_persistent_version.rb b/lib/facter/iptables_persistent_version.rb
index 98fb5b0..ff66f0d 100644
--- a/lib/facter/iptables_persistent_version.rb
+++ b/lib/facter/iptables_persistent_version.rb
@@ -5,16 +5,8 @@ Facter.add(:iptables_persistent_version) do
   setcode do
     # Throw away STDERR because dpkg >= 1.16.7 will make some noise if the
     # package isn't currently installed.
-    os = Facter.value(:operatingsystem)
-    os_release = Facter.value(:operatingsystemrelease)
-    cmd = if (os == 'Debian' && (Puppet::Util::Package.versioncmp(os_release, '8.0') >= 0)) ||
-             (os == 'Ubuntu' && (Puppet::Util::Package.versioncmp(os_release, '14.10') >= 0)) ||
-             (os == 'Debian' && (Puppet::Util::Package.versioncmp(os_release, 'unstable') >= 0))
-            "dpkg-query -Wf '${Version}' netfilter-persistent 2>/dev/null"
-          else
-            "dpkg-query -Wf '${Version}' iptables-persistent 2>/dev/null"
-          end
-    version = Facter::Util::Resolution.exec(cmd)
+    cmd = "dpkg-query -Wf '${Version}' netfilter-persistent 2>/dev/null"
+    version = Facter::Core::Execution.execute(cmd, { on_fail: nil })
 
     if version.nil? || !version.match(%r{\d+\.\d+})
       nil
diff --git a/lib/facter/iptables_version.rb b/lib/facter/iptables_version.rb
index 873a37e..3cc4931 100644
--- a/lib/facter/iptables_version.rb
+++ b/lib/facter/iptables_version.rb
@@ -2,12 +2,9 @@
 
 Facter.add(:iptables_version) do
   confine kernel: :Linux
+  confine { Facter::Core::Execution.which('iptables') }
   setcode do
-    version = Facter::Util::Resolution.exec('iptables --version')
-    if version
-      version.match(%r{\d+\.\d+\.\d+}).to_s
-    else
-      nil
-    end
+    version = Facter::Core::Execution.execute('iptables --version', { on_fail: nil })
+    version.match(%r{\d+\.\d+\.\d+}).to_s if version
   end
 end
diff --git a/lib/puppet/provider/firewall/ip6tables.rb b/lib/puppet/provider/firewall/ip6tables.rb
index 54911ef..77a2a79 100644
--- a/lib/puppet/provider/firewall/ip6tables.rb
+++ b/lib/puppet/provider/firewall/ip6tables.rb
@@ -46,7 +46,6 @@ Puppet::Type.type(:firewall).provide :ip6tables, parent: :iptables, source: :ip6
   has_feature :queue_num
   has_feature :queue_bypass
   has_feature :ct_target
-  has_feature :rpfilter
 
   optional_commands(ip6tables: 'ip6tables',
                     ip6tables_save: 'ip6tables-save')
@@ -66,6 +65,15 @@ Puppet::Type.type(:firewall).provide :ip6tables, parent: :iptables, source: :ip6
     has_feature :random_fully
   end
 
+  if (kernelversion && Puppet::Util::Package.versioncmp(kernelversion, '3.3') >= 0) &&
+     (ip6tables_version && Puppet::Util::Package.versioncmp(ip6tables_version, '1.4.13') >= 0)
+    has_feature :rpfilter
+  end
+
+  if ip6tables_version && Puppet::Util::Package.versioncmp(ip6tables_version, '1.6.1') >= 0
+    has_feature :nflog_size
+  end
+
   def initialize(*args)
     ip6tables_version = Facter.value('ip6tables_version')
     raise ArgumentError, 'The ip6tables provider is not supported on version 1.3 of iptables' if ip6tables_version&.match(%r{1\.3\.\d})
@@ -136,6 +144,7 @@ Puppet::Type.type(:firewall).provide :ip6tables, parent: :iptables, source: :ip6
     nflog_group: '--nflog-group',
     nflog_prefix: '--nflog-prefix',
     nflog_range: '--nflog-range',
+    nflog_size: '--nflog-size',
     nflog_threshold: '--nflog-threshold',
     outiface: '-o',
     pkttype: '-m pkttype --pkt-type',
@@ -309,7 +318,9 @@ Puppet::Type.type(:firewall).provide :ip6tables, parent: :iptables, source: :ip6
                     :ctorigsrcport, :ctorigdstport, :ctreplsrcport, :ctrepldstport, :ctstatus, :ctexpire, :ctdir,
                     :icmp, :hop_limit, :limit, :burst, :length, :recent, :rseconds, :reap,
                     :rhitcount, :rttl, :rname, :mask, :rsource, :rdest, :ipset, :string, :string_hex, :string_algo,
-                    :string_from, :string_to, :jump, :nflog_group, :nflog_prefix, :nflog_range, :nflog_threshold, :clamp_mss_to_pmtu, :gateway, :todest,
+                    :string_from, :string_to, :jump,
+                    :nflog_group, :nflog_prefix, :nflog_range, :nflog_size, :nflog_threshold,
+                    :clamp_mss_to_pmtu, :gateway, :todest,
                     :tosource, :toports, :checksum_fill, :log_level, :log_prefix, :log_uid, :log_tcp_sequence, :log_tcp_options, :log_ip_options, :random_fully,
                     :reject, :set_mss, :set_dscp, :set_dscp_class, :mss, :queue_num, :queue_bypass,
                     :set_mark, :match_mark, :connlimit_above, :connlimit_mask, :connmark, :time_start, :time_stop, :month_days, :week_days, :date_start, :date_stop, :time_contiguous, :kernel_timezone,
diff --git a/lib/puppet/provider/firewall/iptables.rb b/lib/puppet/provider/firewall/iptables.rb
index 9087aa5..9d26f03 100644
--- a/lib/puppet/provider/firewall/iptables.rb
+++ b/lib/puppet/provider/firewall/iptables.rb
@@ -51,7 +51,6 @@ Puppet::Type.type(:firewall).provide :iptables, parent: Puppet::Provider::Firewa
   has_feature :queue_bypass
   has_feature :ipvs
   has_feature :ct_target
-  has_feature :rpfilter
 
   optional_commands(iptables: 'iptables',
                     iptables_save: 'iptables-save')
@@ -72,6 +71,15 @@ Puppet::Type.type(:firewall).provide :iptables, parent: Puppet::Provider::Firewa
     has_feature :random_fully
   end
 
+  if (kernelversion && Puppet::Util::Package.versioncmp(kernelversion, '3.3') >= 0) &&
+     (iptables_version && Puppet::Util::Package.versioncmp(iptables_version, '1.4.13') >= 0)
+    has_feature :rpfilter
+  end
+
+  if iptables_version && Puppet::Util::Package.versioncmp(iptables_version, '1.6.1') >= 0
+    has_feature :nflog_size
+  end
+
   @protocol = 'IPv4'
 
   @resource_map = {
@@ -125,6 +133,7 @@ Puppet::Type.type(:firewall).provide :iptables, parent: Puppet::Provider::Firewa
     nflog_group: '--nflog-group',
     nflog_prefix: '--nflog-prefix',
     nflog_range: '--nflog-range',
+    nflog_size: '--nflog-size',
     nflog_threshold: '--nflog-threshold',
     outiface: '-o',
     pkttype: '-m pkttype --pkt-type',
@@ -347,7 +356,7 @@ Puppet::Type.type(:firewall).provide :iptables, parent: Puppet::Provider::Firewa
     :rhitcount, :rttl, :rname, :mask, :rsource, :rdest, :ipset, :string, :string_hex, :string_algo,
     :string_from, :string_to, :jump, :goto, :clusterip_new, :clusterip_hashmode,
     :clusterip_clustermac, :clusterip_total_nodes, :clusterip_local_node, :clusterip_hash_init, :queue_num, :queue_bypass,
-    :nflog_group, :nflog_prefix, :nflog_range, :nflog_threshold, :clamp_mss_to_pmtu, :gateway,
+    :nflog_group, :nflog_prefix, :nflog_range, :nflog_size, :nflog_threshold, :clamp_mss_to_pmtu, :gateway,
     :set_mss, :set_dscp, :set_dscp_class, :todest, :tosource, :toports, :to, :checksum_fill, :random_fully, :random, :log_prefix,
     :log_level, :log_uid, :log_tcp_sequence, :log_tcp_options, :log_ip_options, :reject, :set_mark, :match_mark, :mss, :connlimit_above, :connlimit_mask, :connmark, :time_start, :time_stop,
     :month_days, :week_days, :date_start, :date_stop, :time_contiguous, :kernel_timezone,
@@ -530,6 +539,17 @@ Puppet::Type.type(:firewall).provide :iptables, parent: Puppet::Provider::Firewa
         (\s--tunnel-src\s\S+)?
         (\s--next)?}x,
                         '--pol "ipsec\1\2\3\4\5\6\7\8" ')
+
+    # rpfilter also takes multiple parameters; use quote trick again
+    rpfilter_opts = values.scan(%r{-m\srpfilter(\s(--loose)|\s(--validmark)|\s(--accept-local)|\s(--invert))+})
+    if rpfilter_opts && rpfilter_opts.length == 1 && rpfilter_opts[0]
+      rpfilter_opts = rpfilter_opts[0][1..-1].reject { |x| x.nil? }
+      values = values.sub(
+        %r{-m\srpfilter(\s(--loose)|\s(--validmark)|\s(--accept-local)|\s(--invert))+},
+        "-m rpfilter \"#{rpfilter_opts.join(' ')}\"",
+      )
+    end
+
     # on some iptables versions, --connlimit-saddr switch is added after the rule is applied
     values = values.gsub(%r{--connlimit-saddr}, '')
 
@@ -545,11 +565,9 @@ Puppet::Type.type(:firewall).provide :iptables, parent: Puppet::Provider::Firewa
                  values.sub(%r{\s-f(?!l)(?=.*--comment)}, ' -f true')
                elsif resource_map[bool].eql?(%r{'--physdev-is-\S+'})
                  values.sub(%r{'#{resource_map[bool]} "! "'}, "#{resource_map[bool]} true")
-               elsif bool == :random
-                 values.sub(%r{#{resource_map[bool]}(\s|$)(?!"!")}, "#{resource_map[bool]} true")
                else
                  # append `true` to booleans that are not already negated (followed by "!")
-                 values.sub(%r{#{resource_map[bool]}(?! "!")}, "#{resource_map[bool]} true")
+                 values.sub(%r{#{resource_map[bool]}(?=\s|$)(?!\s?"!")}, "#{resource_map[bool]} true")
                end
     end
 
@@ -630,6 +648,8 @@ Puppet::Type.type(:firewall).provide :iptables, parent: Puppet::Provider::Firewa
       hash[prop] = hash[prop].split(';') unless hash[prop].nil?
     end
 
+    hash[:rpfilter] = hash[:rpfilter].split(' ') unless hash[:rpfilter].nil?
+
     ## clean up DSCP class to HEX mappings
     valid_dscp_classes = {
       '0x0a' => 'af11',
@@ -916,6 +936,8 @@ Puppet::Type.type(:firewall).provide :iptables, parent: Puppet::Provider::Firewa
         one, two = resource_value.split(' ')
         args << one
         args << two
+      elsif res == :rpfilter
+        args << resource_value
       elsif resource_value.is_a?(Array)
         args << resource_value.join(',')
       elsif !resource_value.nil?
diff --git a/lib/puppet/provider/firewallchain/iptables_chain.rb b/lib/puppet/provider/firewallchain/iptables_chain.rb
index ec135d8..fb02753 100644
--- a/lib/puppet/provider/firewallchain/iptables_chain.rb
+++ b/lib/puppet/provider/firewallchain/iptables_chain.rb
@@ -143,7 +143,7 @@ Puppet::Type.type(:firewallchain).provide :iptables_chain do
     chains = []
 
     MAPPING.each do |p, c|
-      begin
+      begin # rubocop:disable Style/RedundantBegin
         c[:save].call.each_line do |line|
           if line =~ c[:re]
             name = Regexp.last_match(1) + ':' + ((table == 'filter') ? 'filter' : table) + ':' + p.to_s
diff --git a/lib/puppet/type/firewall.rb b/lib/puppet/type/firewall.rb
index d2ece90..86af41b 100644
--- a/lib/puppet/type/firewall.rb
+++ b/lib/puppet/type/firewall.rb
@@ -110,7 +110,7 @@ Puppet::Type.newtype(:firewall) do
 
       * nflog_prefix: The ability to set a prefix for nflog messages.
 
-      * nflog_range: The ability to set nflog_range.
+      * nflog_size: Set the max size of a message to send to nflog.
 
       * nflog_threshold: The ability to set nflog_threshold.
 
@@ -173,6 +173,7 @@ Puppet::Type.newtype(:firewall) do
   feature :mss, 'Match a given TCP MSS value or range.'
   feature :tcp_flags, 'The ability to match on particular TCP flag settings'
   feature :pkttype, 'Match a packet type'
+  feature :rpfilter, 'Perform reverse-path filtering'
   feature :socket, 'Match open sockets'
   feature :isfragment, 'Match fragments'
   feature :address_type, 'The ability match on source or destination address type'
@@ -186,6 +187,7 @@ Puppet::Type.newtype(:firewall) do
   feature :nflog_group, 'netlink group to subscribe to for logging'
   feature :nflog_prefix, ''
   feature :nflog_range, ''
+  feature :nflog_size, ''
   feature :nflog_threshold, ''
   feature :ipset, 'Match against specified ipset list'
   feature :clusterip, 'Configure a simple cluster of nodes that share a certain IP and MAC address without an explicit load balancer in front of them.'
@@ -315,7 +317,7 @@ Puppet::Type.newtype(:firewall) do
       end_addr = matches[2]
 
       [start_addr, end_addr].each do |addr|
-        begin
+        begin # rubocop:disable Style/RedundantBegin
           @resource.host_to_ip(addr)
         rescue StandardError
           raise("Invalid IP address \"#{addr}\" in range \"#{value}\"")
@@ -372,7 +374,7 @@ Puppet::Type.newtype(:firewall) do
       end_addr = matches[2]
 
       [start_addr, end_addr].each do |addr|
-        begin
+        begin # rubocop:disable Style/RedundantBegin
           @resource.host_to_ip(addr)
         rescue StandardError
           raise("Invalid IP address \"#{addr}\" in range \"#{value}\"")
@@ -381,6 +383,17 @@ Puppet::Type.newtype(:firewall) do
     end
   end
 
+  newproperty(:proto) do
+    desc <<-PUPPETCODE
+      The specific protocol to match for this rule.
+    PUPPETCODE
+
+    newvalues(*[:ip, :tcp, :udp, :icmp, :"ipv6-icmp", :esp, :ah, :vrrp, :carp, :igmp, :ipencap, :ipv4, :ipv6, :ospf, :gre, :cbt, :sctp, :pim, :all].map { |proto|
+      [proto, "! #{proto}".to_sym]
+    }.flatten)
+    defaultto 'tcp'
+  end
+
   newproperty(:sport, array_matching: :all) do
     desc <<-PUPPETCODE
       The source port to match for this filter (if the protocol supports
@@ -398,7 +411,7 @@ Puppet::Type.newtype(:firewall) do
     PUPPETCODE
 
     munge do |value|
-      @resource.string_to_port(value, :proto)
+      @resource.string_to_port(value, @resource[:proto])
     end
 
     def to_s?(value)
@@ -428,7 +441,7 @@ Puppet::Type.newtype(:firewall) do
     PUPPETCODE
 
     munge do |value|
-      @resource.string_to_port(value, :proto)
+      @resource.string_to_port(value, @resource[:proto])
     end
 
     def to_s?(value)
@@ -464,7 +477,7 @@ Puppet::Type.newtype(:firewall) do
     end
 
     munge do |value|
-      @resource.string_to_port(value, :proto)
+      @resource.string_to_port(value, @resource[:proto])
     end
 
     def to_s?(value)
@@ -567,17 +580,6 @@ Puppet::Type.newtype(:firewall) do
               }.flatten)
   end
 
-  newproperty(:proto) do
-    desc <<-PUPPETCODE
-      The specific protocol to match for this rule.
-    PUPPETCODE
-
-    newvalues(*[:ip, :tcp, :udp, :icmp, :"ipv6-icmp", :esp, :ah, :vrrp, :carp, :igmp, :ipencap, :ipv4, :ipv6, :ospf, :gre, :cbt, :sctp, :pim, :all].map { |proto|
-      [proto, "! #{proto}".to_sym]
-    }.flatten)
-    defaultto 'tcp'
-  end
-
   # tcp-specific
   newproperty(:mss) do
     desc <<-PUPPETCODE
@@ -894,10 +896,17 @@ Puppet::Type.newtype(:firewall) do
   end
 
   newproperty(:nflog_range, required_features: :nflog_range) do
+    desc <<-PUPPETCODE
+      Used with the jump target NFLOG.
+      This has never worked, use nflog_size instead.
+    PUPPETCODE
+  end
+
+  newproperty(:nflog_size, required_features: :nflog_size) do
     desc <<-PUPPETCODE
       Used with the jump target NFLOG.
       The number of bytes to be copied to userspace (only applicable for nfnetlink_log).
-      nfnetlink_log instances may specify their own range, this option overrides it.
+      nfnetlink_log instances may specify their own size, this option overrides it.
     PUPPETCODE
   end
 
@@ -1704,7 +1713,7 @@ Puppet::Type.newtype(:firewall) do
     newvalues(:true, :false)
   end
 
-  newproperty(:rpfilter, required_features: :rpfilter) do
+  newproperty(:rpfilter, required_features: :rpfilter, array_matching: :all) do
     desc <<-PUPPETCODE
       Enable the rpfilter module.
     PUPPETCODE
@@ -1713,6 +1722,10 @@ Puppet::Type.newtype(:firewall) do
     munge do |value|
       _value = '--' + value
     end
+
+    def insync?(is)
+      is.to_set == should.to_set
+    end
   end
 
   newproperty(:socket, required_features: :socket) do
@@ -1873,8 +1886,8 @@ Puppet::Type.newtype(:firewall) do
     PUPPETCODE
     newvalues(%r{^([0-9a-f]{2}[:]){5}([0-9a-f]{2})$}i)
     facter_os_name = Facter.value(:os)['name'].downcase
-    facter_os_release = Facter.value(:os)['release']['major'].to_i
-    if ['debian-11', 'sles-15'].include?("#{facter_os_name}-#{facter_os_release}")
+    facter_os_release = Facter.value(:os)['release']['major']
+    if ['ubuntu-22.04', 'debian-11', 'sles-15'].include?("#{facter_os_name}-#{facter_os_release}")
       munge do |value|
         _value = value.downcase
       end
@@ -2341,12 +2354,9 @@ Puppet::Type.newtype(:firewall) do
     end
   end
 
-  # autobefore is only provided since puppet 4.0
-  if Puppet::Util::Package.versioncmp(Puppet.version, '4.0') >= 0
-    # On RHEL 7 this needs to be threaded correctly to manage SE Linux permissions after persisting the rules
-    autobefore(:file) do
-      ['/etc/sysconfig/iptables', '/etc/sysconfig/ip6tables']
-    end
+  # On RHEL 7 this needs to be threaded correctly to manage SE Linux permissions after persisting the rules
+  autobefore(:file) do
+    ['/etc/sysconfig/iptables', '/etc/sysconfig/ip6tables']
   end
 
   validate do
diff --git a/lib/puppet/util/firewall.rb b/lib/puppet/util/firewall.rb
index ffa83f3..0801b13 100644
--- a/lib/puppet/util/firewall.rb
+++ b/lib/puppet/util/firewall.rb
@@ -122,7 +122,7 @@ module Puppet::Util::Firewall
 
       new_value = nil
       Resolv.each_address(value) do |addr|
-        begin
+        begin # rubocop:disable Style/RedundantBegin
           new_value = Puppet::Util::IPCidr.new(addr, family)
           break
         rescue # looking for the one that works # rubocop:disable Lint/SuppressedException
@@ -240,6 +240,11 @@ module Puppet::Util::Firewall
             when :IPv6
               ['/bin/sh', '-c', '/usr/sbin/ip6tables-save > /etc/iptables/ip6tables.rules']
             end
+          when :Suse
+            case proto.to_sym
+            when :IPv4
+              ['/bin/sh', '-c', '/usr/sbin/iptables-save > /etc/sysconfig/iptables']
+            end
           end
 
     # Catch unsupported OSs from the case statement above.
diff --git a/manifests/init.pp b/manifests/init.pp
index 02c1109..efbfdb8 100644
--- a/manifests/init.pp
+++ b/manifests/init.pp
@@ -16,7 +16,7 @@
 #   Controls the state of the ipv6 iptables service on your system. Valid options: 'running' or 'stopped'.
 #
 # @param pkg_ensure
-#   Controls the state of the iptables package on your system. Valid options: 'present' or 'latest'.
+#   Controls the state of the iptables package on your system. Valid options: 'present', 'installed' or 'latest'.
 #
 # @param service_name
 #   Specify the name of the IPv4 iptables service.
@@ -31,14 +31,14 @@
 #   Controls whether puppet manages the ebtables package or not. If managed, the package will use the value of pkg_ensure.
 #
 class firewall (
-  $ensure          = running,
-  $ensure_v6       = undef,
-  $pkg_ensure      = present,
-  $service_name    = $firewall::params::service_name,
-  $service_name_v6 = $firewall::params::service_name_v6,
-  $package_name    = $firewall::params::package_name,
-  $ebtables_manage = false,
-) inherits ::firewall::params {
+  Enum[running, stopped, 'running', 'stopped']                       $ensure          = running,
+  Optional[Enum[running, stopped, 'running', 'stopped']]             $ensure_v6       = undef,
+  Enum[present, installed, latest, 'present', 'installed', 'latest'] $pkg_ensure      = present,
+  Variant[String[1], Array[String[1]]]                               $service_name    = $firewall::params::service_name,
+  Optional[String[1]]                                                $service_name_v6 = $firewall::params::service_name_v6,
+  Optional[Variant[String[1], Array[String[1]]]]                     $package_name    = $firewall::params::package_name,
+  Boolean                                                            $ebtables_manage = false,
+) inherits firewall::params {
   $_ensure_v6 = pick($ensure_v6, $ensure)
 
   case $ensure {
@@ -61,7 +61,7 @@ class firewall (
     }
   }
 
-  case $::kernel {
+  case $facts['kernel'] {
     'Linux': {
       class { "${title}::linux":
         ensure          => $ensure,
@@ -74,10 +74,10 @@ class firewall (
       }
       contain "${title}::linux"
     }
-    'FreeBSD', 'windows': {
+    'FreeBSD', 'OpenBSD', 'windows': {
     }
     default: {
-      fail("${title}: Kernel '${::kernel}' is not currently supported")
+      fail("${title}: Kernel '${facts['kernel']}' is not currently supported")
     }
   }
 }
diff --git a/manifests/linux.pp b/manifests/linux.pp
index c782a2c..1d3f8bf 100644
--- a/manifests/linux.pp
+++ b/manifests/linux.pp
@@ -7,7 +7,7 @@
 #   Controls the state of the ipv6 iptables service on your system. Valid options: 'running' or 'stopped'. Defaults to 'running'.
 #
 # @param pkg_ensure
-#   Controls the state of the iptables package on your system. Valid options: 'installed' or 'latest'. Defaults to 'latest'.
+#   Controls the state of the iptables package on your system. Valid options: 'present', 'installed' or 'latest'. Defaults to 'latest'.
 #
 # @param service_name
 #   Specify the name of the IPv4 iptables service. Defaults defined in firewall::params.
@@ -24,15 +24,15 @@
 # @api private
 #
 class firewall::linux (
-  $ensure          = running,
-  $ensure_v6       = undef,
-  $pkg_ensure      = installed,
-  $service_name    = $firewall::params::service_name,
-  $service_name_v6 = $firewall::params::service_name_v6,
-  $package_name    = $firewall::params::package_name,
-  $ebtables_manage = false,
-  $iptables_name   = $firewall::params::iptables_name,
-) inherits ::firewall::params {
+  Enum[running, stopped, 'running', 'stopped']                       $ensure          = running,
+  Optional[Enum[running, stopped, 'running', 'stopped']]             $ensure_v6       = undef,
+  Enum[present, installed, latest, 'present', 'installed', 'latest'] $pkg_ensure      = installed,
+  Variant[String[1], Array[String[1]]]                               $service_name    = $firewall::params::service_name,
+  Optional[String[1]]                                                $service_name_v6 = $firewall::params::service_name_v6,
+  Optional[Variant[String[1], Array[String[1]]]]                     $package_name    = $firewall::params::package_name,
+  Boolean                                                            $ebtables_manage = false,
+  String[1]                                                          $iptables_name   = $firewall::params::iptables_name,
+) inherits firewall::params {
   $enable = $ensure ? {
     'running' => true,
     'stopped' => false,
@@ -46,8 +46,8 @@ class firewall::linux (
   }
 
   package { 'iptables':
-    name   => $iptables_name,
     ensure => $pkg_ensure,
+    name   => $iptables_name,
   }
 
   if $ebtables_manage {
@@ -56,7 +56,7 @@ class firewall::linux (
     }
   }
 
-  case $::operatingsystem {
+  case $facts['os']['name'] {
     'RedHat', 'CentOS', 'Fedora', 'Scientific', 'SL', 'SLC', 'Ascendos',
     'CloudLinux', 'PSBM', 'OracleLinux', 'OVS', 'OEL', 'Amazon', 'XenServer',
     'VirtuozzoLinux', 'Rocky', 'AlmaLinux': {
diff --git a/manifests/linux/archlinux.pp b/manifests/linux/archlinux.pp
index d415caf..af930b1 100644
--- a/manifests/linux/archlinux.pp
+++ b/manifests/linux/archlinux.pp
@@ -19,12 +19,12 @@
 # @api private
 #
 class firewall::linux::archlinux (
-  $ensure         = 'running',
-  $enable         = true,
-  $service_name   = $firewall::params::service_name,
-  $package_name   = $firewall::params::package_name,
-  $package_ensure = $firewall::params::package_ensure,
-) inherits ::firewall::params {
+  Enum[running, stopped, 'running', 'stopped']   $ensure         = 'running',
+  Variant[Boolean, String[1]]                    $enable         = true,
+  Variant[String[1], Array[String[1]]]           $service_name   = $firewall::params::service_name,
+  Optional[Variant[String[1], Array[String[1]]]] $package_name   = $firewall::params::package_name,
+  Enum[present, latest, 'present', 'latest']     $package_ensure = $firewall::params::package_ensure,
+) inherits firewall::params {
   if $package_name {
     package { $package_name:
       ensure => $package_ensure,
diff --git a/manifests/linux/debian.pp b/manifests/linux/debian.pp
index 5b7fc4f..d83fc4d 100644
--- a/manifests/linux/debian.pp
+++ b/manifests/linux/debian.pp
@@ -19,45 +19,24 @@
 # @api private
 #
 class firewall::linux::debian (
-  $ensure         = running,
-  $enable         = true,
-  $service_name   = $firewall::params::service_name,
-  $package_name   = $firewall::params::package_name,
-  $package_ensure = $firewall::params::package_ensure,
-) inherits ::firewall::params {
+  Enum[running, stopped, 'running', 'stopped']   $ensure         = running,
+  Variant[Boolean, String[1]]                    $enable         = true,
+  Variant[String[1], Array[String[1]]]           $service_name   = $firewall::params::service_name,
+  Optional[Variant[String[1], Array[String[1]]]] $package_name   = $firewall::params::package_name,
+  Enum[present, latest, 'present', 'latest']     $package_ensure = $firewall::params::package_ensure,
+) inherits firewall::params {
   if $package_name {
-    #Fixes hang while installing iptables-persistent on debian 8
-    exec { 'iptables-persistent-debconf':
-      command     => "/bin/echo \"${package_name} ${package_name}/autosave_v4 boolean false\" |
-                      /usr/bin/debconf-set-selections && /bin/echo \"${package_name} ${package_name}/autosave_v6 boolean false\" |
-                      /usr/bin/debconf-set-selections",
-
-      refreshonly => true,
-    }
-    ensure_packages([$package_name],{
-        ensure  => $package_ensure,
-        require => Exec['iptables-persistent-debconf']
+    ensure_packages([$package_name], {
+        ensure  => $package_ensure
     })
   }
 
-  if($::operatingsystemrelease =~ /^6\./ and $enable == true and $::iptables_persistent_version
-  and versioncmp($::iptables_persistent_version, '0.5.0') < 0) {
-    # This fixes a bug in the iptables-persistent LSB headers in 6.x, without it
-    # we lose idempotency
-    exec { 'iptables-persistent-enable':
-      logoutput => on_failure,
-      command   => '/usr/sbin/update-rc.d iptables-persistent enable',
-      unless    => '/usr/bin/test -f /etc/rcS.d/S*iptables-persistent',
-      require   => Package[$package_name],
-    }
-  } else {
-    # This isn't a real service/daemon. The start action loads rules, so just
-    # needs to be called on system boot.
-    service { $service_name:
-      ensure    => undef,
-      enable    => $enable,
-      hasstatus => true,
-      require   => Package[$package_name],
-    }
+  # This isn't a real service/daemon. The start action loads rules, so just
+  # needs to be called on system boot.
+  service { $service_name:
+    ensure    => $ensure,
+    enable    => $enable,
+    hasstatus => true,
+    require   => Package[$package_name],
   }
 }
diff --git a/manifests/linux/gentoo.pp b/manifests/linux/gentoo.pp
index 0235a6a..1d2fa09 100644
--- a/manifests/linux/gentoo.pp
+++ b/manifests/linux/gentoo.pp
@@ -19,12 +19,12 @@
 # @api private
 #
 class firewall::linux::gentoo (
-  $ensure         = 'running',
-  $enable         = true,
-  $service_name   = $firewall::params::service_name,
-  $package_name   = $firewall::params::package_name,
-  $package_ensure = $firewall::params::package_ensure,
-) inherits ::firewall::params {
+  Enum[running, stopped, 'running', 'stopped']   $ensure         = running,
+  Variant[Boolean, String[1]]                    $enable         = true,
+  Variant[String[1], Array[String[1]]]           $service_name   = $firewall::params::service_name,
+  Optional[Variant[String[1], Array[String[1]]]] $package_name   = $firewall::params::package_name,
+  Enum[present, latest, 'present', 'latest']     $package_ensure = $firewall::params::package_ensure,
+) inherits firewall::params {
   if $package_name {
     package { $package_name:
       ensure => $package_ensure,
diff --git a/manifests/linux/redhat.pp b/manifests/linux/redhat.pp
index 6945bbc..0231146 100644
--- a/manifests/linux/redhat.pp
+++ b/manifests/linux/redhat.pp
@@ -32,29 +32,30 @@
 # @api private
 #
 class firewall::linux::redhat (
-  $ensure           = running,
-  $ensure_v6        = undef,
-  $enable           = true,
-  $enable_v6        = undef,
-  $service_name     = $firewall::params::service_name,
-  $service_name_v6  = $firewall::params::service_name_v6,
-  $package_name     = $firewall::params::package_name,
-  $package_ensure   = $firewall::params::package_ensure,
-  $sysconfig_manage = $firewall::params::sysconfig_manage,
-) inherits ::firewall::params {
+  Enum[running, stopped, 'running', 'stopped']           $ensure           = running,
+  Optional[Enum[running, stopped, 'running', 'stopped']] $ensure_v6        = undef,
+  Variant[Boolean, String[1]]                            $enable           = true,
+  Optional[Variant[Boolean, String[1]]]                  $enable_v6        = undef,
+  Variant[String[1], Array[String[1]]]                   $service_name     = $firewall::params::service_name,
+  Optional[String[1]]                                    $service_name_v6  = $firewall::params::service_name_v6,
+  Optional[Variant[String[1], Array[String[1]]]]         $package_name     = $firewall::params::package_name,
+  Enum[present, latest, 'present', 'latest']             $package_ensure   = $firewall::params::package_ensure,
+  Boolean                                                $sysconfig_manage = $firewall::params::sysconfig_manage,
+  Boolean                                                $firewalld_manage = $firewall::params::firewalld_manage,
+) inherits firewall::params {
   $_ensure_v6 = pick($ensure_v6, $ensure)
   $_enable_v6 = pick($enable_v6, $enable)
 
   # RHEL 7 / CentOS 7 and later and Fedora 15 and later require the iptables-services
   # package, which provides the /usr/libexec/iptables/iptables.init used by
   # lib/puppet/util/firewall.rb.
-  if ($::operatingsystem != 'Amazon')
-  and (($::operatingsystem != 'Fedora' and versioncmp($::operatingsystemrelease, '7.0') >= 0)
-  or  ($::operatingsystem == 'Fedora' and versioncmp($::operatingsystemrelease, '15') >= 0)) {
-    service { 'firewalld':
-      ensure => stopped,
-      enable => false,
-      before => [Package[$package_name], Service[$service_name]],
+  if ($facts['os']['name'] != 'Amazon') {
+    if $firewalld_manage {
+      service { 'firewalld':
+        ensure => stopped,
+        enable => false,
+        before => [Package[$package_name], Service[$service_name]],
+      }
     }
   }
 
@@ -71,11 +72,12 @@ class firewall::linux::redhat (
     )
   }
 
-  if ($::operatingsystem != 'Amazon')
-  and (($::operatingsystem != 'Fedora' and versioncmp($::operatingsystemrelease, '7.0') >= 0)
-  or  ($::operatingsystem == 'Fedora' and versioncmp($::operatingsystemrelease, '15') >= 0)) {
+  if ($facts['os']['name'] != 'Amazon') {
     if $ensure == 'running' {
+      $running_command = ['/usr/bin/systemctl', 'daemon-reload']
+
       exec { '/usr/bin/systemctl daemon-reload':
+        command     => $running_command,
         require     => Package[$package_name],
         before      => Service[$service_name, $service_name_v6],
         subscribe   => Package[$package_name],
@@ -84,8 +86,8 @@ class firewall::linux::redhat (
     }
   }
 
-  if ($::operatingsystem == 'Amazon') and (versioncmp($::operatingsystemmajrelease, '4') >= 0)
-  or ($::operatingsystem == 'Amazon') and (versioncmp($::operatingsystemmajrelease, '2') >= 0) {
+  if ($facts['os']['name'] == 'Amazon') and (versioncmp($facts['os']['release']['major'], '4') >= 0)
+  or ($facts['os']['name'] == 'Amazon') and (versioncmp($facts['os']['release']['major'], '2') >= 0) {
     service { $service_name:
       ensure    => $ensure,
       enable    => $enable,
@@ -131,26 +133,14 @@ class firewall::linux::redhat (
       }
     }
 
-    # Before puppet 4, the autobefore on the firewall type does not work - therefore
-    # we need to keep this workaround here
-    if versioncmp($::puppetversion, '4.0') <= 0 {
-      File<| title == "/etc/sysconfig/${service_name}" |> -> Service<| title == $service_name |>
-      File<| title == "/etc/sysconfig/${service_name_v6}" |> -> Service<| title == $service_name_v6 |>
-    }
-
     # Redhat 7 selinux user context for /etc/sysconfig/iptables is set to system_u
     # Redhat 7 selinux type context for /etc/sysconfig/iptables is set to system_conf_t
-    case $::selinux {
+    case $facts['os']['selinux']['enabled'] {
       #lint:ignore:quoted_booleans
       'true',true: {
-        case $::operatingsystem {
+        case $facts['os']['name'] {
           'CentOS': {
-            case $::operatingsystemrelease {
-              /^5\..*/: {
-                $seluser = 'system_u'
-                $seltype = 'etc_t'
-              }
-
+            case $facts['os']['release']['full'] {
               /^6\..*/: {
                 $seluser = 'unconfined_u'
                 $seltype = 'system_conf_t'
diff --git a/manifests/params.pp b/manifests/params.pp
index 4f4984d..aa3b94a 100644
--- a/manifests/params.pp
+++ b/manifests/params.pp
@@ -1,53 +1,62 @@
-# @summary Provides defaults for the Apt module parameters.
-# 
+# @summary Provides defaults for the Apt module parameters
+#
 # @api private
 #
 class firewall::params {
   $package_ensure = 'present'
-  case $::osfamily {
+  case $facts['os']['family'] {
     'RedHat': {
-      case $::operatingsystem {
+      case $facts['os']['name'] {
         'Amazon': {
           $service_name = 'iptables'
           $service_name_v6 = 'ip6tables'
           $package_name = undef
           $iptables_name = 'iptables'
           $sysconfig_manage = true
+          $firewalld_manage = true
         }
         'Fedora': {
           $service_name = 'iptables'
           $service_name_v6 = 'ip6tables'
-          if versioncmp($::operatingsystemrelease, '34') >= 0 {
+          if versioncmp($facts['os']['release']['full'], '34') >= 0 {
             $package_name = 'iptables-services'
             $iptables_name = 'iptables-compat'
-          } elsif versioncmp($::operatingsystemrelease, '15') >= 0 {
-            $package_name = 'iptables-services'
-            $iptables_name = 'iptables'
           } else {
             $iptables_name = 'iptables'
             $package_name = undef
           }
           $sysconfig_manage = true
+          $firewalld_manage = true
         }
         default: {
-          if versioncmp($::operatingsystemrelease, '8.0') >= 0 {
+          if versioncmp($facts['os']['release']['full'], '9') >= 0 {
+            $service_name = ['nftables','iptables']
+            $service_name_v6 = 'ip6tables'
+            $package_name = ['iptables-services', 'nftables', 'iptables-nft-services']
+            $iptables_name = 'iptables-nft'
+            $sysconfig_manage = false
+            $firewalld_manage = false
+          } elsif versioncmp($facts['os']['release']['full'], '8.0') >= 0 {
             $service_name = ['iptables', 'nftables']
             $service_name_v6 = 'ip6tables'
             $package_name = ['iptables-services', 'nftables']
             $iptables_name = 'iptables'
             $sysconfig_manage = false
-          } elsif versioncmp($::operatingsystemrelease, '7.0') >= 0 {
+            $firewalld_manage = true
+          } elsif versioncmp($facts['os']['release']['full'], '7.0') >= 0 {
             $service_name = 'iptables'
             $service_name_v6 = 'ip6tables'
             $package_name = 'iptables-services'
             $iptables_name = 'iptables'
             $sysconfig_manage = true
+            $firewalld_manage = true
           } else {
             $service_name = 'iptables'
             $service_name_v6 = 'ip6tables'
             $package_name = 'iptables-ipv6'
             $iptables_name = 'iptables'
             $sysconfig_manage = true
+            $firewalld_manage = true
           }
         }
       }
@@ -55,12 +64,12 @@ class firewall::params {
     'Debian': {
       $service_name_v6 = undef
       $iptables_name = 'iptables'
-      case $::operatingsystem {
+      case $facts['os']['name'] {
         'Debian': {
-          if versioncmp($::operatingsystemrelease, 'unstable') >= 0 {
+          if versioncmp($facts['os']['release']['full'], 'unstable') >= 0 {
             $service_name = 'netfilter-persistent'
             $package_name = 'netfilter-persistent'
-          } elsif versioncmp($::operatingsystemrelease, '8.0') >= 0 {
+          } elsif versioncmp($facts['os']['release']['full'], '8.0') >= 0 {
             $service_name = 'netfilter-persistent'
             $package_name = 'iptables-persistent'
           } else {
@@ -69,7 +78,7 @@ class firewall::params {
           }
         }
         'Ubuntu': {
-          if versioncmp($::operatingsystemrelease, '14.10') >= 0 {
+          if versioncmp($facts['os']['release']['full'], '14.10') >= 0 {
             $service_name = 'netfilter-persistent'
             $package_name = 'iptables-persistent'
           } else {
@@ -91,7 +100,7 @@ class firewall::params {
     default: {
       $iptables_name = 'iptables'
       $service_name_v6 = undef
-      case $::operatingsystem {
+      case $facts['os']['name'] {
         'Archlinux': {
           $service_name = ['iptables','ip6tables']
           $package_name = undef
diff --git a/metadata.json b/metadata.json
index 2f9744d..5ae9f48 100644
--- a/metadata.json
+++ b/metadata.json
@@ -1,6 +1,6 @@
 {
   "name": "puppetlabs-firewall",
-  "version": "3.4.0",
+  "version": "5.0.0",
   "author": "puppetlabs",
   "summary": "Manages Firewalls such as iptables",
   "license": "Apache-2.0",
@@ -17,9 +17,9 @@
     {
       "operatingsystem": "RedHat",
       "operatingsystemrelease": [
-        "6",
         "7",
-        "8"
+        "8",
+        "9"
       ]
     },
     {
@@ -32,14 +32,12 @@
     {
       "operatingsystem": "OracleLinux",
       "operatingsystemrelease": [
-        "6",
         "7"
       ]
     },
     {
       "operatingsystem": "Scientific",
       "operatingsystemrelease": [
-        "6",
         "7"
       ]
     },
@@ -53,7 +51,6 @@
     {
       "operatingsystem": "Debian",
       "operatingsystemrelease": [
-        "9",
         "10",
         "11"
       ]
@@ -61,10 +58,9 @@
     {
       "operatingsystem": "Ubuntu",
       "operatingsystemrelease": [
-        "14.04",
-        "16.04",
         "18.04",
-        "20.04"
+        "20.04",
+        "22.04"
       ]
     },
     {
@@ -83,10 +79,10 @@
   "requirements": [
     {
       "name": "puppet",
-      "version_requirement": ">= 6.0.0 < 8.0.0"
+      "version_requirement": ">= 7.0.0 < 9.0.0"
     }
   ],
   "template-url": "https://github.com/puppetlabs/pdk-templates.git#main",
-  "template-ref": "heads/main-0-gfe51af3",
-  "pdk-version": "2.1.1"
+  "template-ref": "heads/main-0-gc6d4446",
+  "pdk-version": "2.7.1"
 }
diff --git a/provision.yaml b/provision.yaml
index 43201c3..f42a647 100644
--- a/provision.yaml
+++ b/provision.yaml
@@ -16,7 +16,6 @@ travis_deb:
 travis_ub_6:
   provisioner: docker
   images:
-  - litmusimage/ubuntu:14.04
   - litmusimage/ubuntu:16.04
   - litmusimage/ubuntu:18.04
   - litmusimage/ubuntu:20.04

Debdiff

File lists identical (after any substitutions)

No differences were encountered in the control files

More details

Full run details