github.com/cloudfoundry-attic/garden-linux@v0.333.2-candidate/linux_container/iptables_manager/nat_test.go (about) 1 package iptables_manager_test 2 3 import ( 4 "errors" 5 "fmt" 6 "os/exec" 7 8 "github.com/cloudfoundry/gunk/command_runner/fake_command_runner" 9 10 "net" 11 12 "github.com/cloudfoundry-incubator/garden-linux/linux_container/iptables_manager" 13 "github.com/cloudfoundry-incubator/garden-linux/sysconfig" 14 . "github.com/cloudfoundry/gunk/command_runner/fake_command_runner/matchers" 15 . "github.com/onsi/ginkgo" 16 . "github.com/onsi/ginkgo/extensions/table" 17 . "github.com/onsi/gomega" 18 "github.com/pivotal-golang/lager/lagertest" 19 ) 20 21 var _ = Describe("natChain", func() { 22 var ( 23 fakeRunner *fake_command_runner.FakeCommandRunner 24 testCfg *sysconfig.IPTablesNATConfig 25 chain iptables_manager.Chain 26 containerID string 27 bridgeName string 28 ip net.IP 29 network *net.IPNet 30 ) 31 32 BeforeEach(func() { 33 var err error 34 35 fakeRunner = fake_command_runner.New() 36 testCfg = &sysconfig.IPTablesNATConfig{ 37 PreroutingChain: "nat-prerouting-chain", 38 PostroutingChain: "nat-postrouting-chain", 39 InstancePrefix: "nat-instance-prefix", 40 } 41 42 containerID = "some-ctr-id" 43 bridgeName = "some-bridge" 44 ip, network, err = net.ParseCIDR("1.2.3.4/28") 45 Expect(err).NotTo(HaveOccurred()) 46 47 chain = iptables_manager.NewNATChain(testCfg, fakeRunner, lagertest.NewTestLogger("test")) 48 }) 49 50 Describe("ContainerSetup", func() { 51 var specs []fake_command_runner.CommandSpec 52 BeforeEach(func() { 53 expectedNatInstanceChain := testCfg.InstancePrefix + containerID 54 specs = []fake_command_runner.CommandSpec{ 55 fake_command_runner.CommandSpec{ 56 Path: "iptables", 57 Args: []string{"--wait", "--table", "nat", "-N", expectedNatInstanceChain}, 58 }, 59 fake_command_runner.CommandSpec{ 60 Path: "iptables", 61 Args: []string{"--wait", "--table", "nat", "-A", testCfg.PreroutingChain, 62 "--jump", expectedNatInstanceChain}, 63 }, 64 fake_command_runner.CommandSpec{ 65 Path: "sh", 66 Args: []string{"-c", fmt.Sprintf( 67 `(iptables --wait --table nat -S %s | grep "\-j MASQUERADE\b" | grep -q -F -- "-s %s") || iptables --wait --table nat -A %s --source %s ! --destination %s --jump MASQUERADE`, 68 testCfg.PostroutingChain, network.String(), testCfg.PostroutingChain, 69 network.String(), network.String(), 70 )}, 71 }, 72 } 73 }) 74 75 It("should set up the chain", func() { 76 Expect(chain.Setup(containerID, bridgeName, ip, network)).To(Succeed()) 77 78 Expect(fakeRunner).To(HaveExecutedSerially(specs...)) 79 }) 80 81 DescribeTable("iptables failures", 82 func(specIndex int, errorString string) { 83 fakeRunner.WhenRunning(specs[specIndex], func(*exec.Cmd) error { 84 return errors.New("iptables failed") 85 }) 86 87 Expect(chain.Setup(containerID, bridgeName, ip, network)).To(MatchError(errorString)) 88 }, 89 Entry("create nat instance chain", 0, "iptables_manager: nat: iptables failed"), 90 Entry("bind nat instance chain to nat prerouting chain", 1, "iptables_manager: nat: iptables failed"), 91 Entry("enable NAT for traffic coming from containers", 2, "iptables_manager: nat: iptables failed"), 92 ) 93 }) 94 95 Describe("ContainerTeardown", func() { 96 var specs []fake_command_runner.CommandSpec 97 98 Describe("nat chain", func() { 99 BeforeEach(func() { 100 expectedFilterInstanceChain := testCfg.InstancePrefix + containerID 101 specs = []fake_command_runner.CommandSpec{ 102 fake_command_runner.CommandSpec{ 103 Path: "sh", 104 Args: []string{"-c", fmt.Sprintf( 105 `iptables --wait --table nat -S %s 2> /dev/null | grep "\-j %s\b" | sed -e "s/-A/-D/" | xargs --no-run-if-empty --max-lines=1 iptables --wait --table nat`, 106 testCfg.PreroutingChain, expectedFilterInstanceChain, 107 )}, 108 }, 109 fake_command_runner.CommandSpec{ 110 Path: "sh", 111 Args: []string{"-c", fmt.Sprintf( 112 `iptables --wait --table nat -F %s 2> /dev/null || true`, 113 expectedFilterInstanceChain, 114 )}, 115 }, 116 fake_command_runner.CommandSpec{ 117 Path: "sh", 118 Args: []string{"-c", fmt.Sprintf( 119 `iptables --wait --table nat -X %s 2> /dev/null || true`, 120 expectedFilterInstanceChain, 121 )}, 122 }, 123 } 124 }) 125 126 It("should tear down the chain", func() { 127 Expect(chain.Teardown(containerID)).To(Succeed()) 128 129 Expect(fakeRunner).To(HaveExecutedSerially(specs...)) 130 }) 131 132 DescribeTable("iptables failures", 133 func(specIndex int, errorString string) { 134 fakeRunner.WhenRunning(specs[specIndex], func(*exec.Cmd) error { 135 return errors.New("iptables failed") 136 }) 137 138 Expect(chain.Teardown(containerID)).To(MatchError(errorString)) 139 }, 140 Entry("prune prerouting chain", 0, "iptables_manager: nat: iptables failed"), 141 Entry("flush instance chain", 1, "iptables_manager: nat: iptables failed"), 142 Entry("delete instance chain", 2, "iptables_manager: nat: iptables failed"), 143 ) 144 }) 145 }) 146 })