diff options
author | Jakub Guzik <jakubmguzik@gmail.com> | 2021-03-23 00:13:44 +0100 |
---|---|---|
committer | Matthew Heon <mheon@redhat.com> | 2021-03-29 13:26:18 -0400 |
commit | 183a68a817208821a9fc79a3c9c19202a63dfb44 (patch) | |
tree | bd56722c15906e77fa210ac446da6a63213b2279 /pkg | |
parent | d1589f280474dd90236a59f8b32bb2a4a04fd683 (diff) | |
download | podman-183a68a817208821a9fc79a3c9c19202a63dfb44.tar.gz podman-183a68a817208821a9fc79a3c9c19202a63dfb44.tar.bz2 podman-183a68a817208821a9fc79a3c9c19202a63dfb44.zip |
Unification of label filter across list/prune endpoints
Signed-off-by: Jakub Guzik <jakubmguzik@gmail.com>
Diffstat (limited to 'pkg')
-rw-r--r-- | pkg/domain/filters/containers.go | 22 | ||||
-rw-r--r-- | pkg/domain/filters/pods.go | 21 | ||||
-rw-r--r-- | pkg/domain/filters/volumes.go | 17 | ||||
-rw-r--r-- | pkg/util/filters.go | 23 | ||||
-rw-r--r-- | pkg/util/filters_test.go | 77 |
5 files changed, 104 insertions, 56 deletions
diff --git a/pkg/domain/filters/containers.go b/pkg/domain/filters/containers.go index 02727e841..9cae01dc0 100644 --- a/pkg/domain/filters/containers.go +++ b/pkg/domain/filters/containers.go @@ -23,27 +23,7 @@ func GenerateContainerFilterFuncs(filter string, filterValues []string, r *libpo case "label": // we have to match that all given labels exits on that container return func(c *libpod.Container) bool { - labels := c.Labels() - for _, filterValue := range filterValues { - matched := false - filterArray := strings.SplitN(filterValue, "=", 2) - filterKey := filterArray[0] - if len(filterArray) > 1 { - filterValue = filterArray[1] - } else { - filterValue = "" - } - for labelKey, labelValue := range labels { - if labelKey == filterKey && (filterValue == "" || labelValue == filterValue) { - matched = true - break - } - } - if !matched { - return false - } - } - return true + return util.MatchLabelFilters(filterValues, c.Labels()) }, nil case "name": // we only have to match one name diff --git a/pkg/domain/filters/pods.go b/pkg/domain/filters/pods.go index 0490a4848..9a1c7d19d 100644 --- a/pkg/domain/filters/pods.go +++ b/pkg/domain/filters/pods.go @@ -114,26 +114,7 @@ func GeneratePodFilterFunc(filter string, filterValues []string) ( case "label": return func(p *libpod.Pod) bool { labels := p.Labels() - for _, filterValue := range filterValues { - matched := false - filterArray := strings.SplitN(filterValue, "=", 2) - filterKey := filterArray[0] - if len(filterArray) > 1 { - filterValue = filterArray[1] - } else { - filterValue = "" - } - for labelKey, labelValue := range labels { - if labelKey == filterKey && (filterValue == "" || labelValue == filterValue) { - matched = true - break - } - } - if !matched { - return false - } - } - return true + return util.MatchLabelFilters(filterValues, labels) }, nil case "network": return func(p *libpod.Pod) bool { diff --git a/pkg/domain/filters/volumes.go b/pkg/domain/filters/volumes.go index bc1756cf5..9b2fc5280 100644 --- a/pkg/domain/filters/volumes.go +++ b/pkg/domain/filters/volumes.go @@ -5,6 +5,7 @@ import ( "strings" "github.com/containers/podman/v3/libpod" + "github.com/containers/podman/v3/pkg/util" "github.com/pkg/errors" ) @@ -29,21 +30,9 @@ func GenerateVolumeFilters(filters url.Values) ([]libpod.VolumeFilter, error) { return v.Scope() == scopeVal }) case "label": - filterArray := strings.SplitN(val, "=", 2) - filterKey := filterArray[0] - var filterVal string - if len(filterArray) > 1 { - filterVal = filterArray[1] - } else { - filterVal = "" - } + filter := val vf = append(vf, func(v *libpod.Volume) bool { - for labelKey, labelValue := range v.Labels() { - if labelKey == filterKey && (filterVal == "" || labelValue == filterVal) { - return true - } - } - return false + return util.MatchLabelFilters([]string{filter}, v.Labels()) }) case "opt": filterArray := strings.SplitN(val, "=", 2) diff --git a/pkg/util/filters.go b/pkg/util/filters.go index 51b2c5331..90daef402 100644 --- a/pkg/util/filters.go +++ b/pkg/util/filters.go @@ -11,7 +11,7 @@ import ( "github.com/pkg/errors" ) -// ComputeUntilTimestamp extracts unitil timestamp from filters +// ComputeUntilTimestamp extracts until timestamp from filters func ComputeUntilTimestamp(filter string, filterValues []string) (time.Time, error) { invalid := time.Time{} if len(filterValues) != 1 { @@ -93,3 +93,24 @@ func PrepareFilters(r *http.Request) (*map[string][]string, error) { } return &filterMap, nil } + +// MatchLabelFilters matches labels and returs true if they are valid +func MatchLabelFilters(filterValues []string, labels map[string]string) bool { +outer: + for _, filterValue := range filterValues { + filterArray := strings.SplitN(filterValue, "=", 2) + filterKey := filterArray[0] + if len(filterArray) > 1 { + filterValue = filterArray[1] + } else { + filterValue = "" + } + for labelKey, labelValue := range labels { + if labelKey == filterKey && (filterValue == "" || labelValue == filterValue) { + continue outer + } + } + return false + } + return true +} diff --git a/pkg/util/filters_test.go b/pkg/util/filters_test.go new file mode 100644 index 000000000..4771f682b --- /dev/null +++ b/pkg/util/filters_test.go @@ -0,0 +1,77 @@ +package util + +import "testing" + +func TestMatchLabelFilters(t *testing.T) { + testLabels := map[string]string{ + "label1": "", + "label2": "test", + "label3": "", + } + type args struct { + filterValues []string + labels map[string]string + } + tests := []struct { + name string + args args + want bool + }{ + { + name: "Match when all filters the same as labels", + args: args{ + filterValues: []string{"label1", "label3", "label2=test"}, + labels: testLabels, + }, + want: true, + }, + { + name: "Match when filter value not provided in args", + args: args{ + filterValues: []string{"label2"}, + labels: testLabels, + }, + want: true, + }, + { + name: "Match when no filter value is given", + args: args{ + filterValues: []string{"label2="}, + labels: testLabels, + }, + want: true, + }, + { + name: "Do not match when filter value differs", + args: args{ + filterValues: []string{"label2=differs"}, + labels: testLabels, + }, + want: false, + }, + { + name: "Do not match when filter value not listed in labels", + args: args{ + filterValues: []string{"label1=xyz"}, + labels: testLabels, + }, + want: false, + }, + { + name: "Do not match when one from many not ok", + args: args{ + filterValues: []string{"label1=xyz", "invalid=valid"}, + labels: testLabels, + }, + want: false, + }, + } + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + if got := MatchLabelFilters(tt.args.filterValues, tt.args.labels); got != tt.want { + t.Errorf("MatchLabelFilters() = %v, want %v", got, tt.want) + } + }) + } +} |