]> review.fuel-infra Code Review - puppet-modules/puppetlabs-firewall.git/commitdiff
Clusterip implementation
authorJonathan Tripathy <jt@puppetlabs.com>
Mon, 15 Jun 2015 11:58:08 +0000 (12:58 +0100)
committerJonathan Tripathy <jt@puppetlabs.com>
Mon, 15 Jun 2015 12:13:29 +0000 (13:13 +0100)
README.markdown
lib/puppet/provider/firewall/iptables.rb
lib/puppet/type/firewall.rb
spec/acceptance/firewall_clusterip_spec.rb [new file with mode: 0644]

index 98d642e65e9010e2040a2527eb80ca47dbbe9323..92e3228178bc2fda342fe45be5ae4b36968d15e9 100644 (file)
@@ -411,7 +411,7 @@ This type enables you to manage firewall rules within Puppet.
 * `iptables`: Iptables type provider
     * Required binaries: `iptables-save`, `iptables`.
     * Default for `kernel` == `linux`.
-    * Supported features: `address_type`, `connection_limiting`, `dnat`, `icmp_match`, `interface_match`, `iprange`, `ipsec_dir`, `ipsec_policy`, `ipset`, `iptables`, `isfragment`, `log_level`, `log_prefix`, `mark`, `mask`, `mss`, `netmap`, `owner`, `pkttype`, `rate_limiting`, `recent_limiting`, `reject_type`, `snat`, `socket`, `state_match`, `tcp_flags`.
+    * Supported features: `address_type`, `clusterip`, `connection_limiting`, `dnat`, `icmp_match`, `interface_match`, `iprange`, `ipsec_dir`, `ipsec_policy`, `ipset`, `iptables`, `isfragment`, `log_level`, `log_prefix`, `mark`, `mask`, `mss`, `netmap`, `owner`, `pkttype`, `rate_limiting`, `recent_limiting`, `reject_type`, `snat`, `socket`, `state_match`, `tcp_flags`.
 
 **Autorequires:**
 
@@ -423,6 +423,8 @@ If Puppet is managing the iptables or iptables-persistent packages, and the prov
 
 * `address_type`: The ability to match on source or destination address type.
 
+* `clusterip`: Configure a simple cluster of nodes that share a certain IP and MAC address without an explicit load balancer in front of them.
+
 * `connection_limiting`: Connection limiting features.
 
 * `dnat`: Destination NATing.
@@ -490,6 +492,18 @@ If Puppet is managing the iptables or iptables-persistent packages, and the prov
 
 * `burst`: Rate limiting burst value (per second) before limit checks apply. Values must match '/^\d+$/'. Requires the `rate_limiting` feature.
 
+* `clusterip_new`: Create a new ClusterIP. You always have to set this on the first rule for a given ClusterIP. Requires the `clusterip` feature.
+
+* `clusterip_hashmode`: Specify the hashing mode. Valid values are sourceip, sourceip-sourceport, sourceip-sourceport-destport. Requires the `clusterip` feature.
+
+* `clusterip_clustermac`: Specify the ClusterIP MAC address. Has to be a link-layer multicast address. Requires the `clusterip` feature.
+
+* `clusterip_total_nodes`: Number of total nodes within this cluster. Requires the `clusterip` feature.
+
+* `clusterip_local_node`: Local node number within this cluster. Requires the `clusterip` feature.
+
+* `clusterip_hash_init`: Specify the random seed used for hash initialization. Requires the `clusterip` feature.
+
 * `chain`: Name of the chain to use. You can provide a user-based chain or use one of the following built-in chains:'INPUT','FORWARD','OUTPUT','PREROUTING', or 'POSTROUTING'. The default value is 'INPUT'. Values must match '/^[a-zA-Z0-9\-_]+$/'. Requires the `iptables` feature.
 
 * `checksum_fill`: When using a `jump` value of 'CHECKSUM', this boolean makes sure that a checksum is calculated and filled in a packet that lacks a checksum. Valid values are 'true' or 'false'. Requires the `iptables` feature.
index 9c099fee74b76c32fa82f6758e9bfcd52eeb9dec..59da729a8049261812a36b8901423c37b69182cc 100644 (file)
@@ -32,6 +32,7 @@ Puppet::Type.type(:firewall).provide :iptables, :parent => Puppet::Provider::Fir
   has_feature :ipsec_policy
   has_feature :mask
   has_feature :ipset
