Merge pull request #64174 from liggitt/correct-openapi-extensions

Automatic merge from submit-queue (batch tested with PRs 64174, 64187, 64216, 63265, 64223). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>.

Correctly identify types served in the kube-apiserver openapi doc

Fixes https://github.com/kubernetes/kubernetes/issues/52741

Split out from https://github.com/kubernetes/kubernetes/pull/63893

```release-note
The kube-apiserver openapi doc now includes extensions identifying APIService and CustomResourceDefinition kinds
```
This commit is contained in:
Kubernetes Submit Queue 2018-05-24 09:41:09 -07:00 committed by GitHub
commit fa354b3f68
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 112 additions and 16 deletions

View File

@ -85089,7 +85089,14 @@
"description": "Status indicates the actual state of the CustomResourceDefinition", "description": "Status indicates the actual state of the CustomResourceDefinition",
"$ref": "#/definitions/io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.CustomResourceDefinitionStatus" "$ref": "#/definitions/io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.CustomResourceDefinitionStatus"
} }
} },
"x-kubernetes-group-version-kind": [
{
"group": "apiextensions.k8s.io",
"kind": "CustomResourceDefinition",
"version": "v1beta1"
}
]
}, },
"io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.CustomResourceDefinitionCondition": { "io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.CustomResourceDefinitionCondition": {
"description": "CustomResourceDefinitionCondition contains details for the current condition of this pod.", "description": "CustomResourceDefinitionCondition contains details for the current condition of this pod.",
@ -85144,7 +85151,14 @@
"metadata": { "metadata": {
"$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta" "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta"
} }
} },
"x-kubernetes-group-version-kind": [
{
"group": "apiextensions.k8s.io",
"kind": "CustomResourceDefinitionList",
"version": "v1beta1"
}
]
}, },
"io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.CustomResourceDefinitionNames": { "io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.CustomResourceDefinitionNames": {
"description": "CustomResourceDefinitionNames indicates the names to serve this CustomResourceDefinition", "description": "CustomResourceDefinitionNames indicates the names to serve this CustomResourceDefinition",
@ -85804,6 +85818,21 @@
"kind": "DeleteOptions", "kind": "DeleteOptions",
"version": "v1beta1" "version": "v1beta1"
}, },
{
"group": "apiextensions.k8s.io",
"kind": "DeleteOptions",
"version": "v1beta1"
},
{
"group": "apiregistration.k8s.io",
"kind": "DeleteOptions",
"version": "v1"
},
{
"group": "apiregistration.k8s.io",
"kind": "DeleteOptions",
"version": "v1beta1"
},
{ {
"group": "apps", "group": "apps",
"kind": "DeleteOptions", "kind": "DeleteOptions",
@ -86342,6 +86371,21 @@
"kind": "WatchEvent", "kind": "WatchEvent",
"version": "v1beta1" "version": "v1beta1"
}, },
{
"group": "apiextensions.k8s.io",
"kind": "WatchEvent",
"version": "v1beta1"
},
{
"group": "apiregistration.k8s.io",
"kind": "WatchEvent",
"version": "v1"
},
{
"group": "apiregistration.k8s.io",
"kind": "WatchEvent",
"version": "v1beta1"
},
{ {
"group": "apps", "group": "apps",
"kind": "WatchEvent", "kind": "WatchEvent",
@ -86561,7 +86605,14 @@
"description": "Status contains derived information about an API server", "description": "Status contains derived information about an API server",
"$ref": "#/definitions/io.k8s.kube-aggregator.pkg.apis.apiregistration.v1.APIServiceStatus" "$ref": "#/definitions/io.k8s.kube-aggregator.pkg.apis.apiregistration.v1.APIServiceStatus"
} }
} },
"x-kubernetes-group-version-kind": [
{
"group": "apiregistration.k8s.io",
"kind": "APIService",
"version": "v1"
}
]
}, },
"io.k8s.kube-aggregator.pkg.apis.apiregistration.v1.APIServiceCondition": { "io.k8s.kube-aggregator.pkg.apis.apiregistration.v1.APIServiceCondition": {
"required": [ "required": [
@ -86614,7 +86665,14 @@
"metadata": { "metadata": {
"$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta" "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta"
} }
} },
"x-kubernetes-group-version-kind": [
{
"group": "apiregistration.k8s.io",
"kind": "APIServiceList",
"version": "v1"
}
]
}, },
"io.k8s.kube-aggregator.pkg.apis.apiregistration.v1.APIServiceSpec": { "io.k8s.kube-aggregator.pkg.apis.apiregistration.v1.APIServiceSpec": {
"description": "APIServiceSpec contains information for locating and communicating with a server. Only https is supported, though you are able to disable certificate verification.", "description": "APIServiceSpec contains information for locating and communicating with a server. Only https is supported, though you are able to disable certificate verification.",
@ -86706,7 +86764,14 @@
"description": "Status contains derived information about an API server", "description": "Status contains derived information about an API server",
"$ref": "#/definitions/io.k8s.kube-aggregator.pkg.apis.apiregistration.v1beta1.APIServiceStatus" "$ref": "#/definitions/io.k8s.kube-aggregator.pkg.apis.apiregistration.v1beta1.APIServiceStatus"
} }
} },
"x-kubernetes-group-version-kind": [
{
"group": "apiregistration.k8s.io",
"kind": "APIService",
"version": "v1beta1"
}
]
}, },
"io.k8s.kube-aggregator.pkg.apis.apiregistration.v1beta1.APIServiceCondition": { "io.k8s.kube-aggregator.pkg.apis.apiregistration.v1beta1.APIServiceCondition": {
"required": [ "required": [
@ -86759,7 +86824,14 @@
"metadata": { "metadata": {
"$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta" "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta"
} }
} },
"x-kubernetes-group-version-kind": [
{
"group": "apiregistration.k8s.io",
"kind": "APIServiceList",
"version": "v1beta1"
}
]
}, },
"io.k8s.kube-aggregator.pkg.apis.apiregistration.v1beta1.APIServiceSpec": { "io.k8s.kube-aggregator.pkg.apis.apiregistration.v1beta1.APIServiceSpec": {
"description": "APIServiceSpec contains information for locating and communicating with a server. Only https is supported, though you are able to disable certificate verification.", "description": "APIServiceSpec contains information for locating and communicating with a server. Only https is supported, though you are able to disable certificate verification.",

View File

@ -70,6 +70,7 @@ go_library(
"//vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/initializer:go_default_library", "//vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/initializer:go_default_library",
"//vendor/k8s.io/apiserver/pkg/authentication/authenticator:go_default_library", "//vendor/k8s.io/apiserver/pkg/authentication/authenticator:go_default_library",
"//vendor/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library", "//vendor/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library",
"//vendor/k8s.io/apiserver/pkg/endpoints/openapi:go_default_library",
"//vendor/k8s.io/apiserver/pkg/server:go_default_library", "//vendor/k8s.io/apiserver/pkg/server:go_default_library",
"//vendor/k8s.io/apiserver/pkg/server/filters:go_default_library", "//vendor/k8s.io/apiserver/pkg/server/filters:go_default_library",
"//vendor/k8s.io/apiserver/pkg/server/healthz:go_default_library", "//vendor/k8s.io/apiserver/pkg/server/healthz:go_default_library",

View File

@ -35,6 +35,7 @@ import (
"github.com/golang/glog" "github.com/golang/glog"
"github.com/spf13/cobra" "github.com/spf13/cobra"
extensionsapiserver "k8s.io/apiextensions-apiserver/pkg/apiserver"
"k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
utilerrors "k8s.io/apimachinery/pkg/util/errors" utilerrors "k8s.io/apimachinery/pkg/util/errors"
@ -46,6 +47,7 @@ import (
webhookinit "k8s.io/apiserver/pkg/admission/plugin/webhook/initializer" webhookinit "k8s.io/apiserver/pkg/admission/plugin/webhook/initializer"
"k8s.io/apiserver/pkg/authentication/authenticator" "k8s.io/apiserver/pkg/authentication/authenticator"
"k8s.io/apiserver/pkg/authorization/authorizer" "k8s.io/apiserver/pkg/authorization/authorizer"
openapinamer "k8s.io/apiserver/pkg/endpoints/openapi"
"k8s.io/apiserver/pkg/server" "k8s.io/apiserver/pkg/server"
genericapiserver "k8s.io/apiserver/pkg/server" genericapiserver "k8s.io/apiserver/pkg/server"
"k8s.io/apiserver/pkg/server/filters" "k8s.io/apiserver/pkg/server/filters"
@ -61,6 +63,7 @@ import (
"k8s.io/client-go/restmapper" "k8s.io/client-go/restmapper"
certutil "k8s.io/client-go/util/cert" certutil "k8s.io/client-go/util/cert"
aggregatorapiserver "k8s.io/kube-aggregator/pkg/apiserver" aggregatorapiserver "k8s.io/kube-aggregator/pkg/apiserver"
aggregatorscheme "k8s.io/kube-aggregator/pkg/apiserver/scheme"
openapi "k8s.io/kube-openapi/pkg/common" openapi "k8s.io/kube-openapi/pkg/common"
"k8s.io/kubernetes/cmd/kube-apiserver/app/options" "k8s.io/kubernetes/cmd/kube-apiserver/app/options"
"k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/api/legacyscheme"
@ -432,7 +435,7 @@ func BuildGenericConfig(
return return
} }
genericConfig.OpenAPIConfig = genericapiserver.DefaultOpenAPIConfig(generatedopenapi.GetOpenAPIDefinitions, legacyscheme.Scheme) genericConfig.OpenAPIConfig = genericapiserver.DefaultOpenAPIConfig(generatedopenapi.GetOpenAPIDefinitions, openapinamer.NewDefinitionNamer(legacyscheme.Scheme, extensionsapiserver.Scheme, aggregatorscheme.Scheme))
genericConfig.OpenAPIConfig.PostProcessSpec = postProcessOpenAPISpecForBackwardCompatibility genericConfig.OpenAPIConfig.PostProcessSpec = postProcessOpenAPISpecForBackwardCompatibility
genericConfig.OpenAPIConfig.Info.Title = "Kubernetes" genericConfig.OpenAPIConfig.Info.Title = "Kubernetes"
genericConfig.SwaggerConfig = genericapiserver.DefaultSwaggerConfig() genericConfig.SwaggerConfig = genericapiserver.DefaultSwaggerConfig()

View File

@ -1453,6 +1453,7 @@ run_kubectl_old_print_tests() {
"spec": { "spec": {
"group": "company.com", "group": "company.com",
"version": "v1", "version": "v1",
"scope": "Namespaced",
"names": { "names": {
"plural": "foos", "plural": "foos",
"kind": "Foo" "kind": "Foo"
@ -1712,6 +1713,7 @@ run_crd_tests() {
"spec": { "spec": {
"group": "company.com", "group": "company.com",
"version": "v1", "version": "v1",
"scope": "Namespaced",
"names": { "names": {
"plural": "foos", "plural": "foos",
"kind": "Foo" "kind": "Foo"
@ -1733,6 +1735,7 @@ __EOF__
"spec": { "spec": {
"group": "company.com", "group": "company.com",
"version": "v1", "version": "v1",
"scope": "Namespaced",
"names": { "names": {
"plural": "bars", "plural": "bars",
"kind": "Bar" "kind": "Bar"

View File

@ -165,6 +165,7 @@ go_test(
"//vendor/k8s.io/apimachinery/pkg/util/net:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/net:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/version:go_default_library", "//vendor/k8s.io/apimachinery/pkg/version:go_default_library",
"//vendor/k8s.io/apiserver/pkg/endpoints/openapi:go_default_library",
"//vendor/k8s.io/apiserver/pkg/server:go_default_library", "//vendor/k8s.io/apiserver/pkg/server:go_default_library",
"//vendor/k8s.io/apiserver/pkg/server/options:go_default_library", "//vendor/k8s.io/apiserver/pkg/server/options:go_default_library",
"//vendor/k8s.io/apiserver/pkg/server/storage:go_default_library", "//vendor/k8s.io/apiserver/pkg/server/storage:go_default_library",

View File

@ -27,6 +27,7 @@ import (
"net/http/httptest" "net/http/httptest"
"testing" "testing"
openapinamer "k8s.io/apiserver/pkg/endpoints/openapi"
genericapiserver "k8s.io/apiserver/pkg/server" genericapiserver "k8s.io/apiserver/pkg/server"
"k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/api/legacyscheme"
openapigen "k8s.io/kubernetes/pkg/generated/openapi" openapigen "k8s.io/kubernetes/pkg/generated/openapi"
@ -44,7 +45,7 @@ func TestValidOpenAPISpec(t *testing.T) {
defer etcdserver.Terminate(t) defer etcdserver.Terminate(t)
config.GenericConfig.EnableIndex = true config.GenericConfig.EnableIndex = true
config.GenericConfig.OpenAPIConfig = genericapiserver.DefaultOpenAPIConfig(openapigen.GetOpenAPIDefinitions, legacyscheme.Scheme) config.GenericConfig.OpenAPIConfig = genericapiserver.DefaultOpenAPIConfig(openapigen.GetOpenAPIDefinitions, openapinamer.NewDefinitionNamer(legacyscheme.Scheme))
config.GenericConfig.OpenAPIConfig.Info = &spec.Info{ config.GenericConfig.OpenAPIConfig.Info = &spec.Info{
InfoProps: spec.InfoProps{ InfoProps: spec.InfoProps{
Title: "Kubernetes", Title: "Kubernetes",

View File

@ -143,12 +143,24 @@ func typeName(t reflect.Type) string {
} }
// NewDefinitionNamer constructs a new DefinitionNamer to be used to customize OpenAPI spec. // NewDefinitionNamer constructs a new DefinitionNamer to be used to customize OpenAPI spec.
func NewDefinitionNamer(s *runtime.Scheme) DefinitionNamer { func NewDefinitionNamer(schemes ...*runtime.Scheme) *DefinitionNamer {
ret := DefinitionNamer{ ret := &DefinitionNamer{
typeGroupVersionKinds: map[string]groupVersionKinds{}, typeGroupVersionKinds: map[string]groupVersionKinds{},
} }
for gvk, rtype := range s.AllKnownTypes() { for _, s := range schemes {
ret.typeGroupVersionKinds[typeName(rtype)] = append(ret.typeGroupVersionKinds[typeName(rtype)], gvkConvert(gvk)) for gvk, rtype := range s.AllKnownTypes() {
newGVK := gvkConvert(gvk)
exists := false
for _, existingGVK := range ret.typeGroupVersionKinds[typeName(rtype)] {
if newGVK == existingGVK {
exists = true
break
}
}
if !exists {
ret.typeGroupVersionKinds[typeName(rtype)] = append(ret.typeGroupVersionKinds[typeName(rtype)], newGVK)
}
}
} }
for _, gvk := range ret.typeGroupVersionKinds { for _, gvk := range ret.typeGroupVersionKinds {
sort.Sort(gvk) sort.Sort(gvk)

View File

@ -27,6 +27,7 @@ go_test(
"//vendor/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library", "//vendor/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library",
"//vendor/k8s.io/apiserver/pkg/endpoints/discovery:go_default_library", "//vendor/k8s.io/apiserver/pkg/endpoints/discovery:go_default_library",
"//vendor/k8s.io/apiserver/pkg/endpoints/filters:go_default_library", "//vendor/k8s.io/apiserver/pkg/endpoints/filters:go_default_library",
"//vendor/k8s.io/apiserver/pkg/endpoints/openapi:go_default_library",
"//vendor/k8s.io/apiserver/pkg/registry/rest:go_default_library", "//vendor/k8s.io/apiserver/pkg/registry/rest:go_default_library",
"//vendor/k8s.io/apiserver/pkg/server/filters:go_default_library", "//vendor/k8s.io/apiserver/pkg/server/filters:go_default_library",
"//vendor/k8s.io/apiserver/pkg/server/healthz:go_default_library", "//vendor/k8s.io/apiserver/pkg/server/healthz:go_default_library",

View File

@ -278,8 +278,7 @@ func NewRecommendedConfig(codecs serializer.CodecFactory) *RecommendedConfig {
} }
} }
func DefaultOpenAPIConfig(getDefinitions openapicommon.GetOpenAPIDefinitions, scheme *runtime.Scheme) *openapicommon.Config { func DefaultOpenAPIConfig(getDefinitions openapicommon.GetOpenAPIDefinitions, defNamer *apiopenapi.DefinitionNamer) *openapicommon.Config {
defNamer := apiopenapi.NewDefinitionNamer(scheme)
return &openapicommon.Config{ return &openapicommon.Config{
ProtocolList: []string{"https"}, ProtocolList: []string{"https"},
IgnorePrefixes: []string{"/swaggerapi"}, IgnorePrefixes: []string{"/swaggerapi"},

View File

@ -44,6 +44,7 @@ import (
"k8s.io/apiserver/pkg/authorization/authorizer" "k8s.io/apiserver/pkg/authorization/authorizer"
"k8s.io/apiserver/pkg/endpoints/discovery" "k8s.io/apiserver/pkg/endpoints/discovery"
genericapifilters "k8s.io/apiserver/pkg/endpoints/filters" genericapifilters "k8s.io/apiserver/pkg/endpoints/filters"
openapinamer "k8s.io/apiserver/pkg/endpoints/openapi"
"k8s.io/apiserver/pkg/registry/rest" "k8s.io/apiserver/pkg/registry/rest"
genericfilters "k8s.io/apiserver/pkg/server/filters" genericfilters "k8s.io/apiserver/pkg/server/filters"
"k8s.io/client-go/informers" "k8s.io/client-go/informers"
@ -95,7 +96,7 @@ func setUp(t *testing.T) (Config, *assert.Assertions) {
t.Fatal("unable to create fake client set") t.Fatal("unable to create fake client set")
} }
config.OpenAPIConfig = DefaultOpenAPIConfig(testGetOpenAPIDefinitions, runtime.NewScheme()) config.OpenAPIConfig = DefaultOpenAPIConfig(testGetOpenAPIDefinitions, openapinamer.NewDefinitionNamer(runtime.NewScheme()))
config.OpenAPIConfig.Info.Version = "unversioned" config.OpenAPIConfig.Info.Version = "unversioned"
config.SwaggerConfig = DefaultSwaggerConfig() config.SwaggerConfig = DefaultSwaggerConfig()
sharedInformers := informers.NewSharedInformerFactory(clientset, config.LoopbackClientConfig.Timeout) sharedInformers := informers.NewSharedInformerFactory(clientset, config.LoopbackClientConfig.Timeout)

View File

@ -53,6 +53,7 @@ go_library(
"//vendor/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library", "//vendor/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library",
"//vendor/k8s.io/apiserver/pkg/authorization/authorizerfactory:go_default_library", "//vendor/k8s.io/apiserver/pkg/authorization/authorizerfactory:go_default_library",
"//vendor/k8s.io/apiserver/pkg/authorization/union:go_default_library", "//vendor/k8s.io/apiserver/pkg/authorization/union:go_default_library",
"//vendor/k8s.io/apiserver/pkg/endpoints/openapi:go_default_library",
"//vendor/k8s.io/apiserver/pkg/server:go_default_library", "//vendor/k8s.io/apiserver/pkg/server:go_default_library",
"//vendor/k8s.io/apiserver/pkg/server/options:go_default_library", "//vendor/k8s.io/apiserver/pkg/server/options:go_default_library",
"//vendor/k8s.io/apiserver/pkg/server/storage:go_default_library", "//vendor/k8s.io/apiserver/pkg/server/storage:go_default_library",

View File

@ -44,6 +44,7 @@ import (
"k8s.io/apiserver/pkg/authorization/authorizer" "k8s.io/apiserver/pkg/authorization/authorizer"
"k8s.io/apiserver/pkg/authorization/authorizerfactory" "k8s.io/apiserver/pkg/authorization/authorizerfactory"
authorizerunion "k8s.io/apiserver/pkg/authorization/union" authorizerunion "k8s.io/apiserver/pkg/authorization/union"
openapinamer "k8s.io/apiserver/pkg/endpoints/openapi"
genericapiserver "k8s.io/apiserver/pkg/server" genericapiserver "k8s.io/apiserver/pkg/server"
"k8s.io/apiserver/pkg/server/options" "k8s.io/apiserver/pkg/server/options"
serverstorage "k8s.io/apiserver/pkg/server/storage" serverstorage "k8s.io/apiserver/pkg/server/storage"
@ -124,7 +125,7 @@ func startMasterOrDie(masterConfig *master.Config, incomingServer *httptest.Serv
if masterConfig == nil { if masterConfig == nil {
masterConfig = NewMasterConfig() masterConfig = NewMasterConfig()
masterConfig.GenericConfig.OpenAPIConfig = genericapiserver.DefaultOpenAPIConfig(openapi.GetOpenAPIDefinitions, legacyscheme.Scheme) masterConfig.GenericConfig.OpenAPIConfig = genericapiserver.DefaultOpenAPIConfig(openapi.GetOpenAPIDefinitions, openapinamer.NewDefinitionNamer(legacyscheme.Scheme))
masterConfig.GenericConfig.OpenAPIConfig.Info = &spec.Info{ masterConfig.GenericConfig.OpenAPIConfig.Info = &spec.Info{
InfoProps: spec.InfoProps{ InfoProps: spec.InfoProps{
Title: "Kubernetes", Title: "Kubernetes",