Merge pull request #8159 from ywk253100/190627_label_filter

Update replication label filter
This commit is contained in:
Steven Zou 2019-07-03 13:08:54 +08:00 committed by GitHub
commit 8bb18e73d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 53 additions and 23 deletions

View File

@ -72,9 +72,9 @@ func NewVTagNameFilter(pattern string) Filter {
} }
// NewVTagLabelFilter return a Filter to filter vtags according to the label // NewVTagLabelFilter return a Filter to filter vtags according to the label
func NewVTagLabelFilter(label string) Filter { func NewVTagLabelFilter(labels []string) Filter {
return &labelFilter{ return &labelFilter{
label: label, labels: labels,
} }
} }
@ -138,7 +138,7 @@ func (n *nameFilter) Filter(filterables ...Filterable) ([]Filterable, error) {
} }
type labelFilter struct { type labelFilter struct {
label string labels []string
} }
func (l *labelFilter) ApplyTo(filterable Filterable) bool { func (l *labelFilter) ApplyTo(filterable Filterable) bool {
@ -154,18 +154,24 @@ func (l *labelFilter) ApplyTo(filterable Filterable) bool {
func (l *labelFilter) Filter(filterables ...Filterable) ([]Filterable, error) { func (l *labelFilter) Filter(filterables ...Filterable) ([]Filterable, error) {
// if no specified label in the filter, just returns the input filterable // if no specified label in the filter, just returns the input filterable
// candidate as the result // candidate as the result
if len(l.label) == 0 { if len(l.labels) == 0 {
return filterables, nil return filterables, nil
} }
result := []Filterable{} result := []Filterable{}
for _, filterable := range filterables { for _, filterable := range filterables {
match := false labels := map[string]struct{}{}
for _, label := range filterable.GetLabels() { for _, label := range filterable.GetLabels() {
if label == l.label { labels[label] = struct{}{}
match = true }
match := true
for _, label := range l.labels {
if _, exist := labels[label]; !exist {
match = false
break break
} }
} }
// add the filterable to the result list if it contains
// all labels defined for the filter
if match { if match {
result = append(result, filterable) result = append(result, filterable)
} }

View File

@ -120,7 +120,7 @@ func TestFilterOfLabelFilter(t *testing.T) {
} }
// pass the filter // pass the filter
filter := &labelFilter{ filter := &labelFilter{
label: "production", labels: []string{"production"},
} }
result, err := filter.Filter(filterable) result, err := filter.Filter(filterable)
require.Nil(t, err) require.Nil(t, err)
@ -128,7 +128,7 @@ func TestFilterOfLabelFilter(t *testing.T) {
assert.True(t, reflect.DeepEqual(filterable, result[0].(*fakeFilterable))) assert.True(t, reflect.DeepEqual(filterable, result[0].(*fakeFilterable)))
} }
// cannot pass the filter // cannot pass the filter
filter.label = "cannotpass" filter.labels = []string{"production", "ci-pass"}
result, err = filter.Filter(filterable) result, err = filter.Filter(filterable)
require.Nil(t, err) require.Nil(t, err)
assert.Equal(t, 0, len(result)) assert.Equal(t, 0, len(result))
@ -160,7 +160,7 @@ func TestDoFilter(t *testing.T) {
filterables := []Filterable{tag1, tag2} filterables := []Filterable{tag1, tag2}
filters := []Filter{ filters := []Filter{
NewVTagNameFilter("*"), NewVTagNameFilter("*"),
NewVTagLabelFilter("production"), NewVTagLabelFilter([]string{"production"}),
} }
err := DoFilter(&filterables, filters...) err := DoFilter(&filterables, filters...)
require.Nil(t, err) require.Nil(t, err)

View File

@ -88,19 +88,33 @@ func (p *Policy) Valid(v *validation.Validation) {
// valid the filters // valid the filters
for _, filter := range p.Filters { for _, filter := range p.Filters {
value, ok := filter.Value.(string)
if !ok {
v.SetError("filters", "the type of filter value isn't string")
break
}
switch filter.Type { switch filter.Type {
case FilterTypeResource: case FilterTypeResource, FilterTypeName, FilterTypeTag:
rt := ResourceType(value) value, ok := filter.Value.(string)
if !(rt == ResourceTypeImage || rt == ResourceTypeChart) { if !ok {
v.SetError("filters", fmt.Sprintf("invalid resource filter: %s", value)) v.SetError("filters", "the type of filter value isn't string")
break break
} }
case FilterTypeName, FilterTypeTag, FilterTypeLabel: if filter.Type == FilterTypeResource {
rt := ResourceType(value)
if !(rt == ResourceTypeImage || rt == ResourceTypeChart) {
v.SetError("filters", fmt.Sprintf("invalid resource filter: %s", value))
break
}
}
case FilterTypeLabel:
labels, ok := filter.Value.([]interface{})
if !ok {
v.SetError("filters", "the type of label filter value isn't string slice")
break
}
for _, label := range labels {
_, ok := label.(string)
if !ok {
v.SetError("filters", "the type of label filter value isn't string slice")
break
}
}
default: default:
v.SetError("filters", "invalid filter type") v.SetError("filters", "invalid filter type")
break break
@ -148,7 +162,10 @@ func (f *Filter) DoFilter(filterables interface{}) error {
case FilterTypeTag: case FilterTypeTag:
ft = filter.NewVTagNameFilter(f.Value.(string)) ft = filter.NewVTagNameFilter(f.Value.(string))
case FilterTypeLabel: case FilterTypeLabel:
ft = filter.NewVTagLabelFilter(f.Value.(string)) labels, ok := f.Value.([]string)
if ok {
ft = filter.NewVTagLabelFilter(labels)
}
case FilterTypeResource: case FilterTypeResource:
ft = filter.NewResourceTypeFilter(f.Value.(string)) ft = filter.NewResourceTypeFilter(f.Value.(string))
default: default:

View File

@ -105,8 +105,8 @@ func TestValidOfPolicy(t *testing.T) {
Value: ResourceTypeImage, Value: ResourceTypeImage,
}, },
{ {
Type: FilterTypeName, Type: FilterTypeTag,
Value: "a[", Value: "",
}, },
}, },
}, },

View File

@ -271,6 +271,13 @@ func parseFilters(str string) ([]*model.Filter, error) {
if filter.Type == model.FilterTypeResource { if filter.Type == model.FilterTypeResource {
filter.Value = (model.ResourceType)(filter.Value.(string)) filter.Value = (model.ResourceType)(filter.Value.(string))
} }
if filter.Type == model.FilterTypeLabel {
labels := []string{}
for _, label := range filter.Value.([]interface{}) {
labels = append(labels, label.(string))
}
filter.Value = labels
}
filters = append(filters, filter) filters = append(filters, filter)
} }
return filters, nil return filters, nil