101 changes: 76 additions & 25 deletions lib/puppet/type/firewall.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,18 @@
#
# This is a workaround for bug: #4248 whereby ruby files outside of the normal
# provider/type path do not load until pluginsync has occured on the puppetmaster
#
#
# In this case I'm trying the relative path first, then falling back to normal
# mechanisms. This should be fixed in future versions of puppet but it looks
# like we'll need to maintain this for some time perhaps.
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__),"..",".."))
require 'puppet/util/firewall'

# Puppet Firewall type
Puppet::Type.newtype(:firewall) do
include Puppet::Util::Firewall

@doc = <<-EOS
This type provides the capability to manage firewall rules within
This type provides the capability to manage firewall rules within
puppet.
EOS

Expand All @@ -23,6 +22,7 @@
feature :dnat, "Destination NATing"
feature :interface_match, "Interface matching"
feature :icmp_match, "Matching ICMP types"
feature :owner, "Matching owners"
feature :state_match, "Matching stateful firewall states"
feature :reject_type, "The ability to control reject messages"
feature :log_level, "The ability to control the log level"
Expand Down Expand Up @@ -87,6 +87,10 @@
The source can also be an IPv6 address if your provider supports it.
EOS

munge do |value|
@resource.host_to_ip(value)
end
end

newproperty(:destination) do
Expand All @@ -97,11 +101,15 @@
The destination can also be an IPv6 address if your provider supports it.
EOS

munge do |value|
@resource.host_to_ip(value)
end
end

