mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-22 11:21:47 +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/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",
|
||||
|
@ -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 {
|
||||
|
@ -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))
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user