ipscriptables 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +17 -0
  3. data/.rubocop.yml +15 -0
  4. data/.travis.yml +10 -0
  5. data/CHANGELOG.md +6 -0
  6. data/CONTRIBUTING.md +43 -0
  7. data/Gemfile +13 -0
  8. data/LICENSE +20 -0
  9. data/README.md +54 -0
  10. data/Rakefile +22 -0
  11. data/bin/ipscriptables +6 -0
  12. data/cookbook/.gitignore +2 -0
  13. data/cookbook/.kitchen.yml +28 -0
  14. data/cookbook/Berksfile +6 -0
  15. data/cookbook/README.md +53 -0
  16. data/cookbook/attributes/default.rb +3 -0
  17. data/cookbook/chefignore +96 -0
  18. data/cookbook/libraries/default.rb +35 -0
  19. data/cookbook/metadata.rb +9 -0
  20. data/cookbook/providers/rules.rb +21 -0
  21. data/cookbook/recipes/default.rb +10 -0
  22. data/cookbook/recipes/load.rb +8 -0
  23. data/cookbook/resources/rules.rb +17 -0
  24. data/cookbook/test/cookbooks/ipscriptables-test/#metadata.rb# +8 -0
  25. data/cookbook/test/cookbooks/ipscriptables-test/metadata.rb +11 -0
  26. data/cookbook/test/cookbooks/ipscriptables-test/recipes/default.rb +23 -0
  27. data/cookbook/test/cookbooks/ipscriptables-test/recipes/prepare.rb +5 -0
  28. data/cookbook/test/data/.gitignore +1 -0
  29. data/cookbook/test/integration/default/bats/default.bats +9 -0
  30. data/doc/iptables-switches.txt +342 -0
  31. data/ipscriptables.gemspec +38 -0
  32. data/lib/ipscriptables.rb +14 -0
  33. data/lib/ipscriptables/chain.rb +83 -0
  34. data/lib/ipscriptables/cli.rb +19 -0
  35. data/lib/ipscriptables/helpers.rb +39 -0
  36. data/lib/ipscriptables/pretty_print.rb +58 -0
  37. data/lib/ipscriptables/rule.rb +95 -0
  38. data/lib/ipscriptables/ruleset.rb +103 -0
  39. data/lib/ipscriptables/ruleset/class_methods.rb +67 -0
  40. data/lib/ipscriptables/runtime.rb +97 -0
  41. data/lib/ipscriptables/table.rb +77 -0
  42. data/lib/ipscriptables/version.rb +5 -0
  43. data/spec/fixtures/clyhq.txt +40 -0
  44. data/spec/fixtures/docker-plus.txt +31 -0
  45. data/spec/fixtures/drumknott.txt +67 -0
  46. data/spec/fixtures/falcor.txt +39 -0
  47. data/spec/fixtures/ghq.txt +102 -0
  48. data/spec/fixtures/ip6tables-empty.txt +7 -0
  49. data/spec/fixtures/only-docker-c.txt +23 -0
  50. data/spec/fixtures/only-docker.txt +23 -0
  51. data/spec/fixtures/only_docker.rb +22 -0
  52. data/spec/fixtures/runtime.rb +7 -0
  53. data/spec/fixtures/runtime2.rb +16 -0
  54. data/spec/ipscriptables/dsl_spec.rb +74 -0
  55. data/spec/ipscriptables/helpers_spec.rb +58 -0
  56. data/spec/ipscriptables/rule_spec.rb +41 -0
  57. data/spec/ipscriptables/ruleset/class_methods_spec.rb +52 -0
  58. data/spec/ipscriptables/ruleset_spec.rb +199 -0
  59. data/spec/ipscriptables/runtime_spec.rb +227 -0
  60. data/spec/ipscriptables/table_spec.rb +32 -0
  61. data/spec/ipscriptables/version_spec.rb +12 -0
  62. data/spec/spec_helper.rb +60 -0
  63. metadata +350 -0