+  has_feature :clusterip
 
   optional_commands({
     :iptables => 'iptables',
@@ -51,78 +52,84 @@ Puppet::Type.type(:firewall).provide :iptables, :parent => Puppet::Provider::Fir
   @protocol = "IPv4"
 
   @resource_map = {
-    :burst              => "--limit-burst",
-    :checksum_fill      => "--checksum-fill",
-    :clamp_mss_to_pmtu  => "--clamp-mss-to-pmtu",
-    :connlimit_above    => "-m connlimit --connlimit-above",
-    :connlimit_mask     => "--connlimit-mask",
-    :connmark           => "-m connmark --mark",
-    :ctstate            => "-m conntrack --ctstate",
-    :destination        => "-d",
-    :dport              => ["-m multiport --dports", "--dport"],
-    :dst_range          => "--dst-range",
-    :dst_type           => "--dst-type",
-    :gateway            => "--gateway",
-    :gid                => "--gid-owner",
-    :icmp               => "-m icmp --icmp-type",
-    :iniface            => "-i",
-    :ipsec_dir          => "-m policy --dir",
-    :ipsec_policy       => "--pol",
-    :ipset              => "-m set --match-set",
-    :isfragment         => "-f",
-    :jump               => "-j",
-    :limit              => "-m limit --limit",
-    :log_level          => "--log-level",
-    :log_prefix         => "--log-prefix",
-    :mac_source         => ["-m mac --mac-source", "--mac-source"],
-    :mask               => '--mask',
-    :match_mark         => "-m mark --mark",
-    :mss                => '-m tcpmss --mss',
-    :name               => "-m comment --comment",
-    :outiface           => "-o",
-    :pkttype            => "-m pkttype --pkt-type",
-    :port               => '-m multiport --ports',
-    :proto              => "-p",
-    :random             => "--random",
-    :rdest              => "--rdest",
-    :reap               => "--reap",
-    :recent             => "-m recent",
-    :reject             => "--reject-with",
-    :rhitcount          => "--hitcount",
-    :rname              => "--name",
-    :rseconds           => "--seconds",
-    :rsource            => "--rsource",
-    :rttl               => "--rttl",
-    :set_mark           => mark_flag,
-    :set_mss            => '--set-mss',
-    :socket             => "-m socket",
-    :source             => "-s",
-    :sport              => ["-m multiport --sports", "--sport"],
-    :src_range          => "--src-range",
-    :src_type           => "--src-type",
-    :stat_every         => '--every',
-    :stat_mode          => "-m statistic --mode",
-    :stat_packet        => '--packet',
-    :stat_probability   => '--probability',
-    :state              => "-m state --state",
-    :table              => "-t",
-    :tcp_flags          => "-m tcp --tcp-flags",
-    :todest             => "--to-destination",
-    :toports            => "--to-ports",
-    :tosource           => "--to-source",
-    :to                 => "--to",
-    :uid                => "--uid-owner",
-    :physdev_in         => "--physdev-in",
-    :physdev_out        => "--physdev-out",
-    :physdev_is_bridged => "--physdev-is-bridged",
-    :date_start         => "--datestart",
-    :date_stop          => "--datestop",
-    :time_start         => "--timestart",
-    :time_stop          => "--timestop",
-    :month_days         => "--monthdays",
-    :week_days          => "--weekdays",
-    :time_contiguous    => "--contiguous",
-    :kernel_timezone    => "--kerneltz",
+    :burst                 => "--limit-burst",
+    :checksum_fill         => "--checksum-fill",
+    :clamp_mss_to_pmtu     => "--clamp-mss-to-pmtu",
+    :connlimit_above       => "-m connlimit --connlimit-above",
+    :connlimit_mask        => "--connlimit-mask",
+    :connmark              => "-m connmark --mark",
+    :ctstate               => "-m conntrack --ctstate",
+    :destination           => "-d",
+    :dport                 => ["-m multiport --dports", "--dport"],
+    :dst_range             => "--dst-range",
+    :dst_type              => "--dst-type",
+    :gateway               => "--gateway",
+    :gid                   => "--gid-owner",
+    :icmp                  => "-m icmp --icmp-type",
+    :iniface               => "-i",
+    :ipsec_dir             => "-m policy --dir",
+    :ipsec_policy          => "--pol",
+    :ipset                 => "-m set --match-set",
+    :isfragment            => "-f",
+    :jump                  => "-j",
+    :limit                 => "-m limit --limit",
+    :log_level             => "--log-level",
+    :log_prefix            => "--log-prefix",
+    :mac_source            => ["-m mac --mac-source", "--mac-source"],
+    :mask                  => '--mask',
+    :match_mark            => "-m mark --mark",
+    :mss                   => '-m tcpmss --mss',
+    :name                  => "-m comment --comment",
+    :outiface              => "-o",
+    :pkttype               => "-m pkttype --pkt-type",
+    :port                  => '-m multiport --ports',
+    :proto                 => "-p",
+    :random                => "--random",
+    :rdest                 => "--rdest",
+    :reap                  => "--reap",
+    :recent                => "-m recent",
+    :reject                => "--reject-with",
+    :rhitcount             => "--hitcount",
+    :rname                 => "--name",
+    :rseconds              => "--seconds",
+    :rsource               => "--rsource",
+    :rttl                  => "--rttl",
+    :set_mark              => mark_flag,
+    :set_mss               => '--set-mss',
+    :socket                => "-m socket",
+    :source                => "-s",
+    :sport                 => ["-m multiport --sports", "--sport"],
+    :src_range             => "--src-range",
+    :src_type              => "--src-type",
+    :stat_every            => '--every',
+    :stat_mode             => "-m statistic --mode",
+    :stat_packet           => '--packet',
+    :stat_probability      => '--probability',
+    :state                 => "-m state --state",
+    :table                 => "-t",
+    :tcp_flags             => "-m tcp --tcp-flags",
+    :todest                => "--to-destination",
+    :toports               => "--to-ports",
+    :tosource              => "--to-source",
+    :to                    => "--to",
+    :uid                   => "--uid-owner",
+    :physdev_in            => "--physdev-in",
+    :physdev_out           => "--physdev-out",
+    :physdev_is_bridged    => "--physdev-is-bridged",
+    :date_start            => "--datestart",
+    :date_stop             => "--datestop",
+    :time_start            => "--timestart",
+    :time_stop             => "--timestop",
+    :month_days            => "--monthdays",
+    :week_days             => "--weekdays",
+    :time_contiguous       => "--contiguous",
+    :kernel_timezone       => "--kerneltz",
+    :clusterip_new         => "--new",
+    :clusterip_hashmode    => "--hashmode",
+    :clusterip_clustermac  => "--clustermac",
+    :clusterip_total_nodes => "--total-nodes",
+    :clusterip_local_node  => "--local-node",
+    :clusterip_hash_init   => "--hash-init",
   }
 
   # These are known booleans that do not take a value, but we want to munge
@@ -140,6 +147,7 @@ Puppet::Type.type(:firewall).provide :iptables, :parent => Puppet::Provider::Fir
     :physdev_is_bridged,
     :time_contiguous,
     :kernel_timezone,
+    :clusterip_new,
   ]
 
   # Properties that use "-m <ipt module name>" (with the potential to have multiple 
@@ -242,9 +250,11 @@ Puppet::Type.type(:firewall).provide :iptables, :parent => Puppet::Provider::Fir
     :src_range, :dst_range, :tcp_flags, :uid, :gid, :mac_source, :sport, :dport, :port,
     :src_type, :dst_type, :socket, :pkttype, :name, :ipsec_dir, :ipsec_policy,
     :state, :ctstate, :icmp, :limit, :burst, :recent, :rseconds, :reap,
-    :rhitcount, :rttl, :rname, :mask, :rsource, :rdest, :ipset, :jump, :clamp_mss_to_pmtu, :gateway, :set_mss, :todest,
-    :tosource, :toports, :to, :checksum_fill, :random, :log_prefix, :log_level, :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
+    :rhitcount, :rttl, :rname, :mask, :rsource, :rdest, :ipset, :jump, :clusterip_new, :clusterip_hashmode,
+    :clusterip_clustermac, :clusterip_total_nodes, :clusterip_local_node, :clusterip_hash_init,
+    :clamp_mss_to_pmtu, :gateway, :set_mss, :todest, :tosource, :toports, :to, :checksum_fill, :random, :log_prefix,
+    :log_level, :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
   ]
 
   def insert
