From: Patrick Hemmer Date: Tue, 17 Dec 2013 22:00:18 +0000 (-0500) Subject: add support for removing unmanaged firewall rules X-Git-Tag: 0.5.0~12^2~2 X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=9b034b0334e4c8868066fd7bbe2c1fefbfd0c9f4;p=puppet-modules%2Fpuppetlabs-firewall.git add support for removing unmanaged firewall rules --- diff --git a/lib/puppet/type/firewallchain.rb b/lib/puppet/type/firewallchain.rb index 75ffa4e..35cb9ed 100644 --- a/lib/puppet/type/firewallchain.rb +++ b/lib/puppet/type/firewallchain.rb @@ -105,6 +105,46 @@ Puppet::Type.newtype(:firewallchain) do end end + newparam(:purge, :boolean => true) do + desc <<-EOS + Purge unmanaged firewall rules in this chain + EOS + defaultto :false + end + + newparam(:ignore) do + desc <<-EOS + Regex to perform on firewall rules to exempt unmanaged rules from purging (when enabled). + This is matched against the output of `iptables-save`. + + This can be a single regex, or an array of them. + To support flags, use the ruby inline flag mechanism. + Meaning a regex such as + /foo/i + can be written as + '(?i)foo' or '(?i:foo)' + + Full example: + firewallchain { 'INPUT:filter:IPv4': + purge => true, + ignore => [ + '-j fail2ban-ssh', # ignore the fail2ban jump rule + '--comment "[^"]*(?i:ignore)[^"]*"', # ignore any rules with "ignore" (case insensitive) in the comment in the rule + ], + } + EOS + + validate do |value| + unless value.is_a?(Array) or value.is_a?(String) or value == false + self.devfail "Ignore must be a string or an Array" + end + end + munge do |patterns| # convert into an array of {Regex}es + patterns = [patterns] if patterns.is_a?(String) + patterns.map{|p| Regexp.new(p)} + end + end + # Classes would be a better abstraction, pending: # http://projects.puppetlabs.com/issues/19001 autorequire(:package) do @@ -148,4 +188,34 @@ Puppet::Type.newtype(:firewallchain) do self.fail 'The "nat" table is not intended for filtering, the use of DROP is therefore inhibited' end end + + def generate + return [] unless self.purge? + + self[:name].match(Nameformat) + chain = $1 + table = $2 + protocol = $3 + + provider = case protocol + when 'IPv4' + :iptables + when 'IPv6' + :ip6tables + end + + # gather a list of all rules present on the system + rules_resources = Puppet::Type.type(:firewall).instances + + # Keep only rules in this chain + rules_resources.keep_if {|res| res[:provider] == provider and res.provider.properties[:table].to_s == table and res.provider.properties[:chain] == chain} + + # Remove rules which match our ignore filter + rules_resources.delete_if {|res| self[:ignore].find_index{|f| res.provider.properties[:line].match(f)}} if self[:ignore] + + # We mark all remaining rules for deletion, and then let the catalog override us on rules which should be present + rules_resources.each {|res| res[:ensure] = :absent} + + rules_resources + end end