Add new openapi endpoint in aggregator server

pull/6/head
Haowei Cai 2018-02-20 09:22:25 -08:00
parent 8b38e080c4
commit 2eb3d046ce
4 changed files with 35 additions and 5 deletions

View File

@ -175,6 +175,7 @@ func ClusterRoles() []rbac.ClusterRole {
// do not expand this pattern for openapi discovery docs
// move to a single openapi endpoint that takes accept/accept-encoding headers
"/swagger.json", "/swagger-2.0.0.pb-v1",
"/openapi", "/openapi/*",
"/api", "/api/*",
"/apis", "/apis/*",
).RuleOrDie(),

View File

@ -635,6 +635,8 @@ items:
- /apis
- /apis/*
- /healthz
- /openapi
- /openapi/*
- /swagger-2.0.0.pb-v1
- /swagger.json
- /swaggerapi

View File

@ -17,7 +17,7 @@ limitations under the License.
package routes
import (
"github.com/emicklei/go-restful"
restful "github.com/emicklei/go-restful"
"github.com/golang/glog"
"k8s.io/apiserver/pkg/server/mux"
@ -32,8 +32,15 @@ type OpenAPI struct {
// Install adds the SwaggerUI webservice to the given mux.
func (oa OpenAPI) Install(c *restful.Container, mux *mux.PathRecorderMux) {
// NOTE: [DEPRECATION] We will announce deprecation for format-separated endpoints for OpenAPI spec,
// and switch to a single /openapi/v2 endpoint in Kubernetes 1.10. The design doc and deprecation process
// are tracked at: https://docs.google.com/document/d/19lEqE9lc4yHJ3WJAJxS_G7TcORIJXGHyq3wpwcH28nU.
_, err := handler.BuildAndRegisterOpenAPIService("/swagger.json", c.RegisteredWebServices(), oa.Config, mux)
if err != nil {
glog.Fatalf("Failed to register open api spec for root: %v", err)
}
_, err = handler.BuildAndRegisterOpenAPIVersionedService("/openapi/v2", c.RegisteredWebServices(), oa.Config, mux)
if err != nil {
glog.Fatalf("Failed to register versioned open api spec for root: %v", err)
}
}

View File

@ -23,7 +23,7 @@ import (
"sync"
"time"
"github.com/emicklei/go-restful"
restful "github.com/emicklei/go-restful"
"github.com/go-openapi/spec"
"k8s.io/apiserver/pkg/server"
@ -51,7 +51,8 @@ type specAggregator struct {
openAPISpecs map[string]*openAPISpecInfo
// provided for dynamic OpenAPI spec
openAPIService *handler.OpenAPIService
openAPIService *handler.OpenAPIService
openAPIVersionedService *handler.OpenAPIService
}
var _ AggregationManager = &specAggregator{}
@ -109,11 +110,19 @@ func BuildAndRegisterAggregator(downloader *Downloader, delegationTarget server.
}
// Install handler
// NOTE: [DEPRECATION] We will announce deprecation for format-separated endpoints for OpenAPI spec,
// and switch to a single /openapi/v2 endpoint in Kubernetes 1.10. The design doc and deprecation process
// are tracked at: https://docs.google.com/document/d/19lEqE9lc4yHJ3WJAJxS_G7TcORIJXGHyq3wpwcH28nU.
s.openAPIService, err = handler.RegisterOpenAPIService(
specToServe, "/swagger.json", pathHandler)
if err != nil {
return nil, err
}
s.openAPIVersionedService, err = handler.RegisterOpenAPIVersionedService(
specToServe, "/openapi/v2", pathHandler)
if err != nil {
return nil, err
}
return s, nil
}
@ -207,14 +216,25 @@ func (s *specAggregator) buildOpenAPISpec() (specToReturn *spec.Swagger, err err
// updateOpenAPISpec aggregates all OpenAPI specs. It is not thread-safe. The caller is responsible to hold proper locks.
func (s *specAggregator) updateOpenAPISpec() error {
if s.openAPIService == nil {
if s.openAPIService == nil || s.openAPIVersionedService == nil {
// openAPIVersionedService and deprecated openAPIService should be initialized together
if !(s.openAPIService == nil && s.openAPIVersionedService == nil) {
return fmt.Errorf("unexpected openapi service initialization error")
}
return nil
}
specToServe, err := s.buildOpenAPISpec()
if err != nil {
return err
}
return s.openAPIService.UpdateSpec(specToServe)
// openAPIService.UpdateSpec and openAPIVersionedService.UpdateSpec read the same swagger spec
// serially and update their local caches separately. Both endpoints will have same spec in
// their caches if the caller is holding proper locks.
err = s.openAPIService.UpdateSpec(specToServe)
if err != nil {
return err
}
return s.openAPIVersionedService.UpdateSpec(specToServe)
}
// tryUpdatingServiceSpecs tries updating openAPISpecs map with specified specInfo, and keeps the map intact