diff --git a/pkg/api/errors/validation.go b/pkg/api/errors/validation.go index a3b4eddf8d9..f3431a495df 100644 --- a/pkg/api/errors/validation.go +++ b/pkg/api/errors/validation.go @@ -20,6 +20,8 @@ import ( "fmt" "strings" + "github.com/GoogleCloudPlatform/kubernetes/pkg/util/errors" + "github.com/davecgh/go-spew/spew" "github.com/golang/glog" ) @@ -155,3 +157,37 @@ func (list ValidationErrorList) Prefix(prefix string) ValidationErrorList { func (list ValidationErrorList) PrefixIndex(index int) ValidationErrorList { return list.Prefix(fmt.Sprintf("[%d]", index)) } + +// NewValidationErrorFieldPrefixMatcher returns an errors.Matcher that returns true +// if the provided error is a ValidationError and has the provided ValidationErrorType. +func NewValidationErrorTypeMatcher(t ValidationErrorType) errors.Matcher { + return func(err error) bool { + if e, ok := err.(*ValidationError); ok { + return e.Type == t + } + return false + } +} + +// NewValidationErrorFieldPrefixMatcher returns an errors.Matcher that returns true +// if the provided error is a ValidationError and has a field with the provided +// prefix. +func NewValidationErrorFieldPrefixMatcher(prefix string) errors.Matcher { + return func(err error) bool { + if e, ok := err.(*ValidationError); ok { + return strings.HasPrefix(e.Field, prefix) + } + return false + } +} + +// Filter removes items from the ValidationErrorList that match the provided fns. +func (list ValidationErrorList) Filter(fns ...errors.Matcher) ValidationErrorList { + err := errors.FilterOut(errors.NewAggregate(list), fns...) + if err == nil { + return nil + } + // FilterOut that takes an Aggregate returns an Aggregate + agg := err.(errors.Aggregate) + return ValidationErrorList(agg.Errors()) +} diff --git a/pkg/api/errors/validation_test.go b/pkg/api/errors/validation_test.go index 23fa2c5021d..a312a284954 100644 --- a/pkg/api/errors/validation_test.go +++ b/pkg/api/errors/validation_test.go @@ -93,6 +93,32 @@ func TestValidationErrorUsefulMessage(t *testing.T) { } } +func TestErrListFilter(t *testing.T) { + list := ValidationErrorList{ + NewFieldInvalid("test.field", "", ""), + NewFieldInvalid("field.test", "", ""), + NewFieldDuplicate("test", "value"), + } + if len(list.Filter(NewValidationErrorTypeMatcher(ValidationErrorTypeDuplicate))) != 2 { + t.Errorf("should not filter") + } + if len(list.Filter(NewValidationErrorTypeMatcher(ValidationErrorTypeInvalid))) != 1 { + t.Errorf("should filter") + } + if len(list.Filter(NewValidationErrorFieldPrefixMatcher("test"))) != 1 { + t.Errorf("should filter") + } + if len(list.Filter(NewValidationErrorFieldPrefixMatcher("test."))) != 2 { + t.Errorf("should filter") + } + if len(list.Filter(NewValidationErrorFieldPrefixMatcher(""))) != 0 { + t.Errorf("should filter") + } + if len(list.Filter(NewValidationErrorFieldPrefixMatcher("field."), NewValidationErrorTypeMatcher(ValidationErrorTypeDuplicate))) != 1 { + t.Errorf("should filter") + } +} + func TestErrListPrefix(t *testing.T) { testCases := []struct { Err *ValidationError