1
2
3
4
19
20 package testing
21
22 import (
23 "bytes"
24 "strings"
25 "testing"
26
27 "github.com/lithammer/dedent"
28
29 "k8s.io/kubernetes/pkg/util/iptables"
30 )
31
32 func TestFakeIPTables(t *testing.T) {
33 fake := NewFake()
34 buf := bytes.NewBuffer(nil)
35
36 err := fake.SaveInto("", buf)
37 if err != nil {
38 t.Fatalf("unexpected error from SaveInto: %v", err)
39 }
40 expected := dedent.Dedent(strings.Trim(`
41 *nat
42 :PREROUTING - [0:0]
43 :INPUT - [0:0]
44 :OUTPUT - [0:0]
45 :POSTROUTING - [0:0]
46 COMMIT
47 *filter
48 :INPUT - [0:0]
49 :FORWARD - [0:0]
50 :OUTPUT - [0:0]
51 COMMIT
52 *mangle
53 COMMIT
54 `, "\n"))
55 if buf.String() != expected {
56 t.Fatalf("bad initial dump. expected:\n%s\n\ngot:\n%s\n", expected, buf.Bytes())
57 }
58
59
60 existed, err := fake.EnsureChain(iptables.Table("blah"), iptables.Chain("KUBE-TEST"))
61 if err == nil {
62 t.Errorf("did not get expected error creating chain in non-existent table")
63 } else if existed {
64 t.Errorf("wrong return value from EnsureChain with non-existent table")
65 }
66 existed, err = fake.EnsureChain(iptables.TableNAT, iptables.Chain("KUBE-TEST"))
67 if err != nil {
68 t.Errorf("unexpected error creating chain: %v", err)
69 } else if existed {
70 t.Errorf("wrong return value from EnsureChain with non-existent chain")
71 }
72 existed, err = fake.EnsureChain(iptables.TableNAT, iptables.Chain("KUBE-TEST"))
73 if err != nil {
74 t.Errorf("unexpected error creating chain: %v", err)
75 } else if !existed {
76 t.Errorf("wrong return value from EnsureChain with existing chain")
77 }
78
79
80 exists, err := fake.ChainExists(iptables.TableNAT, iptables.Chain("KUBE-TEST"))
81 if err != nil {
82 t.Errorf("unexpected error checking chain: %v", err)
83 } else if !exists {
84 t.Errorf("wrong return value from ChainExists with existing chain")
85 }
86 exists, err = fake.ChainExists(iptables.TableNAT, iptables.Chain("KUBE-TEST-NOT"))
87 if err != nil {
88 t.Errorf("unexpected error checking chain: %v", err)
89 } else if exists {
90 t.Errorf("wrong return value from ChainExists with non-existent chain")
91 }
92
93
94 existed, err = fake.EnsureRule(iptables.Append, iptables.Table("blah"), iptables.Chain("KUBE-TEST"), "-j", "ACCEPT")
95 if err == nil {
96 t.Errorf("did not get expected error creating rule in non-existent table")
97 } else if existed {
98 t.Errorf("wrong return value from EnsureRule with non-existent table")
99 }
100 existed, err = fake.EnsureRule(iptables.Append, iptables.TableNAT, iptables.Chain("KUBE-TEST-NOT"), "-j", "ACCEPT")
101 if err == nil {
102 t.Errorf("did not get expected error creating rule in non-existent chain")
103 } else if existed {
104 t.Errorf("wrong return value from EnsureRule with non-existent chain")
105 }
106 existed, err = fake.EnsureRule(iptables.Append, iptables.TableNAT, iptables.Chain("KUBE-TEST"), "-j", "ACCEPT")
107 if err != nil {
108 t.Errorf("unexpected error creating rule: %v", err)
109 } else if existed {
110 t.Errorf("wrong return value from EnsureRule with non-existent rule")
111 }
112 existed, err = fake.EnsureRule(iptables.Prepend, iptables.TableNAT, iptables.Chain("KUBE-TEST"), "-j", "DROP")
113 if err != nil {
114 t.Errorf("unexpected error creating rule: %v", err)
115 } else if existed {
116 t.Errorf("wrong return value from EnsureRule with non-existent rule")
117 }
118 existed, err = fake.EnsureRule(iptables.Append, iptables.TableNAT, iptables.Chain("KUBE-TEST"), "-j", "DROP")
119 if err != nil {
120 t.Errorf("unexpected error creating rule: %v", err)
121 } else if !existed {
122 t.Errorf("wrong return value from EnsureRule with already-existing rule")
123 }
124
125
126 buf.Reset()
127 err = fake.SaveInto("", buf)
128 if err != nil {
129 t.Fatalf("unexpected error from SaveInto: %v", err)
130 }
131 expected = dedent.Dedent(strings.Trim(`
132 *nat
133 :PREROUTING - [0:0]
134 :INPUT - [0:0]
135 :OUTPUT - [0:0]
136 :POSTROUTING - [0:0]
137 :KUBE-TEST - [0:0]
138 -A KUBE-TEST -j DROP
139 -A KUBE-TEST -j ACCEPT
140 COMMIT
141 *filter
142 :INPUT - [0:0]
143 :FORWARD - [0:0]
144 :OUTPUT - [0:0]
145 COMMIT
146 *mangle
147 COMMIT
148 `, "\n"))
149 if buf.String() != expected {
150 t.Fatalf("bad sanity-check dump. expected:\n%s\n\ngot:\n%s\n", expected, buf.Bytes())
151 }
152
153
154 err = fake.DeleteRule(iptables.Table("blah"), iptables.Chain("KUBE-TEST"), "-j", "DROP")
155 if err == nil {
156 t.Errorf("did not get expected error deleting rule in non-existent table")
157 }
158 err = fake.DeleteRule(iptables.TableNAT, iptables.Chain("KUBE-TEST-NOT"), "-j", "DROP")
159 if err == nil {
160 t.Errorf("did not get expected error deleting rule in non-existent chain")
161 }
162 err = fake.DeleteRule(iptables.TableNAT, iptables.Chain("KUBE-TEST"), "-j", "DROPLET")
163 if err != nil {
164 t.Errorf("unexpected error deleting non-existent rule: %v", err)
165 }
166 err = fake.DeleteRule(iptables.TableNAT, iptables.Chain("KUBE-TEST"), "-j", "DROP")
167 if err != nil {
168 t.Errorf("unexpected error deleting rule: %v", err)
169 }
170
171
172 rules := dedent.Dedent(strings.Trim(`
173 *nat
174 :KUBE-RESTORED - [0:0]
175 :KUBE-MISC-CHAIN - [0:0]
176 :KUBE-MISC-TWO - [0:0]
177 :KUBE-EMPTY - [0:0]
178 -A KUBE-RESTORED -m comment --comment "restored chain" -j ACCEPT
179 -A KUBE-MISC-CHAIN -s 1.2.3.4 -j KUBE-MISC-TWO
180 -A KUBE-MISC-CHAIN -d 5.6.7.8 -j MASQUERADE
181 -A KUBE-MISC-TWO -j ACCEPT
182 COMMIT
183 `, "\n"))
184 err = fake.Restore(iptables.TableNAT, []byte(rules), iptables.NoFlushTables, iptables.NoRestoreCounters)
185 if err != nil {
186 t.Fatalf("unexpected error from Restore: %v", err)
187 }
188
189
190 buf.Reset()
191 err = fake.SaveInto("", buf)
192 if err != nil {
193 t.Fatalf("unexpected error from SaveInto: %v", err)
194 }
195 expected = dedent.Dedent(strings.Trim(`
196 *nat
197 :PREROUTING - [0:0]
198 :INPUT - [0:0]
199 :OUTPUT - [0:0]
200 :POSTROUTING - [0:0]
201 :KUBE-TEST - [0:0]
202 :KUBE-RESTORED - [0:0]
203 :KUBE-MISC-CHAIN - [0:0]
204 :KUBE-MISC-TWO - [0:0]
205 :KUBE-EMPTY - [0:0]
206 -A KUBE-TEST -j ACCEPT
207 -A KUBE-RESTORED -m comment --comment "restored chain" -j ACCEPT
208 -A KUBE-MISC-CHAIN -s 1.2.3.4 -j KUBE-MISC-TWO
209 -A KUBE-MISC-CHAIN -d 5.6.7.8 -j MASQUERADE
210 -A KUBE-MISC-TWO -j ACCEPT
211 COMMIT
212 *filter
213 :INPUT - [0:0]
214 :FORWARD - [0:0]
215 :OUTPUT - [0:0]
216 COMMIT
217 *mangle
218 COMMIT
219 `, "\n"))
220 if buf.String() != expected {
221 t.Fatalf("bad post-restore dump. expected:\n%s\n\ngot:\n%s\n", expected, buf.Bytes())
222 }
223
224
225 rules = dedent.Dedent(strings.Trim(`
226 *nat
227 :KUBE-MISC-TWO - [0:0]
228 -X KUBE-MISC-TWO
229 COMMIT
230 `, "\n"))
231 err = fake.Restore(iptables.TableNAT, []byte(rules), iptables.NoFlushTables, iptables.RestoreCounters)
232 if err == nil || !strings.Contains(err.Error(), "referenced by existing rules") {
233 t.Fatalf("Expected 'referenced by existing rules' error from Restore, got %v", err)
234 }
235
236
237 rules = dedent.Dedent(strings.Trim(`
238 *nat
239 :KUBE-MISC-TWO - [0:0]
240 -A KUBE-MISC-TWO -j KUBE-MISC-THREE
241 COMMIT
242 `, "\n"))
243 err = fake.Restore(iptables.TableNAT, []byte(rules), iptables.NoFlushTables, iptables.RestoreCounters)
244 if err == nil || !strings.Contains(err.Error(), "non-existent chain") {
245 t.Fatalf("Expected 'non-existent chain' error from Restore, got %v", err)
246 }
247
248
249 rules = dedent.Dedent(strings.Trim(`
250 *nat
251 :KUBE-RESTORED - [0:0]
252 :KUBE-TEST - [99:9999]
253 -X KUBE-RESTORED
254 COMMIT
255 `, "\n"))
256 err = fake.Restore(iptables.TableNAT, []byte(rules), iptables.NoFlushTables, iptables.RestoreCounters)
257 if err != nil {
258 t.Fatalf("unexpected error from Restore: %v", err)
259 }
260
261 buf.Reset()
262 err = fake.SaveInto("", buf)
263 if err != nil {
264 t.Fatalf("unexpected error from SaveInto: %v", err)
265 }
266 expected = dedent.Dedent(strings.Trim(`
267 *nat
268 :PREROUTING - [0:0]
269 :INPUT - [0:0]
270 :OUTPUT - [0:0]
271 :POSTROUTING - [0:0]
272 :KUBE-TEST - [99:9999]
273 :KUBE-MISC-CHAIN - [0:0]
274 :KUBE-MISC-TWO - [0:0]
275 :KUBE-EMPTY - [0:0]
276 -A KUBE-MISC-CHAIN -s 1.2.3.4 -j KUBE-MISC-TWO
277 -A KUBE-MISC-CHAIN -d 5.6.7.8 -j MASQUERADE
278 -A KUBE-MISC-TWO -j ACCEPT
279 COMMIT
280 *filter
281 :INPUT - [0:0]
282 :FORWARD - [0:0]
283 :OUTPUT - [0:0]
284 COMMIT
285 *mangle
286 COMMIT
287 `, "\n"))
288 if buf.String() != expected {
289 t.Fatalf("bad post-second-restore dump. expected:\n%s\n\ngot:\n%s\n", expected, buf.Bytes())
290 }
291
292
293 rules = dedent.Dedent(strings.Trim(`
294 *filter
295 :INPUT - [0:0]
296 :FORWARD - [0:0]
297 :OUTPUT - [0:0]
298 :KUBE-TEST - [0:0]
299 -A KUBE-TEST -m comment --comment "filter table KUBE-TEST" -j ACCEPT
300 COMMIT
301 *nat
302 :PREROUTING - [0:0]
303 :INPUT - [0:0]
304 :OUTPUT - [0:0]
305 :POSTROUTING - [0:0]
306 :KUBE-TEST - [88:8888]
307 :KUBE-NEW-CHAIN - [0:0]
308 -A KUBE-NEW-CHAIN -d 172.30.0.1 -j DNAT --to-destination 10.0.0.1
309 -A KUBE-NEW-CHAIN -d 172.30.0.2 -j DNAT --to-destination 10.0.0.2
310 -A KUBE-NEW-CHAIN -d 172.30.0.3 -j DNAT --to-destination 10.0.0.3
311 COMMIT
312 `, "\n"))
313 err = fake.RestoreAll([]byte(rules), iptables.FlushTables, iptables.NoRestoreCounters)
314 if err != nil {
315 t.Fatalf("unexpected error from RestoreAll: %v", err)
316 }
317
318 buf.Reset()
319 err = fake.SaveInto("", buf)
320 if err != nil {
321 t.Fatalf("unexpected error from SaveInto: %v", err)
322 }
323 expected = dedent.Dedent(strings.Trim(`
324 *nat
325 :PREROUTING - [0:0]
326 :INPUT - [0:0]
327 :OUTPUT - [0:0]
328 :POSTROUTING - [0:0]
329 :KUBE-TEST - [88:8888]
330 :KUBE-NEW-CHAIN - [0:0]
331 -A KUBE-NEW-CHAIN -d 172.30.0.1 -j DNAT --to-destination 10.0.0.1
332 -A KUBE-NEW-CHAIN -d 172.30.0.2 -j DNAT --to-destination 10.0.0.2
333 -A KUBE-NEW-CHAIN -d 172.30.0.3 -j DNAT --to-destination 10.0.0.3
334 COMMIT
335 *filter
336 :INPUT - [0:0]
337 :FORWARD - [0:0]
338 :OUTPUT - [0:0]
339 :KUBE-TEST - [0:0]
340 -A KUBE-TEST -m comment --comment "filter table KUBE-TEST" -j ACCEPT
341 COMMIT
342 *mangle
343 COMMIT
344 `, "\n"))
345 if buf.String() != expected {
346 t.Fatalf("bad post-restore-all dump. expected:\n%s\n\ngot:\n%s\n", expected, buf.Bytes())
347 }
348 }
349
View as plain text