From a7fa2acc58f561dc33eafc4c827942c320ca8c5e Mon Sep 17 00:00:00 2001 From: Andrey Voronkov Date: Wed, 17 Aug 2022 15:10:40 +0300 Subject: [PATCH] Add ability match_mark to be negated --- lib/puppet/type/firewall.rb | 17 +++++++++++------ .../firewall_attributes_exceptions_spec.rb | 19 +++++++++++++++++++ 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/lib/puppet/type/firewall.rb b/lib/puppet/type/firewall.rb index 6509c1c..ead7b09 100644 --- a/lib/puppet/type/firewall.rb +++ b/lib/puppet/type/firewall.rb @@ -1481,28 +1481,33 @@ Puppet::Type.newtype(:firewall) do desc <<-PUPPETCODE Match the Netfilter mark value associated with the packet. Accepts either of: mark/mask or mark. These will be converted to hex if they are not already. + + match_mark => '0x02' + + You can also negate a value by putting ! in front. For example: + + match_mark => '! 0x02' PUPPETCODE munge do |value| - mark_regex = %r{\A((?:0x)?[0-9A-F]+)(/)?((?:0x)?[0-9A-F]+)?\z}i + mark_regex = %r{\A(!\s)?((?:0x)?[0-9A-F]+)(/)?((?:0x)?[0-9A-F]+)?\z}i match = value.to_s.match(mark_regex) if match.nil? raise ArgumentError, 'Match MARK value must be integer or hex between 0 and 0xffffffff' end - mark = @resource.to_hex32(match[1]) + mark = @resource.to_hex32(match[2]) # Values that can't be converted to hex. # Or contain a trailing slash with no mask. - if mark.nil? || (mark && match[2] && match[3].nil?) + if mark.nil? || (mark && match[3] && match[4].nil?) raise ArgumentError, 'Match MARK value must be integer or hex between 0 and 0xffffffff' end # There should not be a mask on match_mark - unless match[3].nil? + unless match[4].nil? raise ArgumentError, 'iptables does not support masks on MARK match rules' end - value = mark - value + match[1] ? "! #{mark}" : mark end end diff --git a/spec/acceptance/firewall_attributes_exceptions_spec.rb b/spec/acceptance/firewall_attributes_exceptions_spec.rb index 3616db5..0c35b68 100644 --- a/spec/acceptance/firewall_attributes_exceptions_spec.rb +++ b/spec/acceptance/firewall_attributes_exceptions_spec.rb @@ -1251,6 +1251,25 @@ describe 'firewall basics', docker: true do expect(r.stdout).to match(%r{-A INPUT -m mark --mark 0x1 -m comment --comment "503 match_mark - test" -j REJECT --reject-with icmp-port-unreachable}) end end + + context 'when ! 0x1' do + pp1 = <<-PUPPETCODE + class { '::firewall': } + firewall { '504 match_mark - negate test': + proto => 'all', + match_mark => '! 0x1', + action => reject, + } + PUPPETCODE + it 'applies' do + apply_manifest(pp1, catch_failures: true) + end + + it 'contains the rule' do + run_shell('iptables-save') do |r| + expect(r.stdout).to match(%r{-A INPUT -m mark --mark ! 0x1 -m comment --comment "504 match_mark - negate test" -j REJECT --reject-with icmp-port-unreachable}) + end + end end end -- 2.45.2