Skip to content

Commit

Permalink
Wrap Refs with AllOf
Browse files Browse the repository at this point in the history
  • Loading branch information
Jefftree committed Mar 25, 2022
1 parent 9f9c01d commit d685f8f
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 0 deletions.
29 changes: 29 additions & 0 deletions pkg/builder3/openapi.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (

"k8s.io/kube-openapi/pkg/common"
"k8s.io/kube-openapi/pkg/common/restfuladapter"
"k8s.io/kube-openapi/pkg/schemamutation"
"k8s.io/kube-openapi/pkg/spec3"
"k8s.io/kube-openapi/pkg/util"
"k8s.io/kube-openapi/pkg/validation/spec"
Expand Down Expand Up @@ -396,6 +397,7 @@ func (o *openAPI) buildDefinitionRecursively(name string) error {
}
// delete the embedded v2 schema if exists, otherwise no-op
delete(schema.VendorExtensible.Extensions, common.ExtensionV2Schema)
schema = wrapRefs(schema)
o.spec.Components.Schemas[uniqueName] = schema
for _, v := range item.Dependencies {
if err := o.buildDefinitionRecursively(v); err != nil {
Expand Down Expand Up @@ -436,3 +438,30 @@ func (o *openAPI) toSchema(name string) (_ *spec.Schema, err error) {
}, nil
}
}

// wrapRefs wraps OpenAPI V3 Schema refs that contain sibling elements.
// AllOf is used to wrap the Ref to prevent references from having sibling elements
// Please see https://github.com/kubernetes/kubernetes/issues/106387#issuecomment-967640388
func wrapRefs(schema *spec.Schema) *spec.Schema {
walker := schemamutation.Walker{
SchemaCallback: func(schema *spec.Schema) *spec.Schema {
orig := schema
clone := func() {
if orig == schema {
schema = new(spec.Schema)
*schema = *orig
}
}
if schema.Ref.String() != "" && (schema.Nullable != false || schema.Default != nil || len(schema.Extensions) > 0) {
clone()
newSchema := new(spec.Schema)
newSchema.Ref = schema.Ref
schema.Ref = spec.Ref{}
schema.AllOf = []spec.Schema{*newSchema}
}
return schema
},
RefCallback: schemamutation.RefCallbackNoop,
}
return walker.WalkSchema(schema)
}
54 changes: 54 additions & 0 deletions pkg/builder3/openapi_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,28 @@ func (_ TestInput) OpenAPIDefinition() *openapi.OpenAPIDefinition {
},
},
},
"reference-extension": {
VendorExtensible: spec.VendorExtensible{
Extensions: map[string]interface{}{"extension": "value"},
},
SchemaProps: spec.SchemaProps{
Ref: spec.MustCreateRef("/components/schemas/builder3.TestOutput"),
},
},
"reference-nullable": {
SchemaProps: spec.SchemaProps{
Ref: spec.MustCreateRef("/components/schemas/builder3.TestOutput"),
Nullable: true,
},
},
"reference-default": {
SchemaProps: spec.SchemaProps{
Ref: spec.MustCreateRef("/components/schemas/builder3.TestOutput"),
Default: map[string]interface{}{},
},
},


}
schema.Extensions = spec.Extensions{"x-test": "test"}
def := openapi.EmbedOpenAPIDefinitionIntoV2Extension(openapi.OpenAPIDefinition{
Expand Down Expand Up @@ -338,6 +360,38 @@ func getTestInputDefinition() *spec.Schema {
},
},
},
"reference-extension": {
VendorExtensible: spec.VendorExtensible{
Extensions: map[string]interface{}{"extension": "value"},
},
SchemaProps: spec.SchemaProps{
AllOf: []spec.Schema{{
SchemaProps: spec.SchemaProps{
Ref: spec.MustCreateRef("/components/schemas/builder3.TestOutput"),
},
}},
},
},
"reference-nullable": {
SchemaProps: spec.SchemaProps{
Nullable: true,
AllOf: []spec.Schema{{
SchemaProps: spec.SchemaProps{
Ref: spec.MustCreateRef("/components/schemas/builder3.TestOutput"),
},
}},
},
},
"reference-default": {
SchemaProps: spec.SchemaProps{
AllOf: []spec.Schema{{
SchemaProps: spec.SchemaProps{
Ref: spec.MustCreateRef("/components/schemas/builder3.TestOutput"),
},
}},
Default: map[string]interface{}{},
},
},
},
},
VendorExtensible: spec.VendorExtensible{
Expand Down

0 comments on commit d685f8f

Please sign in to comment.