github.com/goern/docker@v1.9.0-rc1/integration-cli/docker_cli_network_unix_test.go (about)

     1  // +build !windows
     2  
     3  package main
     4  
     5  import (
     6  	"encoding/json"
     7  	"fmt"
     8  	"io/ioutil"
     9  	"net"
    10  	"net/http"
    11  	"net/http/httptest"
    12  	"os"
    13  	"strings"
    14  
    15  	"github.com/docker/docker/api/types"
    16  	"github.com/docker/libnetwork/driverapi"
    17  	"github.com/go-check/check"
    18  )
    19  
    20  const dummyNetworkDriver = "dummy-network-driver"
    21  
    22  func init() {
    23  	check.Suite(&DockerNetworkSuite{
    24  		ds: &DockerSuite{},
    25  	})
    26  }
    27  
    28  type DockerNetworkSuite struct {
    29  	server *httptest.Server
    30  	ds     *DockerSuite
    31  	d      *Daemon
    32  }
    33  
    34  func (s *DockerNetworkSuite) SetUpTest(c *check.C) {
    35  	s.d = NewDaemon(c)
    36  }
    37  
    38  func (s *DockerNetworkSuite) TearDownTest(c *check.C) {
    39  	s.d.Stop()
    40  	s.ds.TearDownTest(c)
    41  }
    42  
    43  func (s *DockerNetworkSuite) SetUpSuite(c *check.C) {
    44  	mux := http.NewServeMux()
    45  	s.server = httptest.NewServer(mux)
    46  	if s.server == nil {
    47  		c.Fatal("Failed to start a HTTP Server")
    48  	}
    49  
    50  	mux.HandleFunc("/Plugin.Activate", func(w http.ResponseWriter, r *http.Request) {
    51  		w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json")
    52  		fmt.Fprintf(w, `{"Implements": ["%s"]}`, driverapi.NetworkPluginEndpointType)
    53  	})
    54  
    55  	mux.HandleFunc(fmt.Sprintf("/%s.GetCapabilities", driverapi.NetworkPluginEndpointType), func(w http.ResponseWriter, r *http.Request) {
    56  		w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json")
    57  		fmt.Fprintf(w, `{"Scope":"local"}`)
    58  	})
    59  
    60  	mux.HandleFunc(fmt.Sprintf("/%s.CreateNetwork", driverapi.NetworkPluginEndpointType), func(w http.ResponseWriter, r *http.Request) {
    61  		w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json")
    62  		fmt.Fprintf(w, "null")
    63  	})
    64  
    65  	mux.HandleFunc(fmt.Sprintf("/%s.DeleteNetwork", driverapi.NetworkPluginEndpointType), func(w http.ResponseWriter, r *http.Request) {
    66  		w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json")
    67  		fmt.Fprintf(w, "null")
    68  	})
    69  
    70  	if err := os.MkdirAll("/etc/docker/plugins", 0755); err != nil {
    71  		c.Fatal(err)
    72  	}
    73  
    74  	fileName := fmt.Sprintf("/etc/docker/plugins/%s.spec", dummyNetworkDriver)
    75  	if err := ioutil.WriteFile(fileName, []byte(s.server.URL), 0644); err != nil {
    76  		c.Fatal(err)
    77  	}
    78  }
    79  
    80  func (s *DockerNetworkSuite) TearDownSuite(c *check.C) {
    81  	if s.server == nil {
    82  		return
    83  	}
    84  
    85  	s.server.Close()
    86  
    87  	if err := os.RemoveAll("/etc/docker/plugins"); err != nil {
    88  		c.Fatal(err)
    89  	}
    90  }
    91  
    92  func assertNwIsAvailable(c *check.C, name string) {
    93  	if !isNwPresent(c, name) {
    94  		c.Fatalf("Network %s not found in network ls o/p", name)
    95  	}
    96  }
    97  
    98  func assertNwNotAvailable(c *check.C, name string) {
    99  	if isNwPresent(c, name) {
   100  		c.Fatalf("Found network %s in network ls o/p", name)
   101  	}
   102  }
   103  
   104  func isNwPresent(c *check.C, name string) bool {
   105  	out, _ := dockerCmd(c, "network", "ls")
   106  	lines := strings.Split(out, "\n")
   107  	for i := 1; i < len(lines)-1; i++ {
   108  		if strings.Contains(lines[i], name) {
   109  			return true
   110  		}
   111  	}
   112  	return false
   113  }
   114  
   115  func getNwResource(c *check.C, name string) *types.NetworkResource {
   116  	out, _ := dockerCmd(c, "network", "inspect", name)
   117  	nr := types.NetworkResource{}
   118  	err := json.Unmarshal([]byte(out), &nr)
   119  	c.Assert(err, check.IsNil)
   120  	return &nr
   121  }
   122  
   123  func (s *DockerNetworkSuite) TestDockerNetworkLsDefault(c *check.C) {
   124  	defaults := []string{"bridge", "host", "none"}
   125  	for _, nn := range defaults {
   126  		assertNwIsAvailable(c, nn)
   127  	}
   128  }
   129  
   130  func (s *DockerNetworkSuite) TestDockerNetworkCreateDelete(c *check.C) {
   131  	dockerCmd(c, "network", "create", "test")
   132  	assertNwIsAvailable(c, "test")
   133  
   134  	dockerCmd(c, "network", "rm", "test")
   135  	assertNwNotAvailable(c, "test")
   136  }
   137  
   138  func (s *DockerNetworkSuite) TestDockerNetworkConnectDisconnect(c *check.C) {
   139  	dockerCmd(c, "network", "create", "test")
   140  	assertNwIsAvailable(c, "test")
   141  	nr := getNwResource(c, "test")
   142  
   143  	c.Assert(nr.Name, check.Equals, "test")
   144  	c.Assert(len(nr.Containers), check.Equals, 0)
   145  
   146  	// run a container
   147  	out, _ := dockerCmd(c, "run", "-d", "--name", "test", "busybox", "top")
   148  	c.Assert(waitRun("test"), check.IsNil)
   149  	containerID := strings.TrimSpace(out)
   150  
   151  	// connect the container to the test network
   152  	dockerCmd(c, "network", "connect", "test", containerID)
   153  
   154  	// inspect the network to make sure container is connected
   155  	nr = getNetworkResource(c, nr.ID)
   156  	c.Assert(len(nr.Containers), check.Equals, 1)
   157  	c.Assert(nr.Containers[containerID], check.NotNil)
   158  
   159  	// check if container IP matches network inspect
   160  	ip, _, err := net.ParseCIDR(nr.Containers[containerID].IPv4Address)
   161  	c.Assert(err, check.IsNil)
   162  	containerIP := findContainerIP(c, "test")
   163  	c.Assert(ip.String(), check.Equals, containerIP)
   164  
   165  	// disconnect container from the network
   166  	dockerCmd(c, "network", "disconnect", "test", containerID)
   167  	nr = getNwResource(c, "test")
   168  	c.Assert(nr.Name, check.Equals, "test")
   169  	c.Assert(len(nr.Containers), check.Equals, 0)
   170  
   171  	// check if network connect fails for inactive containers
   172  	dockerCmd(c, "stop", containerID)
   173  	_, _, err = dockerCmdWithError("network", "connect", "test", containerID)
   174  	c.Assert(err, check.NotNil)
   175  
   176  	dockerCmd(c, "network", "rm", "test")
   177  	assertNwNotAvailable(c, "test")
   178  }
   179  
   180  func (s *DockerNetworkSuite) TestDockerNetworkIpamMultipleNetworks(c *check.C) {
   181  	// test0 bridge network
   182  	dockerCmd(c, "network", "create", "--subnet=192.168.0.0/16", "test1")
   183  	assertNwIsAvailable(c, "test1")
   184  
   185  	// test2 bridge network does not overlap
   186  	dockerCmd(c, "network", "create", "--subnet=192.169.0.0/16", "test2")
   187  	assertNwIsAvailable(c, "test2")
   188  
   189  	// for networks w/o ipam specified, docker will choose proper non-overlapping subnets
   190  	dockerCmd(c, "network", "create", "test3")
   191  	assertNwIsAvailable(c, "test3")
   192  	dockerCmd(c, "network", "create", "test4")
   193  	assertNwIsAvailable(c, "test4")
   194  	dockerCmd(c, "network", "create", "test5")
   195  	assertNwIsAvailable(c, "test5")
   196  
   197  	// test network with multiple subnets
   198  	// bridge network doesnt support multiple subnets. hence, use a dummy driver that supports
   199  
   200  	dockerCmd(c, "network", "create", "-d", dummyNetworkDriver, "--subnet=192.168.0.0/16", "--subnet=192.170.0.0/16", "test6")
   201  	assertNwIsAvailable(c, "test6")
   202  
   203  	// test network with multiple subnets with valid ipam combinations
   204  	// also check same subnet across networks when the driver supports it.
   205  	dockerCmd(c, "network", "create", "-d", dummyNetworkDriver,
   206  		"--subnet=192.168.0.0/16", "--subnet=192.170.0.0/16",
   207  		"--gateway=192.168.0.100", "--gateway=192.170.0.100",
   208  		"--ip-range=192.168.1.0/24",
   209  		"--aux-address", "a=192.168.1.5", "--aux-address", "b=192.168.1.6",
   210  		"--aux-address", "a=192.170.1.5", "--aux-address", "b=192.170.1.6",
   211  		"test7")
   212  	assertNwIsAvailable(c, "test7")
   213  
   214  	// cleanup
   215  	for i := 1; i < 8; i++ {
   216  		dockerCmd(c, "network", "rm", fmt.Sprintf("test%d", i))
   217  	}
   218  }
   219  
   220  func (s *DockerNetworkSuite) TestDockerNetworkInspect(c *check.C) {
   221  	// if unspecified, network gateway will be selected from inside preferred pool
   222  	dockerCmd(c, "network", "create", "--driver=bridge", "--subnet=172.28.0.0/16", "--ip-range=172.28.5.0/24", "--gateway=172.28.5.254", "br0")
   223  	assertNwIsAvailable(c, "br0")
   224  
   225  	nr := getNetworkResource(c, "br0")
   226  	c.Assert(nr.Driver, check.Equals, "bridge")
   227  	c.Assert(nr.Scope, check.Equals, "local")
   228  	c.Assert(nr.IPAM.Driver, check.Equals, "default")
   229  	c.Assert(len(nr.IPAM.Config), check.Equals, 1)
   230  	c.Assert(nr.IPAM.Config[0].Subnet, check.Equals, "172.28.0.0/16")
   231  	c.Assert(nr.IPAM.Config[0].IPRange, check.Equals, "172.28.5.0/24")
   232  	c.Assert(nr.IPAM.Config[0].Gateway, check.Equals, "172.28.5.254")
   233  	dockerCmd(c, "network", "rm", "br0")
   234  }
   235  
   236  func (s *DockerNetworkSuite) TestDockerNetworkIpamInvalidCombinations(c *check.C) {
   237  	// network with ip-range out of subnet range
   238  	_, _, err := dockerCmdWithError("network", "create", "--subnet=192.168.0.0/16", "--ip-range=192.170.0.0/16", "test")
   239  	c.Assert(err, check.NotNil)
   240  
   241  	// network with multiple gateways for a single subnet
   242  	_, _, err = dockerCmdWithError("network", "create", "--subnet=192.168.0.0/16", "--gateway=192.168.0.1", "--gateway=192.168.0.2", "test")
   243  	c.Assert(err, check.NotNil)
   244  
   245  	// Multiple overlaping subnets in the same network must fail
   246  	_, _, err = dockerCmdWithError("network", "create", "--subnet=192.168.0.0/16", "--subnet=192.168.1.0/16", "test")
   247  	c.Assert(err, check.NotNil)
   248  
   249  	// overlapping subnets across networks must fail
   250  	// create a valid test0 network
   251  	dockerCmd(c, "network", "create", "--subnet=192.168.0.0/16", "test0")
   252  	assertNwIsAvailable(c, "test0")
   253  	// create an overlapping test1 network
   254  	_, _, err = dockerCmdWithError("network", "create", "--subnet=192.168.128.0/17", "test1")
   255  	c.Assert(err, check.NotNil)
   256  	dockerCmd(c, "network", "rm", "test0")
   257  }