index 9af7d3eee6befe65e494e495a1f2ebb5e20398f3..e851b7015b19f524e801ba9ce98848eb4ba55d14 100644 (file)
@@ -57,6 +57,7 @@ Puppet::Type.newtype(:firewall) do
   feature :ipsec_dir, "Match IPsec policy direction"
   feature :mask, "Ability to match recent rules based on the ipv4 mask"
   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."
 
   # provider specific features
   feature :iptables, "The provider provides iptables features."
@@ -1255,6 +1256,58 @@ Puppet::Type.newtype(:firewall) do
     newvalues(:true, :false)
   end
 
+  newproperty(:clusterip_new, :required_features => :clusterip) do
+    desc <<-EOS
+      Used with the CLUSTERIP jump target.
+      Create a new ClusterIP. You always have to set this on the first rule for a given ClusterIP.
+    EOS
+
+    newvalues(:true, :false)
+  end
+
+  newproperty(:clusterip_hashmode, :required_features => :clusterip) do
+    desc <<-EOS
+      Used with the CLUSTERIP jump target.
+      Specify the hashing mode. Valid values: sourceip, sourceip-sourceport, sourceip-sourceport-destport.
+    EOS
+
+    newvalues(:sourceip, :'sourceip-sourceport', :'sourceip-sourceport-destport')
+  end
+
+  newproperty(:clusterip_clustermac, :required_features => :clusterip) do
+    desc <<-EOS
+      Used with the CLUSTERIP jump target.
+      Specify the ClusterIP MAC address. Has to be a link-layer multicast address.
+    EOS
+
+    newvalues(/^([0-9a-f]{2}[:]){5}([0-9a-f]{2})$/i)
+  end
+
+  newproperty(:clusterip_total_nodes, :required_features => :clusterip) do
+    desc <<-EOS
+      Used with the CLUSTERIP jump target.
+      Number of total nodes within this cluster.
+    EOS
+
+    newvalues(/\d+/)
+  end
+
+  newproperty(:clusterip_local_node, :required_features => :clusterip) do
+    desc <<-EOS
+      Used with the CLUSTERIP jump target.
+      Specify the random seed used for hash initialization.
+    EOS
+
+    newvalues(/\d+/)
+  end
+
+  newproperty(:clusterip_hash_init, :required_features => :clusterip) do
+    desc <<-EOS
+      Used with the CLUSTERIP jump target.
+      Specify the random seed used for hash initialization.
+    EOS
+  end
+
 
   autorequire(:firewallchain) do
     reqs = []
