mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-22 19:31:44 +00:00
apiextensions: unfold x-kubernetes-embedded-resource in publishing
Co-authored-by: Haowei Cai <haoweic@google.com>
This commit is contained in:
parent
f590120d0f
commit
d6c480122f
@ -24,6 +24,7 @@ go_library(
|
|||||||
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_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/runtime:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/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/apimachinery/pkg/util/wait:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/endpoints:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/endpoints:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/endpoints/openapi:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/endpoints/openapi:go_default_library",
|
||||||
|
@ -30,6 +30,7 @@ import (
|
|||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1"
|
metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
"k8s.io/apiserver/pkg/endpoints"
|
"k8s.io/apiserver/pkg/endpoints"
|
||||||
"k8s.io/apiserver/pkg/endpoints/openapi"
|
"k8s.io/apiserver/pkg/endpoints/openapi"
|
||||||
openapibuilder "k8s.io/kube-openapi/pkg/builder"
|
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).
|
ret.SetProperty("metadata", *spec.RefSchema(objectMetaSchemaRef).
|
||||||
WithDescription(swaggerPartialObjectMetadataDescriptions["metadata"]))
|
WithDescription(swaggerPartialObjectMetadataDescriptions["metadata"]))
|
||||||
addTypeMetaProperties(ret)
|
addTypeMetaProperties(ret)
|
||||||
|
addEmbeddedProperties(ret)
|
||||||
}
|
}
|
||||||
ret.AddExtension(endpoints.ROUTE_META_GVK, []interface{}{
|
ret.AddExtension(endpoints.ROUTE_META_GVK, []interface{}{
|
||||||
map[string]interface{}{
|
map[string]interface{}{
|
||||||
@ -322,6 +324,42 @@ func (b *builder) buildKubeNative(schema *structuralschema.Structural, v2 bool)
|
|||||||
return ret
|
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
|
// getDefinition gets definition for given Kubernetes type. This function is extracted from
|
||||||
// kube-openapi builder logic
|
// kube-openapi builder logic
|
||||||
func getDefinition(name string) spec.Schema {
|
func getDefinition(name string) spec.Schema {
|
||||||
@ -329,6 +367,10 @@ func getDefinition(name string) spec.Schema {
|
|||||||
return definitions[name].Schema
|
return definitions[name].Schema
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func withDescription(s spec.Schema, desc string) spec.Schema {
|
||||||
|
return *s.WithDescription(desc)
|
||||||
|
}
|
||||||
|
|
||||||
func buildDefinitionsFunc() {
|
func buildDefinitionsFunc() {
|
||||||
namer = openapi.NewDefinitionNamer(runtime.NewScheme())
|
namer = openapi.NewDefinitionNamer(runtime.NewScheme())
|
||||||
definitions = generatedopenapi.GetOpenAPIDefinitions(func(name string) spec.Ref {
|
definitions = generatedopenapi.GetOpenAPIDefinitions(func(name string) spec.Ref {
|
||||||
|
@ -21,6 +21,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/go-openapi/spec"
|
"github.com/go-openapi/spec"
|
||||||
|
|
||||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
||||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
|
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
|
||||||
structuralschema "k8s.io/apiextensions-apiserver/pkg/apiserver/schema"
|
structuralschema "k8s.io/apiextensions-apiserver/pkg/apiserver/schema"
|
||||||
@ -154,7 +155,22 @@ 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"}]
|
||||||
@ -305,7 +321,22 @@ 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"}]
|
||||||
@ -373,7 +404,7 @@ func TestNewBuilder(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !reflect.DeepEqual(&wantedSchema, got.schema) {
|
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)
|
gotListProperties := properties(got.listSchema.Properties)
|
||||||
@ -383,7 +414,7 @@ func TestNewBuilder(t *testing.T) {
|
|||||||
|
|
||||||
gotListSchema := got.listSchema.Properties["items"].Items.Schema
|
gotListSchema := got.listSchema.Properties["items"].Items.Schema
|
||||||
if !reflect.DeepEqual(&wantedItemsSchema, gotListSchema) {
|
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
|
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))
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user