From 8451eb76b0481cd3e6c17fde6c32005aa98ed3f5 Mon Sep 17 00:00:00 2001 From: adrianiurca Date: Wed, 2 Dec 2020 17:07:38 +0200 Subject: [PATCH] pdksync: add GA workflows --- .github/workflows/nightly.yml | 217 ++++++++++++++++++ .github/workflows/pr_test.yml | 198 ++++++++++++++++ .sync.yml | 4 + README.md | 14 ++ lib/puppet/provider/firewall/ip6tables.rb | 5 +- lib/puppet/provider/firewall/iptables.rb | 8 +- lib/puppet/type/firewall.rb | 16 ++ metadata.json | 6 +- provision.yaml | 3 - .../firewall_attributes_exceptions_spec.rb | 27 +++ spec/acceptance/resource_cmd_spec.rb | 12 +- spec/spec_helper_acceptance_local.rb | 13 +- spec/unit/puppet/type/firewall_spec.rb | 7 + 13 files changed, 517 insertions(+), 13 deletions(-) create mode 100644 .github/workflows/nightly.yml create mode 100644 .github/workflows/pr_test.yml diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml new file mode 100644 index 0000000..4e115c9 --- /dev/null +++ b/.github/workflows/nightly.yml @@ -0,0 +1,217 @@ +name: "nightly" + +on: + schedule: + - cron: '0 0 * * *' + +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: kvrhdn/gha-buildevents@v1.0.2 + with: + apikey: ${{ env.HONEYCOMB_WRITEKEY }} + dataset: ${{ env.HONEYCOMB_DATASET }} + job-status: ${{ job.status }} + + - name: "Honeycomb: Start first step" + run: | + echo STEP_ID=0 >> $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: actions/setup-ruby@v1 + if: ${{ github.repository_owner == 'puppetlabs' }} + with: + ruby-version: "2.7" + + - name: Cache gems + uses: actions/cache@v2 + if: ${{ github.repository_owner == 'puppetlabs' }} + with: + path: vendor/gems + key: ${{ runner.os }}-${{ github.event_name }}-${{ hashFiles('**/Gemfile') }} + restore-keys: | + ${{ runner.os }}-${{ github.event_name }}- + ${{ runner.os }}- + + - name: Install gems + if: ${{ github.repository_owner == 'puppetlabs' }} + run: | + buildevents cmd $TRACE_ID $STEP_ID 'bundle config path vendor/gems' -- bundle config path vendor/gems + buildevents cmd $TRACE_ID $STEP_ID 'bundle config jobs 8' -- bundle config jobs 8 + buildevents cmd $TRACE_ID $STEP_ID 'bundle config retry 3' -- bundle config retry 3 + buildevents cmd $TRACE_ID $STEP_ID 'bundle install' -- bundle install + buildevents cmd $TRACE_ID $STEP_ID 'bundle clean' -- bundle clean + + - 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 + else + echo "::set-output name=matrix::{}" + fi + + - name: "Honeycomb: Record setup time" + if: ${{ always() }} + run: | + buildevents step $TRACE_ID $STEP_ID $STEP_START 'Setup Test Matrix' + + Acceptance: + 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.platform }}' >> $BUILDEVENT_FILE + echo 'collection=${{ matrix.collection }}' >> $BUILDEVENT_FILE + + - name: "Honeycomb: Start recording" + uses: kvrhdn/gha-buildevents@v1.0.2 + with: + apikey: ${{ env.HONEYCOMB_WRITEKEY }} + dataset: ${{ env.HONEYCOMB_DATASET }} + job-status: ${{ job.status }} + matrix-key: ${{ matrix.platform }}-${{ matrix.collection }} + + - name: "Honeycomb: start first step" + run: | + echo STEP_ID=${{ matrix.platform }}-${{ 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: actions/setup-ruby@v1 + with: + ruby-version: "2.7" + + - name: Cache gems + uses: actions/cache@v2 + with: + path: vendor/gems + key: ${{ runner.os }}-${{ github.event_name }}-${{ hashFiles('**/Gemfile') }} + restore-keys: | + ${{ runner.os }}-${{ github.event_name }}- + ${{ runner.os }}- + + - name: "Honeycomb: Record cache setup time" + if: ${{ always() }} + run: | + buildevents step $TRACE_ID $STEP_ID $STEP_START 'Cache retrieval' + echo STEP_ID=${{ matrix.platform }}-${{ matrix.collection }}-2 >> $GITHUB_ENV + echo STEP_START=$(date +%s) >> $GITHUB_ENV + + - name: Bundler Setup + run: | + buildevents cmd $TRACE_ID $STEP_ID 'bundle config path vendor/gems' -- bundle config path vendor/gems + buildevents cmd $TRACE_ID $STEP_ID 'bundle config jobs 8' -- bundle config jobs 8 + buildevents cmd $TRACE_ID $STEP_ID 'bundle config retry 3' -- bundle config retry 3 + buildevents cmd $TRACE_ID $STEP_ID 'bundle install' -- bundle install + buildevents cmd $TRACE_ID $STEP_ID 'bundle clean' -- bundle clean + echo ::group::bundler environment + buildevents cmd $TRACE_ID $STEP_ID 'bundle env' -- bundle env + echo ::endgroup:: + + - name: "Honeycomb: Record Bundler Setup time" + if: ${{ always() }} + run: | + buildevents step $TRACE_ID $STEP_ID $STEP_START 'Bundler Setup' + echo STEP_ID=${{ matrix.platform }}-${{ matrix.collection }}-3 >> $GITHUB_ENV + echo STEP_START=$(date +%s) >> $GITHUB_ENV + + - name: Provision test environment + run: | + buildevents cmd $TRACE_ID $STEP_ID 'rake litmus:provision ${{ matrix.platform }}' -- bundle exec rake 'litmus:provision[provision::provision_service,${{ matrix.platform }}]' + echo ::group::=== REQUEST === + cat request.json || true + echo + echo ::endgroup:: + echo ::group::=== INVENTORY === + sed -e 's/password: .*/password: "[redacted]"/' < inventory.yaml || 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.platform }}-${{ matrix.collection }}-4 >> $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.platform }}-${{ matrix.collection }}-5 >> $GITHUB_ENV + echo STEP_START=$(date +%s) >> $GITHUB_ENV + + - name: Remove test environment + if: ${{ always() }} + run: | + if [ -f 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' + + slack-workflow-status: + if: always() + name: Post Workflow Status To Slack + needs: + - Acceptance + runs-on: ubuntu-20.04 + steps: + - name: Slack Workflow Notification + uses: Gamesight/slack-workflow-status@master + 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 new file mode 100644 index 0000000..2bfa445 --- /dev/null +++ b/.github/workflows/pr_test.yml @@ -0,0 +1,198 @@ +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: kvrhdn/gha-buildevents@v1.0.2 + with: + apikey: ${{ env.HONEYCOMB_WRITEKEY }} + dataset: ${{ env.HONEYCOMB_DATASET }} + job-status: ${{ job.status }} + + - name: "Honeycomb: Start first step" + run: | + echo STEP_ID=0 >> $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: actions/setup-ruby@v1 + if: ${{ github.repository_owner == 'puppetlabs' }} + with: + ruby-version: "2.7" + + - name: Cache gems + uses: actions/cache@v2 + if: ${{ github.repository_owner == 'puppetlabs' }} + with: + path: vendor/gems + key: ${{ runner.os }}-${{ github.event_name }}-${{ hashFiles('**/Gemfile') }} + restore-keys: | + ${{ runner.os }}-${{ github.event_name }}- + ${{ runner.os }}- + + - name: Install gems + if: ${{ github.repository_owner == 'puppetlabs' }} + run: | + buildevents cmd $TRACE_ID $STEP_ID 'bundle config path vendor/gems' -- bundle config path vendor/gems + buildevents cmd $TRACE_ID $STEP_ID 'bundle config jobs 8' -- bundle config jobs 8 + buildevents cmd $TRACE_ID $STEP_ID 'bundle config retry 3' -- bundle config retry 3 + buildevents cmd $TRACE_ID $STEP_ID 'bundle install' -- bundle install + buildevents cmd $TRACE_ID $STEP_ID 'bundle clean' -- bundle clean + + - 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 + else + echo "::set-output name=matrix::{}" + fi + + - name: "Honeycomb: Record setup time" + if: ${{ always() }} + run: | + buildevents step $TRACE_ID $STEP_ID $STEP_START 'Setup Test Matrix' + + Acceptance: + 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.platform }}' >> $BUILDEVENT_FILE + echo 'collection=${{ matrix.collection }}' >> $BUILDEVENT_FILE + + - name: "Honeycomb: Start recording" + uses: kvrhdn/gha-buildevents@v1.0.2 + with: + apikey: ${{ env.HONEYCOMB_WRITEKEY }} + dataset: ${{ env.HONEYCOMB_DATASET }} + job-status: ${{ job.status }} + matrix-key: ${{ matrix.platform }}-${{ matrix.collection }} + + - name: "Honeycomb: start first step" + run: | + echo STEP_ID=${{ matrix.platform }}-${{ 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: actions/setup-ruby@v1 + with: + ruby-version: "2.7" + + - name: Cache gems + uses: actions/cache@v2 + with: + path: vendor/gems + key: ${{ runner.os }}-${{ github.event_name }}-${{ hashFiles('**/Gemfile') }} + restore-keys: | + ${{ runner.os }}-${{ github.event_name }}- + ${{ runner.os }}- + + - name: "Honeycomb: Record cache setup time" + if: ${{ always() }} + run: | + buildevents step $TRACE_ID $STEP_ID $STEP_START 'Cache retrieval' + echo STEP_ID=${{ matrix.platform }}-${{ matrix.collection }}-2 >> $GITHUB_ENV + echo STEP_START=$(date +%s) >> $GITHUB_ENV + + - name: Bundler Setup + run: | + buildevents cmd $TRACE_ID $STEP_ID 'bundle config path vendor/gems' -- bundle config path vendor/gems + buildevents cmd $TRACE_ID $STEP_ID 'bundle config jobs 8' -- bundle config jobs 8 + buildevents cmd $TRACE_ID $STEP_ID 'bundle config retry 3' -- bundle config retry 3 + buildevents cmd $TRACE_ID $STEP_ID 'bundle install' -- bundle install + buildevents cmd $TRACE_ID $STEP_ID 'bundle clean' -- bundle clean + echo ::group::bundler environment + buildevents cmd $TRACE_ID $STEP_ID 'bundle env' -- bundle env + echo ::endgroup:: + + - name: "Honeycomb: Record Bundler Setup time" + if: ${{ always() }} + run: | + buildevents step $TRACE_ID $STEP_ID $STEP_START 'Bundler Setup' + echo STEP_ID=${{ matrix.platform }}-${{ matrix.collection }}-3 >> $GITHUB_ENV + echo STEP_START=$(date +%s) >> $GITHUB_ENV + + - name: Provision test environment + run: | + buildevents cmd $TRACE_ID $STEP_ID 'rake litmus:provision ${{ matrix.platform }}' -- bundle exec rake 'litmus:provision[provision::provision_service,${{ matrix.platform }}]' + echo ::group::=== REQUEST === + cat request.json || true + echo + echo ::endgroup:: + echo ::group::=== INVENTORY === + sed -e 's/password: .*/password: "[redacted]"/' < inventory.yaml || 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.platform }}-${{ matrix.collection }}-4 >> $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.platform }}-${{ matrix.collection }}-5 >> $GITHUB_ENV + echo STEP_START=$(date +%s) >> $GITHUB_ENV + + - name: Remove test environment + if: ${{ always() }} + run: | + if [ -f 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/.sync.yml b/.sync.yml index 05a7873..89bcf43 100644 --- a/.sync.yml +++ b/.sync.yml @@ -58,3 +58,7 @@ spec/spec_helper.rb: unmanaged: false .gitpod.yml: unmanaged: false +.github/workflows/nightly.yml: + unmanaged: false +.github/workflows/pr_test.yml: + unmanaged: false diff --git a/README.md b/README.md index 573f121..768faf1 100644 --- a/README.md +++ b/README.md @@ -476,6 +476,20 @@ To prevent this issue, do not use MCollective to kick off Puppet runs. Use any o * Use a cron job. * Click [Run Puppet](https://docs.puppet.com/pe/2016.1/console_classes_groups_running_puppet.html#run-puppet-on-an-individual-node) in the console. +### condition parameter + +The `condition` parameter requires `xtables-addons` to be installed locally. +For ubuntu distributions `xtables-addons-common` package can be installed by running command: `apt-get install xtables-addons-common` or +running a manifest: + +```puppet +package { 'xtables-addons-common': + ensure => 'latest', +} +``` + +For other distributions (RedHat, Debian, Centos etc) manual installation of the `xtables-addons` package is required. + #### Reporting Issues Please report any bugs in the Puppetlabs JIRA issue tracker: diff --git a/lib/puppet/provider/firewall/ip6tables.rb b/lib/puppet/provider/firewall/ip6tables.rb index bcf35fa..efab4f8 100644 --- a/lib/puppet/provider/firewall/ip6tables.rb +++ b/lib/puppet/provider/firewall/ip6tables.rb @@ -2,6 +2,7 @@ Puppet::Type.type(:firewall).provide :ip6tables, parent: :iptables, source: :ip6 @doc = 'Ip6tables type provider' has_feature :iptables + has_feature :condition has_feature :connection_limiting has_feature :conntrack has_feature :hop_limiting @@ -83,6 +84,7 @@ Puppet::Type.type(:firewall).provide :ip6tables, parent: :iptables, source: :ip6 burst: '--limit-burst', checksum_fill: '--checksum-fill', clamp_mss_to_pmtu: '--clamp-mss-to-pmtu', + condition: '--condition', connlimit_above: '-m connlimit --connlimit-above', connlimit_mask: '--connlimit-mask', connmark: '-m connmark --mark', @@ -250,6 +252,7 @@ Puppet::Type.type(:firewall).provide :ip6tables, parent: :iptables, source: :ip6 addrtype: [:src_type, :dst_type], iprange: [:src_range, :dst_range], owner: [:uid, :gid], + condition: [:condition], conntrack: [:ctstate, :ctproto, :ctorigsrc, :ctorigdst, :ctreplsrc, :ctrepldst, :ctorigsrcport, :ctorigdstport, :ctreplsrcport, :ctrepldstport, :ctstatus, :ctexpire, :ctdir], time: [:time_start, :time_stop, :month_days, :week_days, :date_start, :date_stop, :time_contiguous, :kernel_timezone], @@ -308,5 +311,5 @@ Puppet::Type.type(:firewall).provide :ip6tables, parent: :iptables, source: :ip6 :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, :src_cc, :dst_cc, :hashlimit_upto, :hashlimit_above, :hashlimit_name, :hashlimit_burst, :hashlimit_mode, :hashlimit_srcmask, :hashlimit_dstmask, :hashlimit_htable_size, - :hashlimit_htable_max, :hashlimit_htable_expire, :hashlimit_htable_gcinterval, :bytecode, :zone, :helper, :rpfilter, :name, :notrack] + :hashlimit_htable_max, :hashlimit_htable_expire, :hashlimit_htable_gcinterval, :bytecode, :zone, :helper, :rpfilter, :condition, :name, :notrack] end diff --git a/lib/puppet/provider/firewall/iptables.rb b/lib/puppet/provider/firewall/iptables.rb index 76dc990..c101ddc 100644 --- a/lib/puppet/provider/firewall/iptables.rb +++ b/lib/puppet/provider/firewall/iptables.rb @@ -7,6 +7,7 @@ Puppet::Type.type(:firewall).provide :iptables, parent: Puppet::Provider::Firewa @doc = 'Iptables type provider' has_feature :iptables + has_feature :condition has_feature :connection_limiting has_feature :conntrack has_feature :rate_limiting @@ -75,6 +76,7 @@ Puppet::Type.type(:firewall).provide :iptables, parent: Puppet::Provider::Firewa burst: '--limit-burst', checksum_fill: '--checksum-fill', clamp_mss_to_pmtu: '--clamp-mss-to-pmtu', + condition: '--condition', connlimit_above: '-m connlimit --connlimit-above', connlimit_mask: '--connlimit-mask', connmark: '-m connmark --mark', @@ -252,6 +254,7 @@ Puppet::Type.type(:firewall).provide :iptables, parent: Puppet::Provider::Firewa addrtype: [:src_type, :dst_type], iprange: [:src_range, :dst_range], owner: [:uid, :gid], + condition: [:condition], conntrack: [:ctstate, :ctproto, :ctorigsrc, :ctorigdst, :ctreplsrc, :ctrepldst, :ctorigsrcport, :ctorigdstport, :ctreplsrcport, :ctrepldstport, :ctstatus, :ctexpire, :ctdir], time: [:time_start, :time_stop, :month_days, :week_days, :date_start, :date_stop, :time_contiguous, :kernel_timezone], @@ -348,7 +351,7 @@ Puppet::Type.type(:firewall).provide :iptables, parent: Puppet::Provider::Firewa :month_days, :week_days, :date_start, :date_stop, :time_contiguous, :kernel_timezone, :src_cc, :dst_cc, :hashlimit_upto, :hashlimit_above, :hashlimit_name, :hashlimit_burst, :hashlimit_mode, :hashlimit_srcmask, :hashlimit_dstmask, :hashlimit_htable_size, - :hashlimit_htable_max, :hashlimit_htable_expire, :hashlimit_htable_gcinterval, :bytecode, :ipvs, :zone, :helper, :cgroup, :rpfilter, :name, :notrack + :hashlimit_htable_max, :hashlimit_htable_expire, :hashlimit_htable_gcinterval, :bytecode, :ipvs, :zone, :helper, :cgroup, :rpfilter, :condition, :name, :notrack ] def insert @@ -452,6 +455,8 @@ Puppet::Type.type(:firewall).provide :iptables, parent: Puppet::Provider::Firewa values = values.gsub(%r{(!\s+)?--tcp-flags (\S*) (\S*)}, '--tcp-flags "\1\2 \3"') # --hex-string output is in quotes, need to move ! inside quotes values = values.gsub(%r{(!\s+)?--hex-string "(\S*?)"}, '--hex-string "\1\2"') + # --condition output is in quotes, need to move ! inside quotes + values.gsub!(%r{(!\s+)?--condition "(\S*?)"}, '--condition "\1\2"') # --match-set can have multiple values with weird iptables format if values =~ %r{-m set (!\s+)?--match-set} values = values.gsub(%r{(!\s+)?--match-set (\S*) (\S*)}, '--match-set \1\2 \3') @@ -653,6 +658,7 @@ Puppet::Type.type(:firewall).provide :iptables, parent: Puppet::Provider::Firewa # Invert any rules that are prefixed with a '!' [ :connmark, + :condition, :ctstate, :ctproto, :ctorigsrc, diff --git a/lib/puppet/type/firewall.rb b/lib/puppet/type/firewall.rb index 2b315a4..3901b3e 100644 --- a/lib/puppet/type/firewall.rb +++ b/lib/puppet/type/firewall.rb @@ -56,6 +56,8 @@ Puppet::Type.newtype(:firewall) do * clusterip: Configure a simple cluster of nodes that share a certain IP and MAC address without an explicit load balancer in front of them. + * condition: Match if a specific condition variable is (un)set (requires xtables-addons) + * connection_limiting: Connection limiting features. * conntrack: Connection tracking features. @@ -146,6 +148,7 @@ Puppet::Type.newtype(:firewall) do PUPPETCODE feature :connection_limiting, 'Connection limiting features.' + feature :condition, 'Match if a specific condition variable is (un)set.' feature :conntrack, 'Connection tracking features.' feature :hop_limiting, 'Hop limiting features.' feature :rate_limiting, 'Rate limiting features.' @@ -2248,6 +2251,19 @@ Puppet::Type.newtype(:firewall) do newvalues(:true, :false) end + newproperty(:condition, required_features: :condition) do + desc <<-PUPPETCODE + Match on boolean value (0/1) stored in /proc/net/nf_condition/name. + PUPPETCODE + validate do |value| + unless value.is_a?(String) + raise ArgumentError, <<-PUPPETCODE + Condition must be a string. + PUPPETCODE + end + end + end + autorequire(:firewallchain) do reqs = [] protocol = nil diff --git a/metadata.json b/metadata.json index d165edc..12c6c25 100644 --- a/metadata.json +++ b/metadata.json @@ -75,10 +75,10 @@ "requirements": [ { "name": "puppet", - "version_requirement": ">= 5.5.10 < 7.0.0" + "version_requirement": ">= 5.5.10 < 8.0.0" } ], "template-url": "https://github.com/puppetlabs/pdk-templates#main", - "template-ref": "heads/main-0-gd9b4054", + "template-ref": "heads/main-0-g62126e1", "pdk-version": "1.18.1" -} +} \ No newline at end of file diff --git a/provision.yaml b/provision.yaml index 7d7f1ab..028dfe6 100644 --- a/provision.yaml +++ b/provision.yaml @@ -26,9 +26,6 @@ travis_ub_6: - litmusimage/ubuntu:16.04 - litmusimage/ubuntu:18.04 - litmusimage/ubuntu:20.04 -travis_el6: - provisioner: docker - images: [] travis_el7: provisioner: docker images: diff --git a/spec/acceptance/firewall_attributes_exceptions_spec.rb b/spec/acceptance/firewall_attributes_exceptions_spec.rb index 867c356..0d9c4b1 100644 --- a/spec/acceptance/firewall_attributes_exceptions_spec.rb +++ b/spec/acceptance/firewall_attributes_exceptions_spec.rb @@ -1369,4 +1369,31 @@ describe 'firewall basics', docker: true do expect(result.stdout).to match(%r{-A POSTROUTING -p tcp -m comment --comment "901 - set random-fully" -j MASQUERADE}) end end + + describe 'condition', condition_parameter_test: false do + context 'is set' do + pp = <<-PUPPETCODE + if $facts['os']['name'] == 'Ubuntu' and versioncmp($facts['os']['release']['full'], '14.04') > 0 { + firewall { '010 isblue ipv4': + ensure => 'present', + condition => '! isblue', + chain => 'INPUT', + iniface => 'enp0s8', + proto => 'icmp', + action => 'drop', + } + } + PUPPETCODE + it 'applies' do + apply_manifest(pp) + end + if fetch_os_name == 'ubuntu' && os[:release].to_i > 14 + it 'contains the rule' do + run_shell('iptables-save') do |r| + expect(r.stdout).to match(%r{-A INPUT -i enp0s8 -p icmp -m condition ! --condition "isblue" -m comment --comment "010 isblue ipv4" -j DROP}) + end + end + end + end + end end diff --git a/spec/acceptance/resource_cmd_spec.rb b/spec/acceptance/resource_cmd_spec.rb index 03a9aae..3c6137e 100644 --- a/spec/acceptance/resource_cmd_spec.rb +++ b/spec/acceptance/resource_cmd_spec.rb @@ -8,8 +8,16 @@ describe 'puppet resource firewall command' do # In order to properly check stderr for anomalies we need to fix the deprecation warnings from puppet.conf. config = run_shell('puppet config print config').stdout run_shell("sed -i -e \'s/^templatedir.*$//\' #{config}") - run_shell('echo export LC_ALL=C > ~/.bashrc') - run_shell('echo export PATH="/opt/puppetlabs/bin:$PATH" > ~/.bashrc') + if fetch_os_name == 'redhat' && [6, 7].include?(os[:release].to_i) + run_shell('echo export LC_ALL="C" > /etc/profile.d/my-custom.lang.sh') + run_shell('echo "## US English ##" >> /etc/profile.d/my-custom.lang.sh') + run_shell('echo export LANG=en_US.UTF-8 >> /etc/profile.d/my-custom.lang.sh') + run_shell('echo export LANGUAGE=en_US.UTF-8 >> /etc/profile.d/my-custom.lang.sh') + run_shell('echo export LC_COLLATE=C >> /etc/profile.d/my-custom.lang.sh') + run_shell('echo export LC_CTYPE=en_US.UTF-8 >> /etc/profile.d/my-custom.lang.sh') + run_shell('source /etc/profile.d/my-custom.lang.sh') + end + run_shell('echo export LC_ALL="C" >> ~/.bashrc') run_shell('source ~/.bashrc') end diff --git a/spec/spec_helper_acceptance_local.rb b/spec/spec_helper_acceptance_local.rb index 204955c..d620d08 100644 --- a/spec/spec_helper_acceptance_local.rb +++ b/spec/spec_helper_acceptance_local.rb @@ -48,6 +48,10 @@ def fetch_os_name end RSpec.configure do |c| + # This flag is disabling test 'condition' from firewall_attributes_exceptions + # because this test is failing on docker containers, but it's compatible with vmpooler machines + # To enable tests on abs/vmpooler machines just set to `true` this flag + c.filter_run_excluding condition_parameter_test: false c.before :suite do if fetch_os_name == 'centos' && os[:release].to_i == 8 pp = <<-PUPPETCODE @@ -65,9 +69,6 @@ RSpec.configure do |c| package { 'net-tools': ensure => 'latest', } - package { 'iptables': - ensure => 'latest', - } PUPPETCODE LitmusHelper.instance.apply_manifest(pp) LitmusHelper.instance.run_shell('update-alternatives --set iptables /usr/sbin/iptables-legacy', expect_failures: true) @@ -77,6 +78,12 @@ RSpec.configure do |c| package { 'conntrack-tools': ensure => 'latest', } + package { 'xtables-addons-common': + ensure => 'latest', + } + package { 'iptables': + ensure => 'latest', + } PUPPETCODE LitmusHelper.instance.apply_manifest(pp) end diff --git a/spec/unit/puppet/type/firewall_spec.rb b/spec/unit/puppet/type/firewall_spec.rb index fbe65eb..70d026f 100755 --- a/spec/unit/puppet/type/firewall_spec.rb +++ b/spec/unit/puppet/type/firewall_spec.rb @@ -823,6 +823,13 @@ describe firewall do # rubocop:disable RSpec/MultipleDescribes end end + describe ':condition' do + it 'accepts value as a string' do + resource[:condition] = 'somefile' + expect(resource[:condition]).to eq('somefile') + end + end + describe 'autorequire packages' do [:iptables, :ip6tables].each do |provider| it "provider #{provider} should autorequire package iptables" do -- 2.45.2