From: Jonathan Tripathy Date: Mon, 15 Jun 2015 11:58:08 +0000 (+0100) Subject: Clusterip implementation X-Git-Tag: 1.7.0~29^2 X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=268a29e15c8cdd3c8a83e12c3ab0bd98cca7b3fb;p=puppet-modules%2Fpuppetlabs-firewall.git Clusterip implementation --- diff --git a/README.markdown b/README.markdown index 98d642e..92e3228 100644 --- a/README.markdown +++ b/README.markdown @@ -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. diff --git a/lib/puppet/provider/firewall/iptables.rb b/lib/puppet/provider/firewall/iptables.rb index 9c099fe..59da729 100644 --- a/lib/puppet/provider/firewall/iptables.rb +++ b/lib/puppet/provider/firewall/iptables.rb @@ -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 " (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 diff --git a/lib/puppet/type/firewall.rb b/lib/puppet/type/firewall.rb index 9af7d3e..e851b70 100644 --- a/lib/puppet/type/firewall.rb +++ b/lib/puppet/type/firewall.rb @@ -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 index 0000000..46b4b5a --- /dev/null +++ b/spec/acceptance/firewall_clusterip_spec.rb @@ -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