newproperty(:sport, :array_matching => :all) do
desc <<-EOS
The source port to match for this filter (if the protocol supports
The source port to match for this filter (if the protocol supports
ports). Will accept a single element or an array.
For some firewall providers you can pass a range of ports in the format:
Expand All @@ -127,7 +135,7 @@ def should_to_s(value)

newproperty(:dport, :array_matching => :all) do
desc <<-EOS
The destination port to match for this filter (if the protocol supports
The destination port to match for this filter (if the protocol supports
ports). Will accept a single element or an array.
For some firewall providers you can pass a range of ports in the format:
Expand All @@ -140,7 +148,7 @@ def should_to_s(value)
This would cover ports 1 to 1024.
EOS

munge do |value|
@resource.string_to_port(value)
end
Expand Down Expand Up @@ -179,11 +187,11 @@ def should_to_s(value)

newproperty(:proto) do
desc <<-EOS
The specific protocol to match for this rule. By default this is
The specific protocol to match for this rule. By default this is
*tcp*.
EOS

newvalues(:tcp, :udp, :icmp, :"ipv6-icmp", :esp, :ah, :vrrp, :igmp, :all)
newvalues(:tcp, :udp, :icmp, :"ipv6-icmp", :esp, :ah, :vrrp, :igmp, :ipencap, :all)
defaultto "tcp"
end

Expand Down Expand Up @@ -226,19 +234,19 @@ def should_to_s(value)

newproperty(:jump, :required_features => :iptables) do
desc <<-EOS
The value for the iptables --jump parameter. Normal values are:
The value for the iptables --jump parameter. Normal values are:
* QUEUE
* RETURN
* DNAT
* SNAT
* LOG
* MASQUERADE
* MASQUERADE
* REDIRECT
But any valid chain name is allowed.
But any valid chain name is allowed.
For the values ACCEPT, DROP and REJECT you must use the generic
For the values ACCEPT, DROP and REJECT you must use the generic
'action' parameter. This is to enfore the use of generic parameters where
possible for maximum cross-platform modelling.
Expand All @@ -249,14 +257,14 @@ def should_to_s(value)
validate do |value|
unless value =~ /^[a-zA-Z0-9\-_]+$/
raise ArgumentError, <<-EOS
Jump destination must consist of alphanumeric characters, an
Jump destination must consist of alphanumeric characters, an
underscore or a yphen.
EOS
end

if ["accept","reject","drop"].include?(value.downcase)
raise ArgumentError, <<-EOS
Jump destination should not be one of ACCEPT, REJECT or DENY. Use
Jump destination should not be one of ACCEPT, REJECT or DENY. Use
the action property instead.
EOS
end
Expand All @@ -282,14 +290,14 @@ def should_to_s(value)
# NAT specific properties
newproperty(:tosource, :required_features => :snat) do
desc <<-EOS
When using jump => "SNAT" you can specify the new source address using
When using jump => "SNAT" you can specify the new source address using
this parameter.
EOS
end

newproperty(:todest, :required_features => :dnat) do
desc <<-EOS
When using jump => "DNAT" you can specify the new destination address
When using jump => "DNAT" you can specify the new destination address
using this paramter.
EOS
end
Expand All @@ -303,22 +311,35 @@ def should_to_s(value)
# Reject ICMP type
newproperty(:reject, :required_features => :reject_type) do
desc <<-EOS
When combined with jump => "REJECT" you can specify a different icmp
When combined with jump => "REJECT" you can specify a different icmp
response to be sent back to the packet sender.
EOS
end

# Logging properties
newproperty(:log_level, :required_features => :log_level) do
desc <<-EOS
When combined with jump => "LOG" specifies the system log level to log
When combined with jump => "LOG" specifies the system log level to log
to.
EOS

munge do |value|
if value.kind_of?(String)
value = @resource.log_level_name_to_number(value)
else
value
end

if value == nil && value != ""
self.fail("Unable to determine log level")
end
value
end
end

newproperty(:log_prefix, :required_features => :log_prefix) do
desc <<-EOS
When combined with jump => "LOG" specifies the log prefix to use when
When combined with jump => "LOG" specifies the log prefix to use when
logging.
EOS
end
Expand All @@ -343,11 +364,11 @@ def should_to_s(value)
end
end

newproperty(:state, :array_matching => :all, :required_features =>
newproperty(:state, :array_matching => :all, :required_features =>
:state_match) do

desc <<-EOS
Matches a packet based on its state in the firewall stateful inspection
Matches a packet based on its state in the firewall stateful inspection
table. Values can be:
* INVALID
Expand All @@ -373,7 +394,7 @@ def should_to_s(value)
# Rate limiting properties
newproperty(:limit, :required_features => :rate_limiting) do
desc <<-EOS
Rate limiting value for matched packets. The format is:
Rate limiting value for matched packets. The format is:
rate/[/second/|/minute|/hour|/day].
Example values are: '50/sec', '40/min', '30/hour', '10/day'."
Expand All @@ -387,12 +408,28 @@ def should_to_s(value)
newvalue(/^\d+$/)
end

newproperty(:uid, :array_matching =>:all, :required_features => :owner) do
desc <<-EOS
UID or Username owner matching rule. Accepts a string argument
only, as iptables does not accept multiple uid in a single
statement.
EOS
end

newproperty(:gid, :array_matching =>:all, :required_features => :owner) do
desc <<-EOS
GID or Group owner matching rule. Accepts a string argument
only, as iptables does not accept multiple gid in a single
statement.
EOS
end

newparam(:line) do
desc <<-EOS
Read-only property for caching the rule line.
EOS
end

validate do
debug("[validate]")

Expand All @@ -405,7 +442,7 @@ def should_to_s(value)
end

# First we make sure the chains and tables are valid combinations
if value(:table).to_s == "filter" &&
if value(:table).to_s == "filter" &&
value(:chain) =~ /PREROUTING|POSTROUTING/

self.fail "PREROUTING and POSTROUTING cannot be used in table 'filter'"
Expand All @@ -415,7 +452,7 @@ def should_to_s(value)
self.fail "INPUT and FORWARD cannot be used in table 'nat'"
end

if value(:table).to_s == "raw" &&
if value(:table).to_s == "raw" &&
value(:chain) =~ /INPUT|FORWARD|POSTROUTING/

self.fail "INPUT, FORWARD and POSTROUTING cannot be used in table raw"
Expand All @@ -437,6 +474,20 @@ def should_to_s(value)
end
end

if value(:uid)
unless value(:chain).to_s =~ /OUTPUT|POSTROUTING/
self.fail "Parameter uid only applies to chains " \
"OUTPUT,POSTROUTING"
end
end

if value(:gid)
unless value(:chain).to_s =~ /OUTPUT|POSTROUTING/
self.fail "Parameter gid only applies to chains " \
"OUTPUT,POSTROUTING"
end
end

if value(:dport)
unless value(:proto).to_s =~ /tcp|udp|sctp/
self.fail "[%s] Parameter dport only applies to sctp, tcp and udp " \
Expand Down
34 changes: 33 additions & 1 deletion lib/puppet/util/firewall.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require 'socket'
require 'resolv'
require 'puppet/util/ipcidr'

# Util module for puppetlabs-firewall
Expand Down Expand Up @@ -27,9 +28,32 @@ def icmp_name_to_number(value_icmp)
end
end

# Convert log_level names to their respective numbers
def log_level_name_to_number(value)
#TODO make this 0-7 only
if value =~ /\d/
value
else
case value
when "panic" then "0"
when "alert" then "1"
when "crit" then "2"
when "err" then "3"
when "error" then "3"
when "warn" then "4"
when "warning" then "4"
when "not" then "5"
when "notice" then "5"
when "info" then "6"
when "debug" then "7"
else nil
end
end
end

# This method takes a string and attempts to convert it to a port number
# if valid.
#
#
# If the string already contains a port number or perhaps a range of ports
# in the format 22:1000 for example, it simply returns the string and does
# nothing.
Expand All @@ -44,4 +68,12 @@ def string_to_port(value)
Socket.getservbyname(value)
end
end

def host_to_ip(value)
begin
Puppet::Util::IPCidr.new(value).cidr
rescue
Puppet::Util::IPCidr.new(Resolv.getaddress(value)).cidr
end
end
end
2 changes: 1 addition & 1 deletion lib/puppet/util/ipcidr.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
module Puppet
module Util
class IPCidr < IPAddr

def netmask
_to_string(@mask_addr)
end
Expand Down
183 changes: 158 additions & 25 deletions spec/fixtures/iptables/conversion_hash.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,41 +5,41 @@

# This hash is for testing a line conversion to a hash of parameters
# which will be used to create a resource.
ARGS_TO_HASH = {
ARGS_TO_HASH = {
'long_rule_1' => {
:line => '-A INPUT -s 1.1.1.1 -d 1.1.1.1 -p tcp -m multiport --dports 7061,7062 -m multiport --sports 7061,7062 -m comment --comment "000 allow foo" -j ACCEPT',
:line => '-A INPUT -s 1.1.1.1/32 -d 1.1.1.1/32 -p tcp -m multiport --dports 7061,7062 -m multiport --sports 7061,7062 -m comment --comment "000 allow foo" -j ACCEPT',
:table => 'filter',
:compare_all => true,
:params => {
:action => "accept",
:chain => "INPUT",
:destination => "1.1.1.1",
:destination => "1.1.1.1/32",
:dport => ["7061","7062"],
:ensure => :present,
:line => '-A INPUT -s 1.1.1.1 -d 1.1.1.1 -p tcp -m multiport --dports 7061,7062 -m multiport --sports 7061,7062 -m comment --comment "000 allow foo" -j ACCEPT',
:line => '-A INPUT -s 1.1.1.1/32 -d 1.1.1.1/32 -p tcp -m multiport --dports 7061,7062 -m multiport --sports 7061,7062 -m comment --comment "000 allow foo" -j ACCEPT',
:name => "000 allow foo",
:proto => "tcp",
:provider => "iptables",
:source => "1.1.1.1",
:source => "1.1.1.1/32",
:sport => ["7061","7062"],
:table => "filter",
},
},
},
},
'action_drop_1' => {
:line => '-A INPUT -m comment --comment "000 allow foo" -j DROP',
:table => 'filter',
:params => {
:jump => nil,
:action => "drop",
},
},
},
},
'action_reject_1' => {
:line => '-A INPUT -m comment --comment "000 allow foo" -j REJECT',
:table => 'filter',
:params => {
:jump => nil,
:action => "reject",
},
},
},
'action_nil_1' => {
:line => '-A INPUT -m comment --comment "000 allow foo"',
Expand Down Expand Up @@ -95,11 +95,29 @@
},
'comment_string_character_validation' => {
:line => '-A INPUT -s 192.168.0.1 -m comment --comment "000 allow from 192.168.0.1, please"',
:tables => 'filter',
:table => 'filter',
:params => {
:source => '192.168.0.1',
},
},
'log_level_debug' => {
:line => '-A INPUT -m comment --comment "956 INPUT log-level" -m state --state NEW -j LOG --log-level 7',
:table => 'filter',
:params => {
:state => ['NEW'],
:log_level => '7',
:jump => 'LOG'
},
},
'log_level_warn' => {
:line => '-A INPUT -m comment --comment "956 INPUT log-level" -m state --state NEW -j LOG',
:table => 'filter',
:params => {
:state => ['NEW'],
:log_level => '4',
:jump => 'LOG'
},
},
'load_limit_module' => {
:line => '-A INPUT -m multiport --dports 123 -m comment --comment "057 INPUT limit NTP" -m limit --limit 15/hour',
:table => 'filter',
Expand All @@ -108,10 +126,53 @@
:limit => '15/hour'
},
},
'proto_ipencap' => {
:line => '-A INPUT -p ipencap -m comment --comment "0100 INPUT accept ipencap"',
:table => 'filter',
:params => {
:proto => 'ipencap',
}
},
'load_uid_owner_filter_module' => {
:line => '-A OUTPUT -m owner --uid-owner root -m comment --comment "057 OUTPUT uid root only" -j ACCEPT',
:table => 'filter',
:params => {
:action => 'accept',
:uid => 'root',
:chain => 'OUTPUT',
},
},
'load_uid_owner_postrouting_module' => {
:line => '-t mangle -A POSTROUTING -m owner --uid-owner root -m comment --comment "057 POSTROUTING uid root only" -j ACCEPT',
:table => 'mangle',
:params => {
:action => 'accept',
:chain => 'POSTROUTING',
:uid => 'root',
},
},
'load_gid_owner_filter_module' => {
:line => '-A OUTPUT -m owner --gid-owner root -m comment --comment "057 OUTPUT gid root only" -j ACCEPT',
:table => 'filter',
:params => {
:action => 'accept',
:chain => 'OUTPUT',
:gid => 'root',
},
},
'load_gid_owner_postrouting_module' => {
:line => '-t mangle -A POSTROUTING -m owner --gid-owner root -m comment --comment "057 POSTROUTING gid root only" -j ACCEPT',
:table => 'mangle',
:params => {
:action => 'accept',
:chain => 'POSTROUTING',
:gid => 'root',
},
},
}