@@ -0,0 +1,227 @@
1
+ # -*- coding: utf-8 -*-
2
+ # rubocop:disable LineLength
3
+ require 'spec_helper'
4
+
5
+ require 'stringio'
6
+
7
+ module IPScriptables
8
+ describe Runtime do
9
+ let(:fixture_text) { File.read(fixture('only-docker-c.txt')) }
10
+ let(:fixture6_text) { File.read(fixture('ip6tables-empty.txt')) }
11
+ let(:runtime) { Runtime.new }
12
+
13
+ before do
14
+ IO.expects(:popen).never # just to be safe
15
+ Helpers.expects(:run_command).with('ip6tables-save', '-c').never
16
+ .at_most_once
17
+ .returns(fixture6_text)
18
+ Helpers.expects(:run_command).with('iptables-save', '-c').never
19
+ .at_most_once
20
+ .returns(fixture_text)
21
+ end
22
+
23
+ it 'does not run undefined rulesets' do
24
+ out, err = capture_io { runtime.execute! }
25
+ expect { out == '' }
26
+ deny { err =~ /Would restore inet/ }
27
+ deny { err =~ /Would restore inet6/ }
28
+ end
29
+
30
+ it 'can load rulesets from file' do
31
+ out, err = capture_io do
32
+ runtime.load_file(fixture('runtime.rb'))
33
+ runtime.execute!
34
+ end
35
+
36
+ expect { err =~ /Loading configuration from #{fixture('runtime.rb')}/ }
37
+ deny { err =~ /Loading configuration from #{fixture('runtime2.rb')}/ }
38
+ expect { out.lines.grep(/^\S/).length == 4 }
39
+ expect { err =~ /Would restore inet/ }
40
+ deny { err =~ /Would restore inet6/ }
41
+ end
42
+
43
+ it 'can load multiple files & won\'t run if rules are unchanged' do
44
+ out, err = capture_io do
45
+ runtime.load_file(fixture('runtime.rb'))
46
+ runtime.load_file(fixture('runtime2.rb'))
47
+ runtime.execute!
48
+ end
49
+
50
+ expect { err =~ /Loading configuration from #{fixture('runtime.rb')}/ }
51
+ expect { err =~ /Loading configuration from #{fixture('runtime2.rb')}/ }
52
+ expect { out.lines.grep(/^\S/).empty? }
53
+ expect { err =~ /No changes for inet, moving along./ }
54
+ end
55
+
56
+ it 'accepts blocks as well as files' do
57
+ out, err = capture_io do
58
+ runtime.load_file(fixture('runtime.rb'))
59
+ runtime.dsl_eval do
60
+ iptables do
61
+ table :nat do
62
+ chain :PREROUTING do
63
+ rule '-m addrtype --dst-type LOCAL -j DOCKER'
64
+ end
65
+ chain :OUTPUT do
66
+ rule '! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER'
67
+ end
68
+ chain :POSTROUTING do
69
+ rule '-s 172.17.0.0/16 ! -d 172.17.0.0/16 -j MASQUERADE'
70
+ rule '-s 10.0.3.0/24 ! -d 10.0.3.0/24 -j MASQUERADE'
71
+ end
72
+ end
73
+ end
74
+ end
75
+ runtime.execute!
76
+ end
77
+
78
+ expect { err =~ /Loading configuration from #{fixture('runtime.rb')}/ }
79
+ expect { out.lines.grep(/^\S/).empty? }
80
+ expect { err =~ /No changes for inet, moving along./ }
81
+ end
82
+
83
+ it 'configures ipv6' do
84
+ out, err = capture_io do
85
+ runtime.dsl_eval do
86
+ ip6tables do
87
+ table :filter do
88
+ chain :INPUT do
89
+ rule :m => :tcp, :p => :tcp, :dport => 22, :j => :ACCEPT
90
+ end
91
+ end
92
+ end
93
+ end
94
+ runtime.execute!
95
+ end
96
+
97
+ expect { out =~ /^\+\[0:0\] -A INPUT -m tcp -p tcp --dport 22 -j ACCEPT$/ }
98
+ expect { err =~ /Would restore inet6/ }
99
+ end
100
+
101
+ it 'doesn\'t allow triggering execution from within DSL' do
102
+ expect do
103
+ rescuing { runtime.dsl_eval { execute! } }.to_s =~
104
+ /I can't let you do that/
105
+ end
106
+ end
107
+
108
+ describe 'options' do
109
+ before do
110
+ $CHILD_STATUS.expects(:success?).at_least(0).returns(true)
111
+
112
+ @out, @err = capture_io do
113
+ runtime.load_file(fixture('runtime.rb'))
114
+ runtime.dsl_eval do
115
+ ip6tables do
116
+ table :filter do
117
+ chain :FORWARD, :DROP
118
+ chain :INPUT, :DROP do
119
+ rule :m => :tcp, :p => :tcp, :dport => 22, :j => :ACCEPT
120
+ end
121
+ end
122
+ end
123
+ end
124
+ end
125
+ end
126
+
127
+ it 'behaves normally without options' do
128
+ out, _err = capture_io { runtime.execute! }
129
+ expect { out.lines.grep(/^\S/).length == 9 }
130
+ expect { @err =~ /Would restore inet/ }
131
+ expect { @err =~ /Would restore inet6/ }
132
+ end
133
+
134
+ it 'can be instructed to skip a ruleset' do
135
+ runtime.opts[:inet6] = false
136
+ out, _err = capture_io { runtime.execute! }
137
+ expect { out.lines.grep(/^\S/).length == 4 }
138
+ expect { @err =~ /Would restore inet/ }
139
+ expect { @err =~ /Skipping inet6 as requested/ }
140
+ end
141
+
142
+ it 'applies rules only when specifically told' do
143
+ runtime.opts[:apply] = true
144
+
145
+ iptables_restore_io = mock('IO')
146
+ iptables_restore_io.expects(:write).once.with <<EOF
147
+ *filter
148
+ :INPUT ACCEPT [211:14626]
149
+ :FORWARD ACCEPT [0:0]
150
+ :OUTPUT ACCEPT [122:11280]
151
+ [1:2] -A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
152
+ [1:2] -A FORWARD -i docker0 ! -o docker0 -j ACCEPT
153
+ [1:2] -A FORWARD -i docker0 -o docker0 -j ACCEPT
154
+ COMMIT
155
+ *nat
156
+ :PREROUTING ACCEPT [5:1208]
157
+ :INPUT ACCEPT [5:1208]
158
+ :OUTPUT ACCEPT [42:3215]
159
+ :POSTROUTING ACCEPT [42:3215]
160
+ :DOCKER - [0:0]
161
+ COMMIT
162
+ EOF
163
+
164
+ ip6tables_restore_io = mock('IO')
165
+ ip6tables_restore_io.expects(:write).once.with <<EOF
166
+ *filter
167
+ :INPUT DROP [128:11760]
168
+ :FORWARD DROP [0:0]
169
+ :OUTPUT ACCEPT [75:12168]
170
+ [0:0] -A INPUT -m tcp -p tcp --dport 22 -j ACCEPT
171
+ COMMIT
172
+ EOF
173
+
174
+ IO.expects(:popen).with(%w(iptables-restore -c), 'w').once.yields(iptables_restore_io)
175
+ IO.expects(:popen).with(%w(ip6tables-restore -c), 'w').once.yields(ip6tables_restore_io)
176
+
177
+ begin
178
+ capture_io { @rv = runtime.execute! }
179
+ rescue Exception => e
180
+ STDERR.puts <<EOF
181
+ ERR
182
+ #{@err}
183
+
184
+ OUT
185
+ #{@out}
186
+ EOF
187
+ raise e
188
+ end
189
+ expect { @err =~ /Restoring inet/ }
190
+ expect { @err =~ /Restoring inet6/ }
191
+ deny { @err =~ /There were errors/ }
192
+ expect { @rv == true }
193
+ end
194
+
195
+ it 'logs error and proceeds, but returns false, when restore command fails' do
196
+ runtime.opts[:apply] = true
197
+
198
+ iptables_restore_io = mock('IO')
199
+ iptables_restore_io.expects(:write).once
200
+ ip6tables_restore_io = mock('IO')
201
+ ip6tables_restore_io.expects(:write).once
202
+ $CHILD_STATUS.expects(:success?)
203
+ .once.returns(false).then.returns(true)
204
+
205
+ IO.expects(:popen).with(%w(iptables-restore -c), 'w').once.yields(iptables_restore_io)
206
+ IO.expects(:popen).with(%w(ip6tables-restore -c), 'w').once.yields(ip6tables_restore_io)
207
+
208
+ out, _err = capture_io { @rv = runtime.execute! }
209
+ expect { out.lines.grep(/^\S/).length == 9 }
210
+ expect { @err =~ /Restoring inet/ }
211
+ expect { @err =~ /Restoring inet6/ }
212
+ expect { @err =~ /ERROR.* Failure restoring inet:/ }
213
+ expect { @err =~ /There were errors/ }
214
+ expect { @rv == false }
215
+ end
216
+
217
+ it 'does not output diff when quiet flag is specified' do
218
+ runtime.opts[:quiet] = true
219
+
220
+ out, _err = capture_io { @rv = runtime.execute! }
221
+ expect { out == '' }
222
+ expect { @err =~ /Would restore inet/ }
223
+ expect { @err =~ /Would restore inet6/ }
224
+ end
225
+ end
226
+ end
227
+ end
@@ -0,0 +1,32 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ module IPScriptables
5
+ describe Table do
6
+ let(:ruleset) do
7
+ rs = mock('ruleset')
8
+ rs.expects(:opts).at_least_once.returns({})
9
+ rs
10
+ end
11
+
12
+ it 'creates built-in chains by default' do
13
+ {
14
+ filter: [:INPUT, :FORWARD, :OUTPUT],
15
+ nat: [:PREROUTING, :INPUT, :OUTPUT, :POSTROUTING],
16
+ mangle: [:PREROUTING, :INPUT, :OUTPUT, :FORWARD, :POSTROUTING],
17
+ raw: [:PREROUTING, :OUTPUT],
18
+ security: [:INPUT, :FORWARD, :OUTPUT]
19
+ }.each do |table_name, expected_chains|
20
+ created_chains = Table.new(table_name, ruleset).map(&:name)
21
+ expect { Set[*created_chains] == Set[*expected_chains] }
22
+ end
23
+ end
24
+
25
+ it 'warns about unrecognized table' do
26
+ out, err = capture_io { @table = Table.new(:whatever, ruleset) }
27
+ expect { out == '' } # sanity
28
+ expect { err =~ /Unrecognized table whatever/ }
29
+ expect { @table.empty? }
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,12 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ # A smoke test spec to make sure tests actually work
5
+
6
+ module IPScriptables
7
+ describe VERSION do
8
+ it 'is equal to itself' do
9
+ expect { VERSION == IPScriptables::VERSION }
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,60 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'rubygems'
4
+ require 'bundler/setup'
5
+
6
+ if ENV['COVERAGE']
7
+ require 'simplecov'
8
+ SimpleCov.start do
9
+ add_filter '/spec/' unless ENV['SPEC_COVERAGE']
10
+ add_filter '/lib/ipscriptables/pretty_print.rb'
11
+ end
12
+ SimpleCov.command_name 'spec'
13
+ end
14
+
15
+ require 'minitest/autorun'
16
+ require 'minitest/spec'
17
+ require 'minitest/pride' if $stderr.tty?
18
+ require 'mocha/setup'
19
+ require 'wrong'
20
+ require 'fauxhai'
21
+ require 'ohai'
22
+
23
+ Wrong.config.alias_assert :expect, override: true
24
+ include Wrong
25
+
26
+ # Prepare testing environment
27
+ class Minitest::Spec # rubocop:disable ClassAndModuleChildren
28
+ include ::Wrong::Assert
29
+ include ::Wrong::Helpers
30
+
31
+ def fauxhai!(args = nil)
32
+ args ||= { platform: 'ubuntu', version: '12.04' }
33
+ fauxhai = Hashie::Mash[Fauxhai.mock(args).data]
34
+ fauxhai.expects(:require_plugin).at_least(0)
35
+ Ohai::System.expects(:new).at_most_once.returns(fauxhai)
36
+ end
37
+
38
+ def slow_case
39
+ skip if !ENV['CI'] && ENV['FASTER']
40
+ end
41
+
42
+ def self.fixture(*path)
43
+ File.join(File.realpath(File.dirname(__FILE__)), 'fixtures', *path)
44
+ end
45
+
46
+ def fixture(*path)
47
+ # Why the hell can't I have module_function in a class, huh?
48
+ self.class.fixture(*path)
49
+ end
50
+
51
+ def increment_assertion_count
52
+ self.assertions += 1
53
+ end
54
+
55
+ def failure_class
56
+ Minitest::Assertion
57
+ end
58
+ end
59
+
60
+ require 'ipscriptables'
metadata ADDED
@@ -0,0 +1,350 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ipscriptables
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Maciej Pasternacki
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-05-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: docile
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ! '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ! '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: hashie
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: systemu
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ! '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: ohai
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ! '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: sigar
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ! '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ! '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: ipaddr_extensions
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ! '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ! '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: diffy
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ! '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ! '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: clamp
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ! '>='
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: bundler
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ~>
130
+ - !ruby/object:Gem::Version
131
+ version: '1.3'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ~>
137
+ - !ruby/object:Gem::Version
138
+ version: '1.3'
139
+ - !ruby/object:Gem::Dependency
140
+ name: minitest
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ! '>='
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ! '>='
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: mocha
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ! '>='
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ! '>='
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: simplecov
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ! '>='
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ! '>='
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
181
+ - !ruby/object:Gem::Dependency
182
+ name: rake
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - ~>
186
+ - !ruby/object:Gem::Version
187
+ version: '10.1'
188
+ type: :development
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - ~>
193
+ - !ruby/object:Gem::Version
194
+ version: '10.1'
195
+ - !ruby/object:Gem::Dependency
196
+ name: wrong
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - ~>
200
+ - !ruby/object:Gem::Version
201
+ version: '0.7'
202
+ type: :development
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - ~>
207
+ - !ruby/object:Gem::Version
208
+ version: '0.7'
209
+ - !ruby/object:Gem::Dependency
210
+ name: fauxhai
211
+ requirement: !ruby/object:Gem::Requirement
212
+ requirements:
213
+ - - ! '>='
214
+ - !ruby/object:Gem::Version
215
+ version: '0'
216
+ type: :development
217
+ prerelease: false
218
+ version_requirements: !ruby/object:Gem::Requirement
219
+ requirements:
220
+ - - ! '>='
221
+ - !ruby/object:Gem::Version
222
+ version: '0'
223
+ - !ruby/object:Gem::Dependency
224
+ name: rubocop
225
+ requirement: !ruby/object:Gem::Requirement
226
+ requirements:
227
+ - - ! '>='
228
+ - !ruby/object:Gem::Version
229
+ version: '0'
230
+ type: :development
231
+ prerelease: false
232
+ version_requirements: !ruby/object:Gem::Requirement
233
+ requirements:
234
+ - - ! '>='
235
+ - !ruby/object:Gem::Version
236
+ version: '0'
237
+ description: Ruby-driven IPTables
238
+ email:
239
+ - maciej@3ofcoins.net
240
+ executables:
241
+ - ipscriptables
242
+ extensions: []
243
+ extra_rdoc_files: []
244
+ files:
245
+ - .gitignore
246
+ - .rubocop.yml
247
+ - .travis.yml
248
+ - CHANGELOG.md
249
+ - CONTRIBUTING.md
250
+ - Gemfile
251
+ - LICENSE
252
+ - README.md
253
+ - Rakefile
254
+ - bin/ipscriptables
255
+ - cookbook/.gitignore
256
+ - cookbook/.kitchen.yml
257
+ - cookbook/Berksfile
258
+ - cookbook/README.md
259
+ - cookbook/attributes/default.rb
260
+ - cookbook/chefignore
261
+ - cookbook/libraries/default.rb
262
+ - cookbook/metadata.rb
263
+ - cookbook/providers/rules.rb
264
+ - cookbook/recipes/default.rb
265
+ - cookbook/recipes/load.rb
266
+ - cookbook/resources/rules.rb
267
+ - cookbook/test/cookbooks/ipscriptables-test/#metadata.rb#
268
+ - cookbook/test/cookbooks/ipscriptables-test/metadata.rb
269
+ - cookbook/test/cookbooks/ipscriptables-test/recipes/default.rb
270
+ - cookbook/test/cookbooks/ipscriptables-test/recipes/prepare.rb
271
+ - cookbook/test/data/.gitignore
272
+ - cookbook/test/integration/default/bats/default.bats
273
+ - doc/iptables-switches.txt
274
+ - ipscriptables.gemspec
275
+ - lib/ipscriptables.rb
276
+ - lib/ipscriptables/chain.rb
277
+ - lib/ipscriptables/cli.rb
278
+ - lib/ipscriptables/helpers.rb
279
+ - lib/ipscriptables/pretty_print.rb
280
+ - lib/ipscriptables/rule.rb
281
+ - lib/ipscriptables/ruleset.rb
282
+ - lib/ipscriptables/ruleset/class_methods.rb
283
+ - lib/ipscriptables/runtime.rb
284
+ - lib/ipscriptables/table.rb
285
+ - lib/ipscriptables/version.rb
286
+ - spec/fixtures/clyhq.txt
287
+ - spec/fixtures/docker-plus.txt
288
+ - spec/fixtures/drumknott.txt
289
+ - spec/fixtures/falcor.txt
290
+ - spec/fixtures/ghq.txt
291
+ - spec/fixtures/ip6tables-empty.txt
292
+ - spec/fixtures/only-docker-c.txt
293
+ - spec/fixtures/only-docker.txt
294
+ - spec/fixtures/only_docker.rb
295
+ - spec/fixtures/runtime.rb
296
+ - spec/fixtures/runtime2.rb
297
+ - spec/ipscriptables/dsl_spec.rb
298
+ - spec/ipscriptables/helpers_spec.rb
299
+ - spec/ipscriptables/rule_spec.rb
300
+ - spec/ipscriptables/ruleset/class_methods_spec.rb
301
+ - spec/ipscriptables/ruleset_spec.rb
302
+ - spec/ipscriptables/runtime_spec.rb
303
+ - spec/ipscriptables/table_spec.rb
304
+ - spec/ipscriptables/version_spec.rb
305
+ - spec/spec_helper.rb
306
+ homepage: https://github.com/3ofcoins/ipscriptables/
307
+ licenses:
308
+ - MIT
309
+ metadata: {}
310
+ post_install_message:
311
+ rdoc_options: []
312
+ require_paths:
313
+ - lib
314
+ required_ruby_version: !ruby/object:Gem::Requirement
315
+ requirements:
316
+ - - ! '>='
317
+ - !ruby/object:Gem::Version
318
+ version: '0'
319
+ required_rubygems_version: !ruby/object:Gem::Requirement
320
+ requirements:
321
+ - - ! '>='
322
+ - !ruby/object:Gem::Version
323
+ version: '0'
324
+ requirements: []
325
+ rubyforge_project:
326
+ rubygems_version: 2.2.2
327
+ signing_key:
328
+ specification_version: 4
329
+ summary: Ruby-driven IPTables
330
+ test_files:
331
+ - spec/fixtures/clyhq.txt
332
+ - spec/fixtures/docker-plus.txt
333
+ - spec/fixtures/drumknott.txt
334
+ - spec/fixtures/falcor.txt
335
+ - spec/fixtures/ghq.txt
336
+ - spec/fixtures/ip6tables-empty.txt
337
+ - spec/fixtures/only-docker-c.txt
338
+ - spec/fixtures/only-docker.txt
339
+ - spec/fixtures/only_docker.rb
340
+ - spec/fixtures/runtime.rb
341
+ - spec/fixtures/runtime2.rb
342
+ - spec/ipscriptables/dsl_spec.rb
343
+ - spec/ipscriptables/helpers_spec.rb
344
+ - spec/ipscriptables/rule_spec.rb
345
+ - spec/ipscriptables/ruleset/class_methods_spec.rb
346
+ - spec/ipscriptables/ruleset_spec.rb
347
+ - spec/ipscriptables/runtime_spec.rb
348
+ - spec/ipscriptables/table_spec.rb
349
+ - spec/ipscriptables/version_spec.rb
350
+ - spec/spec_helper.rb