Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix rule parsing #1210

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions lib/puppet/provider/firewall/firewall.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
# Regex used to retrieve table name
$table_name_regex = %r{^\*(nat|mangle|filter|raw|rawpost|broute|security)}
# Regex used to retrieve Rules
$rules_regex = %r{(-A.*)\n}
$rules_regex = %r{^(-A.*)\n}
# Base command
$base_command = {
'IPv4' => 'iptables -t',
Expand Down Expand Up @@ -466,6 +466,9 @@
iptables_list.scan($table_regex).each do |table|
table_name = table[0].scan($table_name_regex)[0][0]
table[0].scan($rules_regex).each do |rule|
# iptables-save escapes ' symbol in it's output for some reason which leads to an incorrect command
# We need to manually replace \' to '
rule[0].gsub!("\\'","'")

Check failure on line 471 in lib/puppet/provider/firewall/firewall.rb

View workflow job for this annotation

GitHub Actions / Spec / Spec tests (Puppet: ~> 7.24, Ruby Ver: 2.7)

Layout/SpaceAfterComma: Space missing after comma. (https://rubystyle.guide#spaces-operators)

Check failure on line 471 in lib/puppet/provider/firewall/firewall.rb

View workflow job for this annotation

GitHub Actions / Spec / Spec tests (Puppet: ~> 8.0, Ruby Ver: 3.2)

Layout/SpaceAfterComma: Space missing after comma. (https://rubystyle.guide#spaces-operators)
raw_rules = if basic
Puppet::Provider::Firewall::Firewall.rule_to_name(context, rule[0], table_name, protocol)
else
Expand All @@ -489,7 +492,7 @@
rule_hash[:table] = table_name
rule_hash[:protocol] = protocol

name_regex = Regexp.new("#{$resource_map[:name]}\\s(?:\"([^\"]*)|([^\"\\s]*))")
name_regex = Regexp.new("#{$resource_map[:name]}\\s+(?:\"(.+?(?<!\\\\))\"|([^\"\\s]+)\\b)(?:\\s|$)")
name_value = rule.scan(name_regex)[0]
# Combine the returned values and remove and trailing or leading whitespace
rule_hash[:name] = [name_value[0], name_value[1]].join(' ').strip if name_value
Expand Down Expand Up @@ -527,7 +530,7 @@
# When only a single word comment is returned no quotes are given, so we must check for this as well
# First find if flag is present, add a space to ensure accuracy with the more simplistic flags; i.e. `-i`
if rule.match(Regexp.new("#{value}\\s"))
value_regex = Regexp.new("(?:(!\\s))?#{value}\\s(?:\"([^\"]*)|([^\"\\s]*))")
value_regex = Regexp.new("(?:(!\\s))?#{value}\\s+(?:\"(.+?(?<!\\\\))\"|([^\"\\s]+)\\b)(?:\\s|$)")
key_value = rule.scan(value_regex)[0]
# Combine the returned values and remove and trailing or leading whitespace
key_value[1] = [key_value[0], key_value[1], key_value[2]].join
Expand Down
337 changes: 337 additions & 0 deletions spec/unit/puppet/provider/firewall/firewall_output_parsing_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,337 @@
# frozen_string_literal: true

require 'spec_helper'
require 'puppet/resource_api'

ensure_module_defined('Puppet::Provider::Firewall')
require 'puppet/provider/firewall/firewall'

RSpec.describe Puppet::Provider::Firewall::Firewall do
describe 'iptables-save output parsing' do
subject(:provider) { described_class.new }

let(:type) { Puppet::Type.type('firewall') }
let(:context) { Puppet::ResourceApi::BaseContext.new(type.type_definition.definition) }

describe 'get(_context)' do
let(:iptables) do
'
# Generated by iptables-save v1.8.4 on Thu Aug 10 10:15:14 2023
*filter
:INPUT ACCEPT [62:3308]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [39:3092]
:TEST_ONE - [0:0]
:TEST-ANOTHER - [0:0]
COMMIT
-A TEST_ONE -p tcp -m comment --comment "001 custom chain test rule"
-A INPUT -p tcp -m comment --comment "002 \"double-quotes\" test rule"
-A INPUT -p tcp -m comment --comment "007 \'single-quotes\' test rule"
-A TEST-ANOTHER -p tcp -m comment --comment "003 test -A in chain name"
-A TEST_ONE -p tcp -m comment --comment "foreign rule test"
# Completed on Thu Aug 10 10:15:14 2023
# Generated by iptables-save v1.8.4 on Thu Aug 10 10:15:14 2023
*raw
:PREROUTING ACCEPT [13222:23455532]
:OUTPUT ACCEPT [12523:852730]
COMMIT
-A OUTPUT -p tcp -m comment --comment "004 test raw table rule"
# Completed on Thu Aug 10 10:15:14 2023
'
end
let(:ip6tables) do
'
# Generated by ip6tables-save v1.8.4 on Thu Aug 10 10:21:55 2023
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [13:824]
:TEST_TWO - [0:0]
COMMIT
-A OUTPUT -p tcp -m comment --comment "005 test ipv6 rule"
# Completed on Thu Aug 10 10:21:55 2023
*raw
:PREROUTING ACCEPT [13222:23455532]
:OUTPUT ACCEPT [12523:852730]
COMMIT
-A TEST_TWO -p tcp -m comment --comment "006 test ipv6 rule in different table"
# Completed on Thu Aug 10 10:21:55 2023
'
end
let(:returned_data) do
[{chain: "TEST_ONE",

Check failure on line 62 in spec/unit/puppet/provider/firewall/firewall_output_parsing_spec.rb

View workflow job for this annotation

GitHub Actions / Spec / Spec tests (Puppet: ~> 7.24, Ruby Ver: 2.7)

Layout/SpaceInsideHashLiteralBraces: Space inside { missing. (https://rubystyle.guide#spaces-braces)

Check failure on line 62 in spec/unit/puppet/provider/firewall/firewall_output_parsing_spec.rb

View workflow job for this annotation

GitHub Actions / Spec / Spec tests (Puppet: ~> 7.24, Ruby Ver: 2.7)

Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols. (https://rubystyle.guide#consistent-string-literals)

Check failure on line 62 in spec/unit/puppet/provider/firewall/firewall_output_parsing_spec.rb

View workflow job for this annotation

GitHub Actions / Spec / Spec tests (Puppet: ~> 8.0, Ruby Ver: 3.2)

Layout/SpaceInsideHashLiteralBraces: Space inside { missing. (https://rubystyle.guide#spaces-braces)

Check failure on line 62 in spec/unit/puppet/provider/firewall/firewall_output_parsing_spec.rb

View workflow job for this annotation

GitHub Actions / Spec / Spec tests (Puppet: ~> 8.0, Ruby Ver: 3.2)

Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols. (https://rubystyle.guide#consistent-string-literals)
checksum_fill: false,
clamp_mss_to_pmtu: false,
clusterip_new: false,
ensure: "present",

Check failure on line 66 in spec/unit/puppet/provider/firewall/firewall_output_parsing_spec.rb

View workflow job for this annotation

GitHub Actions / Spec / Spec tests (Puppet: ~> 7.24, Ruby Ver: 2.7)

Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols. (https://rubystyle.guide#consistent-string-literals)

Check failure on line 66 in spec/unit/puppet/provider/firewall/firewall_output_parsing_spec.rb

View workflow job for this annotation

GitHub Actions / Spec / Spec tests (Puppet: ~> 8.0, Ruby Ver: 3.2)

Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols. (https://rubystyle.guide#consistent-string-literals)
ipvs: false,
isfirstfrag: false,
isfragment: false,
ishasmorefrags: false,
islastfrag: false,
kernel_timezone: false,
line: "-A TEST_ONE -p tcp -m comment --comment \"001 custom chain test rule\"",

Check failure on line 73 in spec/unit/puppet/provider/firewall/firewall_output_parsing_spec.rb

View workflow job for this annotation

GitHub Actions / Spec / Spec tests (Puppet: ~> 7.24, Ruby Ver: 2.7)

Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols. (https://rubystyle.guide#consistent-string-literals)

Check failure on line 73 in spec/unit/puppet/provider/firewall/firewall_output_parsing_spec.rb

View workflow job for this annotation

GitHub Actions / Spec / Spec tests (Puppet: ~> 8.0, Ruby Ver: 3.2)

Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols. (https://rubystyle.guide#consistent-string-literals)
log_ip_options: false,
log_tcp_options: false,
log_tcp_sequence: false,
log_uid: false,
name: "001 custom chain test rule",

Check failure on line 78 in spec/unit/puppet/provider/firewall/firewall_output_parsing_spec.rb

View workflow job for this annotation

GitHub Actions / Spec / Spec tests (Puppet: ~> 7.24, Ruby Ver: 2.7)

Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols. (https://rubystyle.guide#consistent-string-literals)

Check failure on line 78 in spec/unit/puppet/provider/firewall/firewall_output_parsing_spec.rb

View workflow job for this annotation

GitHub Actions / Spec / Spec tests (Puppet: ~> 8.0, Ruby Ver: 3.2)

Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols. (https://rubystyle.guide#consistent-string-literals)
notrack: false,
physdev_is_bridged: false,
physdev_is_in: false,
physdev_is_out: false,
proto: "tcp",

Check failure on line 83 in spec/unit/puppet/provider/firewall/firewall_output_parsing_spec.rb

View workflow job for this annotation

GitHub Actions / Spec / Spec tests (Puppet: ~> 7.24, Ruby Ver: 2.7)

Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols. (https://rubystyle.guide#consistent-string-literals)

Check failure on line 83 in spec/unit/puppet/provider/firewall/firewall_output_parsing_spec.rb

View workflow job for this annotation

GitHub Actions / Spec / Spec tests (Puppet: ~> 8.0, Ruby Ver: 3.2)

Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols. (https://rubystyle.guide#consistent-string-literals)
protocol: "IPv4",

Check failure on line 84 in spec/unit/puppet/provider/firewall/firewall_output_parsing_spec.rb

View workflow job for this annotation

GitHub Actions / Spec / Spec tests (Puppet: ~> 7.24, Ruby Ver: 2.7)

Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols. (https://rubystyle.guide#consistent-string-literals)

Check failure on line 84 in spec/unit/puppet/provider/firewall/firewall_output_parsing_spec.rb

View workflow job for this annotation

GitHub Actions / Spec / Spec tests (Puppet: ~> 8.0, Ruby Ver: 3.2)

Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols. (https://rubystyle.guide#consistent-string-literals)
queue_bypass: false,
random: false,
random_fully: false,
rdest: false,
reap: false,
rsource: false,
rttl: false,
socket: false,
table: "filter",

Check failure on line 93 in spec/unit/puppet/provider/firewall/firewall_output_parsing_spec.rb

View workflow job for this annotation

GitHub Actions / Spec / Spec tests (Puppet: ~> 7.24, Ruby Ver: 2.7)

Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols. (https://rubystyle.guide#consistent-string-literals)

Check failure on line 93 in spec/unit/puppet/provider/firewall/firewall_output_parsing_spec.rb

View workflow job for this annotation

GitHub Actions / Spec / Spec tests (Puppet: ~> 8.0, Ruby Ver: 3.2)

Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols. (https://rubystyle.guide#consistent-string-literals)
time_contiguous: false},

Check failure on line 94 in spec/unit/puppet/provider/firewall/firewall_output_parsing_spec.rb

View workflow job for this annotation

GitHub Actions / Spec / Spec tests (Puppet: ~> 7.24, Ruby Ver: 2.7)

Layout/SpaceInsideHashLiteralBraces: Space inside } missing. (https://rubystyle.guide#spaces-braces)

Check failure on line 94 in spec/unit/puppet/provider/firewall/firewall_output_parsing_spec.rb

View workflow job for this annotation

GitHub Actions / Spec / Spec tests (Puppet: ~> 8.0, Ruby Ver: 3.2)

Layout/SpaceInsideHashLiteralBraces: Space inside } missing. (https://rubystyle.guide#spaces-braces)
{chain: "INPUT",
checksum_fill: false,
clamp_mss_to_pmtu: false,
clusterip_new: false,
ensure: "present",
ipvs: false,
isfirstfrag: false,
isfragment: false,
ishasmorefrags: false,
islastfrag: false,
kernel_timezone: false,
line: "-A INPUT -p tcp -m comment --comment \"002 \\\"double-quotes\\\" test rule\"",
log_ip_options: false,
log_tcp_options: false,
log_tcp_sequence: false,
log_uid: false,
name: "002 \\\"double-quotes\\\" test rule",
notrack: false,
physdev_is_bridged: false,
physdev_is_in: false,
physdev_is_out: false,
proto: "tcp",
protocol: "IPv4",
queue_bypass: false,
random: false,
random_fully: false,
rdest: false,
reap: false,
rsource: false,
rttl: false,
socket: false,
table: "filter",
time_contiguous: false},
{chain: "INPUT",
checksum_fill: false,
clamp_mss_to_pmtu: false,
clusterip_new: false,
ensure: "present",
ipvs: false,
isfirstfrag: false,
isfragment: false,
ishasmorefrags: false,
islastfrag: false,
kernel_timezone: false,
line: "-A INPUT -p tcp -m comment --comment \"007 'single-quotes' test rule\"",
log_ip_options: false,
log_tcp_options: false,
log_tcp_sequence: false,
log_uid: false,
name: "007 'single-quotes' test rule",
notrack: false,
physdev_is_bridged: false,
physdev_is_in: false,
physdev_is_out: false,
proto: "tcp",
protocol: "IPv4",
queue_bypass: false,
random: false,
random_fully: false,
rdest: false,
reap: false,
rsource: false,
rttl: false,
socket: false,
table: "filter",
time_contiguous: false},
{chain: "TEST-ANOTHER",
checksum_fill: false,
clamp_mss_to_pmtu: false,
clusterip_new: false,
ensure: "present",
ipvs: false,
isfirstfrag: false,
isfragment: false,
ishasmorefrags: false,
islastfrag: false,
kernel_timezone: false,
line: "-A TEST-ANOTHER -p tcp -m comment --comment \"003 test -A in chain name\"",
log_ip_options: false,
log_tcp_options: false,
log_tcp_sequence: false,
log_uid: false,
name: "003 test -A in chain name",
notrack: false,
physdev_is_bridged: false,
physdev_is_in: false,
physdev_is_out: false,
proto: "tcp",
protocol: "IPv4",
queue_bypass: false,
random: false,
random_fully: false,
rdest: false,
reap: false,
rsource: false,
rttl: false,
socket: false,
table: "filter",
time_contiguous: false},
{chain: "TEST_ONE",
checksum_fill: false,
clamp_mss_to_pmtu: false,
clusterip_new: false,
ensure: "present",
ipvs: false,
isfirstfrag: false,
isfragment: false,
ishasmorefrags: false,
islastfrag: false,
kernel_timezone: false,
line: "-A TEST_ONE -p tcp -m comment --comment \"foreign rule test\"",
log_ip_options: false,
log_tcp_options: false,
log_tcp_sequence: false,
log_uid: false,
name: "9005 foreign rule test",
notrack: false,
physdev_is_bridged: false,
physdev_is_in: false,
physdev_is_out: false,
proto: "tcp",
protocol: "IPv4",
queue_bypass: false,
random: false,
random_fully: false,
rdest: false,
reap: false,
rsource: false,
rttl: false,
socket: false,
table: "filter",
time_contiguous: false},
{chain: "OUTPUT",
checksum_fill: false,
clamp_mss_to_pmtu: false,
clusterip_new: false,
ensure: "present",
ipvs: false,
isfirstfrag: false,
isfragment: false,
ishasmorefrags: false,
islastfrag: false,
kernel_timezone: false,
line: "-A OUTPUT -p tcp -m comment --comment \"004 test raw table rule\"",
log_ip_options: false,
log_tcp_options: false,
log_tcp_sequence: false,
log_uid: false,
name: "004 test raw table rule",
notrack: false,
physdev_is_bridged: false,
physdev_is_in: false,
physdev_is_out: false,
proto: "tcp",
protocol: "IPv4",
queue_bypass: false,
random: false,
random_fully: false,
rdest: false,
reap: false,
rsource: false,
rttl: false,
socket: false,
table: "raw",
time_contiguous: false},
{chain: "OUTPUT",
checksum_fill: false,
clamp_mss_to_pmtu: false,
clusterip_new: false,
ensure: "present",
ipvs: false,
isfirstfrag: false,
isfragment: false,
ishasmorefrags: false,
islastfrag: false,
kernel_timezone: false,
line: "-A OUTPUT -p tcp -m comment --comment \"005 test ipv6 rule\"",
log_ip_options: false,
log_tcp_options: false,
log_tcp_sequence: false,
log_uid: false,
name: "005 test ipv6 rule",
notrack: false,
physdev_is_bridged: false,
physdev_is_in: false,
physdev_is_out: false,
proto: "tcp",
protocol: "IPv6",
queue_bypass: false,
random: false,
random_fully: false,
rdest: false,
reap: false,
rsource: false,
rttl: false,
socket: false,
table: "filter",
time_contiguous: false},
{chain: "TEST_TWO",
checksum_fill: false,
clamp_mss_to_pmtu: false,
clusterip_new: false,
ensure: "present",
ipvs: false,
isfirstfrag: false,
isfragment: false,
ishasmorefrags: false,
islastfrag: false,
kernel_timezone: false,
line: "-A TEST_TWO -p tcp -m comment --comment \"006 test ipv6 rule in different table\"",
log_ip_options: false,
log_tcp_options: false,
log_tcp_sequence: false,
log_uid: false,
name: "006 test ipv6 rule in different table",
notrack: false,
physdev_is_bridged: false,
physdev_is_in: false,
physdev_is_out: false,
proto: "tcp",
protocol: "IPv6",
queue_bypass: false,
random: false,
random_fully: false,
rdest: false,
reap: false,
rsource: false,
rttl: false,
socket: false,
table: "raw",
time_contiguous: false}
]
end

it 'processes the resource' do
allow(Puppet::Util::Execution).to receive(:execute).with('iptables-save').and_return(iptables)
allow(Puppet::Util::Execution).to receive(:execute).with('ip6tables-save').and_return(ip6tables)

expect(provider.get(context)).to eq(returned_data)
end
end
end
end