mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-09 12:07:47 +00:00
Omit openapi properties if spec.preserveUnknownFields=true
This commit is contained in:
parent
5b496d2a25
commit
e1857ee90f
@ -51,6 +51,7 @@ go_test(
|
||||
"//vendor/github.com/go-openapi/spec:go_default_library",
|
||||
"//vendor/github.com/stretchr/testify/assert:go_default_library",
|
||||
"//vendor/github.com/stretchr/testify/require:go_default_library",
|
||||
"//vendor/k8s.io/utils/pointer:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
@ -334,12 +334,12 @@ func (b *builder) buildRoute(root, path, httpMethod, actionVerb, operationVerb s
|
||||
|
||||
// buildKubeNative builds input schema with Kubernetes' native object meta, type meta and
|
||||
// extensions
|
||||
func (b *builder) buildKubeNative(schema *structuralschema.Structural, v2 bool) (ret *spec.Schema) {
|
||||
func (b *builder) buildKubeNative(schema *structuralschema.Structural, v2 bool, crdPreserveUnknownFields bool) (ret *spec.Schema) {
|
||||
// only add properties if we have a schema. Otherwise, kubectl would (wrongly) assume additionalProperties=false
|
||||
// and forbid anything outside of apiVersion, kind and metadata. We have to fix kubectl to stop doing this, e.g. by
|
||||
// adding additionalProperties=true support to explicitly allow additional fields.
|
||||
// TODO: fix kubectl to understand additionalProperties=true
|
||||
if schema == nil || (v2 && schema.XPreserveUnknownFields) {
|
||||
if schema == nil || (v2 && (schema.XPreserveUnknownFields || crdPreserveUnknownFields)) {
|
||||
ret = &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{Type: []string{"object"}},
|
||||
}
|
||||
@ -506,7 +506,8 @@ func newBuilder(crd *apiextensions.CustomResourceDefinition, version string, sch
|
||||
}
|
||||
|
||||
// Pre-build schema with Kubernetes native properties
|
||||
b.schema = b.buildKubeNative(schema, v2)
|
||||
preserveUnknownFields := crd.Spec.PreserveUnknownFields != nil && *crd.Spec.PreserveUnknownFields
|
||||
b.schema = b.buildKubeNative(schema, v2, preserveUnknownFields)
|
||||
b.listSchema = b.buildListSchema()
|
||||
|
||||
return b
|
||||
|
@ -33,6 +33,7 @@ import (
|
||||
"k8s.io/apiserver/pkg/endpoints"
|
||||
"k8s.io/apiserver/pkg/features"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
utilpointer "k8s.io/utils/pointer"
|
||||
)
|
||||
|
||||
func TestNewBuilder(t *testing.T) {
|
||||
@ -556,48 +557,63 @@ func TestBuildSwagger(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
schema string
|
||||
preserveUnknownFields *bool
|
||||
wantedSchema string
|
||||
opts Options
|
||||
}{
|
||||
{
|
||||
"nil",
|
||||
"",
|
||||
nil,
|
||||
`{"type":"object","x-kubernetes-group-version-kind":[{"group":"bar.k8s.io","kind":"Foo","version":"v1"}]}`,
|
||||
Options{V2: true, StripDefaults: true},
|
||||
},
|
||||
{
|
||||
"with properties",
|
||||
`{"type":"object","properties":{"spec":{"type":"object"},"status":{"type":"object"}}}`,
|
||||
nil,
|
||||
`{"type":"object","properties":{"apiVersion":{"type":"string"},"kind":{"type":"string"},"metadata":{"$ref":"#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta"},"spec":{"type":"object"},"status":{"type":"object"}},"x-kubernetes-group-version-kind":[{"group":"bar.k8s.io","kind":"Foo","version":"v1"}]}`,
|
||||
Options{V2: true, StripDefaults: true},
|
||||
},
|
||||
{
|
||||
"with invalid-typed properties",
|
||||
`{"type":"object","properties":{"spec":{"type":"bug"},"status":{"type":"object"}}}`,
|
||||
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"}}}`,
|
||||
utilpointer.BoolPtr(true),
|
||||
`{"type":"object","x-kubernetes-group-version-kind":[{"group":"bar.k8s.io","kind":"Foo","version":"v1"}]}`,
|
||||
Options{V2: true, StripDefaults: true},
|
||||
},
|
||||
{
|
||||
"with stripped defaults",
|
||||
`{"type":"object","properties":{"foo":{"type":"string","default":"bar"}}}`,
|
||||
nil,
|
||||
`{"type":"object","properties":{"apiVersion":{"type":"string"},"kind":{"type":"string"},"metadata":{"$ref":"#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta"},"foo":{"type":"string"}},"x-kubernetes-group-version-kind":[{"group":"bar.k8s.io","kind":"Foo","version":"v1"}]}`,
|
||||
Options{V2: true, StripDefaults: true},
|
||||
},
|
||||
{
|
||||
"with stripped defaults",
|
||||
`{"type":"object","properties":{"foo":{"type":"string","default":"bar"}}}`,
|
||||
nil,
|
||||
`{"type":"object","properties":{"apiVersion":{"type":"string"},"kind":{"type":"string"},"metadata":{"$ref":"#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta"},"foo":{"type":"string"}},"x-kubernetes-group-version-kind":[{"group":"bar.k8s.io","kind":"Foo","version":"v1"}]}`,
|
||||
Options{V2: true, StripDefaults: true},
|
||||
},
|
||||
{
|
||||
"v2",
|
||||
`{"type":"object","properties":{"foo":{"type":"string","oneOf":[{"pattern":"a"},{"pattern":"b"}]}}}`,
|
||||
nil,
|
||||
`{"type":"object","properties":{"apiVersion":{"type":"string"},"kind":{"type":"string"},"metadata":{"$ref":"#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta"},"foo":{"type":"string"}},"x-kubernetes-group-version-kind":[{"group":"bar.k8s.io","kind":"Foo","version":"v1"}]}`,
|
||||
Options{V2: true, StripDefaults: true},
|
||||
},
|
||||
{
|
||||
"v3",
|
||||
`{"type":"object","properties":{"foo":{"type":"string","oneOf":[{"pattern":"a"},{"pattern":"b"}]}}}`,
|
||||
nil,
|
||||
`{"type":"object","properties":{"apiVersion":{"type":"string"},"kind":{"type":"string"},"metadata":{"$ref":"#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta"},"foo":{"type":"string","oneOf":[{"pattern":"a"},{"pattern":"b"}]}},"x-kubernetes-group-version-kind":[{"group":"bar.k8s.io","kind":"Foo","version":"v1"}]}`,
|
||||
Options{V2: false, StripDefaults: true},
|
||||
},
|
||||
@ -630,6 +646,7 @@ func TestBuildSwagger(t *testing.T) {
|
||||
},
|
||||
Scope: apiextensions.NamespaceScoped,
|
||||
Validation: validation,
|
||||
PreserveUnknownFields: tt.preserveUnknownFields,
|
||||
},
|
||||
}, "v1", tt.opts)
|
||||
if err != nil {
|
||||
|
Loading…
Reference in New Issue
Block a user