Skip to content

Commit 22bbd8e

Browse files
committed
Merge pull request #496 from jonnytpuppet/munge_resource_map
MODULES-1808 - Implemented code for resource map munging to allow a single ipt module to be used multiple times in a single rule
2 parents 745e270 + 00e1927 commit 22bbd8e

3 files changed

Lines changed: 326 additions & 49 deletions

File tree

lib/puppet/provider/firewall/ip6tables.rb

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,9 @@ def self.iptables_save(*args)
7171
:ctstate => "-m conntrack --ctstate",
7272
:destination => "-d",
7373
:dport => ["-m multiport --dports", "--dport"],
74-
:dst_range => '-m iprange --dst-range',
75-
:dst_type => "-m addrtype --dst-type",
76-
:gid => "-m owner --gid-owner",
74+
:dst_range => '--dst-range',
75+
:dst_type => "--dst-type",
76+
:gid => "--gid-owner",
7777
:hop_limit => "-m hl --hl-eq",
7878
:icmp => "-m icmp6 --icmpv6-type",
7979
:iniface => "-i",
@@ -107,8 +107,8 @@ def self.iptables_save(*args)
107107
:socket => "-m socket",
108108
:source => "-s",
109109
:sport => ["-m multiport --sports", "--sport"],
110-
:src_range => '-m iprange --src-range',
111-
:src_type => "-m addrtype --src-type",
110+
:src_range => '--src-range',
111+
:src_type => "--src-type",
112112
:stat_every => '--every',
113113
:stat_mode => "-m statistic --mode",
114114
:stat_packet => '--packet',
@@ -119,10 +119,10 @@ def self.iptables_save(*args)
119119
:todest => "--to-destination",
120120
:toports => "--to-ports",
121121
:tosource => "--to-source",
122-
:uid => "-m owner --uid-owner",
123-
:physdev_in => "-m physdev --physdev-in",
124-
:physdev_out => "-m physdev --physdev-out",
125-
:physdev_is_bridged => "-m physdev --physdev-is-bridged"
122+
:uid => "--uid-owner",
123+
:physdev_in => "--physdev-in",
124+
:physdev_out => "--physdev-out",
125+
:physdev_is_bridged => "--physdev-is-bridged"
126126
}
127127

128128
# These are known booleans that do not take a value, but we want to munge
@@ -139,6 +139,25 @@ def self.iptables_save(*args)
139139
:physdev_is_bridged
140140
]
141141

142+
# Properties that use "-m <ipt module name>" (with the potential to have multiple
143+
# arguments against the same IPT module) must be in this hash. The keys in this
144+
# hash are the IPT module names, with the values being an array of the respective
145+
# supported arguments for this IPT module.
146+
#
147+
# ** IPT Module arguments must be in order as they would appear in iptables-save **
148+
#
149+
# Exceptions:
150+
# => multiport: (For some reason, the multiport arguments can't be)
151+
# specified within the same "-m multiport", but works in seperate
152+
# ones.
153+
#
154+
@module_to_argument_mapping = {
155+
:physdev => [:physdev_in, :physdev_out, :physdev_is_bridged],
156+
:addrtype => [:src_type, :dst_type],
157+
:iprange => [:src_range, :dst_range],
158+
:owner => [:uid, :gid],
159+
}
160+
142161
# Create property methods dynamically
143162
(@resource_map.keys << :chain << :table << :action).each do |property|
144163
if @known_booleans.include?(property) then
@@ -175,8 +194,8 @@ def self.iptables_save(*args)
175194
# not provided with current parser [georg.koester])
176195
@resource_list = [:table, :source, :destination, :iniface, :outiface, :physdev_in,
177196
:physdev_out, :physdev_is_bridged, :proto, :ishasmorefrags, :islastfrag, :isfirstfrag, :src_range, :dst_range,
178-
:tcp_flags, :gid, :uid, :mac_source, :sport, :dport, :port, :dst_type,
179-
:src_type, :socket, :pkttype, :name, :ipsec_dir, :ipsec_policy, :state,
197+
:tcp_flags, :uid, :gid, :mac_source, :sport, :dport, :port, :src_type,
198+
:dst_type, :socket, :pkttype, :name, :ipsec_dir, :ipsec_policy, :state,
180199
:ctstate, :icmp, :hop_limit, :limit, :burst, :recent, :rseconds, :reap,
181200
:rhitcount, :rttl, :rname, :mask, :rsource, :rdest, :ipset, :jump, :todest,
182201
:tosource, :toports, :log_level, :log_prefix, :reject, :set_mark,

lib/puppet/provider/firewall/iptables.rb

Lines changed: 78 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,9 @@
5757
:ctstate => "-m conntrack --ctstate",
5858
:destination => "-d",
5959
:dport => ["-m multiport --dports", "--dport"],
60-
:dst_range => "-m iprange --dst-range",
61-
:dst_type => "-m addrtype --dst-type",
62-
:gid => "-m owner --gid-owner",
60+
:dst_range => "--dst-range",
61+
:dst_type => "--dst-type",
62+
:gid => "--gid-owner",
6363
:icmp => "-m icmp --icmp-type",
6464
:iniface => "-i",
6565
:ipsec_dir => "-m policy --dir",
@@ -91,8 +91,8 @@
9191
:socket => "-m socket",
9292
:source => "-s",
9393
:sport => ["-m multiport --sports", "--sport"],
94-
:src_range => "-m iprange --src-range",
95-
:src_type => "-m addrtype --src-type",
94+
:src_range => "--src-range",
95+
:src_type => "--src-type",
9696
:stat_every => '--every',
9797
:stat_mode => "-m statistic --mode",
9898
:stat_packet => '--packet',
@@ -104,10 +104,10 @@
104104
:toports => "--to-ports",
105105
:tosource => "--to-source",
106106
:to => "--to",
107-
:uid => "-m owner --uid-owner",
108-
:physdev_in => "-m physdev --physdev-in",
109-
:physdev_out => "-m physdev --physdev-out",
110-
:physdev_is_bridged => "-m physdev --physdev-is-bridged"
107+
:uid => "--uid-owner",
108+
:physdev_in => "--physdev-in",
109+
:physdev_out => "--physdev-out",
110+
:physdev_is_bridged => "--physdev-is-bridged"
111111
}
112112

