From 0f64ec9456efa1f4b74225125d60aecb1813f3a8 Mon Sep 17 00:00:00 2001 From: Jordan Liggitt Date: Thu, 12 Sep 2019 13:35:49 -0400 Subject: [PATCH] Only publish openapi for structural schemas --- .../pkg/apiserver/customresource_handler.go | 2 +- .../pkg/controller/openapi/builder/builder.go | 23 +++++++++++-------- .../openapi/builder/builder_test.go | 7 ++++++ test/integration/master/BUILD | 1 + test/integration/master/crd_test.go | 2 ++ 5 files changed, 25 insertions(+), 10 deletions(-) diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/customresource_handler.go b/staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/customresource_handler.go index bff4962b924..f12008e9d7d 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/customresource_handler.go +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/customresource_handler.go @@ -1236,7 +1236,7 @@ func buildOpenAPIModelsForApply(staticOpenAPISpec *spec.Swagger, crd *apiextensi specs := []*spec.Swagger{} for _, v := range crd.Spec.Versions { - s, err := builder.BuildSwagger(crd, v.Name, builder.Options{V2: false, StripDefaults: true, StripValueValidation: true}) + s, err := builder.BuildSwagger(crd, v.Name, builder.Options{V2: false, StripDefaults: true, StripValueValidation: true, AllowNonStructural: true}) if err != nil { return nil, err } diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/controller/openapi/builder/builder.go b/staging/src/k8s.io/apiextensions-apiserver/pkg/controller/openapi/builder/builder.go index b77128cb13f..8e71458ab6e 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/pkg/controller/openapi/builder/builder.go +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/controller/openapi/builder/builder.go @@ -75,6 +75,9 @@ type Options struct { // Strip value validation. StripValueValidation bool + + // AllowNonStructural indicates swagger should be built for a schema that fits into the structural type but does not meet all structural invariants + AllowNonStructural bool } // BuildSwagger builds swagger for the given crd in the given version @@ -88,17 +91,19 @@ func BuildSwagger(crd *apiextensions.CustomResourceDefinition, version string, o if s != nil && s.OpenAPIV3Schema != nil { if !validation.SchemaHasInvalidTypes(s.OpenAPIV3Schema) { if ss, err := structuralschema.NewStructural(s.OpenAPIV3Schema); err == nil { - // skip non-structural schemas - schema = ss + // skip non-structural schemas unless explicitly asked to produce swagger from them + if opts.AllowNonStructural || len(structuralschema.ValidateStructural(nil, ss)) == 0 { + schema = ss - if opts.StripDefaults { - schema = schema.StripDefaults() - } - if opts.StripValueValidation { - schema = schema.StripValueValidations() - } + if opts.StripDefaults { + schema = schema.StripDefaults() + } + if opts.StripValueValidation { + schema = schema.StripValueValidations() + } - schema = schema.Unfold() + schema = schema.Unfold() + } } } } diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/controller/openapi/builder/builder_test.go b/staging/src/k8s.io/apiextensions-apiserver/pkg/controller/openapi/builder/builder_test.go index 65d1b15aa3e..3412532eec8 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/pkg/controller/openapi/builder/builder_test.go +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/controller/openapi/builder/builder_test.go @@ -582,6 +582,13 @@ func TestBuildSwagger(t *testing.T) { `{"type":"object","x-kubernetes-group-version-kind":[{"group":"bar.k8s.io","kind":"Foo","version":"v1"}]}`, Options{V2: true, StripDefaults: true}, }, + { + "with non-structural schema", + `{"type":"object","properties":{"foo":{"type":"array"}}}`, + nil, + `{"type":"object","x-kubernetes-group-version-kind":[{"group":"bar.k8s.io","kind":"Foo","version":"v1"}]}`, + Options{V2: true, StripDefaults: true}, + }, { "with spec.preseveUnknownFields=true", `{"type":"object","properties":{"foo":{"type":"string"}}}`, diff --git a/test/integration/master/BUILD b/test/integration/master/BUILD index 413b4b46b4e..bf4e4f38e0f 100644 --- a/test/integration/master/BUILD +++ b/test/integration/master/BUILD @@ -70,6 +70,7 @@ go_test( "//vendor/github.com/evanphx/json-patch:go_default_library", "//vendor/github.com/go-openapi/spec:go_default_library", "//vendor/github.com/stretchr/testify/require:go_default_library", + "//vendor/k8s.io/utils/pointer:go_default_library", "//vendor/sigs.k8s.io/yaml:go_default_library", ] + select({ "@io_bazel_rules_go//go/platform:android": [ diff --git a/test/integration/master/crd_test.go b/test/integration/master/crd_test.go index df0e5fb02d5..35f8ffd019e 100644 --- a/test/integration/master/crd_test.go +++ b/test/integration/master/crd_test.go @@ -37,6 +37,7 @@ import ( kubeapiservertesting "k8s.io/kubernetes/cmd/kube-apiserver/app/testing" "k8s.io/kubernetes/test/integration/etcd" "k8s.io/kubernetes/test/integration/framework" + utilpointer "k8s.io/utils/pointer" ) func TestCRDShadowGroup(t *testing.T) { @@ -172,6 +173,7 @@ func TestCRDOpenAPI(t *testing.T) { Plural: "foos", Kind: "Foo", }, + PreserveUnknownFields: utilpointer.BoolPtr(false), Validation: &apiextensionsv1beta1.CustomResourceValidation{ OpenAPIV3Schema: &apiextensionsv1beta1.JSONSchemaProps{ Type: "object",