]> review.fuel-infra Code Review - puppet-modules/puppetlabs-firewall.git/commitdiff
(MODULES-442) Correct boolean properties behavior
authorHunter Haugen <hunter@puppetlabs.com>
Fri, 31 Jan 2014 21:19:27 +0000 (13:19 -0800)
committerHunter Haugen <hunter@puppetlabs.com>
Mon, 3 Feb 2014 20:57:10 +0000 (12:57 -0800)
The boolean properties had a few things incorrect with them.

- Any value passed was considered `true`. This was compounded further by
  the next issue.
- When the read property was false, it was set to 'nil'. This caused
  `<property> => false` to not work after the previous was fixed.

Random other fixes to tests that were failing or poorly implemented are
also included

lib/puppet/provider/firewall/ip6tables.rb
lib/puppet/provider/firewall/iptables.rb
spec/acceptance/change_source_spec.rb
spec/acceptance/firewall_spec.rb
spec/acceptance/firewallchain_spec.rb
spec/acceptance/ip6_fragment_spec.rb [new file with mode: 0644]
spec/acceptance/isfragment_spec.rb [new file with mode: 0644]
spec/acceptance/rules_spec.rb
spec/acceptance/socket_spec.rb [new file with mode: 0644]
spec/spec_helper_acceptance.rb

index 56319b1fa8cc5cd51090d5a41721ea8831f7ca70..b42eab478bd36cfb4919f820cbcd2b9feea5f2f5 100644 (file)
@@ -67,14 +67,34 @@ Puppet::Type.type(:firewall).provide :ip6tables, :parent => :iptables, :source =
     :isfirstfrag => "-m frag --fragid 0 --fragfirst",
   }
 
+  # These are known booleans that do not take a value, but we want to munge
+  # to true if they exist.
+  @known_booleans = [:ishasmorefrags, :islastfrag, :isfirstfrag]
+
   # Create property methods dynamically
   (@resource_map.keys << :chain << :table << :action).each do |property|
-    define_method "#{property}" do
-      @property_hash[property.to_sym]
+    if @known_booleans.include?(property) then
+      # The boolean properties default to '' which should be read as false
+      define_method "#{property}" do
+        @property_hash[property] = :false if @property_hash[property] == nil
+        @property_hash[property.to_sym]
+      end
+    else
+      define_method "#{property}" do
+        @property_hash[property.to_sym]
+      end
     end
 
-    define_method "#{property}=" do |value|
-      @property_hash[:needs_change] = true
+    if property == :chain
+      define_method "#{property}=" do |value|
+        if @property_hash[:chain] != value
+          raise ArgumentError, "Modifying the chain for existing rules is not supported."
+        end
+      end
+    else
+      define_method "#{property}=" do |value|
+        @property_hash[:needs_change] = true
+      end
     end
   end
 
@@ -90,8 +110,4 @@ Puppet::Type.type(:firewall).provide :ip6tables, :parent => :iptables, :source =
     :port, :pkttype, :name, :state, :ctstate, :icmp, :hop_limit, :limit, :burst,
     :jump, :todest, :tosource, :toports, :log_level, :log_prefix, :reject]
 
-  # These are known booleans that do not take a value, but we want to munge
-  # to true if they exist.
-  @known_booleans = [:ishasmorefrags, :islastfrag, :isfirstfrag]
-
 end
index f7a0a7433bca4cc1e32be57c2bc33e096333b4c0..ff5e6b8f8f43b016235a7882bf08819258cc43eb 100644 (file)
@@ -88,8 +88,16 @@ Puppet::Type.type(:firewall).provide :iptables, :parent => Puppet::Provider::Fir
 
   # Create property methods dynamically
   (@resource_map.keys << :chain << :table << :action).each do |property|
