filter.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. package network // import "github.com/docker/docker/daemon/network"
  2. import (
  3. "github.com/docker/docker/api/types"
  4. "github.com/docker/docker/api/types/filters"
  5. "github.com/docker/docker/errdefs"
  6. "github.com/docker/docker/runconfig"
  7. "github.com/pkg/errors"
  8. )
  9. // FilterNetworks filters network list according to user specified filter
  10. // and returns user chosen networks
  11. func FilterNetworks(nws []types.NetworkResource, filter filters.Args) ([]types.NetworkResource, error) {
  12. // if filter is empty, return original network list
  13. if filter.Len() == 0 {
  14. return nws, nil
  15. }
  16. displayNet := nws[:0]
  17. for _, nw := range nws {
  18. if filter.Contains("driver") {
  19. if !filter.ExactMatch("driver", nw.Driver) {
  20. continue
  21. }
  22. }
  23. if filter.Contains("name") {
  24. if !filter.Match("name", nw.Name) {
  25. continue
  26. }
  27. }
  28. if filter.Contains("id") {
  29. if !filter.Match("id", nw.ID) {
  30. continue
  31. }
  32. }
  33. if filter.Contains("label") {
  34. if !filter.MatchKVList("label", nw.Labels) {
  35. continue
  36. }
  37. }
  38. if filter.Contains("scope") {
  39. if !filter.ExactMatch("scope", nw.Scope) {
  40. continue
  41. }
  42. }
  43. if filter.Contains("idOrName") {
  44. if !filter.Match("name", nw.Name) && !filter.Match("id", nw.Name) {
  45. continue
  46. }
  47. }
  48. displayNet = append(displayNet, nw)
  49. }
  50. if values := filter.Get("dangling"); len(values) > 0 {
  51. if len(values) > 1 {
  52. return nil, errdefs.InvalidParameter(errors.New(`got more than one value for filter key "dangling"`))
  53. }
  54. var danglingOnly bool
  55. switch values[0] {
  56. case "0", "false":
  57. // dangling is false already
  58. case "1", "true":
  59. danglingOnly = true
  60. default:
  61. return nil, errdefs.InvalidParameter(errors.New(`invalid value for filter 'dangling', must be "true" (or "1"), or "false" (or "0")`))
  62. }
  63. displayNet = filterNetworkByUse(displayNet, danglingOnly)
  64. }
  65. if filter.Contains("type") {
  66. typeNet := []types.NetworkResource{}
  67. errFilter := filter.WalkValues("type", func(fval string) error {
  68. passList, err := filterNetworkByType(displayNet, fval)
  69. if err != nil {
  70. return err
  71. }
  72. typeNet = append(typeNet, passList...)
  73. return nil
  74. })
  75. if errFilter != nil {
  76. return nil, errFilter
  77. }
  78. displayNet = typeNet
  79. }
  80. return displayNet, nil
  81. }
  82. func filterNetworkByUse(nws []types.NetworkResource, danglingOnly bool) []types.NetworkResource {
  83. retNws := []types.NetworkResource{}
  84. filterFunc := func(nw types.NetworkResource) bool {
  85. if danglingOnly {
  86. return !runconfig.IsPreDefinedNetwork(nw.Name) && len(nw.Containers) == 0 && len(nw.Services) == 0
  87. }
  88. return runconfig.IsPreDefinedNetwork(nw.Name) || len(nw.Containers) > 0 || len(nw.Services) > 0
  89. }
  90. for _, nw := range nws {
  91. if filterFunc(nw) {
  92. retNws = append(retNws, nw)
  93. }
  94. }
  95. return retNws
  96. }
  97. func filterNetworkByType(nws []types.NetworkResource, netType string) ([]types.NetworkResource, error) {
  98. retNws := []types.NetworkResource{}
  99. switch netType {
  100. case "builtin":
  101. for _, nw := range nws {
  102. if runconfig.IsPreDefinedNetwork(nw.Name) {
  103. retNws = append(retNws, nw)
  104. }
  105. }
  106. case "custom":
  107. for _, nw := range nws {
  108. if !runconfig.IsPreDefinedNetwork(nw.Name) {
  109. retNws = append(retNws, nw)
  110. }
  111. }
  112. default:
  113. return nil, errors.Errorf("invalid filter: 'type'='%s'", netType)
  114. }
  115. return retNws, nil
  116. }