ipscriptables 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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