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