-    define_method "#{property}" do
-      @property_hash[property.to_sym]
+    if @known_booleans.include?(property) then
+      # The boolean properties default to '' which should be read as false
+      define_method "#{property}" do
+        @property_hash[property] = :false if @property_hash[property] == nil
+        @property_hash[property.to_sym]
+      end
+    else
+      define_method "#{property}" do
+        @property_hash[property.to_sym]
+      end
     end
 
     if property == :chain
@@ -253,7 +261,7 @@ Puppet::Type.type(:firewall).provide :iptables, :parent => Puppet::Provider::Fir
     # Convert booleans removing the previous cludge we did
     @known_booleans.each do |bool|
       if hash[bool] != nil then
-        unless hash[bool] == "true" then
+        if hash[bool] != "true" then
           raise "Parser error: #{bool} was meant to be a boolean but received value: #{hash[bool]}."
         end
       end
@@ -355,10 +363,13 @@ Puppet::Type.type(:firewall).provide :iptables, :parent => Puppet::Provider::Fir
         resource_value = resource[res]
         # If socket is true then do not add the value as -m socket is standalone
         if known_booleans.include?(res) then
-          resource_value = nil
-        end
-        if res == :isfragment then
-          resource_value = nil
+          if resource[res] == :true then
+            resource_value = nil
+          else
+            # If the property is not :true then we don't want to add the value
+            # to the args list
+            next
+          end
         end
       elsif res == :jump and resource[:action] then
         # In this case, we are substituting jump for action
index 02760b0998ff0c763552f3f44c674ca480045dfd..2a53363107497109a85ecc62f94561198075efd0 100644 (file)
@@ -28,6 +28,11 @@ describe 'firewall type' do
       apply_manifest(pp, :catch_failures => true)
     end
 
+    it 'adds a unmanaged rule without a comment' do
+      shell('/sbin/iptables -A INPUT -t filter -s 8.0.0.3/32 -p tcp -m multiport --ports 102 -j ACCEPT')
+      expect(shell('iptables -S').stdout).to match(/-A INPUT -s 8\.0\.0\.3\/32 -p tcp -m multiport --ports 102 -j ACCEPT/)
+    end
+
     it 'contains the changable 8.0.0.1 rule' do
       shell('iptables -S') do |r|
         expect(r.stdout).to match(/-A INPUT -s 8\.0\.0\.1\/32 -p tcp -m multiport --ports 101 -m comment --comment "101 test source changes" -j ACCEPT/)
@@ -39,11 +44,6 @@ describe 'firewall type' do
       end
     end
 
-    it 'adds a unmanaged rule without a comment' do
-      shell('/sbin/iptables -R INPUT 1 -t filter -s 8.0.0.3/32 -p tcp -m multiport --ports 100 -j ACCEPT')
-      expect(shell('iptables -S').stdout).to match(/-A INPUT -s 8\.0\.0\.3\/32 -p tcp -m multiport --ports 100 -j ACCEPT/)
-    end
-
     it 'changes to 8.0.0.4 second' do
       pp = <<-EOS
           class { '::firewall': }
index 8bc2da42e3a64c164ce89e7134fbcae91b2b9899..864fe016bd17ef38a943432282fa8f5917365e82 100644 (file)
@@ -116,6 +116,7 @@ describe 'firewall type' do
         EOS
 
         apply_manifest(pp, :catch_failures => true)
+        apply_manifest(pp, :catch_changes => true)
       end
 
       it 'should contain the rule' do
@@ -138,6 +139,7 @@ describe 'firewall type' do
         EOS
 
         apply_manifest(pp, :catch_failures => true)
+        apply_manifest(pp, :catch_changes => true)
       end
 
       it 'should contain the rule' do
@@ -187,6 +189,7 @@ describe 'firewall type' do
         EOS
 
         apply_manifest(pp, :catch_failures => true)
+        apply_manifest(pp, :catch_changes => true)
       end
 
       it 'should contain the rule' do
@@ -236,6 +239,7 @@ describe 'firewall type' do
         EOS
 
         apply_manifest(pp, :catch_failures => true)
