Network: add support for 'dangling' filter
Like its counterpart in images and volumes, introduce the dangling filter while listing networks. When the filter value is set to true, only networks which aren't attached to containers and aren't builtin networks are shown. When set to false, all builtin networks and networks which are attached to containers are shown. Signed-off-by: Karthik Nayak <Karthik.188@gmail.com>
This commit is contained in:
parent
8d7889e510
commit
131cbaf5b7
3 changed files with 90 additions and 8 deletions
|
@ -112,12 +112,13 @@ type ConfigReference struct {
|
|||
}
|
||||
|
||||
var acceptedFilters = map[string]bool{
|
||||
"driver": true,
|
||||
"type": true,
|
||||
"name": true,
|
||||
"id": true,
|
||||
"label": true,
|
||||
"scope": true,
|
||||
"driver": true,
|
||||
"type": true,
|
||||
"name": true,
|
||||
"id": true,
|
||||
"label": true,
|
||||
"scope": true,
|
||||
"dangling": true,
|
||||
}
|
||||
|
||||
// ValidateFilters validates the list of filter args with the available filters.
|
||||
|
|
|
@ -3,6 +3,7 @@ package network // import "github.com/docker/docker/daemon/network"
|
|||
import (
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
"github.com/docker/docker/errdefs"
|
||||
"github.com/docker/docker/runconfig"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
@ -51,6 +52,24 @@ func FilterNetworks(nws []types.NetworkResource, filter filters.Args) ([]types.N
|
|||
displayNet = append(displayNet, nw)
|
||||
}
|
||||
|
||||
if values := filter.Get("dangling"); len(values) > 0 {
|
||||
if len(values) > 1 {
|
||||
return nil, errdefs.InvalidParameter(errors.New(`got more than one value for filter key "dangling"`))
|
||||
}
|
||||
|
||||
var danglingOnly bool
|
||||
switch values[0] {
|
||||
case "0", "false":
|
||||
// dangling is false already
|
||||
case "1", "true":
|
||||
danglingOnly = true
|
||||
default:
|
||||
return nil, errdefs.InvalidParameter(errors.New(`invalid value for filter 'dangling', must be "true" (or "1"), or "false" (or "0")`))
|
||||
}
|
||||
|
||||
displayNet = filterNetworkByUse(displayNet, danglingOnly)
|
||||
}
|
||||
|
||||
if filter.Contains("type") {
|
||||
typeNet := []types.NetworkResource{}
|
||||
errFilter := filter.WalkValues("type", func(fval string) error {
|
||||
|
@ -70,6 +89,25 @@ func FilterNetworks(nws []types.NetworkResource, filter filters.Args) ([]types.N
|
|||
return displayNet, nil
|
||||
}
|
||||
|
||||
func filterNetworkByUse(nws []types.NetworkResource, danglingOnly bool) []types.NetworkResource {
|
||||
retNws := []types.NetworkResource{}
|
||||
|
||||
filterFunc := func(nw types.NetworkResource) bool {
|
||||
if danglingOnly {
|
||||
return !runconfig.IsPreDefinedNetwork(nw.Name) && len(nw.Containers) == 0 && len(nw.Services) == 0
|
||||
}
|
||||
return runconfig.IsPreDefinedNetwork(nw.Name) || len(nw.Containers) > 0 || len(nw.Services) > 0
|
||||
}
|
||||
|
||||
for _, nw := range nws {
|
||||
if filterFunc(nw) {
|
||||
retNws = append(retNws, nw)
|
||||
}
|
||||
}
|
||||
|
||||
return retNws
|
||||
}
|
||||
|
||||
func filterNetworkByType(nws []types.NetworkResource, netType string) ([]types.NetworkResource, error) {
|
||||
retNws := []types.NetworkResource{}
|
||||
switch netType {
|
||||
|
|
|
@ -42,6 +42,16 @@ func TestFilterNetworks(t *testing.T) {
|
|||
Driver: "mykvdriver",
|
||||
Scope: "global",
|
||||
},
|
||||
{
|
||||
Name: "networkwithcontainer",
|
||||
Driver: "nwc",
|
||||
Scope: "local",
|
||||
Containers: map[string]types.EndpointResource{
|
||||
"customcontainer": {
|
||||
Name: "customendpoint",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
bridgeDriverFilters := filters.NewArgs()
|
||||
|
@ -71,11 +81,18 @@ func TestFilterNetworks(t *testing.T) {
|
|||
globalScopeFilters := filters.NewArgs()
|
||||
globalScopeFilters.Add("scope", "global")
|
||||
|
||||
trueDanglingFilters := filters.NewArgs()
|
||||
trueDanglingFilters.Add("dangling", "true")
|
||||
|
||||
falseDanglingFilters := filters.NewArgs()
|
||||
falseDanglingFilters.Add("dangling", "false")
|
||||
|
||||
testCases := []struct {
|
||||
filter filters.Args
|
||||
resultCount int
|
||||
err string
|
||||
name string
|
||||
results []string
|
||||
}{
|
||||
{
|
||||
filter: bridgeDriverFilters,
|
||||
|
@ -97,7 +114,7 @@ func TestFilterNetworks(t *testing.T) {
|
|||
},
|
||||
{
|
||||
filter: customDriverFilters,
|
||||
resultCount: 3,
|
||||
resultCount: 4,
|
||||
err: "",
|
||||
name: "custom driver filters",
|
||||
},
|
||||
|
@ -115,7 +132,7 @@ func TestFilterNetworks(t *testing.T) {
|
|||
},
|
||||
{
|
||||
filter: localScopeFilters,
|
||||
resultCount: 4,
|
||||
resultCount: 5,
|
||||
err: "",
|
||||
name: "local scope filters",
|
||||
},
|
||||
|
@ -131,6 +148,20 @@ func TestFilterNetworks(t *testing.T) {
|
|||
err: "",
|
||||
name: "global scope filters",
|
||||
},
|
||||
{
|
||||
filter: trueDanglingFilters,
|
||||
resultCount: 3,
|
||||
err: "",
|
||||
name: "dangling filter is 'True'",
|
||||
results: []string{"myoverlay", "mydrivernet", "mykvnet"},
|
||||
},
|
||||
{
|
||||
filter: falseDanglingFilters,
|
||||
resultCount: 4,
|
||||
err: "",
|
||||
name: "dangling filter is 'False'",
|
||||
results: []string{"host", "bridge", "none", "networkwithcontainer"},
|
||||
},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
|
@ -157,6 +188,18 @@ func TestFilterNetworks(t *testing.T) {
|
|||
if len(result) != testCase.resultCount {
|
||||
t.Fatalf("expect '%d' networks, got '%d' networks", testCase.resultCount, len(result))
|
||||
}
|
||||
|
||||
if len(testCase.results) > 0 {
|
||||
resultMap := make(map[string]bool)
|
||||
for _, r := range result {
|
||||
resultMap[r.Name] = true
|
||||
}
|
||||
for _, r := range testCase.results {
|
||||
if _, ok := resultMap[r]; !ok {
|
||||
t.Fatalf("expected result: '%s' not found", r)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue