Skip to content

Commit 5b66307

Browse files
committed
Speed up ipset entries changes
We now use `--add-entries-from-file` and `--remove-entries-from-file` to change firewalld ipset. Adding or removing entries one by one was really slow. This pull request is based on https://github.com/42wim/puppet-firewalld/blob/04683b46cbe6e6a925c585283941cc363752aceb/lib/puppet/provider/firewalld_ipset/firewall_cmd.rb
1 parent 95507c4 commit 5b66307

File tree

3 files changed

+36
-22
lines changed

3 files changed

+36
-22
lines changed

lib/puppet/provider/firewalld_ipset/firewall_cmd.rb

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ def create
6060
args << ["--option=#{option_name}=#{value}"] if value
6161
end
6262
execute_firewall_cmd(args.flatten, nil)
63-
@resource[:entries].each { |e| add_entry(e) } if @resource[:manage_entries]
63+
add_entries_from_file(@resource[:entries]) if @resource[:manage_entries]
6464
end
6565

6666
%i[type maxelem family hashsize timeout].each do |method|
@@ -80,12 +80,18 @@ def entries
8080
end
8181
end
8282

83-
def add_entry(entry)
84-
execute_firewall_cmd(["--ipset=#{@resource[:name]}", "--add-entry=#{entry}"], nil)
83+
def add_entries_from_file(entries)
84+
f = Tempfile.new('ipset')
85+
entries.each { |e| f.write(e + "\n") }
86+
f.close
87+
execute_firewall_cmd(["--ipset=#{@resource[:name]}", "--add-entries-from-file=#{f.path}"], nil)
8588
end
8689

87-
def remove_entry(entry)
88-
execute_firewall_cmd(["--ipset=#{@resource[:name]}", "--remove-entry=#{entry}"], nil)
90+
def remove_entries_from_file(entries)
91+
f = Tempfile.new('ipset')
92+
entries.each { |e| f.write(e + "\n") }
93+
f.close
94+
execute_firewall_cmd(["--ipset=#{@resource[:name]}", "--remove-entries-from-file=#{f.path}"], nil)
8995
end
9096

9197
def entries=(should_entries)
@@ -96,8 +102,8 @@ def entries=(should_entries)
96102
cur_entries = entries
97103
delete_entries = cur_entries - should_entries
98104
add_entries = should_entries - cur_entries
99-
delete_entries.each { |e| remove_entry(e) }
100-
add_entries.each { |e| add_entry(e) }
105+
remove_entries_from_file(delete_entries) if delete_entries
106+
add_entries_from_file(add_entries) if add_entries
101107
end
102108

103109
def destroy

spec/unit/puppet/provider/firewalld_ipset_spec.rb

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@
1717
let(:provider) { resource.provider }
1818

