github.com/yamamoto-febc/docker@v1.9.0/integration-cli/docker_api_network_test.go (about) 1 package main 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "net" 7 "net/http" 8 "net/url" 9 "strings" 10 11 "github.com/docker/docker/api/types" 12 "github.com/docker/docker/daemon/network" 13 "github.com/docker/docker/pkg/parsers/filters" 14 "github.com/go-check/check" 15 ) 16 17 func (s *DockerSuite) TestApiNetworkGetDefaults(c *check.C) { 18 // By default docker daemon creates 3 networks. check if they are present 19 defaults := []string{"bridge", "host", "none"} 20 for _, nn := range defaults { 21 c.Assert(isNetworkAvailable(c, nn), check.Equals, true) 22 } 23 } 24 25 func (s *DockerSuite) TestApiNetworkCreateDelete(c *check.C) { 26 // Create a network 27 name := "testnetwork" 28 config := types.NetworkCreate{ 29 Name: name, 30 CheckDuplicate: true, 31 } 32 id := createNetwork(c, config, true) 33 c.Assert(isNetworkAvailable(c, name), check.Equals, true) 34 35 // POST another network with same name and CheckDuplicate must fail 36 createNetwork(c, config, false) 37 38 // delete the network and make sure it is deleted 39 deleteNetwork(c, id, true) 40 c.Assert(isNetworkAvailable(c, name), check.Equals, false) 41 } 42 43 func (s *DockerSuite) TestApiNetworkFilter(c *check.C) { 44 nr := getNetworkResource(c, getNetworkIDByName(c, "bridge")) 45 c.Assert(nr.Name, check.Equals, "bridge") 46 } 47 48 func (s *DockerSuite) TestApiNetworkInspect(c *check.C) { 49 // Inspect default bridge network 50 nr := getNetworkResource(c, "bridge") 51 c.Assert(nr.Name, check.Equals, "bridge") 52 53 // run a container and attach it to the default bridge network 54 out, _ := dockerCmd(c, "run", "-d", "--name", "test", "busybox", "top") 55 containerID := strings.TrimSpace(out) 56 containerIP := findContainerIP(c, "test", "bridge") 57 58 // inspect default bridge network again and make sure the container is connected 59 nr = getNetworkResource(c, nr.ID) 60 c.Assert(nr.Driver, check.Equals, "bridge") 61 c.Assert(nr.Scope, check.Equals, "local") 62 c.Assert(nr.IPAM.Driver, check.Equals, "default") 63 c.Assert(len(nr.Containers), check.Equals, 1) 64 c.Assert(nr.Containers[containerID], check.NotNil) 65 66 ip, _, err := net.ParseCIDR(nr.Containers[containerID].IPv4Address) 67 c.Assert(err, check.IsNil) 68 c.Assert(ip.String(), check.Equals, containerIP) 69 70 // IPAM configuration inspect 71 ipam := network.IPAM{ 72 Driver: "default", 73 Config: []network.IPAMConfig{{Subnet: "172.28.0.0/16", IPRange: "172.28.5.0/24", Gateway: "172.28.5.254"}}, 74 } 75 config := types.NetworkCreate{ 76 Name: "br0", 77 Driver: "bridge", 78 IPAM: ipam, 79 Options: map[string]string{"foo": "bar", "opts": "dopts"}, 80 } 81 id0 := createNetwork(c, config, true) 82 c.Assert(isNetworkAvailable(c, "br0"), check.Equals, true) 83 84 nr = getNetworkResource(c, id0) 85 c.Assert(len(nr.IPAM.Config), check.Equals, 1) 86 c.Assert(nr.IPAM.Config[0].Subnet, check.Equals, "172.28.0.0/16") 87 c.Assert(nr.IPAM.Config[0].IPRange, check.Equals, "172.28.5.0/24") 88 c.Assert(nr.IPAM.Config[0].Gateway, check.Equals, "172.28.5.254") 89 // delete the network and make sure it is deleted 90 deleteNetwork(c, id0, true) 91 c.Assert(isNetworkAvailable(c, "br0"), check.Equals, false) 92 } 93 94 func (s *DockerSuite) TestApiNetworkConnectDisconnect(c *check.C) { 95 // Create test network 96 name := "testnetwork" 97 config := types.NetworkCreate{ 98 Name: name, 99 } 100 id := createNetwork(c, config, true) 101 nr := getNetworkResource(c, id) 102 c.Assert(nr.Name, check.Equals, name) 103 c.Assert(nr.ID, check.Equals, id) 104 c.Assert(len(nr.Containers), check.Equals, 0) 105 106 // run a container 107 out, _ := dockerCmd(c, "run", "-d", "--name", "test", "busybox", "top") 108 containerID := strings.TrimSpace(out) 109 110 // connect the container to the test network 111 connectNetwork(c, nr.ID, containerID) 112 113 // inspect the network to make sure container is connected 114 nr = getNetworkResource(c, nr.ID) 115 c.Assert(len(nr.Containers), check.Equals, 1) 116 c.Assert(nr.Containers[containerID], check.NotNil) 117 118 // check if container IP matches network inspect 119 ip, _, err := net.ParseCIDR(nr.Containers[containerID].IPv4Address) 120 c.Assert(err, check.IsNil) 121 containerIP := findContainerIP(c, "test", "testnetwork") 122 c.Assert(ip.String(), check.Equals, containerIP) 123 124 // disconnect container from the network 125 disconnectNetwork(c, nr.ID, containerID) 126 nr = getNetworkResource(c, nr.ID) 127 c.Assert(nr.Name, check.Equals, name) 128 c.Assert(len(nr.Containers), check.Equals, 0) 129 130 // delete the network 131 deleteNetwork(c, nr.ID, true) 132 } 133 134 func (s *DockerSuite) TestApiNetworkIpamMultipleBridgeNetworks(c *check.C) { 135 // test0 bridge network 136 ipam0 := network.IPAM{ 137 Driver: "default", 138 Config: []network.IPAMConfig{{Subnet: "192.178.0.0/16", IPRange: "192.178.128.0/17", Gateway: "192.178.138.100"}}, 139 } 140 config0 := types.NetworkCreate{ 141 Name: "test0", 142 Driver: "bridge", 143 IPAM: ipam0, 144 } 145 id0 := createNetwork(c, config0, true) 146 c.Assert(isNetworkAvailable(c, "test0"), check.Equals, true) 147 148 ipam1 := network.IPAM{ 149 Driver: "default", 150 Config: []network.IPAMConfig{{Subnet: "192.178.128.0/17", Gateway: "192.178.128.1"}}, 151 } 152 // test1 bridge network overlaps with test0 153 config1 := types.NetworkCreate{ 154 Name: "test1", 155 Driver: "bridge", 156 IPAM: ipam1, 157 } 158 createNetwork(c, config1, false) 159 c.Assert(isNetworkAvailable(c, "test1"), check.Equals, false) 160 161 ipam2 := network.IPAM{ 162 Driver: "default", 163 Config: []network.IPAMConfig{{Subnet: "192.169.0.0/16", Gateway: "192.169.100.100"}}, 164 } 165 // test2 bridge network does not overlap 166 config2 := types.NetworkCreate{ 167 Name: "test2", 168 Driver: "bridge", 169 IPAM: ipam2, 170 } 171 createNetwork(c, config2, true) 172 c.Assert(isNetworkAvailable(c, "test2"), check.Equals, true) 173 174 // remove test0 and retry to create test1 175 deleteNetwork(c, id0, true) 176 createNetwork(c, config1, true) 177 c.Assert(isNetworkAvailable(c, "test1"), check.Equals, true) 178 179 // for networks w/o ipam specified, docker will choose proper non-overlapping subnets 180 createNetwork(c, types.NetworkCreate{Name: "test3"}, true) 181 c.Assert(isNetworkAvailable(c, "test3"), check.Equals, true) 182 createNetwork(c, types.NetworkCreate{Name: "test4"}, true) 183 c.Assert(isNetworkAvailable(c, "test4"), check.Equals, true) 184 createNetwork(c, types.NetworkCreate{Name: "test5"}, true) 185 c.Assert(isNetworkAvailable(c, "test5"), check.Equals, true) 186 187 for i := 1; i < 6; i++ { 188 deleteNetwork(c, fmt.Sprintf("test%d", i), true) 189 } 190 } 191 192 func (s *DockerSuite) TestApiCreateDeletePredefinedNetworks(c *check.C) { 193 createDeletePredefinedNetwork(c, "bridge") 194 createDeletePredefinedNetwork(c, "none") 195 createDeletePredefinedNetwork(c, "host") 196 } 197 198 func createDeletePredefinedNetwork(c *check.C, name string) { 199 // Create pre-defined network 200 config := types.NetworkCreate{ 201 Name: name, 202 CheckDuplicate: true, 203 } 204 shouldSucceed := false 205 createNetwork(c, config, shouldSucceed) 206 deleteNetwork(c, name, shouldSucceed) 207 } 208 209 func isNetworkAvailable(c *check.C, name string) bool { 210 status, body, err := sockRequest("GET", "/networks", nil) 211 c.Assert(status, check.Equals, http.StatusOK) 212 c.Assert(err, check.IsNil) 213 214 nJSON := []types.NetworkResource{} 215 err = json.Unmarshal(body, &nJSON) 216 c.Assert(err, check.IsNil) 217 218 for _, n := range nJSON { 219 if n.Name == name { 220 return true 221 } 222 } 223 return false 224 } 225 226 func getNetworkIDByName(c *check.C, name string) string { 227 var ( 228 v = url.Values{} 229 filterArgs = filters.Args{} 230 ) 231 filterArgs["name"] = []string{name} 232 filterJSON, err := filters.ToParam(filterArgs) 233 c.Assert(err, check.IsNil) 234 v.Set("filters", filterJSON) 235 236 status, body, err := sockRequest("GET", "/networks?"+v.Encode(), nil) 237 c.Assert(status, check.Equals, http.StatusOK) 238 c.Assert(err, check.IsNil) 239 240 nJSON := []types.NetworkResource{} 241 err = json.Unmarshal(body, &nJSON) 242 c.Assert(err, check.IsNil) 243 c.Assert(len(nJSON), check.Equals, 1) 244 245 return nJSON[0].ID 246 } 247 248 func getNetworkResource(c *check.C, id string) *types.NetworkResource { 249 _, obj, err := sockRequest("GET", "/networks/"+id, nil) 250 c.Assert(err, check.IsNil) 251 252 nr := types.NetworkResource{} 253 err = json.Unmarshal(obj, &nr) 254 c.Assert(err, check.IsNil) 255 256 return &nr 257 } 258 259 func createNetwork(c *check.C, config types.NetworkCreate, shouldSucceed bool) string { 260 status, resp, err := sockRequest("POST", "/networks/create", config) 261 if !shouldSucceed { 262 c.Assert(status, check.Not(check.Equals), http.StatusCreated) 263 return "" 264 } 265 266 c.Assert(status, check.Equals, http.StatusCreated) 267 c.Assert(err, check.IsNil) 268 269 var nr types.NetworkCreateResponse 270 err = json.Unmarshal(resp, &nr) 271 c.Assert(err, check.IsNil) 272 273 return nr.ID 274 } 275 276 func connectNetwork(c *check.C, nid, cid string) { 277 config := types.NetworkConnect{ 278 Container: cid, 279 } 280 281 status, _, err := sockRequest("POST", "/networks/"+nid+"/connect", config) 282 c.Assert(status, check.Equals, http.StatusOK) 283 c.Assert(err, check.IsNil) 284 } 285 286 func disconnectNetwork(c *check.C, nid, cid string) { 287 config := types.NetworkConnect{ 288 Container: cid, 289 } 290 291 status, _, err := sockRequest("POST", "/networks/"+nid+"/disconnect", config) 292 c.Assert(status, check.Equals, http.StatusOK) 293 c.Assert(err, check.IsNil) 294 } 295 296 func deleteNetwork(c *check.C, id string, shouldSucceed bool) { 297 status, _, err := sockRequest("DELETE", "/networks/"+id, nil) 298 if !shouldSucceed { 299 c.Assert(status, check.Not(check.Equals), http.StatusOK) 300 return 301 } 302 c.Assert(status, check.Equals, http.StatusOK) 303 c.Assert(err, check.IsNil) 304 }