mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-24 20:24:09 +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
|
||||
// adding additionalProperties=true support to explicitly allow additional fields.
|
||||
// TODO: fix kubectl to understand additionalProperties=true
|
||||
if schema == nil {
|
||||
if schema == nil || (v2 && schema.XPreserveUnknownFields) {
|
||||
ret = &spec.Schema{
|
||||
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).
|
||||
WithDescription(swaggerPartialObjectMetadataDescriptions["metadata"]))
|
||||
addTypeMetaProperties(ret)
|
||||
addEmbeddedProperties(ret)
|
||||
addEmbeddedProperties(ret, v2)
|
||||
}
|
||||
ret.AddExtension(endpoints.ROUTE_META_GVK, []interface{}{
|
||||
map[string]interface{}{
|
||||
@ -324,23 +324,28 @@ func (b *builder) buildKubeNative(schema *structuralschema.Structural, v2 bool)
|
||||
return ret
|
||||
}
|
||||
|
||||
func addEmbeddedProperties(s *spec.Schema) {
|
||||
func addEmbeddedProperties(s *spec.Schema, v2 bool) {
|
||||
if s == nil {
|
||||
return
|
||||
}
|
||||
|
||||
for k := range s.Properties {
|
||||
v := s.Properties[k]
|
||||
addEmbeddedProperties(&v)
|
||||
addEmbeddedProperties(&v, v2)
|
||||
s.Properties[k] = v
|
||||
}
|
||||
if s.Items != nil {
|
||||
addEmbeddedProperties(s.Items.Schema)
|
||||
addEmbeddedProperties(s.Items.Schema, v2)
|
||||
}
|
||||
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 {
|
||||
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",
|
||||
|
@ -59,6 +59,18 @@ func TestNewBuilder(t *testing.T) {
|
||||
`{"$ref":"#/definitions/io.k8s.bar.v1.Foo"}`,
|
||||
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",
|
||||
`
|
||||
{
|
||||
@ -155,22 +167,7 @@ func TestNewBuilder(t *testing.T) {
|
||||
"embedded-object": {
|
||||
"x-kubernetes-embedded-resource": true,
|
||||
"x-kubernetes-preserve-unknown-fields": true,
|
||||
"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"
|
||||
}
|
||||
}
|
||||
"type":"object"
|
||||
}
|
||||
},
|
||||
"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
|
||||
}
|
||||
|
||||
if s.XPreserveUnknownFields {
|
||||
// unknown fields break if items or properties are set in kubectl
|
||||
s.Items = nil
|
||||
s.Properties = nil
|
||||
|
||||
changed = true
|
||||
}
|
||||
|
||||
return changed
|
||||
},
|
||||
// we drop all junctors above, and hence, never reach nested value validations
|
||||
|
Loading…
Reference in New Issue
Block a user