# This hash is for testing converting a hash to an argument line.
HASH_TO_ARGS = {
HASH_TO_ARGS = {
'long_rule_1' => {
:params => {
:action => "accept",
Expand All @@ -124,9 +185,9 @@
:source => "1.1.1.1",
:sport => ["7061","7062"],
:table => "filter",
},
:args => ["-t", :filter, "-s", "1.1.1.1", "-d", "1.1.1.1", "-p", :tcp, "-m", "multiport", "--sports", "7061,7062", "-m", "multiport", "--dports", "7061,7062", "-m", "comment", "--comment", "000 allow foo", "-j", "ACCEPT"],
},
},
:args => ["-t", :filter, "-s", "1.1.1.1/32", "-d", "1.1.1.1/32", "-p", :tcp, "-m", "multiport", "--sports", "7061,7062", "-m", "multiport", "--dports", "7061,7062", "-m", "comment", "--comment", "000 allow foo", "-j", "ACCEPT"],
},
'long_rule_2' => {
:params => {
:chain => "INPUT",
Expand All @@ -139,47 +200,47 @@
:source => "1.1.1.1",
:sport => ["7061","7062"],
:table => "filter",
},
:args => ["-t", :filter, "-s", "1.1.1.1", "-d", "2.10.13.3/24", "-p", :udp, "-m", "multiport", "--sports", "7061,7062", "-m", "multiport", "--dports", "7061", "-m", "comment", "--comment", "700 allow bar", "-j", "my_custom_chain"],
},
},
:args => ["-t", :filter, "-s", "1.1.1.1/32", "-d", "2.10.13.0/24", "-p", :udp, "-m", "multiport", "--sports", "7061,7062", "-m", "multiport", "--dports", "7061", "-m", "comment", "--comment", "700 allow bar", "-j", "my_custom_chain"],
},
'no_action' => {
:params => {
:name => "100 no action",
:table => "filter",
},
:args => ["-t", :filter, "-p", :tcp, "-m", "comment", "--comment",
},
:args => ["-t", :filter, "-p", :tcp, "-m", "comment", "--comment",
"100 no action"],
},
'sport_range_1' => {
:params => {
:name => "100 sport range",
:sport => ["1-1024"],
:table => "filter",
},
},
:args => ["-t", :filter, "-p", :tcp, "-m", "multiport", "--sports", "1:1024", "-m", "comment", "--comment", "100 sport range"],
},
'sport_range_2' => {
:params => {
:name => "100 sport range",
:sport => ["15","512-1024"],
:table => "filter",
},
},
:args => ["-t", :filter, "-p", :tcp, "-m", "multiport", "--sports", "15,512:1024", "-m", "comment", "--comment", "100 sport range"],
},
'dport_range_1' => {
:params => {
:name => "100 sport range",
:dport => ["1-1024"],
:table => "filter",
},
},
:args => ["-t", :filter, "-p", :tcp, "-m", "multiport", "--dports", "1:1024", "-m", "comment", "--comment", "100 sport range"],
},
'dport_range_2' => {
:params => {
:name => "100 sport range",
:dport => ["15","512-1024"],
:table => "filter",
},
},
:args => ["-t", :filter, "-p", :tcp, "-m", "multiport", "--dports", "15,512:1024", "-m", "comment", "--comment", "100 sport range"],
},
'states_set_from_array' => {
Expand All @@ -197,7 +258,7 @@
:table => 'filter',
:source => '192.168.0.1'
},
:args => ['-t', :filter, '-s', '192.168.0.1', '-p', :tcp, '-m', 'comment', '--comment', '000 allow from 192.168.0.1, please'],
:args => ['-t', :filter, '-s', '192.168.0.1/32', '-p', :tcp, '-m', 'comment', '--comment', '000 allow from 192.168.0.1, please'],
},
'port_property' => {
:params => {
Expand All @@ -207,6 +268,26 @@
},
:args => ['-t', :filter, '-p', :tcp, '-m', 'multiport', '--ports', '80', '-m', 'comment', '--comment', '001 port property'],
},
'log_level_debug' => {
:params => {
:name => '956 INPUT log-level',
:table => 'filter',
:state => 'NEW',
:jump => 'LOG',
:log_level => 'debug'
},
:args => ['-t', :filter, '-p', :tcp, '-m', 'comment', '--comment', '956 INPUT log-level', '-m', 'state', '--state', 'NEW', '-j', 'LOG', '--log-level', '7'],
},
'log_level_warn' => {
:params => {
:name => '956 INPUT log-level',
:table => 'filter',
:state => 'NEW',
:jump => 'LOG',
:log_level => 'warn'
},
:args => ['-t', :filter, '-p', :tcp, '-m', 'comment', '--comment', '956 INPUT log-level', '-m', 'state', '--state', 'NEW', '-j', 'LOG', '--log-level', '4'],
},
'load_limit_module' => {
:params => {
:name => '057 INPUT limit NTP',
Expand All @@ -216,4 +297,56 @@
},
:args => ['-t', :filter, '-p', :tcp, '-m', 'multiport', '--dports', '123', '-m', 'comment', '--comment', '057 INPUT limit NTP', '-m', 'limit', '--limit', '15/hour'],
},
'proto_ipencap' => {
:params => {
:name => '0100 INPUT accept ipencap',
:table => 'filter',
:proto => 'ipencap',
},
:args => ['-t', :filter, '-p', :ipencap, '-m', 'comment', '--comment', '0100 INPUT accept ipencap'],
},
'load_uid_owner_filter_module' => {
:params => {
:name => '057 OUTPUT uid root only',
:table => 'filter',
:uid => 'root',
:action => 'accept',
:chain => 'OUTPUT',
:proto => 'all',
},
:args => ['-t', :filter, '-p', :all, '-m', 'owner', '--uid-owner', 'root', '-m', 'comment', '--comment', '057 OUTPUT uid root only', '-j', 'ACCEPT'],
},
'load_uid_owner_postrouting_module' => {
:params => {
:name => '057 POSTROUTING uid root only',
:table => 'mangle',
:uid => 'root',
:action => 'accept',
:chain => 'POSTROUTING',
:proto => 'all',
},
:args => ['-t', :mangle, '-p', :all, '-m', 'owner', '--uid-owner', 'root', '-m', 'comment', '--comment', '057 POSTROUTING uid root only', '-j', 'ACCEPT'],
},
'load_gid_owner_filter_module' => {
:params => {
:name => '057 OUTPUT gid root only',
:table => 'filter',
:chain => 'OUTPUT',
:gid => 'root',
:action => 'accept',
:proto => 'all',
},
:args => ['-t', :filter, '-p', :all, '-m', 'owner', '--gid-owner', 'root', '-m', 'comment', '--comment', '057 OUTPUT gid root only', '-j', 'ACCEPT'],
},
'load_gid_owner_postrouting_module' => {
:params => {
:name => '057 POSTROUTING gid root only',
:table => 'mangle',
:gid => 'root',
:action => 'accept',
:chain => 'POSTROUTING',
:proto => 'all',
},
:args => ['-t', :mangle, '-p', :all, '-m', 'owner', '--gid-owner', 'root', '-m', 'comment', '--comment', '057 POSTROUTING gid root only', '-j', 'ACCEPT'],
},
}
21 changes: 21 additions & 0 deletions spec/unit/facter/iptables_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
require 'spec_helper'
require 'facter/iptables'

