Add filter for network ls to hide predefined net
Add filter support for `network ls` to hide predefined network, then user can use "docker network rm `docker network ls -f type=custom`" to delete a bundle of userdefined networks. Signed-off-by: Zhang Wei <zhangwei555@huawei.com> Upstream-commit: 26dd026bd70c9c18a16b0e339821c309e56d8ff0 Component: engine
This commit is contained in:
@ -12,6 +12,7 @@ type Backend interface {
|
||||
FindNetwork(idName string) (libnetwork.Network, error)
|
||||
GetNetwork(idName string, by int) (libnetwork.Network, error)
|
||||
GetNetworksByID(partialID string) []libnetwork.Network
|
||||
GetAllNetworks() []libnetwork.Network
|
||||
CreateNetwork(name, driver string, ipam network.IPAM,
|
||||
options map[string]string) (libnetwork.Network, error)
|
||||
ConnectContainerToNetwork(containerName, networkName string) error
|
||||
|
||||
110
components/engine/api/server/router/network/filter.go
Normal file
110
components/engine/api/server/router/network/filter.go
Normal file
@ -0,0 +1,110 @@
|
||||
package network
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
"github.com/docker/docker/runconfig"
|
||||
"github.com/docker/libnetwork"
|
||||
)
|
||||
|
||||
type filterHandler func([]libnetwork.Network, string) ([]libnetwork.Network, error)
|
||||
|
||||
var (
|
||||
// supportedFilters predefined some supported filter handler function
|
||||
supportedFilters = map[string]filterHandler{
|
||||
"type": filterNetworkByType,
|
||||
"name": filterNetworkByName,
|
||||
"id": filterNetworkByID,
|
||||
}
|
||||
|
||||
// acceptFilters 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) {
|
||||
switch netType {
|
||||
case "builtin":
|
||||
for _, nw := range nws {
|
||||
if runconfig.IsPreDefinedNetwork(nw.Name()) {
|
||||
retNws = append(retNws, nw)
|
||||
}
|
||||
}
|
||||
case "custom":
|
||||
for _, nw := range nws {
|
||||
if !runconfig.IsPreDefinedNetwork(nw.Name()) {
|
||||
retNws = append(retNws, nw)
|
||||
}
|
||||
}
|
||||
default:
|
||||
return nil, fmt.Errorf("Invalid filter: 'type'='%s'", netType)
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
// filterAllNetworks filter network list according to user specified filter
|
||||
// and return user chosen networks
|
||||
func filterNetworks(nws []libnetwork.Network, filter filters.Args) ([]libnetwork.Network, error) {
|
||||
// if filter is empty, return original network list
|
||||
if filter.Len() == 0 {
|
||||
return nws, nil
|
||||
}
|
||||
|
||||
var displayNet []libnetwork.Network
|
||||
for fkey, fhandler := range supportedFilters {
|
||||
errFilter := filter.WalkValues(fkey, func(fval string) error {
|
||||
passList, err := fhandler(nws, fval)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
displayNet = append(displayNet, passList...)
|
||||
return nil
|
||||
})
|
||||
if errFilter != nil {
|
||||
return nil, errFilter
|
||||
}
|
||||
}
|
||||
return displayNet, nil
|
||||
}
|
||||
@ -7,7 +7,6 @@ import (
|
||||
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/docker/docker/api/server/httputils"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
@ -28,29 +27,24 @@ func (n *networkRouter) getNetworksList(ctx context.Context, w http.ResponseWrit
|
||||
return err
|
||||
}
|
||||
|
||||
list := []*types.NetworkResource{}
|
||||
netFilters.WalkValues("name", func(name string) error {
|
||||
if nw, err := n.backend.GetNetwork(name, daemon.NetworkByName); err == nil {
|
||||
list = append(list, buildNetworkResource(nw))
|
||||
} else {
|
||||
logrus.Errorf("failed to get network for filter=%s : %v", name, err)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
netFilters.WalkValues("id", func(id string) error {
|
||||
for _, nw := range n.backend.GetNetworksByID(id) {
|
||||
list = append(list, buildNetworkResource(nw))
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
if !netFilters.Include("name") && !netFilters.Include("id") {
|
||||
nwList := n.backend.GetNetworksByID("")
|
||||
for _, nw := range nwList {
|
||||
list = append(list, buildNetworkResource(nw))
|
||||
if netFilters.Len() != 0 {
|
||||
if err := netFilters.Validate(acceptedFilters); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
list := []*types.NetworkResource{}
|
||||
|
||||
nwList := n.backend.GetAllNetworks()
|
||||
displayable, err := filterNetworks(nwList, netFilters)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, nw := range displayable {
|
||||
list = append(list, buildNetworkResource(nw))
|
||||
}
|
||||
|
||||
return httputils.WriteJSON(w, http.StatusOK, list)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user