113113
# These are known booleans that do not take a value, but we want to munge
@@ -123,6 +123,67 @@
123123
:physdev_is_bridged
124124
]
125125

126+
# Properties that use "-m <ipt module name>" (with the potential to have multiple
127+
# arguments against the same IPT module) must be in this hash. The keys in this
128+
# hash are the IPT module names, with the values being an array of the respective
129+
# supported arguments for this IPT module.
130+
#
131+
# ** IPT Module arguments must be in order as they would appear in iptables-save **
132+
#
133+
# Exceptions:
134+
# => multiport: (For some reason, the multiport arguments can't be)
135+
# specified within the same "-m multiport", but works in seperate
136+
# ones.
137+
#
138+
@module_to_argument_mapping = {
139+
:physdev => [:physdev_in, :physdev_out, :physdev_is_bridged],
140+
:addrtype => [:src_type, :dst_type],
141+
:iprange => [:src_range, :dst_range],
142+
:owner => [:uid, :gid],
143+
}
144+
145+
def self.munge_resource_map_from_existing_values(resource_map_original, compare)
146+
resource_map_new = resource_map_original.clone
147+
148+
@module_to_argument_mapping.each do |ipt_module, arg_array|
149+
arg_array.each do |argument|
150+
if resource_map_original[argument].is_a?(Array)
151+
if compare.include?(resource_map_original[argument].first)
152+
resource_map_new[argument] = resource_map_original[argument].clone
153+
resource_map_new[argument][0] = "-m #{ipt_module.to_s} #{resource_map_original[argument].first}"
154+
break
155+
end
156+
else
157+
if compare.include?(resource_map_original[argument])
158+
resource_map_new[argument] = "-m #{ipt_module.to_s} #{resource_map_original[argument]}"
159+
break
160+
end
161+
end
162+
end
163+
end
164+
resource_map_new
165+
end
166+
167+
def munge_resource_map_from_resource(resource_map_original, compare)
168+
resource_map_new = resource_map_original.clone
169+
module_to_argument_mapping = self.class.instance_variable_get('@module_to_argument_mapping')
170+
171+
module_to_argument_mapping.each do |ipt_module, arg_array|
172+
arg_array.each do |argument|
173+
if compare[argument]
174+
if resource_map_original[argument].is_a?(Array)
175+
resource_map_new[argument] = resource_map_original[argument].clone
176+
resource_map_new[argument][0] = "-m #{ipt_module.to_s} #{resource_map_original[argument].first}"
177+
else
178+
resource_map_new[argument] = "-m #{ipt_module.to_s} #{resource_map_original[argument]}"
179+
end
180+
break
181+
end
182+
end
183+
end
184+
resource_map_new
185+
end
186+
126187

