github.com/fabiokung/docker@v0.11.2-0.20170222101415-4534dcd49497/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/api/types/filters" 13 "github.com/docker/docker/api/types/network" 14 "github.com/docker/docker/integration-cli/checker" 15 "github.com/docker/docker/integration-cli/request" 16 "github.com/go-check/check" 17 ) 18 19 func (s *DockerSuite) TestAPINetworkGetDefaults(c *check.C) { 20 testRequires(c, DaemonIsLinux) 21 // By default docker daemon creates 3 networks. check if they are present 22 defaults := []string{"bridge", "host", "none"} 23 for _, nn := range defaults { 24 c.Assert(isNetworkAvailable(c, nn), checker.Equals, true) 25 } 26 } 27 28 func (s *DockerSuite) TestAPINetworkCreateDelete(c *check.C) { 29 testRequires(c, DaemonIsLinux) 30 // Create a network 31 name := "testnetwork" 32 config := types.NetworkCreateRequest{ 33 Name: name, 34 NetworkCreate: types.NetworkCreate{ 35 CheckDuplicate: true, 36 }, 37 } 38 id := createNetwork(c, config, true) 39 c.Assert(isNetworkAvailable(c, name), checker.Equals, true) 40 41 // delete the network and make sure it is deleted 42 deleteNetwork(c, id, true) 43 c.Assert(isNetworkAvailable(c, name), checker.Equals, false) 44 } 45 46 func (s *DockerSuite) TestAPINetworkCreateCheckDuplicate(c *check.C) { 47 testRequires(c, DaemonIsLinux) 48 name := "testcheckduplicate" 49 configOnCheck := types.NetworkCreateRequest{ 50 Name: name, 51 NetworkCreate: types.NetworkCreate{ 52 CheckDuplicate: true, 53 }, 54 } 55 configNotCheck := types.NetworkCreateRequest{ 56 Name: name, 57 NetworkCreate: types.NetworkCreate{ 58 CheckDuplicate: false, 59 }, 60 } 61 62 // Creating a new network first 63 createNetwork(c, configOnCheck, true) 64 c.Assert(isNetworkAvailable(c, name), checker.Equals, true) 65 66 // Creating another network with same name and CheckDuplicate must fail 67 createNetwork(c, configOnCheck, false) 68 69 // Creating another network with same name and not CheckDuplicate must succeed 70 createNetwork(c, configNotCheck, true) 71 } 72 73 func (s *DockerSuite) TestAPINetworkFilter(c *check.C) { 74 testRequires(c, DaemonIsLinux) 75 nr := getNetworkResource(c, getNetworkIDByName(c, "bridge")) 76 c.Assert(nr.Name, checker.Equals, "bridge") 77 } 78 79 func (s *DockerSuite) TestAPINetworkInspect(c *check.C) { 80 testRequires(c, DaemonIsLinux) 81 // Inspect default bridge network 82 nr := getNetworkResource(c, "bridge") 83 c.Assert(nr.Name, checker.Equals, "bridge") 84 85 // run a container and attach it to the default bridge network 86 out, _ := dockerCmd(c, "run", "-d", "--name", "test", "busybox", "top") 87 containerID := strings.TrimSpace(out) 88 containerIP := findContainerIP(c, "test", "bridge") 89 90 // inspect default bridge network again and make sure the container is connected 91 nr = getNetworkResource(c, nr.ID) 92 c.Assert(nr.Driver, checker.Equals, "bridge") 93 c.Assert(nr.Scope, checker.Equals, "local") 94 c.Assert(nr.Internal, checker.Equals, false) 95 c.Assert(nr.EnableIPv6, checker.Equals, false) 96 c.Assert(nr.IPAM.Driver, checker.Equals, "default") 97 c.Assert(len(nr.Containers), checker.Equals, 1) 98 c.Assert(nr.Containers[containerID], checker.NotNil) 99 100 ip, _, err := net.ParseCIDR(nr.Containers[containerID].IPv4Address) 101 c.Assert(err, checker.IsNil) 102 c.Assert(ip.String(), checker.Equals, containerIP) 103 104 // IPAM configuration inspect 105 ipam := &network.IPAM{ 106 Driver: "default", 107 Config: []network.IPAMConfig{{Subnet: "172.28.0.0/16", IPRange: "172.28.5.0/24", Gateway: "172.28.5.254"}}, 108 } 109 config := types.NetworkCreateRequest{ 110 Name: "br0", 111 NetworkCreate: types.NetworkCreate{ 112 Driver: "bridge", 113 IPAM: ipam, 114 Options: map[string]string{"foo": "bar", "opts": "dopts"}, 115 }, 116 } 117 id0 := createNetwork(c, config, true) 118 c.Assert(isNetworkAvailable(c, "br0"), checker.Equals, true) 119 120 nr = getNetworkResource(c, id0) 121 c.Assert(len(nr.IPAM.Config), checker.Equals, 1) 122 c.Assert(nr.IPAM.Config[0].Subnet, checker.Equals, "172.28.0.0/16") 123 c.Assert(nr.IPAM.Config[0].IPRange, checker.Equals, "172.28.5.0/24") 124 c.Assert(nr.IPAM.Config[0].Gateway, checker.Equals, "172.28.5.254") 125 c.Assert(nr.Options["foo"], checker.Equals, "bar") 126 c.Assert(nr.Options["opts"], checker.Equals, "dopts") 127 128 // delete the network and make sure it is deleted 129 deleteNetwork(c, id0, true) 130 c.Assert(isNetworkAvailable(c, "br0"), checker.Equals, false) 131 } 132 133 func (s *DockerSuite) TestAPINetworkConnectDisconnect(c *check.C) { 134 testRequires(c, DaemonIsLinux) 135 // Create test network 136 name := "testnetwork" 137 config := types.NetworkCreateRequest{ 138 Name: name, 139 } 140 id := createNetwork(c, config, true) 141 nr := getNetworkResource(c, id) 142 c.Assert(nr.Name, checker.Equals, name) 143 c.Assert(nr.ID, checker.Equals, id) 144 c.Assert(len(nr.Containers), checker.Equals, 0) 145 146 // run a container 147 out, _ := dockerCmd(c, "run", "-d", "--name", "test", "busybox", "top") 148 containerID := strings.TrimSpace(out) 149 150 // connect the container to the test network 151 connectNetwork(c, nr.ID, containerID) 152 153 // inspect the network to make sure container is connected 154 nr = getNetworkResource(c, nr.ID) 155 c.Assert(len(nr.Containers), checker.Equals, 1) 156 c.Assert(nr.Containers[containerID], checker.NotNil) 157 158 // check if container IP matches network inspect 159 ip, _, err := net.ParseCIDR(nr.Containers[containerID].IPv4Address) 160 c.Assert(err, checker.IsNil) 161 containerIP := findContainerIP(c, "test", "testnetwork") 162 c.Assert(ip.String(), checker.Equals, containerIP) 163 164 // disconnect container from the network 165 disconnectNetwork(c, nr.ID, containerID) 166 nr = getNetworkResource(c, nr.ID) 167 c.Assert(nr.Name, checker.Equals, name) 168 c.Assert(len(nr.Containers), checker.Equals, 0) 169 170 // delete the network 171 deleteNetwork(c, nr.ID, true) 172 } 173 174 func (s *DockerSuite) TestAPINetworkIPAMMultipleBridgeNetworks(c *check.C) { 175 testRequires(c, DaemonIsLinux) 176 // test0 bridge network 177 ipam0 := &network.IPAM{ 178 Driver: "default", 179 Config: []network.IPAMConfig{{Subnet: "192.178.0.0/16", IPRange: "192.178.128.0/17", Gateway: "192.178.138.100"}}, 180 } 181 config0 := types.NetworkCreateRequest{ 182 Name: "test0", 183 NetworkCreate: types.NetworkCreate{ 184 Driver: "bridge", 185 IPAM: ipam0, 186 }, 187 } 188 id0 := createNetwork(c, config0, true) 189 c.Assert(isNetworkAvailable(c, "test0"), checker.Equals, true) 190 191 ipam1 := &network.IPAM{ 192 Driver: "default", 193 Config: []network.IPAMConfig{{Subnet: "192.178.128.0/17", Gateway: "192.178.128.1"}}, 194 } 195 // test1 bridge network overlaps with test0 196 config1 := types.NetworkCreateRequest{ 197 Name: "test1", 198 NetworkCreate: types.NetworkCreate{ 199 Driver: "bridge", 200 IPAM: ipam1, 201 }, 202 } 203 createNetwork(c, config1, false) 204 c.Assert(isNetworkAvailable(c, "test1"), checker.Equals, false) 205 206 ipam2 := &network.IPAM{ 207 Driver: "default", 208 Config: []network.IPAMConfig{{Subnet: "192.169.0.0/16", Gateway: "192.169.100.100"}}, 209 } 210 // test2 bridge network does not overlap 211 config2 := types.NetworkCreateRequest{ 212 Name: "test2", 213 NetworkCreate: types.NetworkCreate{ 214 Driver: "bridge", 215 IPAM: ipam2, 216 }, 217 } 218 createNetwork(c, config2, true) 219 c.Assert(isNetworkAvailable(c, "test2"), checker.Equals, true) 220 221 // remove test0 and retry to create test1 222 deleteNetwork(c, id0, true) 223 createNetwork(c, config1, true) 224 c.Assert(isNetworkAvailable(c, "test1"), checker.Equals, true) 225 226 // for networks w/o ipam specified, docker will choose proper non-overlapping subnets 227 createNetwork(c, types.NetworkCreateRequest{Name: "test3"}, true) 228 c.Assert(isNetworkAvailable(c, "test3"), checker.Equals, true) 229 createNetwork(c, types.NetworkCreateRequest{Name: "test4"}, true) 230 c.Assert(isNetworkAvailable(c, "test4"), checker.Equals, true) 231 createNetwork(c, types.NetworkCreateRequest{Name: "test5"}, true) 232 c.Assert(isNetworkAvailable(c, "test5"), checker.Equals, true) 233 234 for i := 1; i < 6; i++ { 235 deleteNetwork(c, fmt.Sprintf("test%d", i), true) 236 } 237 } 238 239 func (s *DockerSuite) TestAPICreateDeletePredefinedNetworks(c *check.C) { 240 testRequires(c, DaemonIsLinux) 241 createDeletePredefinedNetwork(c, "bridge") 242 createDeletePredefinedNetwork(c, "none") 243 createDeletePredefinedNetwork(c, "host") 244 } 245 246 func createDeletePredefinedNetwork(c *check.C, name string) { 247 // Create pre-defined network 248 config := types.NetworkCreateRequest{ 249 Name: name, 250 NetworkCreate: types.NetworkCreate{ 251 CheckDuplicate: true, 252 }, 253 } 254 shouldSucceed := false 255 createNetwork(c, config, shouldSucceed) 256 deleteNetwork(c, name, shouldSucceed) 257 } 258 259 func isNetworkAvailable(c *check.C, name string) bool { 260 resp, body, err := request.Get(daemonHost(), "/networks") 261 c.Assert(err, checker.IsNil) 262 defer resp.Body.Close() 263 c.Assert(resp.StatusCode, checker.Equals, http.StatusOK) 264 265 nJSON := []types.NetworkResource{} 266 err = json.NewDecoder(body).Decode(&nJSON) 267 c.Assert(err, checker.IsNil) 268 269 for _, n := range nJSON { 270 if n.Name == name { 271 return true 272 } 273 } 274 return false 275 } 276 277 func getNetworkIDByName(c *check.C, name string) string { 278 var ( 279 v = url.Values{} 280 filterArgs = filters.NewArgs() 281 ) 282 filterArgs.Add("name", name) 283 filterJSON, err := filters.ToParam(filterArgs) 284 c.Assert(err, checker.IsNil) 285 v.Set("filters", filterJSON) 286 287 resp, body, err := request.Get(daemonHost(), "/networks?"+v.Encode()) 288 c.Assert(resp.StatusCode, checker.Equals, http.StatusOK) 289 c.Assert(err, checker.IsNil) 290 291 nJSON := []types.NetworkResource{} 292 err = json.NewDecoder(body).Decode(&nJSON) 293 c.Assert(err, checker.IsNil) 294 c.Assert(len(nJSON), checker.Equals, 1) 295 296 return nJSON[0].ID 297 } 298 299 func getNetworkResource(c *check.C, id string) *types.NetworkResource { 300 _, obj, err := request.Get(daemonHost(), "/networks/"+id) 301 c.Assert(err, checker.IsNil) 302 303 nr := types.NetworkResource{} 304 err = json.NewDecoder(obj).Decode(&nr) 305 c.Assert(err, checker.IsNil) 306 307 return &nr 308 } 309 310 func createNetwork(c *check.C, config types.NetworkCreateRequest, shouldSucceed bool) string { 311 resp, body, err := request.Post(daemonHost(), "/networks/create", request.JSONBody(config)) 312 c.Assert(err, checker.IsNil) 313 defer resp.Body.Close() 314 if !shouldSucceed { 315 c.Assert(resp.StatusCode, checker.Not(checker.Equals), http.StatusCreated) 316 return "" 317 } 318 319 c.Assert(resp.StatusCode, checker.Equals, http.StatusCreated) 320 321 var nr types.NetworkCreateResponse 322 err = json.NewDecoder(body).Decode(&nr) 323 c.Assert(err, checker.IsNil) 324 325 return nr.ID 326 } 327 328 func connectNetwork(c *check.C, nid, cid string) { 329 config := types.NetworkConnect{ 330 Container: cid, 331 } 332 333 resp, _, err := request.Post(daemonHost(), "/networks/"+nid+"/connect", request.JSONBody(config)) 334 c.Assert(resp.StatusCode, checker.Equals, http.StatusOK) 335 c.Assert(err, checker.IsNil) 336 } 337 338 func disconnectNetwork(c *check.C, nid, cid string) { 339 config := types.NetworkConnect{ 340 Container: cid, 341 } 342 343 resp, _, err := request.Post(daemonHost(), "/networks/"+nid+"/disconnect", request.JSONBody(config)) 344 c.Assert(resp.StatusCode, checker.Equals, http.StatusOK) 345 c.Assert(err, checker.IsNil) 346 } 347 348 func deleteNetwork(c *check.C, id string, shouldSucceed bool) { 349 resp, _, err := request.Delete(daemonHost(), "/networks/"+id) 350 c.Assert(err, checker.IsNil) 351 defer resp.Body.Close() 352 if !shouldSucceed { 353 c.Assert(resp.StatusCode, checker.Not(checker.Equals), http.StatusOK) 354 return 355 } 356 c.Assert(resp.StatusCode, checker.Equals, http.StatusNoContent) 357 }