From cca05af615fe6b6701e2426ad6bfc5142124e87e Mon Sep 17 00:00:00 2001 From: "Dr. Stefan Schimanski" Date: Fri, 30 Sep 2016 10:40:34 +0200 Subject: [PATCH] Move swagger+openapi setup to routes and decouple from run --- cmd/kube-apiserver/app/server.go | 4 +- examples/apiserver/apiserver.go | 2 +- .../cmd/federation-apiserver/app/server.go | 6 +- pkg/genericapiserver/config.go | 2 + pkg/genericapiserver/genericapiserver.go | 77 ++++--------------- pkg/genericapiserver/genericapiserver_test.go | 74 +++++++++--------- pkg/genericapiserver/openapi/openapi.go | 5 +- pkg/genericapiserver/routes/openapi.go | 58 ++++++++++++++ pkg/genericapiserver/routes/swagger.go | 49 ++++++++++++ pkg/genericapiserver/routes/swagger_test.go | 48 ++++++++++++ pkg/master/master_test.go | 8 +- test/integration/framework/master_utils.go | 2 +- test/integration/kubectl/kubectl_test.go | 2 - 13 files changed, 218 insertions(+), 119 deletions(-) create mode 100644 pkg/genericapiserver/routes/openapi.go create mode 100644 pkg/genericapiserver/routes/swagger.go create mode 100644 pkg/genericapiserver/routes/swagger_test.go diff --git a/cmd/kube-apiserver/app/server.go b/cmd/kube-apiserver/app/server.go index 4e041ec647b..b0ab7d718b9 100644 --- a/cmd/kube-apiserver/app/server.go +++ b/cmd/kube-apiserver/app/server.go @@ -42,7 +42,6 @@ import ( "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/apiserver" "k8s.io/kubernetes/pkg/apiserver/authenticator" - "k8s.io/kubernetes/pkg/apiserver/openapi" authorizerunion "k8s.io/kubernetes/pkg/auth/authorizer/union" "k8s.io/kubernetes/pkg/auth/user" "k8s.io/kubernetes/pkg/capabilities" @@ -307,7 +306,6 @@ func Run(s *options.APIServer) error { genericConfig.MasterServiceNamespace = s.MasterServiceNamespace genericConfig.OpenAPIConfig.Info.Title = "Kubernetes" genericConfig.OpenAPIConfig.Definitions = generatedopenapi.OpenAPIDefinitions - genericConfig.OpenAPIConfig.GetOperationID = openapi.GetOperationID genericConfig.EnableOpenAPISupport = true genericConfig.OpenAPIConfig.SecurityDefinitions = securityDefinitions @@ -339,6 +337,6 @@ func Run(s *options.APIServer) error { } sharedInformers.Start(wait.NeverStop) - m.GenericAPIServer.Run() + m.GenericAPIServer.PrepareRun().Run() return nil } diff --git a/examples/apiserver/apiserver.go b/examples/apiserver/apiserver.go index 686f3202f3a..2c6ce7ac3ac 100644 --- a/examples/apiserver/apiserver.go +++ b/examples/apiserver/apiserver.go @@ -105,6 +105,6 @@ func Run(serverOptions *genericoptions.ServerRunOptions) error { if err := s.InstallAPIGroup(&apiGroupInfo); err != nil { return fmt.Errorf("Error in installing API: %v", err) } - s.Run() + s.PrepareRun().Run() return nil } diff --git a/federation/cmd/federation-apiserver/app/server.go b/federation/cmd/federation-apiserver/app/server.go index 495372d285c..9c287ff4051 100644 --- a/federation/cmd/federation-apiserver/app/server.go +++ b/federation/cmd/federation-apiserver/app/server.go @@ -33,7 +33,6 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/apiserver/authenticator" - apiserveropenapi "k8s.io/kubernetes/pkg/apiserver/openapi" authorizerunion "k8s.io/kubernetes/pkg/auth/authorizer/union" "k8s.io/kubernetes/pkg/auth/user" "k8s.io/kubernetes/pkg/controller/informers" @@ -196,9 +195,6 @@ func Run(s *options.ServerRunOptions) error { genericConfig.APIResourceConfigSource = storageFactory.APIResourceConfigSource genericConfig.MasterServiceNamespace = s.MasterServiceNamespace genericConfig.OpenAPIConfig.Definitions = openapi.OpenAPIDefinitions - // Reusing api-server's GetOperationID function. if federation and api-server spec diverge and - // this method does not provide good operation IDs for federation, we should create federation's own GetOperationID. - genericConfig.OpenAPIConfig.GetOperationID = apiserveropenapi.GetOperationID genericConfig.EnableOpenAPISupport = true genericConfig.OpenAPIConfig.SecurityDefinitions = securityDefinitions @@ -231,7 +227,7 @@ func Run(s *options.ServerRunOptions) error { installExtensionsAPIs(m, restOptionsFactory) sharedInformers.Start(wait.NeverStop) - m.Run() + m.PrepareRun().Run() return nil } diff --git a/pkg/genericapiserver/config.go b/pkg/genericapiserver/config.go index d2d0bb4af48..b2aa6e08b93 100644 --- a/pkg/genericapiserver/config.go +++ b/pkg/genericapiserver/config.go @@ -37,6 +37,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/unversioned" apiserverfilters "k8s.io/kubernetes/pkg/apiserver/filters" + apiserveropenapi "k8s.io/kubernetes/pkg/apiserver/openapi" "k8s.io/kubernetes/pkg/apiserver/request" "k8s.io/kubernetes/pkg/auth/authenticator" "k8s.io/kubernetes/pkg/auth/authorizer" @@ -222,6 +223,7 @@ func NewConfig() *Config { Description: "Default Response.", }, }, + GetOperationID: apiserveropenapi.GetOperationID, }, LongRunningFunc: genericfilters.BasicLongRunningRequestCheck(longRunningRE, map[string]string{"watch": "true"}), } diff --git a/pkg/genericapiserver/genericapiserver.go b/pkg/genericapiserver/genericapiserver.go index 7974062b85a..b3d9f93f53c 100644 --- a/pkg/genericapiserver/genericapiserver.go +++ b/pkg/genericapiserver/genericapiserver.go @@ -30,10 +30,8 @@ import ( systemd "github.com/coreos/go-systemd/daemon" "github.com/emicklei/go-restful" - "github.com/emicklei/go-restful/swagger" "github.com/golang/glog" - "github.com/go-openapi/spec" "k8s.io/kubernetes/pkg/admission" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/rest" @@ -43,8 +41,8 @@ import ( "k8s.io/kubernetes/pkg/apiserver" "k8s.io/kubernetes/pkg/client/restclient" genericmux "k8s.io/kubernetes/pkg/genericapiserver/mux" - "k8s.io/kubernetes/pkg/genericapiserver/openapi" "k8s.io/kubernetes/pkg/genericapiserver/openapi/common" + "k8s.io/kubernetes/pkg/genericapiserver/routes" "k8s.io/kubernetes/pkg/runtime" certutil "k8s.io/kubernetes/pkg/util/cert" utilnet "k8s.io/kubernetes/pkg/util/net" @@ -151,9 +149,6 @@ type GenericAPIServer struct { // See Config.$name for documentation of these flags: - openAPIInfo spec.Info - openAPIDefaultResponse spec.Response - openAPIDefinitions *common.OpenAPIDefinitions MasterCount int KubernetesServiceNodePort int // TODO(sttts): move into master ServiceReadWriteIP net.IP @@ -179,15 +174,25 @@ func (s *GenericAPIServer) MinRequestTimeout() time.Duration { return s.minRequestTimeout } -func (s *GenericAPIServer) Run() { +type preparedGenericAPIServer struct { + *GenericAPIServer +} + +// PrepareRun does post API installation setup steps. +func (s *GenericAPIServer) PrepareRun() preparedGenericAPIServer { // install APIs which depend on other APIs to be installed if s.enableSwaggerSupport { - s.InstallSwaggerAPI() + routes.Swagger{ExternalAddress: s.ExternalAddress}.Install(s.HandlerContainer) } if s.enableOpenAPISupport { - s.InstallOpenAPI() + routes.OpenAPI{ + Config: s.openAPIConfig, + }.Install(s.HandlerContainer) } + return preparedGenericAPIServer{s} +} +func (s preparedGenericAPIServer) Run() { if s.SecureServingInfo != nil && s.Handler != nil { secureServer := &http.Server{ Addr: s.SecureServingInfo.BindAddress, @@ -424,60 +429,6 @@ func (s *GenericAPIServer) newAPIGroupVersion(apiGroupInfo *APIGroupInfo, groupV }, nil } -// getSwaggerConfig returns swagger config shared between SwaggerAPI and OpenAPI spec generators -func (s *GenericAPIServer) getSwaggerConfig() *swagger.Config { - hostAndPort := s.ExternalAddress - protocol := "https://" - webServicesUrl := protocol + hostAndPort - return &swagger.Config{ - WebServicesUrl: webServicesUrl, - WebServices: s.HandlerContainer.RegisteredWebServices(), - ApiPath: "/swaggerapi/", - SwaggerPath: "/swaggerui/", - SwaggerFilePath: "/swagger-ui/", - SchemaFormatHandler: func(typeName string) string { - switch typeName { - case "unversioned.Time", "*unversioned.Time": - return "date-time" - } - return "" - }, - } -} - -// InstallSwaggerAPI installs the /swaggerapi/ endpoint to allow schema discovery -// and traversal. It is optional to allow consumers of the Kubernetes GenericAPIServer to -// register their own web services into the Kubernetes mux prior to initialization -// of swagger, so that other resource types show up in the documentation. -func (s *GenericAPIServer) InstallSwaggerAPI() { - // Enable swagger UI and discovery API - swagger.RegisterSwaggerService(*s.getSwaggerConfig(), s.HandlerContainer.Container) -} - -// InstallOpenAPI installs spec endpoints for each web service. -func (s *GenericAPIServer) InstallOpenAPI() { - // Install one spec per web service, an ideal client will have a ClientSet containing one client - // per each of these specs. - for _, w := range s.HandlerContainer.RegisteredWebServices() { - if strings.HasPrefix(w.RootPath(), "/swaggerapi") { - continue - } - config := *s.openAPIConfig - config.Info = new(spec.Info) - *config.Info = *s.openAPIConfig.Info - config.Info.Title = config.Info.Title + " " + w.RootPath() - err := openapi.RegisterOpenAPIService(w.RootPath()+"/swagger.json", []*restful.WebService{w}, &config, s.HandlerContainer.Container) - if err != nil { - glog.Fatalf("Failed to register open api spec for %v: %v", w.RootPath(), err) - } - } - err := openapi.RegisterOpenAPIService("/swagger.json", s.HandlerContainer.RegisteredWebServices(), s.openAPIConfig, s.HandlerContainer.Container) - - if err != nil { - glog.Fatalf("Failed to register open api spec for root: %v", err) - } -} - // DynamicApisDiscovery returns a webservice serving api group discovery. // Note: during the server runtime apiGroupsForDiscovery might change. func (s *GenericAPIServer) DynamicApisDiscovery() *restful.WebService { diff --git a/pkg/genericapiserver/genericapiserver_test.go b/pkg/genericapiserver/genericapiserver_test.go index f3ae4331908..45f5017584e 100644 --- a/pkg/genericapiserver/genericapiserver_test.go +++ b/pkg/genericapiserver/genericapiserver_test.go @@ -36,12 +36,13 @@ import ( "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/auth/authorizer" "k8s.io/kubernetes/pkg/auth/user" - genericmux "k8s.io/kubernetes/pkg/genericapiserver/mux" + openapigen "k8s.io/kubernetes/pkg/generated/openapi" ipallocator "k8s.io/kubernetes/pkg/registry/core/service/ipallocator" etcdtesting "k8s.io/kubernetes/pkg/storage/etcd/testing" "k8s.io/kubernetes/pkg/util/sets" "k8s.io/kubernetes/pkg/version" + "github.com/go-openapi/spec" "github.com/stretchr/testify/assert" ) @@ -54,6 +55,16 @@ func setUp(t *testing.T) (*etcdtesting.EtcdTestServer, Config, *assert.Assertion config.RequestContextMapper = api.NewRequestContextMapper() config.LegacyAPIGroupPrefixes = sets.NewString("/api") + config.EnableOpenAPISupport = true + config.EnableSwaggerSupport = true + config.OpenAPIConfig.Definitions = openapigen.OpenAPIDefinitions + config.OpenAPIConfig.Info = &spec.Info{ + InfoProps: spec.InfoProps{ + Title: "Kubernetes", + Version: "unversioned", + }, + } + return etcdServer, *config, assert.New(t) } @@ -142,6 +153,29 @@ func TestInstallAPIGroups(t *testing.T) { } } +func TestPrepareRun(t *testing.T) { + s, etcdserver, config, assert := newMaster(t) + defer etcdserver.Terminate(t) + + assert.True(config.EnableSwaggerSupport) + assert.True(config.EnableOpenAPISupport) + + server := httptest.NewServer(s.HandlerContainer.ServeMux) + defer server.Close() + + s.PrepareRun() + + // openapi is installed in PrepareRun + resp, err := http.Get(server.URL + "/swagger.json") + assert.NoError(err) + assert.Equal(http.StatusOK, resp.StatusCode) + + // swagger is installed in PrepareRun + resp, err = http.Get(server.URL + "/swaggerapi/") + assert.NoError(err) + assert.Equal(http.StatusOK, resp.StatusCode) +} + // TestCustomHandlerChain verifies the handler chain with custom handler chain builder functions. func TestCustomHandlerChain(t *testing.T) { etcdserver, config, _ := setUp(t) @@ -266,41 +300,6 @@ func (authn *mockAuthenticator) AuthenticateRequest(req *http.Request) (user.Inf }, true, nil } -// TestInstallSwaggerAPI verifies that the swagger api is added -// at the proper endpoint. -func TestInstallSwaggerAPI(t *testing.T) { - etcdserver, _, assert := setUp(t) - defer etcdserver.Terminate(t) - - mux := http.NewServeMux() - server := &GenericAPIServer{} - server.HandlerContainer = genericmux.NewAPIContainer(mux, nil) - - // Ensure swagger isn't installed without the call - ws := server.HandlerContainer.RegisteredWebServices() - if !assert.Equal(len(ws), 0) { - for x := range ws { - assert.NotEqual("/swaggerapi", ws[x].RootPath(), "SwaggerAPI was installed without a call to InstallSwaggerAPI()") - } - } - - // Install swagger and test - server.InstallSwaggerAPI() - ws = server.HandlerContainer.RegisteredWebServices() - if assert.NotEqual(0, len(ws), "SwaggerAPI not installed.") { - assert.Equal("/swaggerapi/", ws[0].RootPath(), "SwaggerAPI did not install to the proper path. %s != /swaggerapi", ws[0].RootPath()) - } - - // Empty externalHost verification - mux = http.NewServeMux() - server.HandlerContainer = genericmux.NewAPIContainer(mux, nil) - server.ExternalAddress = "" - server.InstallSwaggerAPI() - if assert.NotEqual(0, len(ws), "SwaggerAPI not installed.") { - assert.Equal("/swaggerapi/", ws[0].RootPath(), "SwaggerAPI did not install to the proper path. %s != /swaggerapi", ws[0].RootPath()) - } -} - func decodeResponse(resp *http.Response, obj interface{}) error { defer resp.Body.Close() @@ -385,8 +384,7 @@ func TestGetServerAddressByClientCIDRs(t *testing.T) { publicAddressCIDRMap := []unversioned.ServerAddressByClientCIDR{ { - ClientCIDR: "0.0.0.0/0", - + ClientCIDR: "0.0.0.0/0", ServerAddress: s.ExternalAddress, }, } diff --git a/pkg/genericapiserver/openapi/openapi.go b/pkg/genericapiserver/openapi/openapi.go index fbe6ad13978..59f4b144191 100644 --- a/pkg/genericapiserver/openapi/openapi.go +++ b/pkg/genericapiserver/openapi/openapi.go @@ -25,6 +25,7 @@ import ( "github.com/emicklei/go-restful" "github.com/go-openapi/spec" + genericmux "k8s.io/kubernetes/pkg/genericapiserver/mux" "k8s.io/kubernetes/pkg/genericapiserver/openapi/common" "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util/json" @@ -42,7 +43,7 @@ type openAPI struct { } // RegisterOpenAPIService registers a handler to provides standard OpenAPI specification. -func RegisterOpenAPIService(servePath string, webServices []*restful.WebService, config *common.Config, containers *restful.Container) (err error) { +func RegisterOpenAPIService(servePath string, webServices []*restful.WebService, config *common.Config, container *genericmux.APIContainer) (err error) { o := openAPI{ config: config, servePath: servePath, @@ -61,7 +62,7 @@ func RegisterOpenAPIService(servePath string, webServices []*restful.WebService, return err } - containers.ServeMux.HandleFunc(servePath, func(w http.ResponseWriter, r *http.Request) { + container.SecretRoutes.HandleFunc(servePath, func(w http.ResponseWriter, r *http.Request) { resp := restful.NewResponse(w) if r.URL.Path != servePath { resp.WriteErrorString(http.StatusNotFound, "Path not found!") diff --git a/pkg/genericapiserver/routes/openapi.go b/pkg/genericapiserver/routes/openapi.go new file mode 100644 index 00000000000..6ed3e782566 --- /dev/null +++ b/pkg/genericapiserver/routes/openapi.go @@ -0,0 +1,58 @@ +/* +Copyright 2016 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package routes + +import ( + "strings" + + "k8s.io/kubernetes/pkg/genericapiserver/mux" + "k8s.io/kubernetes/pkg/genericapiserver/openapi" + "k8s.io/kubernetes/pkg/genericapiserver/openapi/common" + + "github.com/emicklei/go-restful" + "github.com/go-openapi/spec" + "github.com/golang/glog" +) + +// OpenAPI installs spec endpoints for each web service. +type OpenAPI struct { + Config *common.Config +} + +// Install adds the SwaggerUI webservice to the given mux. +func (oa OpenAPI) Install(c *mux.APIContainer) { + // Install one spec per web service, an ideal client will have a ClientSet containing one client + // per each of these specs. + for _, w := range c.RegisteredWebServices() { + if strings.HasPrefix(w.RootPath(), "/swaggerapi") { + continue + } + + config := *oa.Config + config.Info = new(spec.Info) + *config.Info = *oa.Config.Info + config.Info.Title = config.Info.Title + " " + w.RootPath() + err := openapi.RegisterOpenAPIService(w.RootPath()+"/swagger.json", []*restful.WebService{w}, &config, c) + if err != nil { + glog.Fatalf("Failed to register open api spec for %v: %v", w.RootPath(), err) + } + } + err := openapi.RegisterOpenAPIService("/swagger.json", c.RegisteredWebServices(), oa.Config, c) + if err != nil { + glog.Fatalf("Failed to register open api spec for root: %v", err) + } +} diff --git a/pkg/genericapiserver/routes/swagger.go b/pkg/genericapiserver/routes/swagger.go new file mode 100644 index 00000000000..96568442ce8 --- /dev/null +++ b/pkg/genericapiserver/routes/swagger.go @@ -0,0 +1,49 @@ +/* +Copyright 2016 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package routes + +import ( + "k8s.io/kubernetes/pkg/genericapiserver/mux" + + "github.com/emicklei/go-restful/swagger" +) + +// Swagger installs the /swaggerapi/ endpoint to allow schema discovery +// and traversal. It is optional to allow consumers of the Kubernetes GenericAPIServer to +// register their own web services into the Kubernetes mux prior to initialization +// of swagger, so that other resource types show up in the documentation. +type Swagger struct { + ExternalAddress string +} + +// Install adds the SwaggerUI webservice to the given mux. +func (s Swagger) Install(c *mux.APIContainer) { + swagger.RegisterSwaggerService(swagger.Config{ + WebServicesUrl: "https://" + s.ExternalAddress, + WebServices: c.RegisteredWebServices(), + ApiPath: "/swaggerapi/", + SwaggerPath: "/swaggerui/", + SwaggerFilePath: "/swagger-ui/", + SchemaFormatHandler: func(typeName string) string { + switch typeName { + case "unversioned.Time", "*unversioned.Time": + return "date-time" + } + return "" + }, + }, c.Container) +} diff --git a/pkg/genericapiserver/routes/swagger_test.go b/pkg/genericapiserver/routes/swagger_test.go new file mode 100644 index 00000000000..267e4b088cb --- /dev/null +++ b/pkg/genericapiserver/routes/swagger_test.go @@ -0,0 +1,48 @@ +/* +Copyright 2016 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package routes + +import ( + "net/http" + "testing" + + "github.com/stretchr/testify/assert" + + genericmux "k8s.io/kubernetes/pkg/genericapiserver/mux" +) + +// TestInstallSwaggerAPI verifies that the swagger api is added +// at the proper endpoint. +func TestInstallSwaggerAPI(t *testing.T) { + assert := assert.New(t) + + // Install swagger and test + c := genericmux.NewAPIContainer(http.NewServeMux(), nil) + Swagger{ExternalAddress: "1.2.3.4"}.Install(c) + ws := c.RegisteredWebServices() + if assert.NotEqual(0, len(ws), "SwaggerAPI not installed.") { + assert.Equal("/swaggerapi/", ws[0].RootPath(), "SwaggerAPI did not install to the proper path. %s != /swaggerapi", ws[0].RootPath()) + } + + // Empty externalHost verification + c = genericmux.NewAPIContainer(http.NewServeMux(), nil) + Swagger{ExternalAddress: ""}.Install(c) + ws = c.RegisteredWebServices() + if assert.NotEqual(0, len(ws), "SwaggerAPI not installed.") { + assert.Equal("/swaggerapi/", ws[0].RootPath(), "SwaggerAPI did not install to the proper path. %s != /swaggerapi", ws[0].RootPath()) + } +} diff --git a/pkg/master/master_test.go b/pkg/master/master_test.go index bcf76d8596c..e0405b6973b 100644 --- a/pkg/master/master_test.go +++ b/pkg/master/master_test.go @@ -43,7 +43,6 @@ import ( "k8s.io/kubernetes/pkg/apis/extensions" extensionsapiv1beta1 "k8s.io/kubernetes/pkg/apis/extensions/v1beta1" "k8s.io/kubernetes/pkg/apis/rbac" - "k8s.io/kubernetes/pkg/apiserver/openapi" "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake" "k8s.io/kubernetes/pkg/client/restclient" openapigen "k8s.io/kubernetes/pkg/generated/openapi" @@ -487,21 +486,22 @@ func TestValidOpenAPISpec(t *testing.T) { Version: "unversioned", }, } - config.GenericConfig.OpenAPIConfig.GetOperationID = openapi.GetOperationID master, err := config.Complete().New() if err != nil { t.Fatalf("Error in bringing up the master: %v", err) } - // make sure swagger.json is not registered before calling install api. + // make sure swagger.json is not registered before calling PrepareRun. server := httptest.NewServer(master.GenericAPIServer.HandlerContainer.ServeMux) + defer server.Close() resp, err := http.Get(server.URL + "/swagger.json") if !assert.NoError(err) { t.Errorf("unexpected error: %v", err) } assert.Equal(http.StatusNotFound, resp.StatusCode) - master.GenericAPIServer.InstallOpenAPI() + master.GenericAPIServer.PrepareRun() + resp, err = http.Get(server.URL + "/swagger.json") if !assert.NoError(err) { t.Errorf("unexpected error: %v", err) diff --git a/test/integration/framework/master_utils.go b/test/integration/framework/master_utils.go index 0665c36a42e..16e50d29ddb 100644 --- a/test/integration/framework/master_utils.go +++ b/test/integration/framework/master_utils.go @@ -259,6 +259,7 @@ func startMasterOrDie(masterConfig *master.Config, incomingServer *httptest.Serv // TODO have this start method actually use the normal start sequence for the API server // this method never actually calls the `Run` method for the API server // fire the post hooks ourselves + m.GenericAPIServer.PrepareRun() m.GenericAPIServer.RunPostStartHooks() // wait for services to be ready @@ -350,7 +351,6 @@ func NewMasterConfig() *master.Config { genericConfig.APIResourceConfigSource = master.DefaultAPIResourceConfigSource() genericConfig.Authorizer = authorizer.NewAlwaysAllowAuthorizer() genericConfig.AdmissionControl = admit.NewAlwaysAdmit() - genericConfig.EnableOpenAPISupport = true return &master.Config{ GenericConfig: genericConfig, diff --git a/test/integration/kubectl/kubectl_test.go b/test/integration/kubectl/kubectl_test.go index 033b605a7c0..cf3870c781c 100644 --- a/test/integration/kubectl/kubectl_test.go +++ b/test/integration/kubectl/kubectl_test.go @@ -46,8 +46,6 @@ func TestKubectlValidation(t *testing.T) { defer components.Stop(true, true) ctx := clientcmdapi.NewContext() cfg := clientcmdapi.NewConfig() - // Enable swagger api on master. - components.KubeMaster.GenericAPIServer.InstallSwaggerAPI() cluster := clientcmdapi.NewCluster() cluster.Server = components.ApiServer.URL