require 'puppet/provider/firewall'
+require 'digest/md5'
Puppet::Type.type(:firewall).provide :iptables, :parent => Puppet::Provider::Firewall do
include Puppet::Util::Firewall
def delete
debug 'Deleting rule %s' % resource[:name]
- iptables "-D", properties[:chain], insert_order
+ iptables delete_args
end
def exists?
[:dport, :sport, :state].each do |prop|
hash[prop] = hash[prop].split(',') if ! hash[prop].nil?
end
-
+
+ # This forces all existing, commentless rules to be moved to the bottom of the stack.
+ # Puppet-firewall requires that all rules have comments (resource names) and will fail if
+ # a rule in iptables does not have a comment. We get around this by appending a high level
+ if ! hash[:name]
+ hash[:name] = "9999 #{Digest::MD5.hexdigest(line)}"
+ end
+
+ hash[:line] = line
hash[:provider] = self.name.to_s
hash[:table] = table
hash[:ensure] = :present
# Munge some vars here ...
# proto should equal 'all' if undefined
hash[:proto] = "all" if !hash.include?(:proto)
-
hash
end
args
end
+ def delete_args
+ count = []
+ line = properties[:line].gsub(/\-A/, '-D').split
+
+ # Grab all comment indices
+ line.each do |v|
+ if v =~ /"/
+ count << line.index(v)
+ end
+ end
+
+ if ! count.empty?
+ # Remove quotes and set first comment index to full string
+ line[count.first] = line[count.first..count.last].join(' ').gsub(/"/, '')
+
+ # Make all remaining comment indices nil
+ ((count.first + 1)..count.last).each do |i|
+ line[i] = nil
+ end
+ end
+
+ # Return array without nils
+ line.compact
+ end
+
def general_args
debug "Current resource: %s" % resource.class
args = []
:name => '000 test foo' }) }.should raise_error(Puppet::DevError,
"Could not find a default provider for firewall")
end
-
end
describe 'iptables provider' do
end
end
- describe 'when modifying resources' do
+ describe 'when converting rules without comments to resources' do
+ before :each do
+ @rule = '-A INPUT -s 1.1.1.1 -d 1.1.1.1 -p tcp -m multiport --dports 7061,7062 -m multiport --sports 7061, 7062 -j ACCEPT'
+ @resource = @provider.rule_to_hash(@rule, 'filter', 0)
+ @instance = @provider.new(@resource)
+ end
+
+ it 'rule name contains a MD5 sum of the line' do
+ @resource[:name].should == "9999 #{Digest::MD5.hexdigest(@resource[:line])}"
+ end
+ end
+
+ describe 'when creating resources' do
before :each do
@instance = @provider.new(@resource)
@provider.expects(:execute).with(['/sbin/iptables-save']).returns("")
end
- it 'should do something' do
+ it 'insert_args should be an array' do
@instance.insert_args.class.should == Array
end
end
+
+ describe 'when modifying resources' do
+ before :each do
+ @instance = @provider.new(@resource)
+ @provider.expects(:execute).with(['/sbin/iptables-save']).returns ""
+ end
+
+ it 'update_args should be an array' do
+ @instance.update_args.class.should == Array
+ end
+ end
+
+ describe 'when deleting resources' do
+ before :each do
+ @rule = '-A INPUT -s 1.1.1.1 -d 1.1.1.1 -p tcp -m multiport --dports 7061,7062 -m multiport --sports 7061, 7062 -j ACCEPT'
+ @resource = @provider.rule_to_hash(@rule, 'filter', 0)
+ @instance = @provider.new(@resource)
+ end
+
+ it 'resource[:line] looks like the original rule' do
+ @resource[:line] == @rule
+ end
+
+ it 'delete_args is an array' do
+ @instance.delete_args.class.should == Array
+ end
+
+ it 'delete_args is the same as the rule string when joined' do
+ @instance.delete_args.join(' ').should == @rule.gsub(/\-A/, '-D')
+ end
+ end
end