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