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