1919
before do
20+
tempfile = stub('tempfile', class: Tempfile,
21+
write: true,
22+
flush: true,
23+
close!: true,
24+
close: true,
25+
path: '/tmp/ipset-rspec')
26+
Tempfile.stubs(:new).returns(tempfile)
2027
provider.class.stubs(:execute_firewall_cmd).with(['--get-ipsets'], nil).returns('white black')
2128
provider.class.stubs(:execute_firewall_cmd).with(['--state'], nil, false, false, false).returns(Object.any_instance.stubs(exitstatus: 0)) # rubocop:disable RSpec/AnyInstance
2229
provider.class.stubs(:execute_firewall_cmd).with(['--info-ipset=white'], nil).returns('white
@@ -67,8 +74,7 @@
6774
resource.expects(:[]).with(:manage_entries).returns(true)
6875
resource.expects(:[]).with(:entries).returns(['192.168.0/24', '10.0.0/8'])
6976
provider.expects(:execute_firewall_cmd).with(['--new-ipset=white', '--type=hash:net', '--option=family=inet', '--option=hashsize=1024', '--option=maxelem=65536'], nil)
70-
provider.expects(:execute_firewall_cmd).with(['--ipset=white', '--add-entry=192.168.0/24'], nil)
71-
provider.expects(:execute_firewall_cmd).with(['--ipset=white', '--add-entry=10.0.0/8'], nil)
77+
provider.expects(:execute_firewall_cmd).with(['--ipset=white', '--add-entries-from-file=/tmp/ipset-rspec'], nil)
7278
provider.create
7379
end
7480
end
@@ -89,8 +95,7 @@
8995
resource.expects(:[]).with(:entries).returns(['192.168.0/24', '10.0.0/8']).at_least_once
9096
provider.expects(:execute_firewall_cmd).with(['--new-ipset=white', '--type=hash:net', '--option=family=inet'], nil)
9197
provider.expects(:execute_firewall_cmd).with(['--new-ipset=white', '--type=hash:net', '--option=family=inet', '--option=hashsize=2048'], nil)
92-
provider.expects(:execute_firewall_cmd).with(['--ipset=white', '--add-entry=192.168.0/24'], nil).at_least_once
93-
provider.expects(:execute_firewall_cmd).with(['--ipset=white', '--add-entry=10.0.0/8'], nil).at_least_once
98+
provider.expects(:execute_firewall_cmd).with(['--ipset=white', '--add-entries-from-file=/tmp/ipset-rspec'], nil).at_least_once
9499
provider.expects(:execute_firewall_cmd).with(['--delete-ipset=white'], nil)
95100
provider.create
96101
provider.hashsize = 2048
@@ -110,10 +115,8 @@
110115
resource.expects(:[]).with(:entries).returns(['192.168.0.0/24', '10.0.0.0/8']).at_least_once
111116
provider.expects(:entries).returns(['192.168.0.0/24', '10.0.0.0/8'])
112117
provider.expects(:execute_firewall_cmd).with(['--new-ipset=white', '--type=hash:net', '--option=family=inet'], nil)
113-
provider.expects(:execute_firewall_cmd).with(['--ipset=white', '--add-entry=192.168.0.0/24'], nil).at_least_once
114-
provider.expects(:execute_firewall_cmd).with(['--ipset=white', '--add-entry=10.0.0.0/8'], nil).at_least_once
115-
provider.expects(:execute_firewall_cmd).with(['--ipset=white', '--add-entry=192.168.14.0/24'], nil)
116-
provider.expects(:execute_firewall_cmd).with(['--ipset=white', '--remove-entry=192.168.0.0/24'], nil)
118+
provider.expects(:execute_firewall_cmd).with(['--ipset=white', '--remove-entries-from-file=/tmp/ipset-rspec'], nil)
119+
provider.expects(:execute_firewall_cmd).with(['--ipset=white', '--add-entries-from-file=/tmp/ipset-rspec'], nil).at_least_once
117120
provider.create
118121
provider.entries = ['192.168.14.0/24', '10.0.0.0/8']
119122
end

spec/unit/puppet/type/firewalld_ipset_spec.rb

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@
55
describe Puppet::Type.type(:firewalld_ipset) do
66
before do
77
Puppet::Provider::Firewalld.any_instance.stubs(:state).returns(:true) # rubocop:disable RSpec/AnyInstance
8+
tempfile = stub('tempfile', class: Tempfile,
9+
write: true,
10+
flush: true,
11+
close!: true,
12+
close: true,
13+
path: '/tmp/ipset-rspec')
14+
Tempfile.stubs(:new).returns(tempfile)
815
end
916

1017
describe 'type' do
@@ -116,8 +123,7 @@
116123

117124
it 'creates' do
118125
provider.expects(:execute_firewall_cmd).with(['--new-ipset=whitelist', '--type=hash:ip'], nil)
119-
provider.expects(:execute_firewall_cmd).with(['--ipset=whitelist', '--add-entry=192.168.2.2'], nil)
120-
provider.expects(:execute_firewall_cmd).with(['--ipset=whitelist', '--add-entry=10.72.1.100'], nil)
126+
provider.expects(:execute_firewall_cmd).with(['--ipset=whitelist', '--add-entries-from-file=/tmp/ipset-rspec'], nil)
121127
provider.create
122128
end
123129

@@ -128,16 +134,15 @@
128134

129135
it 'sets entries' do
130136
provider.expects(:entries).returns([])
131-
provider.expects(:execute_firewall_cmd).with(['--ipset=whitelist', '--add-entry=192.168.2.2'], nil)
132-
provider.expects(:execute_firewall_cmd).with(['--ipset=whitelist', '--add-entry=10.72.1.100'], nil)
137+
provider.expects(:execute_firewall_cmd).with(['--ipset=whitelist', '--add-entries-from-file=/tmp/ipset-rspec'], nil)
138+
provider.expects(:execute_firewall_cmd).with(['--ipset=whitelist', '--remove-entries-from-file=/tmp/ipset-rspec'], nil)
133139
provider.entries = ['192.168.2.2', '10.72.1.100']
134140
end
135141

136142
it 'removes unconfigured entries' do
137143
provider.expects(:entries).returns(['10.9.9.9', '10.8.8.8', '10.72.1.100'])
138-
provider.expects(:execute_firewall_cmd).with(['--ipset=whitelist', '--add-entry=192.168.2.2'], nil)
139-
provider.expects(:execute_firewall_cmd).with(['--ipset=whitelist', '--remove-entry=10.9.9.9'], nil)
140-
provider.expects(:execute_firewall_cmd).with(['--ipset=whitelist', '--remove-entry=10.8.8.8'], nil)
144+
provider.expects(:execute_firewall_cmd).with(['--ipset=whitelist', '--add-entries-from-file=/tmp/ipset-rspec'], nil)
145+
provider.expects(:execute_firewall_cmd).with(['--ipset=whitelist', '--remove-entries-from-file=/tmp/ipset-rspec'], nil)
141146
provider.entries = ['192.168.2.2', '10.72.1.100']
142147
end
143148
end

0 commit comments

Comments
 (0)