diff --git a/spec/acceptance/firewall_clusterip_spec.rb b/spec/acceptance/firewall_clusterip_spec.rb
new file mode 100644 (file)
index 0000000..46b4b5a
--- /dev/null
@@ -0,0 +1,40 @@
+require 'spec_helper_acceptance'
+
+describe 'firewall type', :unless => UNSUPPORTED_PLATFORMS.include?(fact('osfamily')) do
+
+  before(:all) do
+    shell('iptables --flush; iptables -t nat --flush; iptables -t mangle --flush')
+    shell('ip6tables --flush; ip6tables -t nat --flush; ip6tables -t mangle --flush')
+  end
+
+    describe 'clusterip' do
+      context 'cluster ipv4 test' do
+        it 'applies' do
+          pp = <<-EOS
+            class { '::firewall': }
+            firewall { 
+              '830 - clusterip test':
+                chain                 => 'FORWARD',
+                jump                  => 'CLUSTERIP',
+                destination           => '1.1.1.1',
+                iniface               => 'eth0',
+                clusterip_new         => true,
+                clusterip_hashmode    => "sourceip",
+                clusterip_clustermac  => "01:00:5E:00:00:00",
+                clusterip_total_nodes => "2",
+                clusterip_local_node  => "1",
+                clusterip_hash_init   => "1337",
+            }
+          EOS
+
+          apply_manifest(pp, :catch_failures => true)
+        end
+
+        it 'should contain the rule' do
+          shell('iptables-save') do |r|
+            expect(r.stdout).to match(/-A FORWARD -d (1.1.1.1\/32|1.1.1.1) -i eth0 -p tcp -m comment --comment "830 - clusterip test" -j CLUSTERIP --new --hashmode sourceip --clustermac 01:00:5E:00:00:00 --total-nodes 2 --local-node 1 --hash-init 1337/)
+          end
+        end
+      end
+    end
+end