+        apply_manifest(pp, :catch_changes => true)
       end
 
       it 'should contain the rule' do
@@ -258,6 +262,7 @@ describe 'firewall type' do
         EOS
 
         apply_manifest(pp, :catch_failures => true)
+        apply_manifest(pp, :catch_changes => true)
       end
 
       it 'should contain the rule' do
@@ -307,6 +312,7 @@ describe 'firewall type' do
         EOS
 
         apply_manifest(pp, :catch_failures => true)
+        apply_manifest(pp, :catch_changes => true)
       end
 
       it 'should contain the rule' do
@@ -683,6 +689,11 @@ describe 'firewall type' do
   end
 
   describe 'jump' do
+    after :all do
+      iptables_flush_all_tables
+      expect(shell('iptables -t filter -X TEST').stderr).to eq("")
+    end
+
     context 'MARK' do
       it 'applies' do
         pp = <<-EOS
index cd6d6b8c8604c417b94dfea71d2fef590933e75e..4a9fa76d226706feb1cb2fa9e5c50d22446f7aaa 100644 (file)
@@ -14,7 +14,7 @@ describe 'puppet resource firewallchain command:' do
         EOS
         # Run it twice and test for idempotency
         apply_manifest(pp, :catch_failures => true)
-        expect(apply_manifest(pp, :catch_failures => true).exit_code).to be_zero
+        apply_manifest(pp, :catch_changes => true)
       end
 
       it 'finds the chain' do
@@ -33,7 +33,7 @@ describe 'puppet resource firewallchain command:' do
         EOS
         # Run it twice and test for idempotency
         apply_manifest(pp, :catch_failures => true)
-        expect(apply_manifest(pp, :catch_failures => true).exit_code).to be_zero
+        apply_manifest(pp, :catch_changes => true)
       end
 
       it 'fails to find the chain' do
@@ -44,65 +44,65 @@ describe 'puppet resource firewallchain command:' do
     end
   end
 
-  context 'adding a firewall rule to a chain:' do
-    it 'applies cleanly' do
-      pp = <<-EOS
-        firewallchain { 'MY_CHAIN:filter:IPv4':
-          ensure  => present,
-        }
-        firewall { '100 my rule':
-          chain   => 'MY_CHAIN',
-          action  => 'accept',
-          proto   => 'tcp',
-          dport   => 5000,
-        }
-      EOS
-      # Run it twice and test for idempotency
-      apply_manifest(pp, :catch_failures => true)
-      expect(apply_manifest(pp, :catch_failures => true).exit_code).to be_zero
-    end
-  end
+  # XXX purge => false is not yet implemented
+  #context 'adding a firewall rule to a chain:' do
+  #  it 'applies cleanly' do
+  #    pp = <<-EOS
+  #      firewallchain { 'MY_CHAIN:filter:IPv4':
+  #        ensure  => present,
+  #      }
+  #      firewall { '100 my rule':
+  #        chain   => 'MY_CHAIN',
+  #        action  => 'accept',
+  #        proto   => 'tcp',
+  #        dport   => 5000,
+  #      }
+  #    EOS
+  #    # Run it twice and test for idempotency
+  #    apply_manifest(pp, :catch_failures => true)
+  #    apply_manifest(pp, :catch_changes => true)
+  #  end
+  #end
 