127188
# Create property methods dynamically
128189
(@resource_map.keys << :chain << :table << :action).each do |property|
@@ -158,8 +219,8 @@
158219
@resource_list = [
159220
:table, :source, :destination, :iniface, :outiface, :physdev_in, :physdev_out, :physdev_is_bridged, :proto, :isfragment,
160221
:stat_mode, :stat_every, :stat_packet, :stat_probability,
161-
:src_range, :dst_range, :tcp_flags, :gid, :uid, :mac_source, :sport, :dport, :port,
162-
:dst_type, :src_type, :socket, :pkttype, :name, :ipsec_dir, :ipsec_policy,
222+
:src_range, :dst_range, :tcp_flags, :uid, :gid, :mac_source, :sport, :dport, :port,
223+
:src_type, :dst_type, :socket, :pkttype, :name, :ipsec_dir, :ipsec_policy,
163224
:state, :ctstate, :icmp, :limit, :burst, :recent, :rseconds, :reap,
164225
:rhitcount, :rttl, :rname, :mask, :rsource, :rdest, :ipset, :jump, :todest,
165226
:tosource, :toports, :to, :random, :log_prefix, :log_level, :reject, :set_mark,
@@ -252,17 +313,7 @@ def self.rule_to_hash(line, table, counter)
252313
'--pol "ipsec\1\2\3\4\5\6\7\8" '
253314
)
254315

255-
# Handle resource_map values depending on whether physdev-in, physdev-out, ,physdev-is-bridged, or all three are specified
256-
if values.include? "--physdev-in"
257-
@resource_map[:physdev_in] = "-m physdev --physdev-in"
258-
@resource_map[:physdev_out] = "--physdev-out"
259-
@resource_map[:physdev_is_bridged] = "--physdev-is-bridged"
260-
elsif values.include? "--physdev-out"
261-
@resource_map[:physdev_out] = "-m physdev --physdev-out"
262-
@resource_map[:physdev_is_bridged] = "--physdev-is-bridged"
263-
else
264-
@resource_map[:physdev_is_bridged] = "-m physdev --physdev-is-bridged"
265-
end
316+
resource_map = munge_resource_map_from_existing_values(@resource_map, values)
266317

267318
# Trick the system for booleans
268319
@known_booleans.each do |bool|
@@ -273,15 +324,15 @@ def self.rule_to_hash(line, table, counter)
273324
# distinguish between -f and the '-f' inside of --tcp-flags.
274325
values = values.sub(/-f(?!l)(?=.*--comment)/, '-f true')
275326
else
276-
values = values.sub(/#{@resource_map[bool]}/, "#{@resource_map[bool]} true")
327+
values = values.sub(/#{resource_map[bool]}/, "#{resource_map[bool]} true")
277328
end
278329
end
279330

280331
############
281332
# Populate parser_list with used value, in the correct order
282333
############
283334
map_index={}
284-
@resource_map.each_pair do |map_k,map_v|
335+
resource_map.each_pair do |map_k,map_v|
285336
[map_v].flatten.each do |v|
286337
ind=values.index(/\s#{v}\s/)
287338
next unless ind
@@ -298,7 +349,7 @@ def self.rule_to_hash(line, table, counter)
298349

299350
# Here we iterate across our values to generate an array of keys
300351
parser_list.reverse.each do |k|
301-
resource_map_key = @resource_map[k]
352+
resource_map_key = resource_map[k]
302353
[resource_map_key].flatten.each do |opt|
303354
if values.slice!(/\s#{opt}/)
304355
keys << k
@@ -455,20 +506,9 @@ def general_args
455506

456507
args = []
457508
resource_list = self.class.instance_variable_get('@resource_list')
458-
resource_map = self.class.instance_variable_get('@resource_map')
459509
known_booleans = self.class.instance_variable_get('@known_booleans')
460-
461-
# Handle physdev args depending on whether physdev-in, physdev-out, physdev-is-bridged, or all three are specified
462-
if (resource[:physdev_in])
463-
resource_map[:physdev_in] = "-m physdev --physdev-in"
464-
resource_map[:physdev_out] = "--physdev-out"
465-
resource_map[:physdev_is_bridged] = "--physdev-is-bridged"
466-
elsif (resource[:physdev_out])
467-
resource_map[:physdev_out] = "-m physdev --physdev-out"
468-
resource_map[:physdev_is_bridged] = "--physdev-is-bridged"
469-
else
470-
resource_map[:physdev_is_bridged] = "-m physdev --physdev-is-bridged"
471-
end
510+
resource_map = self.class.instance_variable_get('@resource_map')
511+
resource_map = munge_resource_map_from_resource(resource_map, resource)
472512

473513
resource_list.each do |res|
474514
resource_value = nil

0 commit comments

Comments
 (0)