mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Add Subnets info for user-defined network
* If user doesn't specify the subnets to create a network, it will pick subnets from inside preferred pool. This PR aims to inspect these subnets info * Add integration tests for docker inspect the subnets. * docker-py project is already synchronized. * jenkins checks depend on https://github.com/docker/docker-py/pull/888 Fixes issue #18626 Signed-off-by: Wen Cheng Ma <wenchma@cn.ibm.com>
This commit is contained in:
parent
954613fb24
commit
5cc672b006
8 changed files with 169 additions and 34 deletions
|
@ -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 {
|
||||
|
|
|
@ -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/<network-id>` now returns subnets info for user-defined networks.
|
||||
|
||||
### v1.21 API changes
|
||||
|
||||
|
|
|
@ -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": ""
|
||||
}
|
||||
},
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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": ""
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Add table
Reference in a new issue