From a950afecdce7b5006252c63323e93d353640b04e Mon Sep 17 00:00:00 2001 From: Antoine Pelisse Date: Wed, 16 Aug 2017 15:16:24 -0700 Subject: [PATCH] openapi-validation: Handle List special case --- .../cmd/util/openapi/validation/validation.go | 36 +++++++++++++++---- .../openapi/validation/validation_test.go | 28 +++++++++++++++ 2 files changed, 57 insertions(+), 7 deletions(-) diff --git a/pkg/kubectl/cmd/util/openapi/validation/validation.go b/pkg/kubectl/cmd/util/openapi/validation/validation.go index dce8c783721..afb51fd9af3 100644 --- a/pkg/kubectl/cmd/util/openapi/validation/validation.go +++ b/pkg/kubectl/cmd/util/openapi/validation/validation.go @@ -19,6 +19,7 @@ package validation import ( "errors" "fmt" + "strings" "k8s.io/apimachinery/pkg/runtime/schema" utilerrors "k8s.io/apimachinery/pkg/util/errors" @@ -49,21 +50,42 @@ func (v *SchemaValidation) ValidateBytes(data []byte) error { return err } + if strings.HasSuffix(gvk.Kind, "List") { + return utilerrors.NewAggregate(v.validateList(obj)) + } + + return utilerrors.NewAggregate(v.validateResource(obj, gvk)) +} + +func (v *SchemaValidation) validateList(object interface{}) []error { + fields := object.(map[string]interface{}) + if fields == nil { + return []error{errors.New("invalid object to validate")} + } + + errs := []error{} + for _, item := range fields["items"].([]interface{}) { + if gvk, err := getObjectKind(item); err != nil { + errs = append(errs, err) + } else { + errs = append(errs, v.validateResource(item, gvk)...) + } + } + return errs +} + +func (v *SchemaValidation) validateResource(obj interface{}, gvk schema.GroupVersionKind) []error { resource := v.resources.LookupResource(gvk) if resource == nil { - return fmt.Errorf("unknown object type %#v", gvk) + return []error{fmt.Errorf("unknown object type %#v", gvk)} } rootValidation, err := itemFactory(openapi.NewPath(gvk.Kind), obj) if err != nil { - return err + return []error{err} } resource.Accept(rootValidation) - errs := rootValidation.Errors() - if errs != nil { - return utilerrors.NewAggregate(errs) - } - return nil + return rootValidation.Errors() } func parse(data []byte) (interface{}, error) { diff --git a/pkg/kubectl/cmd/util/openapi/validation/validation_test.go b/pkg/kubectl/cmd/util/openapi/validation/validation_test.go index 4737e524524..3eb3975dc9d 100644 --- a/pkg/kubectl/cmd/util/openapi/validation/validation_test.go +++ b/pkg/kubectl/cmd/util/openapi/validation/validation_test.go @@ -328,4 +328,32 @@ spec: Expect(err).To(BeNil()) }) + + It("can validate lists", func() { + err := validator.ValidateBytes([]byte(` +apiVersion: v1 +kind: List +items: + - apiVersion: v1 + kind: Pod + metadata: + labels: + name: redis-master + name: name + spec: + containers: + - name: name +`)) + + Expect(err).To(Equal(utilerrors.NewAggregate([]error{ + validation.ValidationError{ + Path: "Pod.spec.containers[0]", + Err: validation.MissingRequiredFieldError{ + Path: "io.k8s.api.core.v1.Container", + Field: "image", + }, + }, + }))) + }) + })