describe "Facter::Util::Fact" do
before {
Facter.fact(:kernel).stubs(:value).returns("Linux")
Facter.fact(:kernelrelease).stubs(:value).returns("2.6")
}

describe 'iptables_version' do
it {
Facter::Util::Resolution.stubs(:exec).with('iptables --version').returns('iptables v1.4.7')
Facter.fact(:iptables_version).value.should == '1.4.7'
}
end

describe 'ip6tables_version' do
before { Facter::Util::Resolution.stubs(:exec).with('ip6tables --version').returns('ip6tables v1.4.7') }
it { Facter.fact(:ip6tables_version).value.should == '1.4.7' }
end
end
51 changes: 49 additions & 2 deletions spec/unit/puppet/type/firewall_spec.rb
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@
end

describe ':proto' do
[:tcp, :udp, :icmp, :esp, :ah, :vrrp, :igmp, :all].each do |proto|
[:tcp, :udp, :icmp, :esp, :ah, :vrrp, :igmp, :ipencap, :all].each do |proto|
it "should accept proto value #{proto}" do
@resource[:proto] = proto
@resource[:proto].should == proto
Expand Down Expand Up @@ -114,7 +114,7 @@
describe addr do
it "should accept a #{addr} as a string" do
@resource[addr] = '127.0.0.1'
@resource[addr].should == '127.0.0.1'
@resource[addr].should == '127.0.0.1/32'
end
end
end
Expand Down Expand Up @@ -175,6 +175,35 @@
end
end

