mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Merge pull request #21495 from HackToday/addnetworkfilter
Add network label filter support
This commit is contained in:
commit
75cc2c926b
6 changed files with 195 additions and 149 deletions
|
@ -2,8 +2,6 @@ package network
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"regexp"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/docker/docker/runconfig"
|
"github.com/docker/docker/runconfig"
|
||||||
"github.com/docker/engine-api/types/filters"
|
"github.com/docker/engine-api/types/filters"
|
||||||
|
@ -13,27 +11,13 @@ import (
|
||||||
type filterHandler func([]libnetwork.Network, string) ([]libnetwork.Network, error)
|
type filterHandler func([]libnetwork.Network, string) ([]libnetwork.Network, error)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// supportedFilters predefined some supported filter handler function
|
// AcceptedFilters is an acceptable filters for validation
|
||||||
supportedFilters = map[string]filterHandler{
|
AcceptedFilters = map[string]bool{
|
||||||
"type": filterNetworkByType,
|
"type": true,
|
||||||
"name": filterNetworkByName,
|
"name": true,
|
||||||
"id": filterNetworkByID,
|
"id": true,
|
||||||
|
"label": true,
|
||||||
}
|
}
|
||||||
|
|
||||||
// AcceptedFilters is an acceptable filter flag list
|
|
||||||
// generated for validation. e.g.
|
|
||||||
// acceptedFilters = map[string]bool{
|
|
||||||
// "type": true,
|
|
||||||
// "name": true,
|
|
||||||
// "id": true,
|
|
||||||
// }
|
|
||||||
AcceptedFilters = func() map[string]bool {
|
|
||||||
ret := make(map[string]bool)
|
|
||||||
for k := range supportedFilters {
|
|
||||||
ret[k] = true
|
|
||||||
}
|
|
||||||
return ret
|
|
||||||
}()
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func filterNetworkByType(nws []libnetwork.Network, netType string) (retNws []libnetwork.Network, err error) {
|
func filterNetworkByType(nws []libnetwork.Network, netType string) (retNws []libnetwork.Network, err error) {
|
||||||
|
@ -56,34 +40,6 @@ func filterNetworkByType(nws []libnetwork.Network, netType string) (retNws []lib
|
||||||
return retNws, nil
|
return retNws, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func filterNetworkByName(nws []libnetwork.Network, name string) (retNws []libnetwork.Network, err error) {
|
|
||||||
for _, nw := range nws {
|
|
||||||
// exact match (fast path)
|
|
||||||
if nw.Name() == name {
|
|
||||||
retNws = append(retNws, nw)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// regexp match (slow path)
|
|
||||||
match, err := regexp.MatchString(name, nw.Name())
|
|
||||||
if err != nil || !match {
|
|
||||||
continue
|
|
||||||
} else {
|
|
||||||
retNws = append(retNws, nw)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return retNws, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func filterNetworkByID(nws []libnetwork.Network, id string) (retNws []libnetwork.Network, err error) {
|
|
||||||
for _, nw := range nws {
|
|
||||||
if strings.HasPrefix(nw.ID(), id) {
|
|
||||||
retNws = append(retNws, nw)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return retNws, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// FilterNetworks filters network list according to user specified filter
|
// FilterNetworks filters network list according to user specified filter
|
||||||
// and returns user chosen networks
|
// and returns user chosen networks
|
||||||
func FilterNetworks(nws []libnetwork.Network, filter filters.Args) ([]libnetwork.Network, error) {
|
func FilterNetworks(nws []libnetwork.Network, filter filters.Args) ([]libnetwork.Network, error) {
|
||||||
|
@ -93,18 +49,40 @@ func FilterNetworks(nws []libnetwork.Network, filter filters.Args) ([]libnetwork
|
||||||
}
|
}
|
||||||
|
|
||||||
var displayNet []libnetwork.Network
|
var displayNet []libnetwork.Network
|
||||||
for fkey, fhandler := range supportedFilters {
|
for _, nw := range nws {
|
||||||
errFilter := filter.WalkValues(fkey, func(fval string) error {
|
if filter.Include("name") {
|
||||||
passList, err := fhandler(nws, fval)
|
if !filter.Match("name", nw.Name()) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if filter.Include("id") {
|
||||||
|
if !filter.Match("id", nw.ID()) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if filter.Include("label") {
|
||||||
|
if !filter.MatchKVList("label", nw.Info().Labels()) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
displayNet = append(displayNet, nw)
|
||||||
|
}
|
||||||
|
|
||||||
|
if filter.Include("type") {
|
||||||
|
var typeNet []libnetwork.Network
|
||||||
|
errFilter := filter.WalkValues("type", func(fval string) error {
|
||||||
|
passList, err := filterNetworkByType(displayNet, fval)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
displayNet = append(displayNet, passList...)
|
typeNet = append(typeNet, passList...)
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
if errFilter != nil {
|
if errFilter != nil {
|
||||||
return nil, errFilter
|
return nil, errFilter
|
||||||
}
|
}
|
||||||
|
displayNet = typeNet
|
||||||
}
|
}
|
||||||
|
|
||||||
return displayNet, nil
|
return displayNet, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,6 +118,7 @@ This section lists each version from latest to oldest. Each listing includes a
|
||||||
|
|
||||||
* `POST /containers/create` now takes `StorageOpt` field.
|
* `POST /containers/create` now takes `StorageOpt` field.
|
||||||
* `GET /info` now returns `SecurityOptions` field, showing if `apparmor`, `seccomp`, or `selinux` is supported.
|
* `GET /info` now returns `SecurityOptions` field, showing if `apparmor`, `seccomp`, or `selinux` is supported.
|
||||||
|
* `GET /networks` now supports filtering by `label`.
|
||||||
|
|
||||||
### v1.23 API changes
|
### v1.23 API changes
|
||||||
|
|
||||||
|
|
|
@ -2961,8 +2961,9 @@ Content-Type: application/json
|
||||||
Query Parameters:
|
Query Parameters:
|
||||||
|
|
||||||
- **filters** - JSON encoded network list filter. The filter value is one of:
|
- **filters** - JSON encoded network list filter. The filter value is one of:
|
||||||
- `name=<network-name>` Matches all or part of a network name.
|
|
||||||
- `id=<network-id>` Matches all or part of a network id.
|
- `id=<network-id>` Matches all or part of a network id.
|
||||||
|
- `label=<key>` or `label=<key>=<value>` of a network label.
|
||||||
|
- `name=<network-name>` Matches all or part of a network name.
|
||||||
- `type=["custom"|"builtin"]` Filters networks by type. The `custom` keyword returns all user-defined networks.
|
- `type=["custom"|"builtin"]` Filters networks by type. The `custom` keyword returns all user-defined networks.
|
||||||
|
|
||||||
Status Codes:
|
Status Codes:
|
||||||
|
|
|
@ -52,54 +52,10 @@ Multiple filter flags are combined as an `OR` filter. For example,
|
||||||
The currently supported filters are:
|
The currently supported filters are:
|
||||||
|
|
||||||
* id (network's id)
|
* id (network's id)
|
||||||
|
* label (`label=<key>` or `label=<key>=<value>`)
|
||||||
* name (network's name)
|
* name (network's name)
|
||||||
* type (custom|builtin)
|
* type (custom|builtin)
|
||||||
|
|
||||||
#### Type
|
|
||||||
|
|
||||||
The `type` filter supports two values; `builtin` displays predefined networks
|
|
||||||
(`bridge`, `none`, `host`), whereas `custom` displays user defined networks.
|
|
||||||
|
|
||||||
The following filter matches all user defined networks:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ docker network ls --filter type=custom
|
|
||||||
NETWORK ID NAME DRIVER
|
|
||||||
95e74588f40d foo bridge
|
|
||||||
63d1ff1f77b0 dev bridge
|
|
||||||
```
|
|
||||||
|
|
||||||
By having this flag it allows for batch cleanup. For example, use this filter
|
|
||||||
to delete all user defined networks:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ docker network rm `docker network ls --filter type=custom -q`
|
|
||||||
```
|
|
||||||
|
|
||||||
A warning will be issued when trying to remove a network that has containers
|
|
||||||
attached.
|
|
||||||
|
|
||||||
#### Name
|
|
||||||
|
|
||||||
The `name` filter matches on all or part of a network's name.
|
|
||||||
|
|
||||||
The following filter matches all networks with a name containing the `foobar` string.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ docker network ls --filter name=foobar
|
|
||||||
NETWORK ID NAME DRIVER
|
|
||||||
06e7eef0a170 foobar bridge
|
|
||||||
```
|
|
||||||
|
|
||||||
You can also filter for a substring in a name as this shows:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ docker network ls --filter name=foo
|
|
||||||
NETWORK ID NAME DRIVER
|
|
||||||
95e74588f40d foo bridge
|
|
||||||
06e7eef0a170 foobar bridge
|
|
||||||
```
|
|
||||||
|
|
||||||
#### ID
|
#### ID
|
||||||
|
|
||||||
The `id` filter matches on all or part of a network's ID.
|
The `id` filter matches on all or part of a network's ID.
|
||||||
|
@ -125,6 +81,73 @@ NETWORK ID NAME DRIVER
|
||||||
95e74588f40d foo bridge
|
95e74588f40d foo bridge
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Label
|
||||||
|
|
||||||
|
The `label` filter matches containers based on the presence of a `label` alone or a `label` and a
|
||||||
|
value.
|
||||||
|
|
||||||
|
The following filter matches networks with the `usage` label regardless of its value.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ docker network ls -f "label=usage"
|
||||||
|
NETWORK ID NAME DRIVER
|
||||||
|
db9db329f835 test1 bridge
|
||||||
|
f6e212da9dfd test2 bridge
|
||||||
|
```
|
||||||
|
|
||||||
|
The following filter matches containers with the `usage` label with the `prod` value.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ docker network ls -f "label=usage=prod"
|
||||||
|
NETWORK ID NAME DRIVER
|
||||||
|
f6e212da9dfd test2 bridge
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Name
|
||||||
|
|
||||||
|
The `name` filter matches on all or part of a network's name.
|
||||||
|
|
||||||
|
The following filter matches all networks with a name containing the `foobar` string.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ docker network ls --filter name=foobar
|
||||||
|
NETWORK ID NAME DRIVER
|
||||||
|
06e7eef0a170 foobar bridge
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also filter for a substring in a name as this shows:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ docker network ls --filter name=foo
|
||||||
|
NETWORK ID NAME DRIVER
|
||||||
|
95e74588f40d foo bridge
|
||||||
|
06e7eef0a170 foobar bridge
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Type
|
||||||
|
|
||||||
|
The `type` filter supports two values; `builtin` displays predefined networks
|
||||||
|
(`bridge`, `none`, `host`), whereas `custom` displays user defined networks.
|
||||||
|
|
||||||
|
The following filter matches all user defined networks:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ docker network ls --filter type=custom
|
||||||
|
NETWORK ID NAME DRIVER
|
||||||
|
95e74588f40d foo bridge
|
||||||
|
63d1ff1f77b0 dev bridge
|
||||||
|
```
|
||||||
|
|
||||||
|
By having this flag it allows for batch cleanup. For example, use this filter
|
||||||
|
to delete all user defined networks:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ docker network rm `docker network ls --filter type=custom -q`
|
||||||
|
```
|
||||||
|
|
||||||
|
A warning will be issued when trying to remove a network that has containers
|
||||||
|
attached.
|
||||||
|
|
||||||
## Related information
|
## Related information
|
||||||
|
|
||||||
* [network disconnect ](network_disconnect.md)
|
* [network disconnect ](network_disconnect.md)
|
||||||
|
|
|
@ -309,16 +309,23 @@ func (s *DockerNetworkSuite) TestDockerNetworkRmPredefined(c *check.C) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DockerNetworkSuite) TestDockerNetworkLsFilter(c *check.C) {
|
func (s *DockerNetworkSuite) TestDockerNetworkLsFilter(c *check.C) {
|
||||||
|
testNet := "testnet1"
|
||||||
|
testLabel := "foo"
|
||||||
|
testValue := "bar"
|
||||||
out, _ := dockerCmd(c, "network", "create", "dev")
|
out, _ := dockerCmd(c, "network", "create", "dev")
|
||||||
defer func() {
|
defer func() {
|
||||||
dockerCmd(c, "network", "rm", "dev")
|
dockerCmd(c, "network", "rm", "dev")
|
||||||
|
dockerCmd(c, "network", "rm", testNet)
|
||||||
}()
|
}()
|
||||||
networkID := strings.TrimSpace(out)
|
networkID := strings.TrimSpace(out)
|
||||||
|
|
||||||
// filter with partial ID and partial name
|
// filter with partial ID
|
||||||
// only show 'bridge' and 'dev' network
|
// only show 'dev' network
|
||||||
out, _ = dockerCmd(c, "network", "ls", "-f", "id="+networkID[0:5], "-f", "name=dge")
|
out, _ = dockerCmd(c, "network", "ls", "-f", "id="+networkID[0:5])
|
||||||
assertNwList(c, out, []string{"bridge", "dev"})
|
assertNwList(c, out, []string{"dev"})
|
||||||
|
|
||||||
|
out, _ = dockerCmd(c, "network", "ls", "-f", "name=dge")
|
||||||
|
assertNwList(c, out, []string{"bridge"})
|
||||||
|
|
||||||
// only show built-in network (bridge, none, host)
|
// only show built-in network (bridge, none, host)
|
||||||
out, _ = dockerCmd(c, "network", "ls", "-f", "type=builtin")
|
out, _ = dockerCmd(c, "network", "ls", "-f", "type=builtin")
|
||||||
|
@ -332,6 +339,19 @@ func (s *DockerNetworkSuite) TestDockerNetworkLsFilter(c *check.C) {
|
||||||
// it should be equivalent of ls without option
|
// it should be equivalent of ls without option
|
||||||
out, _ = dockerCmd(c, "network", "ls", "-f", "type=custom", "-f", "type=builtin")
|
out, _ = dockerCmd(c, "network", "ls", "-f", "type=custom", "-f", "type=builtin")
|
||||||
assertNwList(c, out, []string{"bridge", "dev", "host", "none"})
|
assertNwList(c, out, []string{"bridge", "dev", "host", "none"})
|
||||||
|
|
||||||
|
out, _ = dockerCmd(c, "network", "create", "--label", testLabel+"="+testValue, testNet)
|
||||||
|
assertNwIsAvailable(c, testNet)
|
||||||
|
|
||||||
|
out, _ = dockerCmd(c, "network", "ls", "-f", "label="+testLabel)
|
||||||
|
assertNwList(c, out, []string{testNet})
|
||||||
|
|
||||||
|
out, _ = dockerCmd(c, "network", "ls", "-f", "label="+testLabel+"="+testValue)
|
||||||
|
assertNwList(c, out, []string{testNet})
|
||||||
|
|
||||||
|
out, _ = dockerCmd(c, "network", "ls", "-f", "label=nonexistent")
|
||||||
|
outArr := strings.Split(strings.TrimSpace(out), "\n")
|
||||||
|
c.Assert(len(outArr), check.Equals, 1, check.Commentf("%s\n", out))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DockerNetworkSuite) TestDockerNetworkCreateDelete(c *check.C) {
|
func (s *DockerNetworkSuite) TestDockerNetworkCreateDelete(c *check.C) {
|
||||||
|
|
|
@ -47,54 +47,10 @@ Multiple filter flags are combined as an `OR` filter. For example,
|
||||||
The currently supported filters are:
|
The currently supported filters are:
|
||||||
|
|
||||||
* id (network's id)
|
* id (network's id)
|
||||||
|
* label (`label=<key>` or `label=<key>=<value>`)
|
||||||
* name (network's name)
|
* name (network's name)
|
||||||
* type (custom|builtin)
|
* type (custom|builtin)
|
||||||
|
|
||||||
#### Type
|
|
||||||
|
|
||||||
The `type` filter supports two values; `builtin` displays predefined networks
|
|
||||||
(`bridge`, `none`, `host`), whereas `custom` displays user defined networks.
|
|
||||||
|
|
||||||
The following filter matches all user defined networks:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ docker network ls --filter type=custom
|
|
||||||
NETWORK ID NAME DRIVER
|
|
||||||
95e74588f40d foo bridge
|
|
||||||
63d1ff1f77b0 dev bridge
|
|
||||||
```
|
|
||||||
|
|
||||||
By having this flag it allows for batch cleanup. For example, use this filter
|
|
||||||
to delete all user defined networks:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ docker network rm `docker network ls --filter type=custom -q`
|
|
||||||
```
|
|
||||||
|
|
||||||
A warning will be issued when trying to remove a network that has containers
|
|
||||||
attached.
|
|
||||||
|
|
||||||
#### Name
|
|
||||||
|
|
||||||
The `name` filter matches on all or part of a network's name.
|
|
||||||
|
|
||||||
The following filter matches all networks with a name containing the `foobar` string.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ docker network ls --filter name=foobar
|
|
||||||
NETWORK ID NAME DRIVER
|
|
||||||
06e7eef0a170 foobar bridge
|
|
||||||
```
|
|
||||||
|
|
||||||
You can also filter for a substring in a name as this shows:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ docker network ls --filter name=foo
|
|
||||||
NETWORK ID NAME DRIVER
|
|
||||||
95e74588f40d foo bridge
|
|
||||||
06e7eef0a170 foobar bridge
|
|
||||||
```
|
|
||||||
|
|
||||||
#### ID
|
#### ID
|
||||||
|
|
||||||
The `id` filter matches on all or part of a network's ID.
|
The `id` filter matches on all or part of a network's ID.
|
||||||
|
@ -120,6 +76,73 @@ NETWORK ID NAME DRIVER
|
||||||
95e74588f40d foo bridge
|
95e74588f40d foo bridge
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Label
|
||||||
|
|
||||||
|
The `label` filter matches containers based on the presence of a `label` alone or a `label` and a
|
||||||
|
value.
|
||||||
|
|
||||||
|
The following filter matches networks with the `usage` label regardless of its value.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ docker network ls -f "label=usage"
|
||||||
|
NETWORK ID NAME DRIVER
|
||||||
|
db9db329f835 test1 bridge
|
||||||
|
f6e212da9dfd test2 bridge
|
||||||
|
```
|
||||||
|
|
||||||
|
The following filter matches containers with the `usage` label with the `prod` value.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ docker network ls -f "label=usage=prod"
|
||||||
|
NETWORK ID NAME DRIVER
|
||||||
|
f6e212da9dfd test2 bridge
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Name
|
||||||
|
|
||||||
|
The `name` filter matches on all or part of a network's name.
|
||||||
|
|
||||||
|
The following filter matches all networks with a name containing the `foobar` string.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ docker network ls --filter name=foobar
|
||||||
|
NETWORK ID NAME DRIVER
|
||||||
|
06e7eef0a170 foobar bridge
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also filter for a substring in a name as this shows:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ docker network ls --filter name=foo
|
||||||
|
NETWORK ID NAME DRIVER
|
||||||
|
95e74588f40d foo bridge
|
||||||
|
06e7eef0a170 foobar bridge
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Type
|
||||||
|
|
||||||
|
The `type` filter supports two values; `builtin` displays predefined networks
|
||||||
|
(`bridge`, `none`, `host`), whereas `custom` displays user defined networks.
|
||||||
|
|
||||||
|
The following filter matches all user defined networks:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ docker network ls --filter type=custom
|
||||||
|
NETWORK ID NAME DRIVER
|
||||||
|
95e74588f40d foo bridge
|
||||||
|
63d1ff1f77b0 dev bridge
|
||||||
|
```
|
||||||
|
|
||||||
|
By having this flag it allows for batch cleanup. For example, use this filter
|
||||||
|
to delete all user defined networks:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ docker network rm `docker network ls --filter type=custom -q`
|
||||||
|
```
|
||||||
|
|
||||||
|
A warning will be issued when trying to remove a network that has containers
|
||||||
|
attached.
|
||||||
|
|
||||||
# OPTIONS
|
# OPTIONS
|
||||||
|
|
||||||
**-f**, **--filter**=*[]*
|
**-f**, **--filter**=*[]*
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue