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 78de23af7ec..fac53c71b58 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 @@ -172,8 +172,7 @@ func TestNewBuilder(t *testing.T) { }, "embedded-object": { "x-kubernetes-embedded-resource": true, - "x-kubernetes-preserve-unknown-fields": true, - "type":"object" + "x-kubernetes-preserve-unknown-fields": true } }, "x-kubernetes-group-version-kind":[{"group":"bar.k8s.io","kind":"Foo","version":"v1"}] diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/controller/openapi/v2/conversion.go b/staging/src/k8s.io/apiextensions-apiserver/pkg/controller/openapi/v2/conversion.go index 320529bf68d..ae5b86a1932 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/pkg/controller/openapi/v2/conversion.go +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/controller/openapi/v2/conversion.go @@ -81,6 +81,13 @@ func ToStructuralOpenAPIV2(in *structuralschema.Structural) *structuralschema.St changed = true } + if s.XPreserveUnknownFields && s.Type == "object" { + // similar as above, kubectl doesn't properly handle object fields with `x-kubernetes-preserve-unknown-fields: true` + s.Type = "" + + changed = true + } + for f, fs := range s.Properties { if fs.Nullable { s.ValueValidation.Required, changed = filterOut(s.ValueValidation.Required, f) diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/controller/openapi/v2/conversion_test.go b/staging/src/k8s.io/apiextensions-apiserver/pkg/controller/openapi/v2/conversion_test.go index eacb92efb98..7a8cb5aabe6 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/pkg/controller/openapi/v2/conversion_test.go +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/controller/openapi/v2/conversion_test.go @@ -666,8 +666,7 @@ func Test_ConvertJSONSchemaPropsToOpenAPIv2SchemaByType(t *testing.T) { }, }, }, - expected: withVendorExtensions(new(spec.Schema), "x-kubernetes-preserve-unknown-fields", true). - Typed("object", ""), + expected: withVendorExtensions(new(spec.Schema), "x-kubernetes-preserve-unknown-fields", true), }, } diff --git a/test/e2e/apimachinery/crd_publish_openapi.go b/test/e2e/apimachinery/crd_publish_openapi.go index d4e141bd47e..5cae2d273ab 100644 --- a/test/e2e/apimachinery/crd_publish_openapi.go +++ b/test/e2e/apimachinery/crd_publish_openapi.go @@ -231,7 +231,7 @@ var _ = SIGDescribe("CustomResourcePublishOpenAPI [Privileged:ClusterAdmin]", fu ns := fmt.Sprintf("--namespace=%v", f.Namespace.Name) ginkgo.By("client-side validation (kubectl create and apply) allows request with any unknown properties") - randomCR := fmt.Sprintf(`{%s,"spec":{"b":[{"c":"d"}]}}`, meta) + randomCR := fmt.Sprintf(`{%s,"spec":{"a":null,"b":[{"c":"d"}]}}`, meta) if _, err := framework.RunKubectlInput(f.Namespace.Name, randomCR, ns, "create", "-f", "-"); err != nil { framework.Failf("failed to create random CR %s for CRD that allows unknown properties in a nested object: %v", randomCR, err) }