describe ':log_level' do
values = {
'panic' => '0',
'alert' => '1',
'crit' => '2',
'err' => '3',
'warn' => '4',
'warning' => '4',
'not' => '5',
'notice' => '5',
'info' => '6',
'debug' => '7'
}

values.each do |k,v|
it {
@resource[:log_level] = k
@resource[:log_level].should == v
}

it {
@resource[:log_level] = 3
@resource[:log_level].should == 3
}

it { lambda { @resource[:log_level] = 'foo' }.should raise_error(Puppet::Error) }
end
end

describe ':icmp' do
values = {
'0' => 'echo-reply',
Expand Down Expand Up @@ -247,4 +276,22 @@
}.should raise_error(Puppet::Error, /^Only one of the parameters 'action' and 'jump' can be set$/)
end
end
describe ':gid and :uid' do
it 'should allow me to set uid' do
@resource[:uid] = 'root'
@resource[:uid].should == ['root']
end
it 'should allow me to set uid as an array, breaking iptables' do
@resource[:uid] = ['root', 'bobby']
@resource[:uid].should == ['root', 'bobby']
end
it 'should allow me to set gid' do
@resource[:gid] = 'root'
@resource[:gid].should == ['root']
end
it 'should allow me to set gid as an array, breaking iptables' do
@resource[:gid] = ['root', 'bobby']
@resource[:gid].should == ['root', 'bobby']
end
end
end
45 changes: 45 additions & 0 deletions spec/unit/puppet/util/firewall_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
require 'spec_helper'

