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