diff --git a/api/server/router/network/network_routes.go b/api/server/router/network/network_routes.go index e436cf314a..85fa88db00 100644 --- a/api/server/router/network/network_routes.go +++ b/api/server/router/network/network_routes.go @@ -184,12 +184,17 @@ func buildNetworkResource(nw libnetwork.Network) *types.NetworkResource { func buildIpamResources(r *types.NetworkResource, nw libnetwork.Network) { id, opts, ipv4conf, ipv6conf := nw.Info().IpamConfig() + ipv4Info, ipv6Info := nw.Info().IpamInfo() + r.IPAM.Driver = id r.IPAM.Options = opts r.IPAM.Config = []network.IPAMConfig{} for _, ip4 := range ipv4conf { + if ip4.PreferredPool == "" { + continue + } iData := network.IPAMConfig{} iData.Subnet = ip4.PreferredPool iData.IPRange = ip4.SubPool @@ -198,7 +203,21 @@ func buildIpamResources(r *types.NetworkResource, nw libnetwork.Network) { r.IPAM.Config = append(r.IPAM.Config, iData) } + if len(r.IPAM.Config) == 0 { + for _, ip4Info := range ipv4Info { + iData := network.IPAMConfig{} + iData.Subnet = ip4Info.IPAMData.Pool.String() + iData.Gateway = ip4Info.IPAMData.Gateway.String() + r.IPAM.Config = append(r.IPAM.Config, iData) + } + } + + hasIpv6Conf := false for _, ip6 := range ipv6conf { + if ip6.PreferredPool == "" { + continue + } + hasIpv6Conf = true iData := network.IPAMConfig{} iData.Subnet = ip6.PreferredPool iData.IPRange = ip6.SubPool @@ -206,6 +225,15 @@ func buildIpamResources(r *types.NetworkResource, nw libnetwork.Network) { iData.AuxAddress = ip6.AuxAddresses r.IPAM.Config = append(r.IPAM.Config, iData) } + + if !hasIpv6Conf { + for _, ip6Info := range ipv6Info { + iData := network.IPAMConfig{} + iData.Subnet = ip6Info.IPAMData.Pool.String() + iData.Gateway = ip6Info.IPAMData.Gateway.String() + r.IPAM.Config = append(r.IPAM.Config, iData) + } + } } func buildEndpointResource(e libnetwork.Endpoint) types.EndpointResource { diff --git a/docs/reference/api/docker_remote_api.md b/docs/reference/api/docker_remote_api.md index 81ed415615..a7d8fdb240 100644 --- a/docs/reference/api/docker_remote_api.md +++ b/docs/reference/api/docker_remote_api.md @@ -121,6 +121,7 @@ This section lists each version from latest to oldest. Each listing includes a for custom IPAM plugins. * `GET /networks/{network-id}` Now returns IPAM config options for custom IPAM plugins if any are available. +* `GET /networks/` now returns subnets info for user-defined networks. ### v1.21 API changes diff --git a/docs/reference/api/docker_remote_api_v1.22.md b/docs/reference/api/docker_remote_api_v1.22.md index 067c7006dc..d523b95449 100644 --- a/docs/reference/api/docker_remote_api_v1.22.md +++ b/docs/reference/api/docker_remote_api_v1.22.md @@ -2937,7 +2937,7 @@ Status Codes: **Example request**: - GET /networks/f2de39df4171b0dc801e8002d1d999b77256983dfc63041c0f34030aa3977566 HTTP/1.1 + GET /networks/7d86d31b1478e7cca9ebed7e73aa0fdeec46c5ca29497431d3007d2d9e15ed99 HTTP/1.1 **Example response**: @@ -2946,15 +2946,16 @@ HTTP/1.1 200 OK Content-Type: application/json { - "Name": "bridge", - "Id": "f2de39df4171b0dc801e8002d1d999b77256983dfc63041c0f34030aa3977566", + "Name": "net01", + "Id": "7d86d31b1478e7cca9ebed7e73aa0fdeec46c5ca29497431d3007d2d9e15ed99", "Scope": "local", "Driver": "bridge", "IPAM": { "Driver": "default", "Config": [ { - "Subnet": "172.17.0.0/16" + "Subnet": "172.19.0.0/16", + "Gateway": "172.19.0.1/16" } ], "Options": { @@ -2962,11 +2963,11 @@ Content-Type: application/json } }, "Containers": { - "39b69226f9d79f5634485fb236a23b2fe4e96a0a94128390a7fbbcc167065867": { - "Name": "mad_mclean", - "EndpointID": "ed2419a97c1d9954d05b46e462e7002ea552f216e9b136b80a7db8d98b442eda", - "MacAddress": "02:42:ac:11:00:02", - "IPv4Address": "172.17.0.2/16", + "19a4d5d687db25203351ed79d478946f861258f018fe384f229f2efa4b23513c": { + "Name": "test", + "EndpointID": "628cadb8bcb92de107b2a1e516cbffe463e321f548feb37697cce00ad694f21a", + "MacAddress": "02:42:ac:13:00:02", + "IPv4Address": "172.19.0.2/16", "IPv6Address": "" } }, diff --git a/docs/reference/commandline/network_inspect.md b/docs/reference/commandline/network_inspect.md index 00b886d766..9e0d87fa29 100644 --- a/docs/reference/commandline/network_inspect.md +++ b/docs/reference/commandline/network_inspect.md @@ -17,7 +17,7 @@ parent = "smn_cli" -f, --format= Format the output using the given go template. --help Print usage -Returns information about one or more networks. By default, this command renders all results in a JSON object. For example, if you connect two containers to a network: +Returns information about one or more networks. By default, this command renders all results in a JSON object. For example, if you connect two containers to the default `bridge` network: ```bash $ sudo docker run -itd --name=container1 busybox @@ -78,6 +78,32 @@ $ sudo docker network inspect bridge ] ``` +Returns the information about the user-defined network: + +```bash +$ docker network create simple-network +69568e6336d8c96bbf57869030919f7c69524f71183b44d80948bd3927c87f6a +$ docker network inspect simple-network +[ + { + "Name": "simple-network", + "Id": "69568e6336d8c96bbf57869030919f7c69524f71183b44d80948bd3927c87f6a", + "Scope": "local", + "Driver": "bridge", + "IPAM": { + "Driver": "default", + "Config": [ + { + "Subnet": "172.22.0.0/16", + "Gateway": "172.22.0.1/16" + } + ] + }, + "Containers": {}, + "Options": {} + } +] +``` ## Related information diff --git a/docs/userguide/networking/dockernetworks.md b/docs/userguide/networking/dockernetworks.md index 3f8b9a4ff3..6e7688413f 100644 --- a/docs/userguide/networking/dockernetworks.md +++ b/docs/userguide/networking/dockernetworks.md @@ -305,19 +305,22 @@ features and some old features that aren't available. ``` $ docker network create --driver bridge isolated_nw -c5ee82f76de30319c75554a57164c682e7372d2c694fec41e42ac3b77e570f6b +1196a4c5af43a21ae38ef34515b6af19236a3fc48122cf585e3f3054d509679b $ docker network inspect isolated_nw [ { "Name": "isolated_nw", - "Id": "c5ee82f76de30319c75554a57164c682e7372d2c694fec41e42ac3b77e570f6b", + "Id": "1196a4c5af43a21ae38ef34515b6af19236a3fc48122cf585e3f3054d509679b", "Scope": "local", "Driver": "bridge", "IPAM": { "Driver": "default", "Config": [ - {} + { + "Subnet": "172.21.0.0/16", + "Gateway": "172.21.0.1/16" + } ] }, "Containers": {}, @@ -338,13 +341,13 @@ After you create the network, you can launch containers on it using the `docker ``` $ docker run --net=isolated_nw -itd --name=container3 busybox -885b7b4f792bae534416c95caa35ba272f201fa181e18e59beba0c80d7d77c1d +8c1a0a5be480921d669a073393ade66a3fc49933f08bcc5515b37b8144f6d47c $ docker network inspect isolated_nw [ { "Name": "isolated_nw", - "Id": "c5ee82f76de30319c75554a57164c682e7372d2c694fec41e42ac3b77e570f6b", + "Id": "1196a4c5af43a21ae38ef34515b6af19236a3fc48122cf585e3f3054d509679b", "Scope": "local", "Driver": "bridge", "IPAM": { @@ -354,8 +357,8 @@ $ docker network inspect isolated_nw ] }, "Containers": { - "885b7b4f792bae534416c95caa35ba272f201fa181e18e59beba0c80d7d77c1d": { - "EndpointID": "514e1b419074397ea92bcfaa6698d17feb62db49d1320a27393b853ec65319c3", + "8c1a0a5be480921d669a073393ade66a3fc49933f08bcc5515b37b8144f6d47c": { + "EndpointID": "93b2db4a9b9a997beb912d28bcfc117f7b0eb924ff91d48cfa251d473e6a9b08", "MacAddress": "02:42:ac:15:00:02", "IPv4Address": "172.21.0.2/16", "IPv6Address": "" diff --git a/docs/userguide/networking/work-with-networks.md b/docs/userguide/networking/work-with-networks.md index b4dea7d768..d5fac70449 100644 --- a/docs/userguide/networking/work-with-networks.md +++ b/docs/userguide/networking/work-with-networks.md @@ -36,18 +36,21 @@ A `bridge` network resides on a single host running an instance of Docker Engine ```bash $ docker network create simple-network -de792b8258895cf5dc3b43835e9d61a9803500b991654dacb1f4f0546b1c88f8 +69568e6336d8c96bbf57869030919f7c69524f71183b44d80948bd3927c87f6a $ docker network inspect simple-network [ { "Name": "simple-network", - "Id": "de792b8258895cf5dc3b43835e9d61a9803500b991654dacb1f4f0546b1c88f8", + "Id": "69568e6336d8c96bbf57869030919f7c69524f71183b44d80948bd3927c87f6a", "Scope": "local", "Driver": "bridge", "IPAM": { "Driver": "default", "Config": [ - {} + { + "Subnet": "172.22.0.0/16", + "Gateway": "172.22.0.1/16" + } ] }, "Containers": {}, @@ -134,7 +137,8 @@ $ docker network inspect isolated_nw "Driver": "default", "Config": [ { - "Subnet": "172.25.0.0/16" + "Subnet": "172.21.0.0/16", + "Gateway": "172.21.0.1/16" } ] }, @@ -662,7 +666,8 @@ $ docker network inspect isolated_nw "Driver": "default", "Config": [ { - "Subnet": "172.25.0.0/16" + "Subnet": "172.21.0.0/16", + "Gateway": "172.21.0.1/16" } ] }, @@ -746,7 +751,8 @@ docker network inspect isolated_nw "Driver": "default", "Config": [ { - "Subnet": "172.25.0.0/16" + "Subnet": "172.21.0.0/16", + "Gateway": "172.21.0.1/16" } ] }, diff --git a/integration-cli/docker_cli_network_unix_test.go b/integration-cli/docker_cli_network_unix_test.go index 04e0dbe953..d09c2f2917 100644 --- a/integration-cli/docker_cli_network_unix_test.go +++ b/integration-cli/docker_cli_network_unix_test.go @@ -282,11 +282,11 @@ func (s *DockerNetworkSuite) TestDockerNetworkLsFilter(c *check.C) { defer func() { dockerCmd(c, "network", "rm", "dev") }() - containerID := strings.TrimSpace(out) + networkID := strings.TrimSpace(out) // filter with partial ID and partial name // only show 'bridge' and 'dev' network - out, _ = dockerCmd(c, "network", "ls", "-f", "id="+containerID[0:5], "-f", "name=dge") + out, _ = dockerCmd(c, "network", "ls", "-f", "id="+networkID[0:5], "-f", "name=dge") assertNwList(c, out, []string{"dev", "bridge"}) // only show built-in network (bridge, none, host) @@ -324,10 +324,11 @@ func (s *DockerSuite) TestDockerNetworkDeleteMultiple(c *check.C) { dockerCmd(c, "network", "create", "testDelMulti2") assertNwIsAvailable(c, "testDelMulti2") out, _ := dockerCmd(c, "run", "-d", "--net", "testDelMulti2", "busybox", "top") - waitRun(strings.TrimSpace(out)) + containerID := strings.TrimSpace(out) + waitRun(containerID) // delete three networks at the same time, since testDelMulti2 - // contains active container, it's deletion should fail. + // contains active container, its deletion should fail. out, _, err := dockerCmdWithError("network", "rm", "testDelMulti0", "testDelMulti1", "testDelMulti2") // err should not be nil due to deleting testDelMulti2 failed. c.Assert(err, checker.NotNil, check.Commentf("out: %s", out)) @@ -335,7 +336,7 @@ func (s *DockerSuite) TestDockerNetworkDeleteMultiple(c *check.C) { c.Assert(out, checker.Contains, "has active endpoints") assertNwNotAvailable(c, "testDelMulti0") assertNwNotAvailable(c, "testDelMulti1") - // testDelMulti2 can't be deleted, so it should exists + // testDelMulti2 can't be deleted, so it should exist assertNwIsAvailable(c, "testDelMulti2") } @@ -535,8 +536,46 @@ func (s *DockerNetworkSuite) TestDockerNetworkIpamOptions(c *check.C) { c.Assert(opts["opt2"], checker.Equals, "drv2") } -func (s *DockerNetworkSuite) TestDockerNetworkInspect(c *check.C) { - // if unspecified, network gateway will be selected from inside preferred pool +func (s *DockerNetworkSuite) TestDockerNetworkInspectDefault(c *check.C) { + nr := getNetworkResource(c, "none") + c.Assert(nr.Driver, checker.Equals, "null") + c.Assert(nr.Scope, checker.Equals, "local") + c.Assert(nr.IPAM.Driver, checker.Equals, "default") + c.Assert(len(nr.IPAM.Config), checker.Equals, 0) + + nr = getNetworkResource(c, "host") + c.Assert(nr.Driver, checker.Equals, "host") + c.Assert(nr.Scope, checker.Equals, "local") + c.Assert(nr.IPAM.Driver, checker.Equals, "default") + c.Assert(len(nr.IPAM.Config), checker.Equals, 0) + + nr = getNetworkResource(c, "bridge") + c.Assert(nr.Driver, checker.Equals, "bridge") + c.Assert(nr.Scope, checker.Equals, "local") + c.Assert(nr.IPAM.Driver, checker.Equals, "default") + c.Assert(len(nr.IPAM.Config), checker.Equals, 1) + c.Assert(nr.IPAM.Config[0].Subnet, checker.NotNil) + c.Assert(nr.IPAM.Config[0].Gateway, checker.NotNil) +} + +func (s *DockerNetworkSuite) TestDockerNetworkInspectCustomUnspecified(c *check.C) { + // if unspecified, network subnet will be selected from inside preferred pool + dockerCmd(c, "network", "create", "test01") + assertNwIsAvailable(c, "test01") + + nr := getNetworkResource(c, "test01") + c.Assert(nr.Driver, checker.Equals, "bridge") + c.Assert(nr.Scope, checker.Equals, "local") + c.Assert(nr.IPAM.Driver, checker.Equals, "default") + c.Assert(len(nr.IPAM.Config), checker.Equals, 1) + c.Assert(nr.IPAM.Config[0].Subnet, checker.NotNil) + c.Assert(nr.IPAM.Config[0].Gateway, checker.NotNil) + + dockerCmd(c, "network", "rm", "test01") + assertNwNotAvailable(c, "test01") +} + +func (s *DockerNetworkSuite) TestDockerNetworkInspectCustomSpecified(c *check.C) { dockerCmd(c, "network", "create", "--driver=bridge", "--subnet=172.28.0.0/16", "--ip-range=172.28.5.0/24", "--gateway=172.28.5.254", "br0") assertNwIsAvailable(c, "br0") @@ -549,6 +588,7 @@ func (s *DockerNetworkSuite) TestDockerNetworkInspect(c *check.C) { c.Assert(nr.IPAM.Config[0].IPRange, checker.Equals, "172.28.5.0/24") c.Assert(nr.IPAM.Config[0].Gateway, checker.Equals, "172.28.5.254") dockerCmd(c, "network", "rm", "br0") + assertNwNotAvailable(c, "test01") } func (s *DockerNetworkSuite) TestDockerNetworkIpamInvalidCombinations(c *check.C) { @@ -572,6 +612,7 @@ func (s *DockerNetworkSuite) TestDockerNetworkIpamInvalidCombinations(c *check.C _, _, err = dockerCmdWithError("network", "create", "--subnet=192.168.128.0/17", "test1") c.Assert(err, check.NotNil) dockerCmd(c, "network", "rm", "test0") + assertNwNotAvailable(c, "test0") } func (s *DockerNetworkSuite) TestDockerNetworkDriverOptions(c *check.C) { @@ -584,6 +625,7 @@ func (s *DockerNetworkSuite) TestDockerNetworkDriverOptions(c *check.C) { c.Assert(opts["opt1"], checker.Equals, "drv1") c.Assert(opts["opt2"], checker.Equals, "drv2") dockerCmd(c, "network", "rm", "testopt") + assertNwNotAvailable(c, "testopt") } @@ -818,7 +860,7 @@ func connectContainerToNetworks(c *check.C, d *Daemon, cName string, nws []strin out, err := d.Cmd("run", "-d", "--name", cName, "busybox", "top") c.Assert(err, checker.IsNil, check.Commentf(out)) - // Attach the container to other three networks + // Attach the container to other networks for _, nw := range nws { out, err = d.Cmd("network", "create", nw) c.Assert(err, checker.IsNil, check.Commentf(out)) @@ -828,7 +870,7 @@ func connectContainerToNetworks(c *check.C, d *Daemon, cName string, nws []strin } func verifyContainerIsConnectedToNetworks(c *check.C, d *Daemon, cName string, nws []string) { - // Verify container is connected to all three networks + // Verify container is connected to all the networks for _, nw := range nws { out, err := d.Cmd("inspect", "-f", fmt.Sprintf("{{.NetworkSettings.Networks.%s}}", nw), cName) c.Assert(err, checker.IsNil, check.Commentf(out)) @@ -878,7 +920,8 @@ func (s *DockerNetworkSuite) TestDockerNetworkMultipleNetworksUngracefulDaemonRe func (s *DockerNetworkSuite) TestDockerNetworkRunNetByID(c *check.C) { out, _ := dockerCmd(c, "network", "create", "one") - dockerCmd(c, "run", "-d", "--net", strings.TrimSpace(out), "busybox", "top") + containerOut, _, err := dockerCmdWithError("run", "-d", "--net", strings.TrimSpace(out), "busybox", "top") + c.Assert(err, checker.IsNil, check.Commentf(containerOut)) } func (s *DockerNetworkSuite) TestDockerNetworkHostModeUngracefulDaemonRestart(c *check.C) { diff --git a/man/docker-network-inspect.1.md b/man/docker-network-inspect.1.md index 889967ae85..ceba3688fe 100644 --- a/man/docker-network-inspect.1.md +++ b/man/docker-network-inspect.1.md @@ -12,7 +12,7 @@ NETWORK [NETWORK...] # DESCRIPTION -Returns information about one or more networks. By default, this command renders all results in a JSON object. For example, if you connect two containers to a network: +Returns information about one or more networks. By default, this command renders all results in a JSON object. For example, if you connect two containers to the default `bridge` network: ```bash $ sudo docker run -itd --name=container1 busybox @@ -73,6 +73,33 @@ $ sudo docker network inspect bridge ] ``` +Returns the information about the user-defined network: + +```bash +$ docker network create simple-network +69568e6336d8c96bbf57869030919f7c69524f71183b44d80948bd3927c87f6a +$ docker network inspect simple-network +[ + { + "Name": "simple-network", + "Id": "69568e6336d8c96bbf57869030919f7c69524f71183b44d80948bd3927c87f6a", + "Scope": "local", + "Driver": "bridge", + "IPAM": { + "Driver": "default", + "Config": [ + { + "Subnet": "172.22.0.0/16", + "Gateway": "172.22.0.1/16" + } + ] + }, + "Containers": {}, + "Options": {} + } +] +``` + # OPTIONS **-f**, **--format**="" Format the output using the given go template.