describe 'Puppet::Util::Firewall' do
let(:resource) {
type = Puppet::Type.type(:firewall)
provider = stub 'provider'
provider.stubs(:name).returns(:iptables)
Puppet::Type::Firewall.stubs(:defaultprovider).returns(provider)
type.new({:name => '000 test foo'})
}

before(:each) { resource }

describe '#host_to_ip' do
subject { resource }
specify { subject.host_to_ip('puppetlabs.com').should == '96.126.112.51/32' }
specify { subject.host_to_ip('96.126.112.51').should == '96.126.112.51/32' }
specify { subject.host_to_ip('96.126.112.51/32').should == '96.126.112.51/32' }
specify { subject.host_to_ip('2001:db8:85a3:0:0:8a2e:370:7334').should == '2001:db8:85a3::8a2e:370:7334/128' }
specify { subject.host_to_ip('2001:db8:1234::/48').should == '2001:db8:1234::/48' }
end

describe '#icmp_name_to_number' do
subject { resource }
specify { subject.icmp_name_to_number('echo-reply').should == '0' }
specify { subject.icmp_name_to_number('destination-unreachable').should == '3' }
specify { subject.icmp_name_to_number('source-quench').should == '4' }
specify { subject.icmp_name_to_number('redirect').should == '6' }
specify { subject.icmp_name_to_number('echo-request').should == '8' }
specify { subject.icmp_name_to_number('router-advertisement').should == '9' }
specify { subject.icmp_name_to_number('router-solicitation').should == '10' }
specify { subject.icmp_name_to_number('time-exceeded').should == '11' }
specify { subject.icmp_name_to_number('parameter-problem').should == '12' }
specify { subject.icmp_name_to_number('timestamp-request').should == '13' }
specify { subject.icmp_name_to_number('timestamp-reply').should == '14' }
specify { subject.icmp_name_to_number('address-mask-request').should == '17' }
specify { subject.icmp_name_to_number('address-mask-reply').should == '18' }
end

