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/go-openapi/spec:go_default_library",
|
||||||
"//vendor/github.com/stretchr/testify/assert:go_default_library",
|
"//vendor/github.com/stretchr/testify/assert:go_default_library",
|
||||||
"//vendor/github.com/stretchr/testify/require: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
|
// buildKubeNative builds input schema with Kubernetes' native object meta, type meta and
|
||||||
// extensions
|
// 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
|
// 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
|
// 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.
|
// adding additionalProperties=true support to explicitly allow additional fields.
|
||||||
// TODO: fix kubectl to understand additionalProperties=true
|
// TODO: fix kubectl to understand additionalProperties=true
|
||||||
if schema == nil || (v2 && schema.XPreserveUnknownFields) {
|
if schema == nil || (v2 && (schema.XPreserveUnknownFields || crdPreserveUnknownFields)) {
|
||||||
ret = &spec.Schema{
|
ret = &spec.Schema{
|
||||||
SchemaProps: spec.SchemaProps{Type: []string{"object"}},
|
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
|
// 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()
|
b.listSchema = b.buildListSchema()
|
||||||
|
|
||||||
return b
|
return b
|
||||||
|
@ -33,6 +33,7 @@ import (
|
|||||||
"k8s.io/apiserver/pkg/endpoints"
|
"k8s.io/apiserver/pkg/endpoints"
|
||||||
"k8s.io/apiserver/pkg/features"
|
"k8s.io/apiserver/pkg/features"
|
||||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||||
|
utilpointer "k8s.io/utils/pointer"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestNewBuilder(t *testing.T) {
|
func TestNewBuilder(t *testing.T) {
|
||||||
@ -556,48 +557,63 @@ func TestBuildSwagger(t *testing.T) {
|
|||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
schema string
|
schema string
|
||||||
|
preserveUnknownFields *bool
|
||||||
wantedSchema string
|
wantedSchema string
|
||||||
opts Options
|
opts Options
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
"nil",
|
"nil",
|
||||||
"",
|
"",
|
||||||
|
nil,
|
||||||
`{"type":"object","x-kubernetes-group-version-kind":[{"group":"bar.k8s.io","kind":"Foo","version":"v1"}]}`,
|
`{"type":"object","x-kubernetes-group-version-kind":[{"group":"bar.k8s.io","kind":"Foo","version":"v1"}]}`,
|
||||||
Options{V2: true, StripDefaults: true},
|
Options{V2: true, StripDefaults: true},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"with properties",
|
"with properties",
|
||||||
`{"type":"object","properties":{"spec":{"type":"object"},"status":{"type":"object"}}}`,
|
`{"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"}]}`,
|
`{"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},
|
Options{V2: true, StripDefaults: true},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"with invalid-typed properties",
|
"with invalid-typed properties",
|
||||||
`{"type":"object","properties":{"spec":{"type":"bug"},"status":{"type":"object"}}}`,
|
`{"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"}]}`,
|
`{"type":"object","x-kubernetes-group-version-kind":[{"group":"bar.k8s.io","kind":"Foo","version":"v1"}]}`,
|
||||||
Options{V2: true, StripDefaults: true},
|
Options{V2: true, StripDefaults: true},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"with stripped defaults",
|
"with stripped defaults",
|
||||||
`{"type":"object","properties":{"foo":{"type":"string","default":"bar"}}}`,
|
`{"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"}]}`,
|
`{"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},
|
Options{V2: true, StripDefaults: true},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"with stripped defaults",
|
"with stripped defaults",
|
||||||
`{"type":"object","properties":{"foo":{"type":"string","default":"bar"}}}`,
|
`{"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"}]}`,
|
`{"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},
|
Options{V2: true, StripDefaults: true},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"v2",
|
"v2",
|
||||||
`{"type":"object","properties":{"foo":{"type":"string","oneOf":[{"pattern":"a"},{"pattern":"b"}]}}}`,
|
`{"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"}]}`,
|
`{"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},
|
Options{V2: true, StripDefaults: true},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"v3",
|
"v3",
|
||||||
`{"type":"object","properties":{"foo":{"type":"string","oneOf":[{"pattern":"a"},{"pattern":"b"}]}}}`,
|
`{"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"}]}`,
|
`{"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},
|
Options{V2: false, StripDefaults: true},
|
||||||
},
|
},
|
||||||
@ -630,6 +646,7 @@ func TestBuildSwagger(t *testing.T) {
|
|||||||
},
|
},
|
||||||
Scope: apiextensions.NamespaceScoped,
|
Scope: apiextensions.NamespaceScoped,
|
||||||
Validation: validation,
|
Validation: validation,
|
||||||
|
PreserveUnknownFields: tt.preserveUnknownFields,
|
||||||
},
|
},
|
||||||
}, "v1", tt.opts)
|
}, "v1", tt.opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
Loading…
Reference in New Issue
Block a user