From 4e87d2d57218cc314e64d95265f0bad1c835273c Mon Sep 17 00:00:00 2001 From: Antoine Pelisse Date: Fri, 11 Aug 2017 10:59:16 -0700 Subject: [PATCH] openapi: Handle properly empty/null fileds --- .../cmd/util/openapi/validation/types.go | 12 ++- .../openapi/validation/validation_test.go | 99 +++++++++++++++++-- 2 files changed, 103 insertions(+), 8 deletions(-) diff --git a/pkg/kubectl/cmd/util/openapi/validation/types.go b/pkg/kubectl/cmd/util/openapi/validation/types.go index e209930b4a9..335444c6c24 100644 --- a/pkg/kubectl/cmd/util/openapi/validation/types.go +++ b/pkg/kubectl/cmd/util/openapi/validation/types.go @@ -103,6 +103,9 @@ func (item *mapItem) VisitMap(schema *openapi.Map) { func (item *mapItem) VisitKind(schema *openapi.Kind) { // Verify each sub-field. for _, key := range item.sortedKeys() { + if item.Map[key] == nil { + continue + } subItem, err := itemFactory(item.Path().FieldPath(key), item.Map[key]) if err != nil { item.AddError(err) @@ -118,7 +121,7 @@ func (item *mapItem) VisitKind(schema *openapi.Kind) { // Verify that all required fields are present. for _, required := range schema.RequiredFields { - if _, ok := item.Map[required]; !ok { + if v, ok := item.Map[required]; !ok || v == nil { item.AddValidationError(MissingRequiredFieldError{Path: schema.GetPath().String(), Field: required}) } } @@ -139,7 +142,12 @@ func (item *arrayItem) VisitPrimitive(schema *openapi.Primitive) { func (item *arrayItem) VisitArray(schema *openapi.Array) { for i, v := range item.Array { - subItem, err := itemFactory(item.Path().ArrayPath(i), v) + path := item.Path().ArrayPath(i) + if v == nil { + item.AddValidationError(InvalidObjectTypeError{Type: "nil", Path: path.String()}) + continue + } + subItem, err := itemFactory(path, v) if err != nil { item.AddError(err) continue diff --git a/pkg/kubectl/cmd/util/openapi/validation/validation_test.go b/pkg/kubectl/cmd/util/openapi/validation/validation_test.go index 34563abedbc..4737e524524 100644 --- a/pkg/kubectl/cmd/util/openapi/validation/validation_test.go +++ b/pkg/kubectl/cmd/util/openapi/validation/validation_test.go @@ -231,14 +231,101 @@ spec: `)) Expect(err).To(Equal(utilerrors.NewAggregate([]error{ - validation.InvalidObjectTypeError{ - Path: "Pod.spec.containers[0].args[0]", - Type: "nil", + validation.ValidationError{ + Path: "Pod.spec.containers[0].args", + Err: validation.InvalidObjectTypeError{ + Path: "Pod.spec.containers[0].args[0]", + Type: "nil", + }, }, - validation.InvalidObjectTypeError{ - Path: "Pod.spec.containers[0].command[0]", - Type: "nil", + validation.ValidationError{ + Path: "Pod.spec.containers[0].command", + Err: validation.InvalidObjectTypeError{ + Path: "Pod.spec.containers[0].command[0]", + Type: "nil", + }, }, }))) }) + + It("fails if required fields are missing", func() { + err := validator.ValidateBytes([]byte(` +apiVersion: v1 +kind: Pod +metadata: + labels: + name: redis-master + name: name +spec: + containers: + - command: ["my", "command"] +`)) + + 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: "name", + }, + }, + validation.ValidationError{ + Path: "Pod.spec.containers[0]", + Err: validation.MissingRequiredFieldError{ + Path: "io.k8s.api.core.v1.Container", + Field: "image", + }, + }, + }))) + }) + + It("fails if required fields are empty", func() { + err := validator.ValidateBytes([]byte(` +apiVersion: v1 +kind: Pod +metadata: + labels: + name: redis-master + name: name +spec: + containers: + - image: + 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: "name", + }, + }, + validation.ValidationError{ + Path: "Pod.spec.containers[0]", + Err: validation.MissingRequiredFieldError{ + Path: "io.k8s.api.core.v1.Container", + Field: "image", + }, + }, + }))) + }) + + It("is fine with empty non-mandatory fields", func() { + err := validator.ValidateBytes([]byte(` +apiVersion: v1 +kind: Pod +metadata: + labels: + name: redis-master + name: name +spec: + containers: + - image: image + name: name + command: +`)) + + Expect(err).To(BeNil()) + }) })