describe '#string_to_port' do
subject { resource }
specify { subject.string_to_port('80').should == '80' }
specify { subject.string_to_port('http').should == '80' }
end
end
51 changes: 51 additions & 0 deletions spec/unit/puppet/util/ipcidr_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
require 'spec_helper'

describe 'Puppet::Util::IPCidr' do
describe 'ipv4 address' do
before { @ipaddr = Puppet::Util::IPCidr.new('96.126.112.51') }
subject { @ipaddr }
specify { subject.cidr.should == '96.126.112.51/32' }
specify { subject.prefixlen.should == 32 }
specify { subject.netmask.should == '255.255.255.255' }
end

describe 'single ipv4 address with cidr' do
before { @ipcidr = Puppet::Util::IPCidr.new('96.126.112.51/32') }
subject { @ipcidr }
specify { subject.cidr.should == '96.126.112.51/32' }
specify { subject.prefixlen.should == 32 }
specify { subject.netmask.should == '255.255.255.255' }
end

describe 'ipv4 address range with cidr' do
before { @ipcidr = Puppet::Util::IPCidr.new('96.126.112.0/24') }
subject { @ipcidr }
specify { subject.cidr.should == '96.126.112.0/24' }
specify { subject.prefixlen.should == 24 }
specify { subject.netmask.should == '255.255.255.0' }
end

describe 'ipv6 address' do
before { @ipaddr = Puppet::Util::IPCidr.new('2001:db8:85a3:0:0:8a2e:370:7334') }
subject { @ipaddr }
specify { subject.cidr.should == '2001:db8:85a3::8a2e:370:7334/128' }
specify { subject.prefixlen.should == 128 }
specify { subject.netmask.should == 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff' }
end

describe 'single ipv6 addr with cidr' do
before { @ipaddr = Puppet::Util::IPCidr.new('2001:db8:85a3:0:0:8a2e:370:7334/128') }
subject { @ipaddr }
specify { subject.cidr.should == '2001:db8:85a3::8a2e:370:7334/128' }
specify { subject.prefixlen.should == 128 }
specify { subject.netmask.should == 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff' }
end

describe 'ipv6 addr range with cidr' do
before { @ipaddr = Puppet::Util::IPCidr.new('2001:db8:1234::/48') }
subject { @ipaddr }
specify { subject.cidr.should == '2001:db8:1234::/48' }
specify { subject.prefixlen.should == 48 }
specify { subject.netmask.should == 'ffff:ffff:ffff:0000:0000:0000:0000:0000' }
end
end