-  context 'not purge firewallchain chains:' do
-    it 'does not purge the rule' do
-      pp = <<-EOS
-        firewallchain { 'MY_CHAIN:filter:IPv4':
-          ensure  => present,
-          purge   => false,
-          before  => Resources['firewall'],
-        }
-        resources { 'firewall':
-          purge => true,
-        }
-      EOS
-      # Run it twice and test for idempotency
-      apply_manifest(pp, :catch_failures => true) do |r|
-        expect(r.stdout).to_not match(/removed/)
-        expect(r.stderr).to eq('')
-        expect(r.exit_code).to eq(0)
-      end
-      expect(apply_manifest(pp, :catch_failures => true).exit_code).to be_zero
-    end
+  #context 'not purge firewallchain chains:' do
+  #  it 'does not purge the rule' do
+  #    pp = <<-EOS
+  #      firewallchain { 'MY_CHAIN:filter:IPv4':
+  #        ensure  => present,
+  #        purge   => false,
+  #        before  => Resources['firewall'],
+  #      }
+  #      resources { 'firewall':
+  #        purge => true,
+  #      }
+  #    EOS
+  #    # Run it twice and test for idempotency
+  #    apply_manifest(pp, :catch_failures => true) do |r|
+  #      expect(r.stdout).to_not match(/removed/)
+  #      expect(r.stderr).to eq('')
+  #    end
+  #    apply_manifest(pp, :catch_changes => true)
+  #  end
 
-    it 'still has the rule' do
-      pp = <<-EOS
-        firewall { '100 my rule':
-          chain   => 'MY_CHAIN',
-          action  => 'accept',
-          proto   => 'tcp',
-          dport   => 5000,
-        }
-      EOS
-      # Run it twice and test for idempotency
-      apply_manifest(pp, :catch_failures => true) do |r|
-        expect(r.stderr).to eq('')
-        expect(r.exit_code).to eq(0)
-      end
-      expect(apply_manifest(pp, :catch_failures => true).exit_code).to be_zero
-    end
-  end
+  #  it 'still has the rule' do
+  #    pp = <<-EOS
+  #      firewall { '100 my rule':
+  #        chain   => 'MY_CHAIN',
+  #        action  => 'accept',
+  #        proto   => 'tcp',
+  #        dport   => 5000,
+  #      }
+  #    EOS
+  #    # Run it twice and test for idempotency
+  #    apply_manifest(pp, :catch_changes => true)
+  #  end
+  #end
 
   describe 'policy' do
+    after :all do
+      shell('iptables -t filter -P FORWARD ACCEPT')
+    end
+
     context 'DROP' do
       it 'applies cleanly' do
         pp = <<-EOS
@@ -112,7 +112,7 @@ describe 'puppet resource firewallchain command:' do
         EOS
         # Run it twice and test for idempotency
         apply_manifest(pp, :catch_failures => true)
-        expect(apply_manifest(pp, :catch_failures => true).exit_code).to be_zero
+        apply_manifest(pp, :catch_changes => true)
       end
 
       it 'finds the chain' do
@@ -122,5 +122,4 @@ describe 'puppet resource firewallchain command:' do
       end
     end
   end
-
 end
