mirror of
https://github.com/goharbor/harbor.git
synced 2025-01-16 04:31:22 +01:00
Update replication label filter
Support specify multiple labels in one label filter Signed-off-by: Wenkai Yin <yinw@vmware.com>
This commit is contained in:
parent
108b9284a5
commit
6ba2ace0a6
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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:
|
||||
|
@ -105,8 +105,8 @@ func TestValidOfPolicy(t *testing.T) {
|
||||
Value: ResourceTypeImage,
|
||||
},
|
||||
{
|
||||
Type: FilterTypeName,
|
||||
Value: "a[",
|
||||
Type: FilterTypeTag,
|
||||
Value: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user