apiextensions: unfold x-kubernetes-embedded-resource in publishing

Co-authored-by: Haowei Cai <haoweic@google.com>
This commit is contained in:
Jordan Liggitt 2019-06-07 00:36:12 -04:00 committed by Dr. Stefan Schimanski
parent f590120d0f
commit d6c480122f
3 changed files with 90 additions and 4 deletions

View File

@ -24,6 +24,7 @@ go_library(
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/endpoints:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/endpoints/openapi:go_default_library",

View File

@ -30,6 +30,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apiserver/pkg/endpoints"
"k8s.io/apiserver/pkg/endpoints/openapi"
openapibuilder "k8s.io/kube-openapi/pkg/builder"
@ -310,6 +311,7 @@ func (b *builder) buildKubeNative(schema *structuralschema.Structural, v2 bool)
ret.SetProperty("metadata", *spec.RefSchema(objectMetaSchemaRef).
WithDescription(swaggerPartialObjectMetadataDescriptions["metadata"]))
addTypeMetaProperties(ret)
addEmbeddedProperties(ret)
}
ret.AddExtension(endpoints.ROUTE_META_GVK, []interface{}{
map[string]interface{}{
@ -322,6 +324,42 @@ func (b *builder) buildKubeNative(schema *structuralschema.Structural, v2 bool)
return ret
}
func addEmbeddedProperties(s *spec.Schema) {
if s == nil {
return
}
for k := range s.Properties {
v := s.Properties[k]
addEmbeddedProperties(&v)
s.Properties[k] = v
}
if s.Items != nil {
addEmbeddedProperties(s.Items.Schema)
}
if s.AdditionalProperties != nil {
addEmbeddedProperties(s.AdditionalProperties.Schema)
}
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",
))
s.SetProperty("kind", withDescription(getDefinition(typeMetaType).SchemaProps.Properties["kind"],
"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",
))
s.SetProperty("metadata", *spec.RefSchema(objectMetaSchemaRef).WithDescription(swaggerPartialObjectMetadataDescriptions["metadata"]))
req := sets.NewString(s.Required...)
if !req.Has("kind") {
s.Required = append(s.Required, "kind")
}
if !req.Has("apiVersion") {
s.Required = append(s.Required, "apiVersion")
}
}
}
// getDefinition gets definition for given Kubernetes type. This function is extracted from
// kube-openapi builder logic
func getDefinition(name string) spec.Schema {
@ -329,6 +367,10 @@ func getDefinition(name string) spec.Schema {
return definitions[name].Schema
}
func withDescription(s spec.Schema, desc string) spec.Schema {
return *s.WithDescription(desc)
}
func buildDefinitionsFunc() {
namer = openapi.NewDefinitionNamer(runtime.NewScheme())
definitions = generatedopenapi.GetOpenAPIDefinitions(func(name string) spec.Ref {

View File

@ -21,6 +21,7 @@ import (
"testing"
"github.com/go-openapi/spec"
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
structuralschema "k8s.io/apiextensions-apiserver/pkg/apiserver/schema"
@ -154,7 +155,22 @@ func TestNewBuilder(t *testing.T) {
"embedded-object": {
"x-kubernetes-embedded-resource": 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"}]
@ -305,7 +321,22 @@ func TestNewBuilder(t *testing.T) {
"embedded-object": {
"x-kubernetes-embedded-resource": 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"}]
@ -373,7 +404,7 @@ func TestNewBuilder(t *testing.T) {
}
if !reflect.DeepEqual(&wantedSchema, got.schema) {
t.Errorf("unexpected schema: %s\nwant = %#v\ngot = %#v", diff.ObjectDiff(&wantedSchema, got.schema), &wantedSchema, got.schema)
t.Errorf("unexpected schema: %s\nwant = %#v\ngot = %#v", schemaDiff(&wantedSchema, got.schema), &wantedSchema, got.schema)
}
gotListProperties := properties(got.listSchema.Properties)
@ -383,7 +414,7 @@ func TestNewBuilder(t *testing.T) {
gotListSchema := got.listSchema.Properties["items"].Items.Schema
if !reflect.DeepEqual(&wantedItemsSchema, gotListSchema) {
t.Errorf("unexpected list schema: %s (want/got)", diff.ObjectDiff(&wantedItemsSchema, &gotListSchema))
t.Errorf("unexpected list schema: %s (want/got)", schemaDiff(&wantedItemsSchema, gotListSchema))
}
})
}
@ -396,3 +427,15 @@ func properties(p map[string]spec.Schema) sets.String {
}
return ret
}
func schemaDiff(a, b *spec.Schema) string {
as, err := json.Marshal(a)
if err != nil {
panic(err)
}
bs, err := json.Marshal(b)
if err != nil {
panic(err)
}
return diff.StringDiff(string(as), string(bs))
}