diff --git a/spec/acceptance/ip6_fragment_spec.rb b/spec/acceptance/ip6_fragment_spec.rb
new file mode 100644 (file)
index 0000000..b398d45
--- /dev/null
@@ -0,0 +1,94 @@
+require 'spec_helper_acceptance'
+
+describe 'firewall ishasmorefrags/islastfrag/isfirstfrag properties' do
+  before :all do
+    ip6tables_flush_all_tables
+  end
+
+  shared_examples "is idempotent" do |values, line_match|
+    it "changes the values to #{values}" do
+      pp = <<-EOS
+          class { '::firewall': }
+          firewall { '599 - test':
+            ensure   => present,
+            proto    => 'tcp',
+            provider => 'ip6tables',
+            #{values}
+          }
+      EOS
+
+      apply_manifest(pp, :catch_failures => true)
+      apply_manifest(pp, :catch_changes => true)
+
+      shell('ip6tables -S') do |r|
+        expect(r.stdout).to match(/#{line_match}/)
+      end
+    end
+  end
+  shared_examples "doesn't change" do |values, line_match|
+    it "doesn't change the values to #{values}" do
+      pp = <<-EOS
+          class { '::firewall': }
+          firewall { '599 - test':
+            ensure   => present,
+            proto    => 'tcp',
+            provider => 'ip6tables',
+            #{values}
+          }
+      EOS
+
+      apply_manifest(pp, :catch_changes => true)
+
+      shell('ip6tables -S') do |r|
+        expect(r.stdout).to match(/#{line_match}/)
+      end
+    end
+  end
+
+  describe 'adding a rule' do
+    context 'when unset' do
+      before :all do
+        ip6tables_flush_all_tables
+      end
+      it_behaves_like 'is idempotent', '', /-A INPUT -p tcp -m comment --comment "599 - test"/
+    end
+    context 'when set to true' do
+      before :all do
+        ip6tables_flush_all_tables
+      end
+      it_behaves_like "is idempotent", 'ishasmorefrags => true, islastfrag => true, isfirstfrag => true', /-A INPUT -p tcp -m frag --fragid 0 --fragmore -m frag --fragid 0 --fraglast -m frag --fragid 0 --fragfirst -m comment --comment "599 - test"/
+    end
+    context 'when set to false' do
+      before :all do
+        ip6tables_flush_all_tables
+      end
+      it_behaves_like "is idempotent", 'ishasmorefrags => false, islastfrag => false, isfirstfrag => false', /-A INPUT -p tcp -m comment --comment "599 - test"/
+    end
+  end
+  describe 'editing a rule' do
+    context 'when unset or false' do
+      before :each do
+        ip6tables_flush_all_tables
+        shell('/sbin/ip6tables -A INPUT -p tcp -m comment --comment "599 - test"')
+      end
+      context 'and current value is false' do
+        it_behaves_like "doesn't change", 'ishasmorefrags => false, islastfrag => false, isfirstfrag => false', /-A INPUT -p tcp -m comment --comment "599 - test"/
+      end
+      context 'and current value is true' do
+        it_behaves_like "is idempotent", 'ishasmorefrags => true, islastfrag => true, isfirstfrag => true', /-A INPUT -p tcp -m frag --fragid 0 --fragmore -m frag --fragid 0 --fraglast -m frag --fragid 0 --fragfirst -m comment --comment "599 - test"/
+      end
+    end
+    context 'when set to true' do
+      before :each do
+        ip6tables_flush_all_tables
+        shell('/sbin/ip6tables -A INPUT -p tcp -m frag --fragid 0 --fragmore -m frag --fragid 0 --fraglast -m frag --fragid 0 --fragfirst -m comment --comment "599 - test"')
+      end
+      context 'and current value is false' do
+        it_behaves_like "is idempotent", 'ishasmorefrags => false, islastfrag => false, isfirstfrag => false', /-A INPUT -p tcp -m comment --comment "599 - test"/
+      end
+      context 'and current value is true' do
+        it_behaves_like "doesn't change", 'ishasmorefrags => true, islastfrag => true, isfirstfrag => true', /-A INPUT -p tcp -m frag --fragid 0 --fragmore -m frag --fragid 0 --fraglast -m frag --fragid 0 --fragfirst -m comment --comment "599 - test"/
+      end
+    end
+  end
+end
diff --git a/spec/acceptance/isfragment_spec.rb b/spec/acceptance/isfragment_spec.rb
new file mode 100644 (file)
index 0000000..c81baa6
--- /dev/null
@@ -0,0 +1,92 @@
+require 'spec_helper_acceptance'
+
+describe 'firewall isfragment property' do
+  before :all do
+    iptables_flush_all_tables
+  end
+
+  shared_examples "is idempotent" do |value, line_match|
+    it "changes the value to #{value}" do
+      pp = <<-EOS
+          class { '::firewall': }
+          firewall { '597 - test':
+            ensure => present,
+            proto  => 'tcp',
+            #{value}
+          }
+      EOS
+
+      apply_manifest(pp, :catch_failures => true)
+      apply_manifest(pp, :catch_changes => true)
+
+      shell('iptables -S') do |r|
+        expect(r.stdout).to match(/#{line_match}/)
+      end
+    end
+  end
+  shared_examples "doesn't change" do |value, line_match|
+    it "doesn't change the value to #{value}" do
+      pp = <<-EOS
+          class { '::firewall': }
+          firewall { '597 - test':
+            ensure => present,
+            proto  => 'tcp',
+            #{value}
+          }
+      EOS
+
+      apply_manifest(pp, :catch_changes => true)
+
+      shell('iptables -S') do |r|
+        expect(r.stdout).to match(/#{line_match}/)
+      end
+    end
+  end
+
+  describe 'adding a rule' do
+    context 'when unset' do
+      before :all do
+        iptables_flush_all_tables
+      end
+      it_behaves_like 'is idempotent', '', /-A INPUT -p tcp -m comment --comment "597 - test"/
+    end
+    context 'when set to true' do
+      before :all do
+        iptables_flush_all_tables
+      end
+      it_behaves_like 'is idempotent', 'isfragment => true,', /-A INPUT -p tcp -f -m comment --comment "597 - test"/
+    end
+    context 'when set to false' do
+      before :all do
+        iptables_flush_all_tables
+      end
+      it_behaves_like "is idempotent", 'isfragment => false,', /-A INPUT -p tcp -m comment --comment "597 - test"/
+    end
+  end
+  describe 'editing a rule' do
+    context 'when unset or false' do
+      before :each do
+        iptables_flush_all_tables
+        shell('/sbin/iptables -A INPUT -p tcp -m comment --comment "597 - test"')
+      end
+      context 'and current value is false' do
+        it_behaves_like "doesn't change", 'isfragment => false,', /-A INPUT -p tcp -m comment --comment "597 - test"/
+      end
+      context 'and current value is true' do
+        it_behaves_like "is idempotent", 'isfragment => true,', /-A INPUT -p tcp -f -m comment --comment "597 - test"/
+      end
+    end
+    context 'when set to true' do
+      before :each do
+        iptables_flush_all_tables
+        shell('/sbin/iptables -A INPUT -p tcp -f -m comment --comment "597 - test"')
+      end
+      context 'and current value is false' do
+        it_behaves_like "is idempotent", 'isfragment => false,', /-A INPUT -p tcp -m comment --comment "597 - test"/
+      end
+      context 'and current value is true' do
+        it_behaves_like "doesn't change", 'isfragment => true,', /-A INPUT -p tcp -f -m comment --comment "597 - test"/
+      end
+    end
+  end
+end
index eac0d12f465fc6816f2aa91d77e58a8e9cac9101..8b154beb98b46a67100d18d0cdf58b3827644f44 100644 (file)
@@ -1,6 +1,17 @@
 require 'spec_helper_acceptance'
 
 describe 'complex ruleset 1' do
+  before :all do
+    iptables_flush_all_tables
+  end
+
+  after :all do
+    shell('iptables -t filter -P INPUT ACCEPT')
+    shell('iptables -t filter -P FORWARD ACCEPT')
+    shell('iptables -t filter -P OUTPUT ACCEPT')
+    shell('iptables -t filter --flush')
+  end
+
   it 'applies cleanly' do
     pp = <<-EOS
       firewall { '090 forward allow local':
@@ -87,10 +98,30 @@ describe 'complex ruleset 1' do
   end
 
   it 'contains appropriate rules' do
+    shell('iptables -S') do |r|
+      expect(r.stdout).to eq(
+        "-P INPUT ACCEPT\n" +
+        "-P FORWARD ACCEPT\n" +
+        "-P OUTPUT ACCEPT\n" +
+        "-A FORWARD -s 10.0.0.0/8 -d 10.0.0.0/8 -m comment --comment \"090 forward allow local\" -j ACCEPT \n" +
+        "-A FORWARD -s 10.0.0.0/8 ! -d 10.0.0.0/8 -p icmp -m comment --comment \"100 forward standard allow icmp\" -j ACCEPT \n" +
+        "-A FORWARD -s 10.0.0.0/8 ! -d 10.0.0.0/8 -p tcp -m multiport --ports 80,443,21,20,22,53,123,43,873,25,465 -m comment --comment \"100 forward standard allow tcp\" -m state --state NEW -j ACCEPT \n" +
+        "-A FORWARD -s 10.0.0.0/8 ! -d 10.0.0.0/8 -p udp -m multiport --ports 53,123 -m comment --comment \"100 forward standard allow udp\" -j ACCEPT \n"
+      )
+    end
   end
 end
 
 describe 'complex ruleset 2' do
+  after :all do
+    shell('iptables -t filter -P INPUT ACCEPT')
+    shell('iptables -t filter -P FORWARD ACCEPT')
+    shell('iptables -t filter -P OUTPUT ACCEPT')
+    shell('iptables -t filter --flush')
+    expect(shell('iptables -t filter -X LOCAL_INPUT').stderr).to eq("")
+    expect(shell('iptables -t filter -X LOCAL_INPUT_PRE').stderr).to eq("")
+  end
+
   it 'applies cleanly' do
     pp = <<-EOS
       class { '::firewall': }
@@ -190,10 +221,28 @@ describe 'complex ruleset 2' do
 
     # Run it twice and test for idempotency
     apply_manifest(pp, :catch_failures => true)
-    expect(apply_manifest(pp, :catch_failures => true).exit_code).to be_zero
+    apply_manifest(pp, :catch_changes => true)
   end
 
   it 'contains appropriate rules' do
+    shell('iptables -S') do |r|
+      expect(r.stdout).to eq(
+        "-P INPUT DROP\n" +
+        "-P FORWARD DROP\n" +
+        "-P OUTPUT ACCEPT\n" +
+        "-N LOCAL_INPUT\n" +
+        "-N LOCAL_INPUT_PRE\n" +
+        "-A INPUT -m comment --comment \"001 LOCAL_INPUT_PRE\" -j LOCAL_INPUT_PRE \n" +
+        "-A INPUT -m comment --comment \"010 INPUT allow established and related\" -m state --state RELATED,ESTABLISHED -j ACCEPT \n" +
+        "-A INPUT -i lo -m comment --comment \"012 accept loopback\" -j ACCEPT \n" +
+        "-A INPUT -p icmp -m comment --comment \"013 icmp destination-unreachable\" -m icmp --icmp-type 3 -j ACCEPT \n" +
+        "-A INPUT -s 10.0.0.0/8 -p icmp -m comment --comment \"013 icmp echo-request\" -m icmp --icmp-type 8 -j ACCEPT \n" +
+        "-A INPUT -p icmp -m comment --comment \"013 icmp time-exceeded\" -m icmp --icmp-type 11 -j ACCEPT \n" +
+        "-A INPUT -p tcp -m multiport --dports 22 -m comment --comment \"020 ssh\" -m state --state NEW -j ACCEPT \n" +
+        "-A INPUT -m comment --comment \"900 LOCAL_INPUT\" -j LOCAL_INPUT \n" +
+        "-A INPUT -m comment --comment \"999 reject\" -j REJECT --reject-with icmp-host-prohibited \n" +
+        "-A FORWARD -m comment --comment \"010 allow established and related\" -m state --state RELATED,ESTABLISHED -j ACCEPT \n"
+      )
+    end
   end
 end
-
diff --git a/spec/acceptance/socket_spec.rb b/spec/acceptance/socket_spec.rb
new file mode 100644 (file)
index 0000000..f53545b
--- /dev/null
@@ -0,0 +1,96 @@
+require 'spec_helper_acceptance'
+
+describe 'firewall socket property' do
+  before :all do
+    iptables_flush_all_tables
+  end
+
+  shared_examples "is idempotent" do |value, line_match|
+    it "changes the value to #{value}" do
+      pp = <<-EOS
+          class { '::firewall': }
+          firewall { '598 - test':
+            ensure => present,
+            proto  => 'tcp',
+            chain  => 'PREROUTING',
+            table  => 'raw',
+            #{value}
+          }
+      EOS
+
+      apply_manifest(pp, :catch_failures => true)
+      apply_manifest(pp, :catch_changes => true)
+
+      shell('iptables -t raw -S') do |r|
+        expect(r.stdout).to match(/#{line_match}/)
+      end
+    end
+  end
+  shared_examples "doesn't change" do |value, line_match|
+    it "doesn't change the value to #{value}" do
+      pp = <<-EOS
+          class { '::firewall': }
+          firewall { '598 - test':
+            ensure => present,
+            proto  => 'tcp',
+            chain  => 'PREROUTING',
+            table  => 'raw',
+            #{value}
+          }
+      EOS
+
+      apply_manifest(pp, :catch_changes => true)
+
+      shell('iptables -t raw -S') do |r|
+        expect(r.stdout).to match(/#{line_match}/)
+      end
+    end
+  end
+
+  describe 'adding a rule' do
+    context 'when unset' do
+      before :all do
+        iptables_flush_all_tables
+      end
+      it_behaves_like 'is idempotent', '', /-A PREROUTING -p tcp -m comment --comment "598 - test"/
+    end
+    context 'when set to true' do
+      before :all do
+        iptables_flush_all_tables
+      end
+      it_behaves_like 'is idempotent', 'socket => true,', /-A PREROUTING -p tcp -m socket -m comment --comment "598 - test"/
+    end
+    context 'when set to false' do
+      before :all do
+        iptables_flush_all_tables
+      end
+      it_behaves_like "is idempotent", 'socket => false,', /-A PREROUTING -p tcp -m comment --comment "598 - test"/
+    end
+  end
+  describe 'editing a rule' do
+    context 'when unset or false' do
+      before :each do
+        iptables_flush_all_tables
+        shell('/sbin/iptables -t raw -A PREROUTING -p tcp -m comment --comment "598 - test"')
+      end
+      context 'and current value is false' do
+        it_behaves_like "doesn't change", 'socket => false,', /-A PREROUTING -p tcp -m comment --comment "598 - test"/
+      end
+      context 'and current value is true' do
+        it_behaves_like "is idempotent", 'socket => true,', /-A PREROUTING -p tcp -m socket -m comment --comment "598 - test"/
+      end
+    end
+    context 'when set to true' do
+      before :each do
+        iptables_flush_all_tables
+        shell('/sbin/iptables -t raw -A PREROUTING -p tcp -m socket -m comment --comment "598 - test"')
+      end
+      context 'and current value is false' do
+        it_behaves_like "is idempotent", 'socket => false,', /-A PREROUTING -p tcp -m comment --comment "598 - test"/
+      end
+      context 'and current value is true' do
+        it_behaves_like "doesn't change", 'socket => true,', /-A PREROUTING -p tcp -m socket -m comment --comment "598 - test"/
+      end
+    end
+  end
+end
index cc7cae3980e7bbd8a9b7a962dc7e03c0f50caebb..afa3f057119d006f3d6e8712fe588a4a8ce877a8 100644 (file)
@@ -2,10 +2,13 @@ require 'beaker-rspec'
 
 def iptables_flush_all_tables
   ['filter', 'nat', 'mangle', 'raw'].each do |t|
-    shell "/sbin/iptables -t #{t} -F" do |r|
-      r.stderr.should be_empty
-      r.exit_code.should be_zero
-    end
+    expect(shell("/sbin/iptables -t #{t} -F").stderr).to eq("")
+  end
+end
+
+def ip6tables_flush_all_tables
+  ['filter'].each do |t|
+    expect(shell("/sbin/ip6tables -t #{t} -F").stderr).to eq("")
   end
 end