Add OpenAPI v3 publishing under feature gate OpenAPIV3

Kubernetes-commit: 5bf3ed7a98e1e5247fe3fc2f6f948e6ed9a23521
This commit is contained in:
Jefftree 2021-10-26 11:11:59 -07:00 committed by Kubernetes Publisher
parent 11cdd66c3e
commit 649cd36479
2 changed files with 49 additions and 6 deletions

View File

@ -49,9 +49,10 @@ import (
utilopenapi "k8s.io/apiserver/pkg/util/openapi"
restclient "k8s.io/client-go/rest"
"k8s.io/klog/v2"
openapibuilder "k8s.io/kube-openapi/pkg/builder"
openapibuilder2 "k8s.io/kube-openapi/pkg/builder"
openapicommon "k8s.io/kube-openapi/pkg/common"
"k8s.io/kube-openapi/pkg/handler"
"k8s.io/kube-openapi/pkg/handler3"
openapiutil "k8s.io/kube-openapi/pkg/util"
openapiproto "k8s.io/kube-openapi/pkg/util/proto"
"k8s.io/kube-openapi/pkg/validation/spec"
@ -144,6 +145,10 @@ type GenericAPIServer struct {
// It is set during PrepareRun if `openAPIConfig` is non-nil unless `skipOpenAPIInstallation` is true.
OpenAPIVersionedService *handler.OpenAPIService
// OpenAPIV3VersionedService controls the /openapi/v3 endpoint and can be used to update the served spec.
// It is set during PrepareRun if `openAPIConfig` is non-nil unless `skipOpenAPIInstallation` is true.
OpenAPIV3VersionedService *handler3.OpenAPIService
// StaticOpenAPISpec is the spec derived from the restful container endpoints.
// It is set during PrepareRun.
StaticOpenAPISpec *spec.Swagger
@ -345,7 +350,12 @@ func (s *GenericAPIServer) PrepareRun() preparedGenericAPIServer {
if s.openAPIConfig != nil && !s.skipOpenAPIInstallation {
s.OpenAPIVersionedService, s.StaticOpenAPISpec = routes.OpenAPI{
Config: s.openAPIConfig,
}.Install(s.Handler.GoRestfulContainer, s.Handler.NonGoRestfulMux)
}.InstallV2(s.Handler.GoRestfulContainer, s.Handler.NonGoRestfulMux)
if utilfeature.DefaultFeatureGate.Enabled(features.OpenAPIV3) {
s.OpenAPIV3VersionedService = routes.OpenAPI{
Config: s.openAPIConfig,
}.InstallV3(s.Handler.GoRestfulContainer, s.Handler.NonGoRestfulMux)
}
}
s.installHealthz()
@ -706,7 +716,7 @@ func (s *GenericAPIServer) getOpenAPIModels(apiPrefix string, apiGroupInfos ...*
}
// Build the openapi definitions for those resources and convert it to proto models
openAPISpec, err := openapibuilder.BuildOpenAPIDefinitionsForResources(s.openAPIConfig, resourceNames...)
openAPISpec, err := openapibuilder2.BuildOpenAPIDefinitionsForResources(s.openAPIConfig, resourceNames...)
if err != nil {
return nil, err
}

View File

@ -21,9 +21,11 @@ import (
"k8s.io/klog/v2"
"k8s.io/apiserver/pkg/server/mux"
"k8s.io/kube-openapi/pkg/builder"
builder2 "k8s.io/kube-openapi/pkg/builder"
"k8s.io/kube-openapi/pkg/builder3"
"k8s.io/kube-openapi/pkg/common"
"k8s.io/kube-openapi/pkg/handler"
"k8s.io/kube-openapi/pkg/handler3"
"k8s.io/kube-openapi/pkg/validation/spec"
)
@ -33,8 +35,8 @@ type OpenAPI struct {
}
// Install adds the SwaggerUI webservice to the given mux.
func (oa OpenAPI) Install(c *restful.Container, mux *mux.PathRecorderMux) (*handler.OpenAPIService, *spec.Swagger) {
spec, err := builder.BuildOpenAPISpec(c.RegisteredWebServices(), oa.Config)
func (oa OpenAPI) InstallV2(c *restful.Container, mux *mux.PathRecorderMux) (*handler.OpenAPIService, *spec.Swagger) {
spec, err := builder2.BuildOpenAPISpec(c.RegisteredWebServices(), oa.Config)
if err != nil {
klog.Fatalf("Failed to build open api spec for root: %v", err)
}
@ -51,3 +53,34 @@ func (oa OpenAPI) Install(c *restful.Container, mux *mux.PathRecorderMux) (*hand
return openAPIVersionedService, spec
}
// InstallV3 adds the static group/versions defined in the RegisteredWebServices to the OpenAPI v3 spec
func (oa OpenAPI) InstallV3(c *restful.Container, mux *mux.PathRecorderMux) *handler3.OpenAPIService {
openAPIVersionedService, err := handler3.NewOpenAPIService(nil)
if err != nil {
klog.Fatalf("Failed to create OpenAPIService: %v", err)
}
err = openAPIVersionedService.RegisterOpenAPIV3VersionedService("/openapi/v3", mux)
if err != nil {
klog.Fatalf("Failed to register versioned open api spec for root: %v", err)
}
grouped := make(map[string][]*restful.WebService)
for _, t := range c.RegisteredWebServices() {
// Strip the "/" prefix from the name
gvName := t.RootPath()[1:]
grouped[gvName] = []*restful.WebService{t}
}
for gv, ws := range grouped {
spec, err := builder3.BuildOpenAPISpec(ws, oa.Config)
if err != nil {
klog.Errorf("Failed to build OpenAPI v3 for group %s, %q", gv, err)
}
openAPIVersionedService.UpdateGroupVersion(gv, spec)
}
return openAPIVersionedService
}