mirror of
https://github.com/goharbor/harbor
synced 2024-09-21 10:48:26 +00:00
Merge pull request #8159 from ywk253100/190627_label_filter
Update replication label filter
This commit is contained in:
commit
8bb18e73d2
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -105,8 +105,8 @@ func TestValidOfPolicy(t *testing.T) {
|
||||||
Value: ResourceTypeImage,
|
Value: ResourceTypeImage,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Type: FilterTypeName,
|
Type: FilterTypeTag,
|
||||||
Value: "a[",
|
Value: "",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue
Block a user