iptables_test.go 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768
  1. /*
  2. Copyright 2014 The Kubernetes Authors.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package iptables
  14. import (
  15. "strings"
  16. "testing"
  17. "time"
  18. "k8s.io/kubernetes/pkg/util/dbus"
  19. "k8s.io/kubernetes/pkg/util/exec"
  20. "k8s.io/kubernetes/pkg/util/sets"
  21. )
  22. func getIptablesCommand(protocol Protocol) string {
  23. if protocol == ProtocolIpv4 {
  24. return cmdIptables
  25. }
  26. if protocol == ProtocolIpv6 {
  27. return cmdIp6tables
  28. }
  29. panic("Unknown protocol")
  30. }
  31. func testEnsureChain(t *testing.T, protocol Protocol) {
  32. fcmd := exec.FakeCmd{
  33. CombinedOutputScript: []exec.FakeCombinedOutputAction{
  34. // iptables version check
  35. func() ([]byte, error) { return []byte("iptables v1.9.22"), nil },
  36. // Success.
  37. func() ([]byte, error) { return []byte{}, nil },
  38. // Exists.
  39. func() ([]byte, error) { return nil, &exec.FakeExitError{Status: 1} },
  40. // Failure.
  41. func() ([]byte, error) { return nil, &exec.FakeExitError{Status: 2} },
  42. },
  43. }
  44. fexec := exec.FakeExec{
  45. CommandScript: []exec.FakeCommandAction{
  46. func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
  47. func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
  48. func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
  49. func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
  50. },
  51. }
  52. runner := New(&fexec, dbus.NewFake(nil, nil), protocol)
  53. defer runner.Destroy()
  54. // Success.
  55. exists, err := runner.EnsureChain(TableNAT, Chain("FOOBAR"))
  56. if err != nil {
  57. t.Errorf("expected success, got %v", err)
  58. }
  59. if exists {
  60. t.Errorf("expected exists = false")
  61. }
  62. if fcmd.CombinedOutputCalls != 2 {
  63. t.Errorf("expected 2 CombinedOutput() calls, got %d", fcmd.CombinedOutputCalls)
  64. }
  65. cmd := getIptablesCommand(protocol)
  66. if !sets.NewString(fcmd.CombinedOutputLog[1]...).HasAll(cmd, "-t", "nat", "-N", "FOOBAR") {
  67. t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[1])
  68. }
  69. // Exists.
  70. exists, err = runner.EnsureChain(TableNAT, Chain("FOOBAR"))
  71. if err != nil {
  72. t.Errorf("expected success, got %v", err)
  73. }
  74. if !exists {
  75. t.Errorf("expected exists = true")
  76. }
  77. // Failure.
  78. _, err = runner.EnsureChain(TableNAT, Chain("FOOBAR"))
  79. if err == nil {
  80. t.Errorf("expected failure")
  81. }
  82. }
  83. func TestEnsureChainIpv4(t *testing.T) {
  84. testEnsureChain(t, ProtocolIpv4)
  85. }
  86. func TestEnsureChainIpv6(t *testing.T) {
  87. testEnsureChain(t, ProtocolIpv6)
  88. }
  89. func TestFlushChain(t *testing.T) {
  90. fcmd := exec.FakeCmd{
  91. CombinedOutputScript: []exec.FakeCombinedOutputAction{
  92. // iptables version check
  93. func() ([]byte, error) { return []byte("iptables v1.9.22"), nil },
  94. // Success.
  95. func() ([]byte, error) { return []byte{}, nil },
  96. // Failure.
  97. func() ([]byte, error) { return nil, &exec.FakeExitError{Status: 1} },
  98. },
  99. }
  100. fexec := exec.FakeExec{
  101. CommandScript: []exec.FakeCommandAction{
  102. func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
  103. func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
  104. func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
  105. },
  106. }
  107. runner := New(&fexec, dbus.NewFake(nil, nil), ProtocolIpv4)
  108. defer runner.Destroy()
  109. // Success.
  110. err := runner.FlushChain(TableNAT, Chain("FOOBAR"))
  111. if err != nil {
  112. t.Errorf("expected success, got %v", err)
  113. }
  114. if fcmd.CombinedOutputCalls != 2 {
  115. t.Errorf("expected 2 CombinedOutput() calls, got %d", fcmd.CombinedOutputCalls)
  116. }
  117. if !sets.NewString(fcmd.CombinedOutputLog[1]...).HasAll("iptables", "-t", "nat", "-F", "FOOBAR") {
  118. t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[1])
  119. }
  120. // Failure.
  121. err = runner.FlushChain(TableNAT, Chain("FOOBAR"))
  122. if err == nil {
  123. t.Errorf("expected failure")
  124. }
  125. }
  126. func TestDeleteChain(t *testing.T) {
  127. fcmd := exec.FakeCmd{
  128. CombinedOutputScript: []exec.FakeCombinedOutputAction{
  129. // iptables version check
  130. func() ([]byte, error) { return []byte("iptables v1.9.22"), nil },
  131. // Success.
  132. func() ([]byte, error) { return []byte{}, nil },
  133. // Failure.
  134. func() ([]byte, error) { return nil, &exec.FakeExitError{Status: 1} },
  135. },
  136. }
  137. fexec := exec.FakeExec{
  138. CommandScript: []exec.FakeCommandAction{
  139. func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
  140. func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
  141. func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
  142. },
  143. }
  144. runner := New(&fexec, dbus.NewFake(nil, nil), ProtocolIpv4)
  145. defer runner.Destroy()
  146. // Success.
  147. err := runner.DeleteChain(TableNAT, Chain("FOOBAR"))
  148. if err != nil {
  149. t.Errorf("expected success, got %v", err)
  150. }
  151. if fcmd.CombinedOutputCalls != 2 {
  152. t.Errorf("expected 2 CombinedOutput() calls, got %d", fcmd.CombinedOutputCalls)
  153. }
  154. if !sets.NewString(fcmd.CombinedOutputLog[1]...).HasAll("iptables", "-t", "nat", "-X", "FOOBAR") {
  155. t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[1])
  156. }
  157. // Failure.
  158. err = runner.DeleteChain(TableNAT, Chain("FOOBAR"))
  159. if err == nil {
  160. t.Errorf("expected failure")
  161. }
  162. }
  163. func TestEnsureRuleAlreadyExists(t *testing.T) {
  164. fcmd := exec.FakeCmd{
  165. CombinedOutputScript: []exec.FakeCombinedOutputAction{
  166. // iptables version check
  167. func() ([]byte, error) { return []byte("iptables v1.9.22"), nil },
  168. // Success.
  169. func() ([]byte, error) { return []byte{}, nil },
  170. },
  171. }
  172. fexec := exec.FakeExec{
  173. CommandScript: []exec.FakeCommandAction{
  174. // iptables version check
  175. func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
  176. // The second Command() call is checking the rule. Success of that exec means "done".
  177. func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
  178. },
  179. }
  180. runner := New(&fexec, dbus.NewFake(nil, nil), ProtocolIpv4)
  181. defer runner.Destroy()
  182. exists, err := runner.EnsureRule(Append, TableNAT, ChainOutput, "abc", "123")
  183. if err != nil {
  184. t.Errorf("expected success, got %v", err)
  185. }
  186. if !exists {
  187. t.Errorf("expected exists = true")
  188. }
  189. if fcmd.CombinedOutputCalls != 2 {
  190. t.Errorf("expected 2 CombinedOutput() calls, got %d", fcmd.CombinedOutputCalls)
  191. }
  192. if !sets.NewString(fcmd.CombinedOutputLog[1]...).HasAll("iptables", "-t", "nat", "-C", "OUTPUT", "abc", "123") {
  193. t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[1])
  194. }
  195. }
  196. func TestEnsureRuleNew(t *testing.T) {
  197. fcmd := exec.FakeCmd{
  198. CombinedOutputScript: []exec.FakeCombinedOutputAction{
  199. // iptables version check
  200. func() ([]byte, error) { return []byte("iptables v1.9.22"), nil },
  201. // Status 1 on the first call.
  202. func() ([]byte, error) { return nil, &exec.FakeExitError{Status: 1} },
  203. // Success on the second call.
  204. func() ([]byte, error) { return []byte{}, nil },
  205. },
  206. }
  207. fexec := exec.FakeExec{
  208. CommandScript: []exec.FakeCommandAction{
  209. // iptables version check
  210. func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
  211. // The second Command() call is checking the rule. Failure of that means create it.
  212. func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
  213. func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
  214. },
  215. }
  216. runner := New(&fexec, dbus.NewFake(nil, nil), ProtocolIpv4)
  217. defer runner.Destroy()
  218. exists, err := runner.EnsureRule(Append, TableNAT, ChainOutput, "abc", "123")
  219. if err != nil {
  220. t.Errorf("expected success, got %v", err)
  221. }
  222. if exists {
  223. t.Errorf("expected exists = false")
  224. }
  225. if fcmd.CombinedOutputCalls != 3 {
  226. t.Errorf("expected 3 CombinedOutput() calls, got %d", fcmd.CombinedOutputCalls)
  227. }
  228. if !sets.NewString(fcmd.CombinedOutputLog[2]...).HasAll("iptables", "-t", "nat", "-A", "OUTPUT", "abc", "123") {
  229. t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[2])
  230. }
  231. }
  232. func TestEnsureRuleErrorChecking(t *testing.T) {
  233. fcmd := exec.FakeCmd{
  234. CombinedOutputScript: []exec.FakeCombinedOutputAction{
  235. // iptables version check
  236. func() ([]byte, error) { return []byte("iptables v1.9.22"), nil },
  237. // Status 2 on the first call.
  238. func() ([]byte, error) { return nil, &exec.FakeExitError{Status: 2} },
  239. },
  240. }
  241. fexec := exec.FakeExec{
  242. CommandScript: []exec.FakeCommandAction{
  243. // iptables version check
  244. func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
  245. // The second Command() call is checking the rule. Failure of that means create it.
  246. func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
  247. },
  248. }
  249. runner := New(&fexec, dbus.NewFake(nil, nil), ProtocolIpv4)
  250. defer runner.Destroy()
  251. _, err := runner.EnsureRule(Append, TableNAT, ChainOutput, "abc", "123")
  252. if err == nil {
  253. t.Errorf("expected failure")
  254. }
  255. if fcmd.CombinedOutputCalls != 2 {
  256. t.Errorf("expected 2 CombinedOutput() calls, got %d", fcmd.CombinedOutputCalls)
  257. }
  258. }
  259. func TestEnsureRuleErrorCreating(t *testing.T) {
  260. fcmd := exec.FakeCmd{
  261. CombinedOutputScript: []exec.FakeCombinedOutputAction{
  262. // iptables version check
  263. func() ([]byte, error) { return []byte("iptables v1.9.22"), nil },
  264. // Status 1 on the first call.
  265. func() ([]byte, error) { return nil, &exec.FakeExitError{Status: 1} },
  266. // Status 1 on the second call.
  267. func() ([]byte, error) { return nil, &exec.FakeExitError{Status: 1} },
  268. },
  269. }
  270. fexec := exec.FakeExec{
  271. CommandScript: []exec.FakeCommandAction{
  272. // iptables version check
  273. func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
  274. // The second Command() call is checking the rule. Failure of that means create it.
  275. func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
  276. func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
  277. },
  278. }
  279. runner := New(&fexec, dbus.NewFake(nil, nil), ProtocolIpv4)
  280. defer runner.Destroy()
  281. _, err := runner.EnsureRule(Append, TableNAT, ChainOutput, "abc", "123")
  282. if err == nil {
  283. t.Errorf("expected failure")
  284. }
  285. if fcmd.CombinedOutputCalls != 3 {
  286. t.Errorf("expected 3 CombinedOutput() calls, got %d", fcmd.CombinedOutputCalls)
  287. }
  288. }
  289. func TestDeleteRuleAlreadyExists(t *testing.T) {
  290. fcmd := exec.FakeCmd{
  291. CombinedOutputScript: []exec.FakeCombinedOutputAction{
  292. // iptables version check
  293. func() ([]byte, error) { return []byte("iptables v1.9.22"), nil },
  294. // Status 1 on the first call.
  295. func() ([]byte, error) { return nil, &exec.FakeExitError{Status: 1} },
  296. },
  297. }
  298. fexec := exec.FakeExec{
  299. CommandScript: []exec.FakeCommandAction{
  300. // iptables version check
  301. func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
  302. // The second Command() call is checking the rule. Failure of that exec means "does not exist".
  303. func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
  304. },
  305. }
  306. runner := New(&fexec, dbus.NewFake(nil, nil), ProtocolIpv4)
  307. defer runner.Destroy()
  308. err := runner.DeleteRule(TableNAT, ChainOutput, "abc", "123")
  309. if err != nil {
  310. t.Errorf("expected success, got %v", err)
  311. }
  312. if fcmd.CombinedOutputCalls != 2 {
  313. t.Errorf("expected 2 CombinedOutput() calls, got %d", fcmd.CombinedOutputCalls)
  314. }
  315. if !sets.NewString(fcmd.CombinedOutputLog[1]...).HasAll("iptables", "-t", "nat", "-C", "OUTPUT", "abc", "123") {
  316. t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[1])
  317. }
  318. }
  319. func TestDeleteRuleNew(t *testing.T) {
  320. fcmd := exec.FakeCmd{
  321. CombinedOutputScript: []exec.FakeCombinedOutputAction{
  322. // iptables version check
  323. func() ([]byte, error) { return []byte("iptables v1.9.22"), nil },
  324. // Success on the first call.
  325. func() ([]byte, error) { return []byte{}, nil },
  326. // Success on the second call.
  327. func() ([]byte, error) { return []byte{}, nil },
  328. },
  329. }
  330. fexec := exec.FakeExec{
  331. CommandScript: []exec.FakeCommandAction{
  332. // iptables version check
  333. func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
  334. // The second Command() call is checking the rule. Success of that means delete it.
  335. func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
  336. func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
  337. },
  338. }
  339. runner := New(&fexec, dbus.NewFake(nil, nil), ProtocolIpv4)
  340. defer runner.Destroy()
  341. err := runner.DeleteRule(TableNAT, ChainOutput, "abc", "123")
  342. if err != nil {
  343. t.Errorf("expected success, got %v", err)
  344. }
  345. if fcmd.CombinedOutputCalls != 3 {
  346. t.Errorf("expected 3 CombinedOutput() calls, got %d", fcmd.CombinedOutputCalls)
  347. }
  348. if !sets.NewString(fcmd.CombinedOutputLog[2]...).HasAll("iptables", "-t", "nat", "-D", "OUTPUT", "abc", "123") {
  349. t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[2])
  350. }
  351. }
  352. func TestDeleteRuleErrorChecking(t *testing.T) {
  353. fcmd := exec.FakeCmd{
  354. CombinedOutputScript: []exec.FakeCombinedOutputAction{
  355. // iptables version check
  356. func() ([]byte, error) { return []byte("iptables v1.9.22"), nil },
  357. // Status 2 on the first call.
  358. func() ([]byte, error) { return nil, &exec.FakeExitError{Status: 2} },
  359. },
  360. }
  361. fexec := exec.FakeExec{
  362. CommandScript: []exec.FakeCommandAction{
  363. // iptables version check
  364. func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
  365. // The second Command() call is checking the rule. Failure of that means create it.
  366. func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
  367. },
  368. }
  369. runner := New(&fexec, dbus.NewFake(nil, nil), ProtocolIpv4)
  370. defer runner.Destroy()
  371. err := runner.DeleteRule(TableNAT, ChainOutput, "abc", "123")
  372. if err == nil {
  373. t.Errorf("expected failure")
  374. }
  375. if fcmd.CombinedOutputCalls != 2 {
  376. t.Errorf("expected 2 CombinedOutput() calls, got %d", fcmd.CombinedOutputCalls)
  377. }
  378. }
  379. func TestDeleteRuleErrorCreating(t *testing.T) {
  380. fcmd := exec.FakeCmd{
  381. CombinedOutputScript: []exec.FakeCombinedOutputAction{
  382. // iptables version check
  383. func() ([]byte, error) { return []byte("iptables v1.9.22"), nil },
  384. // Success on the first call.
  385. func() ([]byte, error) { return []byte{}, nil },
  386. // Status 1 on the second call.
  387. func() ([]byte, error) { return nil, &exec.FakeExitError{Status: 1} },
  388. },
  389. }
  390. fexec := exec.FakeExec{
  391. CommandScript: []exec.FakeCommandAction{
  392. // iptables version check
  393. func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
  394. // The second Command() call is checking the rule. Success of that means delete it.
  395. func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
  396. func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
  397. },
  398. }
  399. runner := New(&fexec, dbus.NewFake(nil, nil), ProtocolIpv4)
  400. defer runner.Destroy()
  401. err := runner.DeleteRule(TableNAT, ChainOutput, "abc", "123")
  402. if err == nil {
  403. t.Errorf("expected failure")
  404. }
  405. if fcmd.CombinedOutputCalls != 3 {
  406. t.Errorf("expected 3 CombinedOutput() calls, got %d", fcmd.CombinedOutputCalls)
  407. }
  408. }
  409. func TestGetIptablesHasCheckCommand(t *testing.T) {
  410. testCases := []struct {
  411. Version string
  412. Err bool
  413. Expected bool
  414. }{
  415. {"iptables v1.4.7", false, false},
  416. {"iptables v1.4.11", false, true},
  417. {"iptables v1.4.19.1", false, true},
  418. {"iptables v2.0.0", false, true},
  419. {"total junk", true, false},
  420. }
  421. for _, testCase := range testCases {
  422. fcmd := exec.FakeCmd{
  423. CombinedOutputScript: []exec.FakeCombinedOutputAction{
  424. func() ([]byte, error) { return []byte(testCase.Version), nil },
  425. },
  426. }
  427. fexec := exec.FakeExec{
  428. CommandScript: []exec.FakeCommandAction{
  429. func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
  430. },
  431. }
  432. version, err := getIptablesVersionString(&fexec)
  433. if (err != nil) != testCase.Err {
  434. t.Errorf("Expected error: %v, Got error: %v", testCase.Err, err)
  435. }
  436. if err == nil {
  437. check := getIptablesHasCheckCommand(version)
  438. if testCase.Expected != check {
  439. t.Errorf("Expected result: %v, Got result: %v", testCase.Expected, check)
  440. }
  441. }
  442. }
  443. }
  444. func TestCheckRuleWithoutCheckPresent(t *testing.T) {
  445. iptables_save_output := `# Generated by iptables-save v1.4.7 on Wed Oct 29 14:56:01 2014
  446. *nat
  447. :PREROUTING ACCEPT [2136997:197881818]
  448. :POSTROUTING ACCEPT [4284525:258542680]
  449. :OUTPUT ACCEPT [5901660:357267963]
  450. -A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
  451. COMMIT
  452. # Completed on Wed Oct 29 14:56:01 2014`
  453. fcmd := exec.FakeCmd{
  454. CombinedOutputScript: []exec.FakeCombinedOutputAction{
  455. // Success.
  456. func() ([]byte, error) { return []byte(iptables_save_output), nil },
  457. },
  458. }
  459. fexec := exec.FakeExec{
  460. CommandScript: []exec.FakeCommandAction{
  461. // The first Command() call is checking the rule. Success of that exec means "done".
  462. func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
  463. },
  464. }
  465. runner := &runner{exec: &fexec}
  466. exists, err := runner.checkRuleWithoutCheck(TableNAT, ChainPrerouting, "-m", "addrtype", "-j", "DOCKER", "--dst-type", "LOCAL")
  467. if err != nil {
  468. t.Errorf("expected success, got %v", err)
  469. }
  470. if !exists {
  471. t.Errorf("expected exists = true")
  472. }
  473. if fcmd.CombinedOutputCalls != 1 {
  474. t.Errorf("expected 1 CombinedOutput() call, got %d", fcmd.CombinedOutputCalls)
  475. }
  476. if !sets.NewString(fcmd.CombinedOutputLog[0]...).HasAll("iptables-save", "-t", "nat") {
  477. t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[0])
  478. }
  479. }
  480. func TestCheckRuleWithoutCheckAbsent(t *testing.T) {
  481. iptables_save_output := `# Generated by iptables-save v1.4.7 on Wed Oct 29 14:56:01 2014
  482. *nat
  483. :PREROUTING ACCEPT [2136997:197881818]
  484. :POSTROUTING ACCEPT [4284525:258542680]
  485. :OUTPUT ACCEPT [5901660:357267963]
  486. -A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
  487. COMMIT
  488. # Completed on Wed Oct 29 14:56:01 2014`
  489. fcmd := exec.FakeCmd{
  490. CombinedOutputScript: []exec.FakeCombinedOutputAction{
  491. // Success.
  492. func() ([]byte, error) { return []byte(iptables_save_output), nil },
  493. },
  494. }
  495. fexec := exec.FakeExec{
  496. CommandScript: []exec.FakeCommandAction{
  497. // The first Command() call is checking the rule. Success of that exec means "done".
  498. func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
  499. },
  500. }
  501. runner := &runner{exec: &fexec}
  502. exists, err := runner.checkRuleWithoutCheck(TableNAT, ChainPrerouting, "-m", "addrtype", "-j", "DOCKER")
  503. if err != nil {
  504. t.Errorf("expected success, got %v", err)
  505. }
  506. if exists {
  507. t.Errorf("expected exists = false")
  508. }
  509. if fcmd.CombinedOutputCalls != 1 {
  510. t.Errorf("expected 1 CombinedOutput() call, got %d", fcmd.CombinedOutputCalls)
  511. }
  512. if !sets.NewString(fcmd.CombinedOutputLog[0]...).HasAll("iptables-save", "-t", "nat") {
  513. t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[0])
  514. }
  515. }
  516. func TestIptablesWaitFlag(t *testing.T) {
  517. testCases := []struct {
  518. Version string
  519. Result string
  520. }{
  521. {"0.55.55", ""},
  522. {"1.0.55", ""},
  523. {"1.4.19", ""},
  524. {"1.4.20", "-w"},
  525. {"1.4.21", "-w"},
  526. {"1.4.22", "-w2"},
  527. {"1.5.0", "-w2"},
  528. {"2.0.0", "-w2"},
  529. }
  530. for _, testCase := range testCases {
  531. result := getIptablesWaitFlag(testCase.Version)
  532. if strings.Join(result, "") != testCase.Result {
  533. t.Errorf("For %s expected %v got %v", testCase.Version, testCase.Result, result)
  534. }
  535. }
  536. }
  537. func TestWaitFlagUnavailable(t *testing.T) {
  538. fcmd := exec.FakeCmd{
  539. CombinedOutputScript: []exec.FakeCombinedOutputAction{
  540. // iptables version check
  541. func() ([]byte, error) { return []byte("iptables v1.4.19"), nil },
  542. // Success.
  543. func() ([]byte, error) { return []byte{}, nil },
  544. },
  545. }
  546. fexec := exec.FakeExec{
  547. CommandScript: []exec.FakeCommandAction{
  548. func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
  549. func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
  550. },
  551. }
  552. runner := New(&fexec, dbus.NewFake(nil, nil), ProtocolIpv4)
  553. defer runner.Destroy()
  554. err := runner.DeleteChain(TableNAT, Chain("FOOBAR"))
  555. if err != nil {
  556. t.Errorf("expected success, got %v", err)
  557. }
  558. if fcmd.CombinedOutputCalls != 2 {
  559. t.Errorf("expected 2 CombinedOutput() calls, got %d", fcmd.CombinedOutputCalls)
  560. }
  561. if sets.NewString(fcmd.CombinedOutputLog[1]...).HasAny("-w", "-w2") {
  562. t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[1])
  563. }
  564. }
  565. func TestWaitFlagOld(t *testing.T) {
  566. fcmd := exec.FakeCmd{
  567. CombinedOutputScript: []exec.FakeCombinedOutputAction{
  568. // iptables version check
  569. func() ([]byte, error) { return []byte("iptables v1.4.20"), nil },
  570. // Success.
  571. func() ([]byte, error) { return []byte{}, nil },
  572. },
  573. }
  574. fexec := exec.FakeExec{
  575. CommandScript: []exec.FakeCommandAction{
  576. func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
  577. func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
  578. },
  579. }
  580. runner := New(&fexec, dbus.NewFake(nil, nil), ProtocolIpv4)
  581. defer runner.Destroy()
  582. err := runner.DeleteChain(TableNAT, Chain("FOOBAR"))
  583. if err != nil {
  584. t.Errorf("expected success, got %v", err)
  585. }
  586. if fcmd.CombinedOutputCalls != 2 {
  587. t.Errorf("expected 2 CombinedOutput() calls, got %d", fcmd.CombinedOutputCalls)
  588. }
  589. if !sets.NewString(fcmd.CombinedOutputLog[1]...).HasAll("iptables", "-w") {
  590. t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[1])
  591. }
  592. if sets.NewString(fcmd.CombinedOutputLog[1]...).HasAny("-w2") {
  593. t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[1])
  594. }
  595. }
  596. func TestWaitFlagNew(t *testing.T) {
  597. fcmd := exec.FakeCmd{
  598. CombinedOutputScript: []exec.FakeCombinedOutputAction{
  599. // iptables version check
  600. func() ([]byte, error) { return []byte("iptables v1.4.22"), nil },
  601. // Success.
  602. func() ([]byte, error) { return []byte{}, nil },
  603. },
  604. }
  605. fexec := exec.FakeExec{
  606. CommandScript: []exec.FakeCommandAction{
  607. func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
  608. func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
  609. },
  610. }
  611. runner := New(&fexec, dbus.NewFake(nil, nil), ProtocolIpv4)
  612. defer runner.Destroy()
  613. err := runner.DeleteChain(TableNAT, Chain("FOOBAR"))
  614. if err != nil {
  615. t.Errorf("expected success, got %v", err)
  616. }
  617. if fcmd.CombinedOutputCalls != 2 {
  618. t.Errorf("expected 2 CombinedOutput() calls, got %d", fcmd.CombinedOutputCalls)
  619. }
  620. if !sets.NewString(fcmd.CombinedOutputLog[1]...).HasAll("iptables", "-w2") {
  621. t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[1])
  622. }
  623. if sets.NewString(fcmd.CombinedOutputLog[1]...).HasAny("-w") {
  624. t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[1])
  625. }
  626. }
  627. func TestReload(t *testing.T) {
  628. dbusConn := dbus.NewFakeConnection()
  629. dbusConn.SetBusObject(func(method string, args ...interface{}) ([]interface{}, error) { return nil, nil })
  630. dbusConn.AddObject(firewalldName, firewalldPath, func(method string, args ...interface{}) ([]interface{}, error) { return nil, nil })
  631. fdbus := dbus.NewFake(dbusConn, nil)
  632. reloaded := make(chan bool, 2)
  633. fcmd := exec.FakeCmd{
  634. CombinedOutputScript: []exec.FakeCombinedOutputAction{
  635. // iptables version check
  636. func() ([]byte, error) { return []byte("iptables v1.4.22"), nil },
  637. // first reload
  638. // EnsureChain
  639. func() ([]byte, error) { return []byte{}, nil },
  640. // EnsureRule abc check
  641. func() ([]byte, error) { return []byte{}, &exec.FakeExitError{Status: 1} },
  642. // EnsureRule abc
  643. func() ([]byte, error) { return []byte{}, nil },
  644. // second reload
  645. // EnsureChain
  646. func() ([]byte, error) { return []byte{}, nil },
  647. // EnsureRule abc check
  648. func() ([]byte, error) { return []byte{}, &exec.FakeExitError{Status: 1} },
  649. // EnsureRule abc
  650. func() ([]byte, error) { return []byte{}, nil },
  651. },
  652. }
  653. fexec := exec.FakeExec{
  654. CommandScript: []exec.FakeCommandAction{
  655. func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
  656. func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
  657. func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
  658. func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
  659. func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
  660. func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
  661. func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
  662. },
  663. }
  664. runner := New(&fexec, fdbus, ProtocolIpv4)
  665. defer runner.Destroy()
  666. runner.AddReloadFunc(func() {
  667. exists, err := runner.EnsureChain(TableNAT, Chain("FOOBAR"))
  668. if err != nil {
  669. t.Errorf("expected success, got %v", err)
  670. }
  671. if exists {
  672. t.Errorf("expected exists = false")
  673. }
  674. reloaded <- true
  675. })
  676. runner.AddReloadFunc(func() {
  677. exists, err := runner.EnsureRule(Append, TableNAT, ChainOutput, "abc", "123")
  678. if err != nil {
  679. t.Errorf("expected success, got %v", err)
  680. }
  681. if exists {
  682. t.Errorf("expected exists = false")
  683. }
  684. reloaded <- true
  685. })
  686. dbusConn.EmitSignal("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "NameOwnerChanged", firewalldName, "", ":1.1")
  687. <-reloaded
  688. <-reloaded
  689. if fcmd.CombinedOutputCalls != 4 {
  690. t.Errorf("expected 4 CombinedOutput() calls total, got %d", fcmd.CombinedOutputCalls)
  691. }
  692. if !sets.NewString(fcmd.CombinedOutputLog[1]...).HasAll("iptables", "-t", "nat", "-N", "FOOBAR") {
  693. t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[1])
  694. }
  695. if !sets.NewString(fcmd.CombinedOutputLog[2]...).HasAll("iptables", "-t", "nat", "-C", "OUTPUT", "abc", "123") {
  696. t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[2])
  697. }
  698. if !sets.NewString(fcmd.CombinedOutputLog[3]...).HasAll("iptables", "-t", "nat", "-A", "OUTPUT", "abc", "123") {
  699. t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[3])
  700. }
  701. go func() { time.Sleep(time.Second / 100); reloaded <- true }()
  702. dbusConn.EmitSignal(firewalldName, firewalldPath, firewalldInterface, "DefaultZoneChanged", "public")
  703. dbusConn.EmitSignal("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "NameOwnerChanged", "io.k8s.Something", "", ":1.1")
  704. <-reloaded
  705. if fcmd.CombinedOutputCalls != 4 {
  706. t.Errorf("Incorrect signal caused a reload")
  707. }
  708. dbusConn.EmitSignal(firewalldName, firewalldPath, firewalldInterface, "Reloaded")
  709. <-reloaded
  710. <-reloaded
  711. if fcmd.CombinedOutputCalls != 7 {
  712. t.Errorf("expected 7 CombinedOutput() calls total, got %d", fcmd.CombinedOutputCalls)
  713. }
  714. if !sets.NewString(fcmd.CombinedOutputLog[4]...).HasAll("iptables", "-t", "nat", "-N", "FOOBAR") {
  715. t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[4])
  716. }
  717. if !sets.NewString(fcmd.CombinedOutputLog[5]...).HasAll("iptables", "-t", "nat", "-C", "OUTPUT", "abc", "123") {
  718. t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[5])
  719. }
  720. if !sets.NewString(fcmd.CombinedOutputLog[6]...).HasAll("iptables", "-t", "nat", "-A", "OUTPUT", "abc", "123") {
  721. t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[6])
  722. }
  723. }