mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-27 05:27:21 +00:00
Fix publishing x-kubernetes-preserve-unknown-fields working with kubectl
This commit is contained in:
parent
8756e2c5e4
commit
66453d9372
@ -297,7 +297,7 @@ func (b *builder) buildKubeNative(schema *structuralschema.Structural, v2 bool)
|
|||||||
// 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 {
|
if schema == nil || (v2 && schema.XPreserveUnknownFields) {
|
||||||
ret = &spec.Schema{
|
ret = &spec.Schema{
|
||||||
SchemaProps: spec.SchemaProps{Type: []string{"object"}},
|
SchemaProps: spec.SchemaProps{Type: []string{"object"}},
|
||||||
}
|
}
|
||||||
@ -311,7 +311,7 @@ func (b *builder) buildKubeNative(schema *structuralschema.Structural, v2 bool)
|
|||||||
ret.SetProperty("metadata", *spec.RefSchema(objectMetaSchemaRef).
|
ret.SetProperty("metadata", *spec.RefSchema(objectMetaSchemaRef).
|
||||||
WithDescription(swaggerPartialObjectMetadataDescriptions["metadata"]))
|
WithDescription(swaggerPartialObjectMetadataDescriptions["metadata"]))
|
||||||
addTypeMetaProperties(ret)
|
addTypeMetaProperties(ret)
|
||||||
addEmbeddedProperties(ret)
|
addEmbeddedProperties(ret, v2)
|
||||||
}
|
}
|
||||||
ret.AddExtension(endpoints.ROUTE_META_GVK, []interface{}{
|
ret.AddExtension(endpoints.ROUTE_META_GVK, []interface{}{
|
||||||
map[string]interface{}{
|
map[string]interface{}{
|
||||||
@ -324,23 +324,28 @@ func (b *builder) buildKubeNative(schema *structuralschema.Structural, v2 bool)
|
|||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
func addEmbeddedProperties(s *spec.Schema) {
|
func addEmbeddedProperties(s *spec.Schema, v2 bool) {
|
||||||
if s == nil {
|
if s == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
for k := range s.Properties {
|
for k := range s.Properties {
|
||||||
v := s.Properties[k]
|
v := s.Properties[k]
|
||||||
addEmbeddedProperties(&v)
|
addEmbeddedProperties(&v, v2)
|
||||||
s.Properties[k] = v
|
s.Properties[k] = v
|
||||||
}
|
}
|
||||||
if s.Items != nil {
|
if s.Items != nil {
|
||||||
addEmbeddedProperties(s.Items.Schema)
|
addEmbeddedProperties(s.Items.Schema, v2)
|
||||||
}
|
}
|
||||||
if s.AdditionalProperties != nil {
|
if s.AdditionalProperties != nil {
|
||||||
addEmbeddedProperties(s.AdditionalProperties.Schema)
|
addEmbeddedProperties(s.AdditionalProperties.Schema, v2)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if isTrue, ok := s.VendorExtensible.Extensions.GetBool("x-kubernetes-preserve-unknown-fields"); ok && isTrue && v2 {
|
||||||
|
// don't add metadata properties if we're publishing to openapi v2 and are allowing unknown fields.
|
||||||
|
// adding these metadata properties makes kubectl refuse to validate unknown fields.
|
||||||
|
return
|
||||||
|
}
|
||||||
if isTrue, ok := s.VendorExtensible.Extensions.GetBool("x-kubernetes-embedded-resource"); ok && isTrue {
|
if isTrue, ok := s.VendorExtensible.Extensions.GetBool("x-kubernetes-embedded-resource"); ok && isTrue {
|
||||||
s.SetProperty("apiVersion", withDescription(getDefinition(typeMetaType).SchemaProps.Properties["apiVersion"],
|
s.SetProperty("apiVersion", withDescription(getDefinition(typeMetaType).SchemaProps.Properties["apiVersion"],
|
||||||
"apiVersion defines the versioned schema of this representation of an object. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources",
|
"apiVersion defines the versioned schema of this representation of an object. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources",
|
||||||
|
@ -59,6 +59,18 @@ func TestNewBuilder(t *testing.T) {
|
|||||||
`{"$ref":"#/definitions/io.k8s.bar.v1.Foo"}`,
|
`{"$ref":"#/definitions/io.k8s.bar.v1.Foo"}`,
|
||||||
true,
|
true,
|
||||||
},
|
},
|
||||||
|
{"preserve unknown at root v2",
|
||||||
|
`{"type":"object","x-kubernetes-preserve-unknown-fields":true}`,
|
||||||
|
`{"type":"object","x-kubernetes-group-version-kind":[{"group":"bar.k8s.io","kind":"Foo","version":"v1"}]}`,
|
||||||
|
`{"$ref":"#/definitions/io.k8s.bar.v1.Foo"}`,
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{"preserve unknown at root v3",
|
||||||
|
`{"type":"object","x-kubernetes-preserve-unknown-fields":true}`,
|
||||||
|
`{"type":"object","x-kubernetes-preserve-unknown-fields":true,"properties":{"apiVersion":{"type":"string"},"kind":{"type":"string"},"metadata":{"$ref":"#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta"}},"x-kubernetes-group-version-kind":[{"group":"bar.k8s.io","kind":"Foo","version":"v1"}]}`,
|
||||||
|
`{"$ref":"#/definitions/io.k8s.bar.v1.Foo"}`,
|
||||||
|
false,
|
||||||
|
},
|
||||||
{"with extensions",
|
{"with extensions",
|
||||||
`
|
`
|
||||||
{
|
{
|
||||||
@ -155,22 +167,7 @@ func TestNewBuilder(t *testing.T) {
|
|||||||
"embedded-object": {
|
"embedded-object": {
|
||||||
"x-kubernetes-embedded-resource": true,
|
"x-kubernetes-embedded-resource": true,
|
||||||
"x-kubernetes-preserve-unknown-fields": true,
|
"x-kubernetes-preserve-unknown-fields": true,
|
||||||
"type": "object",
|
"type":"object"
|
||||||
"required":["kind","apiVersion"],
|
|
||||||
"properties":{
|
|
||||||
"apiVersion":{
|
|
||||||
"description":"apiVersion defines the versioned schema of this representation of an object. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources",
|
|
||||||
"type":"string"
|
|
||||||
},
|
|
||||||
"kind":{
|
|
||||||
"description":"kind is a string value representing the type of this object. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds",
|
|
||||||
"type":"string"
|
|
||||||
},
|
|
||||||
"metadata":{
|
|
||||||
"description":"Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata",
|
|
||||||
"$ref":"#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"x-kubernetes-group-version-kind":[{"group":"bar.k8s.io","kind":"Foo","version":"v1"}]
|
"x-kubernetes-group-version-kind":[{"group":"bar.k8s.io","kind":"Foo","version":"v1"}]
|
||||||
|
@ -65,6 +65,14 @@ func ToStructuralOpenAPIV2(in *structuralschema.Structural) *structuralschema.St
|
|||||||
changed = true
|
changed = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if s.XPreserveUnknownFields {
|
||||||
|
// unknown fields break if items or properties are set in kubectl
|
||||||
|
s.Items = nil
|
||||||
|
s.Properties = nil
|
||||||
|
|
||||||
|
changed = true
|
||||||
|
}
|
||||||
|
|
||||||
return changed
|
return changed
|
||||||
},
|
},
|
||||||
// we drop all junctors above, and hence, never reach nested value validations
|
// we drop all junctors above, and hence, never reach nested value validations
|
||||||
|
Loading…
Reference in New Issue
Block a user