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
func NewVTagLabelFilter(label string) Filter {
func NewVTagLabelFilter(labels []string) Filter {
return &labelFilter{
label: label,
labels: labels,
}
}
@ -138,7 +138,7 @@ func (n *nameFilter) Filter(filterables ...Filterable) ([]Filterable, error) {
}
type labelFilter struct {
label string
labels []string
}
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) {
// if no specified label in the filter, just returns the input filterable
// candidate as the result
if len(l.label) == 0 {
if len(l.labels) == 0 {
return filterables, nil
}
result := []Filterable{}
for _, filterable := range filterables {
match := false
labels := map[string]struct{}{}
for _, label := range filterable.GetLabels() {
if label == l.label {
match = true
labels[label] = struct{}{}
}
match := true
for _, label := range l.labels {
if _, exist := labels[label]; !exist {
match = false
break
}
}
// add the filterable to the result list if it contains
// all labels defined for the filter
if match {
result = append(result, filterable)
}

View File

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

View File

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

View File

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

View File

@ -271,6 +271,13 @@ func parseFilters(str string) ([]*model.Filter, error) {
if filter.Type == model.FilterTypeResource {
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)
}
return filters, nil