github.com/lacework-dev/go-moby@v20.10.12+incompatible/integration/container/nat_test.go (about) 1 package container // import "github.com/docker/docker/integration/container" 2 3 import ( 4 "bytes" 5 "context" 6 "fmt" 7 "io" 8 "io/ioutil" 9 "net" 10 "strings" 11 "testing" 12 "time" 13 14 "github.com/docker/docker/api/types" 15 "github.com/docker/docker/integration/internal/container" 16 "github.com/docker/go-connections/nat" 17 "gotest.tools/v3/assert" 18 is "gotest.tools/v3/assert/cmp" 19 "gotest.tools/v3/poll" 20 "gotest.tools/v3/skip" 21 ) 22 23 func TestNetworkNat(t *testing.T) { 24 skip.If(t, testEnv.OSType == "windows", "FIXME") 25 skip.If(t, testEnv.IsRemoteDaemon) 26 27 defer setupTest(t)() 28 29 msg := "it works" 30 startServerContainer(t, msg, 8080) 31 32 endpoint := getExternalAddress(t) 33 conn, err := net.Dial("tcp", net.JoinHostPort(endpoint.String(), "8080")) 34 assert.NilError(t, err) 35 defer conn.Close() 36 37 data, err := ioutil.ReadAll(conn) 38 assert.NilError(t, err) 39 assert.Check(t, is.Equal(msg, strings.TrimSpace(string(data)))) 40 } 41 42 func TestNetworkLocalhostTCPNat(t *testing.T) { 43 skip.If(t, testEnv.IsRemoteDaemon) 44 45 defer setupTest(t)() 46 47 msg := "hi yall" 48 startServerContainer(t, msg, 8081) 49 50 conn, err := net.Dial("tcp", "localhost:8081") 51 assert.NilError(t, err) 52 defer conn.Close() 53 54 data, err := ioutil.ReadAll(conn) 55 assert.NilError(t, err) 56 assert.Check(t, is.Equal(msg, strings.TrimSpace(string(data)))) 57 } 58 59 func TestNetworkLoopbackNat(t *testing.T) { 60 skip.If(t, testEnv.OSType == "windows", "FIXME") 61 skip.If(t, testEnv.IsRemoteDaemon) 62 63 defer setupTest(t)() 64 65 msg := "it works" 66 serverContainerID := startServerContainer(t, msg, 8080) 67 68 endpoint := getExternalAddress(t) 69 70 client := testEnv.APIClient() 71 ctx := context.Background() 72 73 cID := container.Run(ctx, t, client, 74 container.WithCmd("sh", "-c", fmt.Sprintf("stty raw && nc -w 1 %s 8080", endpoint.String())), 75 container.WithTty(true), 76 container.WithNetworkMode("container:"+serverContainerID), 77 ) 78 79 poll.WaitOn(t, container.IsStopped(ctx, client, cID), poll.WithDelay(100*time.Millisecond)) 80 81 body, err := client.ContainerLogs(ctx, cID, types.ContainerLogsOptions{ 82 ShowStdout: true, 83 }) 84 assert.NilError(t, err) 85 defer body.Close() 86 87 var b bytes.Buffer 88 _, err = io.Copy(&b, body) 89 assert.NilError(t, err) 90 91 assert.Check(t, is.Equal(msg, strings.TrimSpace(b.String()))) 92 } 93 94 func startServerContainer(t *testing.T, msg string, port int) string { 95 t.Helper() 96 client := testEnv.APIClient() 97 ctx := context.Background() 98 99 cID := container.Run(ctx, t, client, 100 container.WithName("server-"+t.Name()), 101 container.WithCmd("sh", "-c", fmt.Sprintf("echo %q | nc -lp %d", msg, port)), 102 container.WithExposedPorts(fmt.Sprintf("%d/tcp", port)), 103 func(c *container.TestContainerConfig) { 104 c.HostConfig.PortBindings = nat.PortMap{ 105 nat.Port(fmt.Sprintf("%d/tcp", port)): []nat.PortBinding{ 106 { 107 HostPort: fmt.Sprintf("%d", port), 108 }, 109 }, 110 } 111 }) 112 113 poll.WaitOn(t, container.IsInState(ctx, client, cID, "running"), poll.WithDelay(100*time.Millisecond)) 114 115 return cID 116 } 117 118 // getExternalAddress() returns the external IP-address from eth0. If eth0 has 119 // multiple IP-addresses, it returns the first IPv4 IP-address; if no IPv4 120 // address is present, it returns the first IP-address found. 121 func getExternalAddress(t *testing.T) net.IP { 122 t.Helper() 123 iface, err := net.InterfaceByName("eth0") 124 skip.If(t, err != nil, "Test not running with `make test-integration`. Interface eth0 not found: %s", err) 125 126 ifaceAddrs, err := iface.Addrs() 127 assert.NilError(t, err) 128 assert.Check(t, 0 != len(ifaceAddrs)) 129 130 if len(ifaceAddrs) > 1 { 131 // Prefer IPv4 address if multiple addresses found, as rootlesskit 132 // does not handle IPv6 currently https://github.com/moby/moby/pull/41908#issuecomment-774200001 133 for _, a := range ifaceAddrs { 134 ifaceIP, _, err := net.ParseCIDR(a.String()) 135 assert.NilError(t, err) 136 if ifaceIP.To4() != nil { 137 return ifaceIP 138 } 139 } 140 } 141 ifaceIP, _, err := net.ParseCIDR(ifaceAddrs[0].String()) 142 assert.NilError(t, err) 143 144 return ifaceIP 145 }