mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-28 14:07:14 +00:00
Merge pull request #45370 from deads2k/server-23-handlers
Automatic merge from submit-queue refactor names for the apiserver handling chain The names and structure around the handling chain got a bit confused. This simplifies it back out into a single struct with three parts: overall handler, gorestful handler, pathrecording mux and makes the delegate wiring simpler
This commit is contained in:
commit
843c40e32e
@ -82,7 +82,6 @@ go_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",
|
||||||
"//vendor/k8s.io/apiserver/pkg/server/mux: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",
|
||||||
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
|
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
|
||||||
|
@ -30,7 +30,6 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
genericapiserver "k8s.io/apiserver/pkg/server"
|
genericapiserver "k8s.io/apiserver/pkg/server"
|
||||||
"k8s.io/apiserver/pkg/server/healthz"
|
"k8s.io/apiserver/pkg/server/healthz"
|
||||||
"k8s.io/apiserver/pkg/server/mux"
|
|
||||||
genericoptions "k8s.io/apiserver/pkg/server/options"
|
genericoptions "k8s.io/apiserver/pkg/server/options"
|
||||||
kubeclientset "k8s.io/client-go/kubernetes"
|
kubeclientset "k8s.io/client-go/kubernetes"
|
||||||
"k8s.io/kube-aggregator/pkg/apis/apiregistration"
|
"k8s.io/kube-aggregator/pkg/apis/apiregistration"
|
||||||
@ -46,7 +45,6 @@ func createAggregatorConfig(kubeAPIServerConfig genericapiserver.Config, command
|
|||||||
// make a shallow copy to let us twiddle a few things
|
// make a shallow copy to let us twiddle a few things
|
||||||
// most of the config actually remains the same. We only need to mess with a couple items related to the particulars of the aggregator
|
// most of the config actually remains the same. We only need to mess with a couple items related to the particulars of the aggregator
|
||||||
genericConfig := kubeAPIServerConfig
|
genericConfig := kubeAPIServerConfig
|
||||||
genericConfig.FallThroughHandler = mux.NewPathRecorderMux()
|
|
||||||
|
|
||||||
// the aggregator doesn't wire these up. It just delegates them to the kubeapiserver
|
// the aggregator doesn't wire these up. It just delegates them to the kubeapiserver
|
||||||
genericConfig.EnableSwaggerUI = false
|
genericConfig.EnableSwaggerUI = false
|
||||||
|
@ -110,7 +110,7 @@ func Run(runOptions *options.ServerRunOptions, stopCh <-chan struct{}) error {
|
|||||||
|
|
||||||
// run the insecure server now, don't block. It doesn't have any aggregator goodies since authentication wouldn't work
|
// run the insecure server now, don't block. It doesn't have any aggregator goodies since authentication wouldn't work
|
||||||
if insecureServingOptions != nil {
|
if insecureServingOptions != nil {
|
||||||
insecureHandlerChain := kubeserver.BuildInsecureHandlerChain(kubeAPIServer.GenericAPIServer.HandlerContainer.ServeMux, kubeAPIServerConfig.GenericConfig)
|
insecureHandlerChain := kubeserver.BuildInsecureHandlerChain(kubeAPIServer.GenericAPIServer.UnprotectedHandler(), kubeAPIServerConfig.GenericConfig)
|
||||||
if err := kubeserver.NonBlockingRun(insecureServingOptions, insecureHandlerChain, stopCh); err != nil {
|
if err := kubeserver.NonBlockingRun(insecureServingOptions, insecureHandlerChain, stopCh); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -139,7 +139,7 @@ func Run(runOptions *options.ServerRunOptions, stopCh <-chan struct{}) error {
|
|||||||
|
|
||||||
// CreateKubeAPIServer creates and wires a workable kube-apiserver
|
// CreateKubeAPIServer creates and wires a workable kube-apiserver
|
||||||
func CreateKubeAPIServer(kubeAPIServerConfig *master.Config, sharedInformers informers.SharedInformerFactory, stopCh <-chan struct{}) (*master.Master, error) {
|
func CreateKubeAPIServer(kubeAPIServerConfig *master.Config, sharedInformers informers.SharedInformerFactory, stopCh <-chan struct{}) (*master.Master, error) {
|
||||||
kubeAPIServer, err := kubeAPIServerConfig.Complete().New()
|
kubeAPIServer, err := kubeAPIServerConfig.Complete().New(genericapiserver.EmptyDelegate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -224,13 +224,13 @@ func NonBlockingRun(s *options.ServerRunOptions, stopCh <-chan struct{}) error {
|
|||||||
cachesize.SetWatchCacheSizes(s.GenericServerRunOptions.WatchCacheSizes)
|
cachesize.SetWatchCacheSizes(s.GenericServerRunOptions.WatchCacheSizes)
|
||||||
}
|
}
|
||||||
|
|
||||||
m, err := genericConfig.Complete().New()
|
m, err := genericConfig.Complete().New(genericapiserver.EmptyDelegate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
routes.UIRedirect{}.Install(m.FallThroughHandler)
|
routes.UIRedirect{}.Install(m.Handler.PostGoRestfulMux)
|
||||||
routes.Logs{}.Install(m.HandlerContainer)
|
routes.Logs{}.Install(m.Handler.GoRestfulContainer)
|
||||||
|
|
||||||
apiResourceConfigSource := storageFactory.APIResourceConfigSource
|
apiResourceConfigSource := storageFactory.APIResourceConfigSource
|
||||||
installFederationAPIs(m, genericConfig.RESTOptionsGetter, apiResourceConfigSource)
|
installFederationAPIs(m, genericConfig.RESTOptionsGetter, apiResourceConfigSource)
|
||||||
@ -241,7 +241,7 @@ func NonBlockingRun(s *options.ServerRunOptions, stopCh <-chan struct{}) error {
|
|||||||
|
|
||||||
// run the insecure server now
|
// run the insecure server now
|
||||||
if insecureServingOptions != nil {
|
if insecureServingOptions != nil {
|
||||||
insecureHandlerChain := kubeserver.BuildInsecureHandlerChain(m.HandlerContainer.ServeMux, genericConfig)
|
insecureHandlerChain := kubeserver.BuildInsecureHandlerChain(m.UnprotectedHandler(), genericConfig)
|
||||||
if err := kubeserver.NonBlockingRun(insecureServingOptions, insecureHandlerChain, stopCh); err != nil {
|
if err := kubeserver.NonBlockingRun(insecureServingOptions, insecureHandlerChain, stopCh); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -206,21 +206,21 @@ func (c *Config) SkipComplete() completedConfig {
|
|||||||
// Certain config fields will be set to a default value if unset.
|
// Certain config fields will be set to a default value if unset.
|
||||||
// Certain config fields must be specified, including:
|
// Certain config fields must be specified, including:
|
||||||
// KubeletClientConfig
|
// KubeletClientConfig
|
||||||
func (c completedConfig) New() (*Master, error) {
|
func (c completedConfig) New(delegationTarget genericapiserver.DelegationTarget) (*Master, error) {
|
||||||
if reflect.DeepEqual(c.KubeletClientConfig, kubeletclient.KubeletClientConfig{}) {
|
if reflect.DeepEqual(c.KubeletClientConfig, kubeletclient.KubeletClientConfig{}) {
|
||||||
return nil, fmt.Errorf("Master.New() called with empty config.KubeletClientConfig")
|
return nil, fmt.Errorf("Master.New() called with empty config.KubeletClientConfig")
|
||||||
}
|
}
|
||||||
|
|
||||||
s, err := c.Config.GenericConfig.SkipComplete().New() // completion is done in Complete, no need for a second time
|
s, err := c.Config.GenericConfig.SkipComplete().New(delegationTarget) // completion is done in Complete, no need for a second time
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.EnableUISupport {
|
if c.EnableUISupport {
|
||||||
routes.UIRedirect{}.Install(s.FallThroughHandler)
|
routes.UIRedirect{}.Install(s.Handler.PostGoRestfulMux)
|
||||||
}
|
}
|
||||||
if c.EnableLogsSupport {
|
if c.EnableLogsSupport {
|
||||||
routes.Logs{}.Install(s.HandlerContainer)
|
routes.Logs{}.Install(s.Handler.GoRestfulContainer)
|
||||||
}
|
}
|
||||||
|
|
||||||
m := &Master{
|
m := &Master{
|
||||||
|
@ -53,13 +53,13 @@ func TestValidOpenAPISpec(t *testing.T) {
|
|||||||
}
|
}
|
||||||
config.GenericConfig.SwaggerConfig = genericapiserver.DefaultSwaggerConfig()
|
config.GenericConfig.SwaggerConfig = genericapiserver.DefaultSwaggerConfig()
|
||||||
|
|
||||||
master, err := config.Complete().New()
|
master, err := config.Complete().New(genericapiserver.EmptyDelegate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Error in bringing up the master: %v", err)
|
t.Fatalf("Error in bringing up the master: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sure swagger.json is not registered before calling PrepareRun.
|
// make sure swagger.json is not registered before calling PrepareRun.
|
||||||
server := httptest.NewServer(master.GenericAPIServer.HandlerContainer.ServeMux)
|
server := httptest.NewServer(master.GenericAPIServer.Handler.GoRestfulContainer.ServeMux)
|
||||||
defer server.Close()
|
defer server.Close()
|
||||||
resp, err := http.Get(server.URL + "/swagger.json")
|
resp, err := http.Get(server.URL + "/swagger.json")
|
||||||
if !assert.NoError(err) {
|
if !assert.NoError(err) {
|
||||||
|
@ -107,7 +107,7 @@ func setUp(t *testing.T) (*etcdtesting.EtcdTestServer, Config, *assert.Assertion
|
|||||||
func newMaster(t *testing.T) (*Master, *etcdtesting.EtcdTestServer, Config, *assert.Assertions) {
|
func newMaster(t *testing.T) (*Master, *etcdtesting.EtcdTestServer, Config, *assert.Assertions) {
|
||||||
etcdserver, config, assert := setUp(t)
|
etcdserver, config, assert := setUp(t)
|
||||||
|
|
||||||
master, err := config.Complete().New()
|
master, err := config.Complete().New(genericapiserver.EmptyDelegate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Error in bringing up the master: %v", err)
|
t.Fatalf("Error in bringing up the master: %v", err)
|
||||||
}
|
}
|
||||||
@ -133,7 +133,7 @@ func limitedAPIResourceConfigSource() *serverstorage.ResourceConfig {
|
|||||||
func newLimitedMaster(t *testing.T) (*Master, *etcdtesting.EtcdTestServer, Config, *assert.Assertions) {
|
func newLimitedMaster(t *testing.T) (*Master, *etcdtesting.EtcdTestServer, Config, *assert.Assertions) {
|
||||||
etcdserver, config, assert := setUp(t)
|
etcdserver, config, assert := setUp(t)
|
||||||
config.APIResourceConfigSource = limitedAPIResourceConfigSource()
|
config.APIResourceConfigSource = limitedAPIResourceConfigSource()
|
||||||
master, err := config.Complete().New()
|
master, err := config.Complete().New(genericapiserver.EmptyDelegate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Error in bringing up the master: %v", err)
|
t.Fatalf("Error in bringing up the master: %v", err)
|
||||||
}
|
}
|
||||||
@ -226,7 +226,7 @@ func TestAPIVersionOfDiscoveryEndpoints(t *testing.T) {
|
|||||||
master, etcdserver, _, assert := newMaster(t)
|
master, etcdserver, _, assert := newMaster(t)
|
||||||
defer etcdserver.Terminate(t)
|
defer etcdserver.Terminate(t)
|
||||||
|
|
||||||
server := httptest.NewServer(master.GenericAPIServer.HandlerContainer.ServeMux)
|
server := httptest.NewServer(master.GenericAPIServer.Handler.GoRestfulContainer.ServeMux)
|
||||||
|
|
||||||
// /api exists in release-1.1
|
// /api exists in release-1.1
|
||||||
resp, err := http.Get(server.URL + "/api")
|
resp, err := http.Get(server.URL + "/api")
|
||||||
|
10
pkg/master/thirdparty/thirdparty.go
vendored
10
pkg/master/thirdparty/thirdparty.go
vendored
@ -156,11 +156,11 @@ func (m *ThirdPartyResourceServer) RemoveThirdPartyResource(path string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
services := m.genericAPIServer.HandlerContainer.RegisteredWebServices()
|
services := m.genericAPIServer.Handler.GoRestfulContainer.RegisteredWebServices()
|
||||||
for ix := range services {
|
for ix := range services {
|
||||||
root := services[ix].RootPath()
|
root := services[ix].RootPath()
|
||||||
if root == path || strings.HasPrefix(root, path+"/") {
|
if root == path || strings.HasPrefix(root, path+"/") {
|
||||||
m.genericAPIServer.HandlerContainer.Remove(services[ix])
|
m.genericAPIServer.Handler.GoRestfulContainer.Remove(services[ix])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -281,13 +281,13 @@ func (m *ThirdPartyResourceServer) InstallThirdPartyResource(rsrc *extensions.Th
|
|||||||
// the group with the new API
|
// the group with the new API
|
||||||
if m.hasThirdPartyGroupStorage(path) {
|
if m.hasThirdPartyGroupStorage(path) {
|
||||||
m.addThirdPartyResourceStorage(path, plural.Resource, thirdparty.Storage[plural.Resource].(*thirdpartyresourcedatastore.REST), apiGroup)
|
m.addThirdPartyResourceStorage(path, plural.Resource, thirdparty.Storage[plural.Resource].(*thirdpartyresourcedatastore.REST), apiGroup)
|
||||||
return thirdparty.UpdateREST(m.genericAPIServer.HandlerContainer.Container)
|
return thirdparty.UpdateREST(m.genericAPIServer.Handler.GoRestfulContainer)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := thirdparty.InstallREST(m.genericAPIServer.HandlerContainer.Container); err != nil {
|
if err := thirdparty.InstallREST(m.genericAPIServer.Handler.GoRestfulContainer); err != nil {
|
||||||
glog.Errorf("Unable to setup thirdparty api: %v", err)
|
glog.Errorf("Unable to setup thirdparty api: %v", err)
|
||||||
}
|
}
|
||||||
m.genericAPIServer.HandlerContainer.Add(discovery.NewAPIGroupHandler(api.Codecs, apiGroup).WebService())
|
m.genericAPIServer.Handler.GoRestfulContainer.Add(discovery.NewAPIGroupHandler(api.Codecs, apiGroup).WebService())
|
||||||
|
|
||||||
m.addThirdPartyResourceStorage(path, plural.Resource, thirdparty.Storage[plural.Resource].(*thirdpartyresourcedatastore.REST), apiGroup)
|
m.addThirdPartyResourceStorage(path, plural.Resource, thirdparty.Storage[plural.Resource].(*thirdpartyresourcedatastore.REST), apiGroup)
|
||||||
api.Registry.AddThirdPartyAPIGroupVersions(schema.GroupVersion{Group: group, Version: rsrc.Versions[0].Name})
|
api.Registry.AddThirdPartyAPIGroupVersions(schema.GroupVersion{Group: group, Version: rsrc.Versions[0].Name})
|
||||||
|
@ -21,14 +21,12 @@ import (
|
|||||||
"path"
|
"path"
|
||||||
|
|
||||||
"github.com/emicklei/go-restful"
|
"github.com/emicklei/go-restful"
|
||||||
|
|
||||||
"k8s.io/apiserver/pkg/server/mux"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Logs adds handlers for the /logs path serving log files from /var/log.
|
// Logs adds handlers for the /logs path serving log files from /var/log.
|
||||||
type Logs struct{}
|
type Logs struct{}
|
||||||
|
|
||||||
func (l Logs) Install(c *mux.APIContainer) {
|
func (l Logs) Install(c *restful.Container) {
|
||||||
// use restful: ws.Route(ws.GET("/logs/{logpath:*}").To(fileHandler))
|
// use restful: ws.Route(ws.GET("/logs/{logpath:*}").To(fileHandler))
|
||||||
// See github.com/emicklei/go-restful/blob/master/examples/restful-serve-static.go
|
// See github.com/emicklei/go-restful/blob/master/examples/restful-serve-static.go
|
||||||
ws := new(restful.WebService)
|
ws := new(restful.WebService)
|
||||||
|
@ -35,7 +35,6 @@ go_test(
|
|||||||
"//vendor/k8s.io/apiserver/pkg/endpoints/request:go_default_library",
|
"//vendor/k8s.io/apiserver/pkg/endpoints/request: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/healthz:go_default_library",
|
"//vendor/k8s.io/apiserver/pkg/server/healthz:go_default_library",
|
||||||
"//vendor/k8s.io/apiserver/pkg/server/mux:go_default_library",
|
|
||||||
"//vendor/k8s.io/apiserver/pkg/storage/etcd/testing:go_default_library",
|
"//vendor/k8s.io/apiserver/pkg/storage/etcd/testing:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/rest:go_default_library",
|
"//vendor/k8s.io/client-go/rest:go_default_library",
|
||||||
],
|
],
|
||||||
@ -48,6 +47,7 @@ go_library(
|
|||||||
"config_selfclient.go",
|
"config_selfclient.go",
|
||||||
"doc.go",
|
"doc.go",
|
||||||
"genericapiserver.go",
|
"genericapiserver.go",
|
||||||
|
"handler.go",
|
||||||
"healthz.go",
|
"healthz.go",
|
||||||
"hooks.go",
|
"hooks.go",
|
||||||
"serve.go",
|
"serve.go",
|
||||||
@ -55,11 +55,13 @@ go_library(
|
|||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
deps = [
|
deps = [
|
||||||
"//vendor/github.com/coreos/go-systemd/daemon:go_default_library",
|
"//vendor/github.com/coreos/go-systemd/daemon:go_default_library",
|
||||||
|
"//vendor/github.com/emicklei/go-restful:go_default_library",
|
||||||
"//vendor/github.com/emicklei/go-restful-swagger12:go_default_library",
|
"//vendor/github.com/emicklei/go-restful-swagger12:go_default_library",
|
||||||
"//vendor/github.com/go-openapi/spec:go_default_library",
|
"//vendor/github.com/go-openapi/spec:go_default_library",
|
||||||
"//vendor/github.com/golang/glog:go_default_library",
|
"//vendor/github.com/golang/glog:go_default_library",
|
||||||
"//vendor/github.com/pborman/uuid:go_default_library",
|
"//vendor/github.com/pborman/uuid:go_default_library",
|
||||||
"//vendor/github.com/pkg/errors:go_default_library",
|
"//vendor/github.com/pkg/errors:go_default_library",
|
||||||
|
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/apimachinery:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/apimachinery:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/apimachinery/registered:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/apimachinery/registered:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||||
@ -83,6 +85,7 @@ go_library(
|
|||||||
"//vendor/k8s.io/apiserver/pkg/endpoints:go_default_library",
|
"//vendor/k8s.io/apiserver/pkg/endpoints: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/handlers/responsewriters:go_default_library",
|
||||||
"//vendor/k8s.io/apiserver/pkg/endpoints/openapi:go_default_library",
|
"//vendor/k8s.io/apiserver/pkg/endpoints/openapi:go_default_library",
|
||||||
"//vendor/k8s.io/apiserver/pkg/endpoints/request:go_default_library",
|
"//vendor/k8s.io/apiserver/pkg/endpoints/request:go_default_library",
|
||||||
"//vendor/k8s.io/apiserver/pkg/registry/generic:go_default_library",
|
"//vendor/k8s.io/apiserver/pkg/registry/generic:go_default_library",
|
||||||
|
@ -53,7 +53,6 @@ import (
|
|||||||
genericregistry "k8s.io/apiserver/pkg/registry/generic"
|
genericregistry "k8s.io/apiserver/pkg/registry/generic"
|
||||||
genericfilters "k8s.io/apiserver/pkg/server/filters"
|
genericfilters "k8s.io/apiserver/pkg/server/filters"
|
||||||
"k8s.io/apiserver/pkg/server/healthz"
|
"k8s.io/apiserver/pkg/server/healthz"
|
||||||
"k8s.io/apiserver/pkg/server/mux"
|
|
||||||
"k8s.io/apiserver/pkg/server/routes"
|
"k8s.io/apiserver/pkg/server/routes"
|
||||||
restclient "k8s.io/client-go/rest"
|
restclient "k8s.io/client-go/rest"
|
||||||
certutil "k8s.io/client-go/util/cert"
|
certutil "k8s.io/client-go/util/cert"
|
||||||
@ -110,10 +109,6 @@ type Config struct {
|
|||||||
// Will default to a value based on secure serving info and available ipv4 IPs.
|
// Will default to a value based on secure serving info and available ipv4 IPs.
|
||||||
ExternalAddress string
|
ExternalAddress string
|
||||||
|
|
||||||
// FallThroughHandler is the final HTTP handler in the chain. If it is nil, one will be created for you.
|
|
||||||
// It comes after all filters and the API handling
|
|
||||||
FallThroughHandler *mux.PathRecorderMux
|
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
// Fields you probably don't care about changing
|
// Fields you probably don't care about changing
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
@ -312,6 +307,17 @@ func (c *Config) Complete() completedConfig {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if c.OpenAPIConfig.Info == nil {
|
||||||
|
c.OpenAPIConfig.Info = &spec.Info{}
|
||||||
|
}
|
||||||
|
if c.OpenAPIConfig.Info.Version == "" {
|
||||||
|
if c.Version != nil {
|
||||||
|
c.OpenAPIConfig.Info.Version = strings.Split(c.Version.String(), "-")[0]
|
||||||
|
} else {
|
||||||
|
c.OpenAPIConfig.Info.Version = "unversioned"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if c.SwaggerConfig != nil && len(c.SwaggerConfig.WebServicesUrl) == 0 {
|
if c.SwaggerConfig != nil && len(c.SwaggerConfig.WebServicesUrl) == 0 {
|
||||||
if c.SecureServingInfo != nil {
|
if c.SecureServingInfo != nil {
|
||||||
@ -342,9 +348,6 @@ func (c *Config) Complete() completedConfig {
|
|||||||
tokenAuthorizer := authorizerfactory.NewPrivilegedGroups(user.SystemPrivilegedGroup)
|
tokenAuthorizer := authorizerfactory.NewPrivilegedGroups(user.SystemPrivilegedGroup)
|
||||||
c.Authorizer = authorizerunion.New(tokenAuthorizer, c.Authorizer)
|
c.Authorizer = authorizerunion.New(tokenAuthorizer, c.Authorizer)
|
||||||
}
|
}
|
||||||
if c.FallThroughHandler == nil {
|
|
||||||
c.FallThroughHandler = mux.NewPathRecorderMux()
|
|
||||||
}
|
|
||||||
|
|
||||||
return completedConfig{c}
|
return completedConfig{c}
|
||||||
}
|
}
|
||||||
@ -354,38 +357,10 @@ func (c *Config) SkipComplete() completedConfig {
|
|||||||
return completedConfig{c}
|
return completedConfig{c}
|
||||||
}
|
}
|
||||||
|
|
||||||
// New returns a new instance of GenericAPIServer from the given config.
|
// New creates a new server which logically combines the handling chain with the passed server.
|
||||||
// Certain config fields will be set to a default value if unset,
|
func (c completedConfig) New(delegationTarget DelegationTarget) (*GenericAPIServer, error) {
|
||||||
// including:
|
// The delegationTarget and the config must agree on the RequestContextMapper
|
||||||
// ServiceClusterIPRange
|
|
||||||
// ServiceNodePortRange
|
|
||||||
// MasterCount
|
|
||||||
// ReadWritePort
|
|
||||||
// PublicAddress
|
|
||||||
// Public fields:
|
|
||||||
// Handler -- The returned GenericAPIServer has a field TopHandler which is an
|
|
||||||
// http.Handler which handles all the endpoints provided by the GenericAPIServer,
|
|
||||||
// including the API, the UI, and miscellaneous debugging endpoints. All
|
|
||||||
// these are subject to authorization and authentication.
|
|
||||||
// InsecureHandler -- an http.Handler which handles all the same
|
|
||||||
// endpoints as Handler, but no authorization and authentication is done.
|
|
||||||
// Public methods:
|
|
||||||
// HandleWithAuth -- Allows caller to add an http.Handler for an endpoint
|
|
||||||
// that uses the same authentication and authorization (if any is configured)
|
|
||||||
// as the GenericAPIServer's built-in endpoints.
|
|
||||||
// If the caller wants to add additional endpoints not using the GenericAPIServer's
|
|
||||||
// auth, then the caller should create a handler for those endpoints, which delegates the
|
|
||||||
// any unhandled paths to "Handler".
|
|
||||||
func (c completedConfig) New() (*GenericAPIServer, error) {
|
|
||||||
s, err := c.constructServer()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return c.buildHandlers(s, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c completedConfig) constructServer() (*GenericAPIServer, error) {
|
|
||||||
if c.Serializer == nil {
|
if c.Serializer == nil {
|
||||||
return nil, fmt.Errorf("Genericapiserver.New() called with config.Serializer == nil")
|
return nil, fmt.Errorf("Genericapiserver.New() called with config.Serializer == nil")
|
||||||
}
|
}
|
||||||
@ -393,7 +368,10 @@ func (c completedConfig) constructServer() (*GenericAPIServer, error) {
|
|||||||
return nil, fmt.Errorf("Genericapiserver.New() called with config.LoopbackClientConfig == nil")
|
return nil, fmt.Errorf("Genericapiserver.New() called with config.LoopbackClientConfig == nil")
|
||||||
}
|
}
|
||||||
|
|
||||||
handlerContainer := mux.NewAPIContainer(http.NewServeMux(), c.Serializer, c.FallThroughHandler)
|
handlerChainBuilder := func(handler http.Handler) http.Handler {
|
||||||
|
return c.BuildHandlerChainFunc(handler, c.Config)
|
||||||
|
}
|
||||||
|
apiServerHandler := NewAPIServerHandler(c.Serializer, handlerChainBuilder, delegationTarget.UnprotectedHandler())
|
||||||
|
|
||||||
s := &GenericAPIServer{
|
s := &GenericAPIServer{
|
||||||
discoveryAddresses: c.DiscoveryAddresses,
|
discoveryAddresses: c.DiscoveryAddresses,
|
||||||
@ -408,10 +386,9 @@ func (c completedConfig) constructServer() (*GenericAPIServer, error) {
|
|||||||
SecureServingInfo: c.SecureServingInfo,
|
SecureServingInfo: c.SecureServingInfo,
|
||||||
ExternalAddress: c.ExternalAddress,
|
ExternalAddress: c.ExternalAddress,
|
||||||
|
|
||||||
HandlerContainer: handlerContainer,
|
Handler: apiServerHandler,
|
||||||
FallThroughHandler: c.FallThroughHandler,
|
|
||||||
|
|
||||||
listedPathProvider: routes.ListedPathProviders{handlerContainer, c.FallThroughHandler},
|
listedPathProvider: apiServerHandler,
|
||||||
|
|
||||||
swaggerConfig: c.SwaggerConfig,
|
swaggerConfig: c.SwaggerConfig,
|
||||||
openAPIConfig: c.OpenAPIConfig,
|
openAPIConfig: c.OpenAPIConfig,
|
||||||
@ -424,20 +401,6 @@ func (c completedConfig) constructServer() (*GenericAPIServer, error) {
|
|||||||
DiscoveryGroupManager: discovery.NewRootAPIsHandler(c.DiscoveryAddresses, c.Serializer),
|
DiscoveryGroupManager: discovery.NewRootAPIsHandler(c.DiscoveryAddresses, c.Serializer),
|
||||||
}
|
}
|
||||||
|
|
||||||
return s, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewWithDelegate creates a new server which logically combines the handling chain with the passed server.
|
|
||||||
func (c completedConfig) NewWithDelegate(delegationTarget DelegationTarget) (*GenericAPIServer, error) {
|
|
||||||
// some pieces of the delegationTarget take precendence. Callers should already have ensured that these
|
|
||||||
// were wired correctly. Documenting them here.
|
|
||||||
// c.RequestContextMapper = delegationTarget.RequestContextMapper()
|
|
||||||
|
|
||||||
s, err := c.constructServer()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
for k, v := range delegationTarget.PostStartHooks() {
|
for k, v := range delegationTarget.PostStartHooks() {
|
||||||
s.postStartHooks[k] = v
|
s.postStartHooks[k] = v
|
||||||
}
|
}
|
||||||
@ -459,38 +422,17 @@ func (c completedConfig) NewWithDelegate(delegationTarget DelegationTarget) (*Ge
|
|||||||
|
|
||||||
s.listedPathProvider = routes.ListedPathProviders{s.listedPathProvider, delegationTarget}
|
s.listedPathProvider = routes.ListedPathProviders{s.listedPathProvider, delegationTarget}
|
||||||
|
|
||||||
|
installAPI(s, c.Config)
|
||||||
|
|
||||||
// use the UnprotectedHandler from the delegation target to ensure that we don't attempt to double authenticator, authorize,
|
// use the UnprotectedHandler from the delegation target to ensure that we don't attempt to double authenticator, authorize,
|
||||||
// or some other part of the filter chain in delegation cases.
|
// or some other part of the filter chain in delegation cases.
|
||||||
return c.buildHandlers(s, delegationTarget.UnprotectedHandler())
|
if delegationTarget.UnprotectedHandler() == nil && c.EnableIndex {
|
||||||
}
|
s.Handler.PostGoRestfulMux.NotFoundHandler(routes.IndexLister{
|
||||||
|
|
||||||
// buildHandlers builds our handling chain
|
|
||||||
func (c completedConfig) buildHandlers(s *GenericAPIServer, delegate http.Handler) (*GenericAPIServer, error) {
|
|
||||||
if s.openAPIConfig != nil {
|
|
||||||
if s.openAPIConfig.Info == nil {
|
|
||||||
s.openAPIConfig.Info = &spec.Info{}
|
|
||||||
}
|
|
||||||
if s.openAPIConfig.Info.Version == "" {
|
|
||||||
if c.Version != nil {
|
|
||||||
s.openAPIConfig.Info.Version = strings.Split(c.Version.String(), "-")[0]
|
|
||||||
} else {
|
|
||||||
s.openAPIConfig.Info.Version = "unversioned"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
installAPI(s, c.Config)
|
|
||||||
if delegate != nil {
|
|
||||||
s.FallThroughHandler.NotFoundHandler(delegate)
|
|
||||||
} else if c.EnableIndex {
|
|
||||||
s.FallThroughHandler.NotFoundHandler(routes.IndexLister{
|
|
||||||
StatusCode: http.StatusNotFound,
|
StatusCode: http.StatusNotFound,
|
||||||
PathProvider: s.listedPathProvider,
|
PathProvider: s.listedPathProvider,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
s.Handler = c.BuildHandlerChainFunc(s.HandlerContainer.ServeMux, c.Config)
|
|
||||||
|
|
||||||
return s, nil
|
return s, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -510,28 +452,28 @@ func DefaultBuildHandlerChain(apiHandler http.Handler, c *Config) http.Handler {
|
|||||||
|
|
||||||
func installAPI(s *GenericAPIServer, c *Config) {
|
func installAPI(s *GenericAPIServer, c *Config) {
|
||||||
if c.EnableIndex {
|
if c.EnableIndex {
|
||||||
routes.Index{}.Install(s.listedPathProvider, c.FallThroughHandler)
|
routes.Index{}.Install(s.listedPathProvider, s.Handler.PostGoRestfulMux)
|
||||||
}
|
}
|
||||||
if c.SwaggerConfig != nil && c.EnableSwaggerUI {
|
if c.SwaggerConfig != nil && c.EnableSwaggerUI {
|
||||||
routes.SwaggerUI{}.Install(s.FallThroughHandler)
|
routes.SwaggerUI{}.Install(s.Handler.PostGoRestfulMux)
|
||||||
}
|
}
|
||||||
if c.EnableProfiling {
|
if c.EnableProfiling {
|
||||||
routes.Profiling{}.Install(s.FallThroughHandler)
|
routes.Profiling{}.Install(s.Handler.PostGoRestfulMux)
|
||||||
if c.EnableContentionProfiling {
|
if c.EnableContentionProfiling {
|
||||||
goruntime.SetBlockProfileRate(1)
|
goruntime.SetBlockProfileRate(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if c.EnableMetrics {
|
if c.EnableMetrics {
|
||||||
if c.EnableProfiling {
|
if c.EnableProfiling {
|
||||||
routes.MetricsWithReset{}.Install(s.FallThroughHandler)
|
routes.MetricsWithReset{}.Install(s.Handler.PostGoRestfulMux)
|
||||||
} else {
|
} else {
|
||||||
routes.DefaultMetrics{}.Install(s.FallThroughHandler)
|
routes.DefaultMetrics{}.Install(s.Handler.PostGoRestfulMux)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
routes.Version{Version: c.Version}.Install(s.HandlerContainer)
|
routes.Version{Version: c.Version}.Install(s.Handler.GoRestfulContainer)
|
||||||
|
|
||||||
if c.EnableDiscovery {
|
if c.EnableDiscovery {
|
||||||
s.HandlerContainer.Add(s.DiscoveryGroupManager.WebService())
|
s.Handler.GoRestfulContainer.Add(s.DiscoveryGroupManager.WebService())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +28,6 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
|
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
|
||||||
"k8s.io/apiserver/pkg/server/healthz"
|
"k8s.io/apiserver/pkg/server/healthz"
|
||||||
"k8s.io/apiserver/pkg/server/mux"
|
|
||||||
"k8s.io/client-go/rest"
|
"k8s.io/client-go/rest"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -38,7 +37,6 @@ func TestNewWithDelegate(t *testing.T) {
|
|||||||
delegateConfig.RequestContextMapper = genericapirequest.NewRequestContextMapper()
|
delegateConfig.RequestContextMapper = genericapirequest.NewRequestContextMapper()
|
||||||
delegateConfig.LegacyAPIGroupPrefixes = sets.NewString("/api")
|
delegateConfig.LegacyAPIGroupPrefixes = sets.NewString("/api")
|
||||||
delegateConfig.LoopbackClientConfig = &rest.Config{}
|
delegateConfig.LoopbackClientConfig = &rest.Config{}
|
||||||
delegateConfig.FallThroughHandler = mux.NewPathRecorderMux()
|
|
||||||
delegateConfig.SwaggerConfig = DefaultSwaggerConfig()
|
delegateConfig.SwaggerConfig = DefaultSwaggerConfig()
|
||||||
|
|
||||||
delegateHealthzCalled := false
|
delegateHealthzCalled := false
|
||||||
@ -47,14 +45,13 @@ func TestNewWithDelegate(t *testing.T) {
|
|||||||
return fmt.Errorf("delegate failed healthcheck")
|
return fmt.Errorf("delegate failed healthcheck")
|
||||||
}))
|
}))
|
||||||
|
|
||||||
delegateConfig.FallThroughHandler.HandleFunc("/foo", func(w http.ResponseWriter, _ *http.Request) {
|
delegateServer, err := delegateConfig.SkipComplete().New(EmptyDelegate)
|
||||||
w.WriteHeader(http.StatusForbidden)
|
|
||||||
})
|
|
||||||
|
|
||||||
delegateServer, err := delegateConfig.SkipComplete().New()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
delegateServer.Handler.PostGoRestfulMux.HandleFunc("/foo", func(w http.ResponseWriter, _ *http.Request) {
|
||||||
|
w.WriteHeader(http.StatusForbidden)
|
||||||
|
})
|
||||||
|
|
||||||
delegateServer.AddPostStartHook("delegate-post-start-hook", func(context PostStartHookContext) error {
|
delegateServer.AddPostStartHook("delegate-post-start-hook", func(context PostStartHookContext) error {
|
||||||
return nil
|
return nil
|
||||||
@ -68,7 +65,6 @@ func TestNewWithDelegate(t *testing.T) {
|
|||||||
wrappingConfig.RequestContextMapper = genericapirequest.NewRequestContextMapper()
|
wrappingConfig.RequestContextMapper = genericapirequest.NewRequestContextMapper()
|
||||||
wrappingConfig.LegacyAPIGroupPrefixes = sets.NewString("/api")
|
wrappingConfig.LegacyAPIGroupPrefixes = sets.NewString("/api")
|
||||||
wrappingConfig.LoopbackClientConfig = &rest.Config{}
|
wrappingConfig.LoopbackClientConfig = &rest.Config{}
|
||||||
wrappingConfig.FallThroughHandler = mux.NewPathRecorderMux()
|
|
||||||
wrappingConfig.SwaggerConfig = DefaultSwaggerConfig()
|
wrappingConfig.SwaggerConfig = DefaultSwaggerConfig()
|
||||||
|
|
||||||
wrappingHealthzCalled := false
|
wrappingHealthzCalled := false
|
||||||
@ -77,14 +73,13 @@ func TestNewWithDelegate(t *testing.T) {
|
|||||||
return fmt.Errorf("wrapping failed healthcheck")
|
return fmt.Errorf("wrapping failed healthcheck")
|
||||||
}))
|
}))
|
||||||
|
|
||||||
wrappingConfig.FallThroughHandler.HandleFunc("/bar", func(w http.ResponseWriter, r *http.Request) {
|
wrappingServer, err := wrappingConfig.Complete().New(delegateServer)
|
||||||
w.WriteHeader(http.StatusUnauthorized)
|
|
||||||
})
|
|
||||||
|
|
||||||
wrappingServer, err := wrappingConfig.Complete().NewWithDelegate(delegateServer)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
wrappingServer.Handler.PostGoRestfulMux.HandleFunc("/bar", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.WriteHeader(http.StatusUnauthorized)
|
||||||
|
})
|
||||||
|
|
||||||
wrappingServer.AddPostStartHook("wrapping-post-start-hook", func(context PostStartHookContext) error {
|
wrappingServer.AddPostStartHook("wrapping-post-start-hook", func(context PostStartHookContext) error {
|
||||||
return nil
|
return nil
|
||||||
|
@ -42,8 +42,6 @@ import (
|
|||||||
apirequest "k8s.io/apiserver/pkg/endpoints/request"
|
apirequest "k8s.io/apiserver/pkg/endpoints/request"
|
||||||
"k8s.io/apiserver/pkg/registry/rest"
|
"k8s.io/apiserver/pkg/registry/rest"
|
||||||
"k8s.io/apiserver/pkg/server/healthz"
|
"k8s.io/apiserver/pkg/server/healthz"
|
||||||
"k8s.io/apiserver/pkg/server/mux"
|
|
||||||
genericmux "k8s.io/apiserver/pkg/server/mux"
|
|
||||||
"k8s.io/apiserver/pkg/server/routes"
|
"k8s.io/apiserver/pkg/server/routes"
|
||||||
restclient "k8s.io/client-go/rest"
|
restclient "k8s.io/client-go/rest"
|
||||||
)
|
)
|
||||||
@ -101,9 +99,6 @@ type GenericAPIServer struct {
|
|||||||
// requestContextMapper provides a way to get the context for a request. It may be nil.
|
// requestContextMapper provides a way to get the context for a request. It may be nil.
|
||||||
requestContextMapper apirequest.RequestContextMapper
|
requestContextMapper apirequest.RequestContextMapper
|
||||||
|
|
||||||
// The registered APIs
|
|
||||||
HandlerContainer *genericmux.APIContainer
|
|
||||||
|
|
||||||
SecureServingInfo *SecureServingInfo
|
SecureServingInfo *SecureServingInfo
|
||||||
|
|
||||||
// numerical ports, set after listening
|
// numerical ports, set after listening
|
||||||
@ -121,10 +116,8 @@ type GenericAPIServer struct {
|
|||||||
Serializer runtime.NegotiatedSerializer
|
Serializer runtime.NegotiatedSerializer
|
||||||
|
|
||||||
// "Outputs"
|
// "Outputs"
|
||||||
Handler http.Handler
|
// Handler holdes the handlers being used by this API server
|
||||||
// FallThroughHandler is the final HTTP handler in the chain.
|
Handler *APIServerHandler
|
||||||
// It comes after all filters and the API handling
|
|
||||||
FallThroughHandler *mux.PathRecorderMux
|
|
||||||
|
|
||||||
// listedPathProvider is a lister which provides the set of paths to show at /
|
// listedPathProvider is a lister which provides the set of paths to show at /
|
||||||
listedPathProvider routes.ListedPathProvider
|
listedPathProvider routes.ListedPathProvider
|
||||||
@ -171,7 +164,7 @@ type DelegationTarget interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *GenericAPIServer) UnprotectedHandler() http.Handler {
|
func (s *GenericAPIServer) UnprotectedHandler() http.Handler {
|
||||||
return s.HandlerContainer.ServeMux
|
return s.Handler.GoRestfulContainer.ServeMux
|
||||||
}
|
}
|
||||||
func (s *GenericAPIServer) PostStartHooks() map[string]postStartHookEntry {
|
func (s *GenericAPIServer) PostStartHooks() map[string]postStartHookEntry {
|
||||||
return s.postStartHooks
|
return s.postStartHooks
|
||||||
@ -233,12 +226,12 @@ type preparedGenericAPIServer struct {
|
|||||||
// PrepareRun does post API installation setup steps.
|
// PrepareRun does post API installation setup steps.
|
||||||
func (s *GenericAPIServer) PrepareRun() preparedGenericAPIServer {
|
func (s *GenericAPIServer) PrepareRun() preparedGenericAPIServer {
|
||||||
if s.swaggerConfig != nil {
|
if s.swaggerConfig != nil {
|
||||||
routes.Swagger{Config: s.swaggerConfig}.Install(s.HandlerContainer)
|
routes.Swagger{Config: s.swaggerConfig}.Install(s.Handler.GoRestfulContainer)
|
||||||
}
|
}
|
||||||
if s.openAPIConfig != nil {
|
if s.openAPIConfig != nil {
|
||||||
routes.OpenAPI{
|
routes.OpenAPI{
|
||||||
Config: s.openAPIConfig,
|
Config: s.openAPIConfig,
|
||||||
}.Install(s.HandlerContainer, s.FallThroughHandler)
|
}.Install(s.Handler.GoRestfulContainer, s.Handler.PostGoRestfulMux)
|
||||||
}
|
}
|
||||||
|
|
||||||
s.installHealthz()
|
s.installHealthz()
|
||||||
@ -306,7 +299,7 @@ func (s *GenericAPIServer) installAPIResources(apiPrefix string, apiGroupInfo *A
|
|||||||
apiGroupVersion.OptionsExternalVersion = apiGroupInfo.OptionsExternalVersion
|
apiGroupVersion.OptionsExternalVersion = apiGroupInfo.OptionsExternalVersion
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := apiGroupVersion.InstallREST(s.HandlerContainer.Container); err != nil {
|
if err := apiGroupVersion.InstallREST(s.Handler.GoRestfulContainer); err != nil {
|
||||||
return fmt.Errorf("Unable to setup API %v: %v", apiGroupInfo, err)
|
return fmt.Errorf("Unable to setup API %v: %v", apiGroupInfo, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -329,7 +322,7 @@ func (s *GenericAPIServer) InstallLegacyAPIGroup(apiPrefix string, apiGroupInfo
|
|||||||
}
|
}
|
||||||
// Install the version handler.
|
// Install the version handler.
|
||||||
// Add a handler at /<apiPrefix> to enumerate the supported api versions.
|
// Add a handler at /<apiPrefix> to enumerate the supported api versions.
|
||||||
s.HandlerContainer.Add(discovery.NewLegacyRootAPIHandler(s.discoveryAddresses, s.Serializer, apiPrefix, apiVersions).WebService())
|
s.Handler.GoRestfulContainer.Add(discovery.NewLegacyRootAPIHandler(s.discoveryAddresses, s.Serializer, apiPrefix, apiVersions).WebService())
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -373,7 +366,7 @@ func (s *GenericAPIServer) InstallAPIGroup(apiGroupInfo *APIGroupInfo) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
s.DiscoveryGroupManager.AddGroup(apiGroup)
|
s.DiscoveryGroupManager.AddGroup(apiGroup)
|
||||||
s.HandlerContainer.Add(discovery.NewAPIGroupHandler(s.Serializer, apiGroup).WebService())
|
s.Handler.GoRestfulContainer.Add(discovery.NewAPIGroupHandler(s.Serializer, apiGroup).WebService())
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,6 @@ import (
|
|||||||
"k8s.io/apiserver/pkg/endpoints/discovery"
|
"k8s.io/apiserver/pkg/endpoints/discovery"
|
||||||
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
|
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
|
||||||
"k8s.io/apiserver/pkg/registry/rest"
|
"k8s.io/apiserver/pkg/registry/rest"
|
||||||
"k8s.io/apiserver/pkg/server/mux"
|
|
||||||
etcdtesting "k8s.io/apiserver/pkg/storage/etcd/testing"
|
etcdtesting "k8s.io/apiserver/pkg/storage/etcd/testing"
|
||||||
restclient "k8s.io/client-go/rest"
|
restclient "k8s.io/client-go/rest"
|
||||||
)
|
)
|
||||||
@ -90,7 +89,6 @@ func setUp(t *testing.T) (*etcdtesting.EtcdTestServer, Config, *assert.Assertion
|
|||||||
config.RequestContextMapper = genericapirequest.NewRequestContextMapper()
|
config.RequestContextMapper = genericapirequest.NewRequestContextMapper()
|
||||||
config.LegacyAPIGroupPrefixes = sets.NewString("/api")
|
config.LegacyAPIGroupPrefixes = sets.NewString("/api")
|
||||||
config.LoopbackClientConfig = &restclient.Config{}
|
config.LoopbackClientConfig = &restclient.Config{}
|
||||||
config.FallThroughHandler = mux.NewPathRecorderMux()
|
|
||||||
|
|
||||||
// TODO restore this test, but right now, eliminate our cycle
|
// TODO restore this test, but right now, eliminate our cycle
|
||||||
// config.OpenAPIConfig = DefaultOpenAPIConfig(testGetOpenAPIDefinitions, runtime.NewScheme())
|
// config.OpenAPIConfig = DefaultOpenAPIConfig(testGetOpenAPIDefinitions, runtime.NewScheme())
|
||||||
@ -108,7 +106,7 @@ func setUp(t *testing.T) (*etcdtesting.EtcdTestServer, Config, *assert.Assertion
|
|||||||
func newMaster(t *testing.T) (*GenericAPIServer, *etcdtesting.EtcdTestServer, Config, *assert.Assertions) {
|
func newMaster(t *testing.T) (*GenericAPIServer, *etcdtesting.EtcdTestServer, Config, *assert.Assertions) {
|
||||||
etcdserver, config, assert := setUp(t)
|
etcdserver, config, assert := setUp(t)
|
||||||
|
|
||||||
s, err := config.Complete().New()
|
s, err := config.Complete().New(EmptyDelegate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Error in bringing up the server: %v", err)
|
t.Fatalf("Error in bringing up the server: %v", err)
|
||||||
}
|
}
|
||||||
@ -140,7 +138,7 @@ func TestInstallAPIGroups(t *testing.T) {
|
|||||||
config.LegacyAPIGroupPrefixes = sets.NewString("/apiPrefix")
|
config.LegacyAPIGroupPrefixes = sets.NewString("/apiPrefix")
|
||||||
config.DiscoveryAddresses = discovery.DefaultAddresses{DefaultAddress: "ExternalAddress"}
|
config.DiscoveryAddresses = discovery.DefaultAddresses{DefaultAddress: "ExternalAddress"}
|
||||||
|
|
||||||
s, err := config.SkipComplete().New()
|
s, err := config.SkipComplete().New(EmptyDelegate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Error in bringing up the server: %v", err)
|
t.Fatalf("Error in bringing up the server: %v", err)
|
||||||
}
|
}
|
||||||
@ -304,7 +302,7 @@ func TestPrepareRun(t *testing.T) {
|
|||||||
assert.NotNil(config.SwaggerConfig)
|
assert.NotNil(config.SwaggerConfig)
|
||||||
// assert.NotNil(config.OpenAPIConfig)
|
// assert.NotNil(config.OpenAPIConfig)
|
||||||
|
|
||||||
server := httptest.NewServer(s.HandlerContainer.ServeMux)
|
server := httptest.NewServer(s.Handler.GoRestfulContainer.ServeMux)
|
||||||
defer server.Close()
|
defer server.Close()
|
||||||
|
|
||||||
s.PrepareRun()
|
s.PrepareRun()
|
||||||
@ -345,13 +343,13 @@ func TestCustomHandlerChain(t *testing.T) {
|
|||||||
called = true
|
called = true
|
||||||
})
|
})
|
||||||
|
|
||||||
s, err := config.SkipComplete().New()
|
s, err := config.SkipComplete().New(EmptyDelegate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Error in bringing up the server: %v", err)
|
t.Fatalf("Error in bringing up the server: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
s.FallThroughHandler.Handle("/nonswagger", handler)
|
s.Handler.PostGoRestfulMux.Handle("/nonswagger", handler)
|
||||||
s.FallThroughHandler.Handle("/secret", handler)
|
s.Handler.PostGoRestfulMux.Handle("/secret", handler)
|
||||||
|
|
||||||
type Test struct {
|
type Test struct {
|
||||||
handler http.Handler
|
handler http.Handler
|
||||||
@ -400,7 +398,7 @@ func TestNotRestRoutesHaveAuth(t *testing.T) {
|
|||||||
kubeVersion := fakeVersion()
|
kubeVersion := fakeVersion()
|
||||||
config.Version = &kubeVersion
|
config.Version = &kubeVersion
|
||||||
|
|
||||||
s, err := config.SkipComplete().New()
|
s, err := config.SkipComplete().New(EmptyDelegate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Error in bringing up the server: %v", err)
|
t.Fatalf("Error in bringing up the server: %v", err)
|
||||||
}
|
}
|
||||||
|
128
staging/src/k8s.io/apiserver/pkg/server/handler.go
Normal file
128
staging/src/k8s.io/apiserver/pkg/server/handler.go
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2017 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 server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
rt "runtime"
|
||||||
|
"sort"
|
||||||
|
|
||||||
|
"github.com/emicklei/go-restful"
|
||||||
|
"github.com/golang/glog"
|
||||||
|
|
||||||
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
|
"k8s.io/apiserver/pkg/endpoints/handlers/responsewriters"
|
||||||
|
"k8s.io/apiserver/pkg/server/mux"
|
||||||
|
genericmux "k8s.io/apiserver/pkg/server/mux"
|
||||||
|
)
|
||||||
|
|
||||||
|
// APIServerHandlers holds the different http.Handlers used by the API server.
|
||||||
|
// This includes the full handler chain, the gorestful handler (used for the API) which falls through to the postGoRestful handler
|
||||||
|
// and the postGoRestful handler (which can contain a fallthrough of its own)
|
||||||
|
type APIServerHandler struct {
|
||||||
|
// FullHandlerChain is the one that is eventually served with. It should include the full filter
|
||||||
|
// chain and then call the GoRestfulContainer.
|
||||||
|
FullHandlerChain http.Handler
|
||||||
|
// The registered APIs
|
||||||
|
GoRestfulContainer *restful.Container
|
||||||
|
// PostGoRestfulMux is the final HTTP handler in the chain.
|
||||||
|
// It comes after all filters and the API handling
|
||||||
|
PostGoRestfulMux *mux.PathRecorderMux
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandlerChainBuilderFn is used to wrap the GoRestfulContainer handler using the provided handler chain.
|
||||||
|
// It is normally used to apply filtering like authentication and authorization
|
||||||
|
type HandlerChainBuilderFn func(apiHandler http.Handler) http.Handler
|
||||||
|
|
||||||
|
func NewAPIServerHandler(s runtime.NegotiatedSerializer, handlerChainBuilder HandlerChainBuilderFn, notFoundHandler http.Handler) *APIServerHandler {
|
||||||
|
postGoRestfulMux := genericmux.NewPathRecorderMux()
|
||||||
|
if notFoundHandler != nil {
|
||||||
|
postGoRestfulMux.NotFoundHandler(notFoundHandler)
|
||||||
|
}
|
||||||
|
|
||||||
|
gorestfulContainer := restful.NewContainer()
|
||||||
|
gorestfulContainer.ServeMux = http.NewServeMux()
|
||||||
|
gorestfulContainer.Router(restful.CurlyRouter{}) // e.g. for proxy/{kind}/{name}/{*}
|
||||||
|
gorestfulContainer.RecoverHandler(func(panicReason interface{}, httpWriter http.ResponseWriter) {
|
||||||
|
logStackOnRecover(s, panicReason, httpWriter)
|
||||||
|
})
|
||||||
|
gorestfulContainer.ServiceErrorHandler(func(serviceErr restful.ServiceError, request *restful.Request, response *restful.Response) {
|
||||||
|
serviceErrorHandler(s, serviceErr, request, response)
|
||||||
|
})
|
||||||
|
|
||||||
|
// register the defaultHandler for everything. This will allow an unhandled request to fall through to another handler instead of
|
||||||
|
// ending up with a forced 404
|
||||||
|
gorestfulContainer.Handle("/", postGoRestfulMux)
|
||||||
|
|
||||||
|
return &APIServerHandler{
|
||||||
|
FullHandlerChain: handlerChainBuilder(gorestfulContainer.ServeMux),
|
||||||
|
GoRestfulContainer: gorestfulContainer,
|
||||||
|
PostGoRestfulMux: postGoRestfulMux,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListedPaths returns the paths that should be shown under /
|
||||||
|
func (a *APIServerHandler) ListedPaths() []string {
|
||||||
|
var handledPaths []string
|
||||||
|
// Extract the paths handled using restful.WebService
|
||||||
|
for _, ws := range a.GoRestfulContainer.RegisteredWebServices() {
|
||||||
|
handledPaths = append(handledPaths, ws.RootPath())
|
||||||
|
}
|
||||||
|
handledPaths = append(handledPaths, a.PostGoRestfulMux.ListedPaths()...)
|
||||||
|
sort.Strings(handledPaths)
|
||||||
|
|
||||||
|
return handledPaths
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: Unify with RecoverPanics?
|
||||||
|
func logStackOnRecover(s runtime.NegotiatedSerializer, panicReason interface{}, w http.ResponseWriter) {
|
||||||
|
var buffer bytes.Buffer
|
||||||
|
buffer.WriteString(fmt.Sprintf("recover from panic situation: - %v\r\n", panicReason))
|
||||||
|
for i := 2; ; i++ {
|
||||||
|
_, file, line, ok := rt.Caller(i)
|
||||||
|
if !ok {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
buffer.WriteString(fmt.Sprintf(" %s:%d\r\n", file, line))
|
||||||
|
}
|
||||||
|
glog.Errorln(buffer.String())
|
||||||
|
|
||||||
|
headers := http.Header{}
|
||||||
|
if ct := w.Header().Get("Content-Type"); len(ct) > 0 {
|
||||||
|
headers.Set("Accept", ct)
|
||||||
|
}
|
||||||
|
responsewriters.ErrorNegotiated(apierrors.NewGenericServerResponse(http.StatusInternalServerError, "", schema.GroupResource{}, "", "", 0, false), s, schema.GroupVersion{}, w, &http.Request{Header: headers})
|
||||||
|
}
|
||||||
|
|
||||||
|
func serviceErrorHandler(s runtime.NegotiatedSerializer, serviceErr restful.ServiceError, request *restful.Request, resp *restful.Response) {
|
||||||
|
responsewriters.ErrorNegotiated(
|
||||||
|
apierrors.NewGenericServerResponse(serviceErr.Code, "", schema.GroupResource{}, "", serviceErr.Message, 0, false),
|
||||||
|
s,
|
||||||
|
schema.GroupVersion{},
|
||||||
|
resp,
|
||||||
|
request.Request,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ServeHTTP makes it an http.Handler
|
||||||
|
func (a *APIServerHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
|
a.FullHandlerChain.ServeHTTP(w, r)
|
||||||
|
}
|
@ -41,5 +41,5 @@ func (s *GenericAPIServer) installHealthz() {
|
|||||||
defer s.healthzLock.Unlock()
|
defer s.healthzLock.Unlock()
|
||||||
s.healthzCreated = true
|
s.healthzCreated = true
|
||||||
|
|
||||||
healthz.InstallHandler(s.FallThroughHandler, s.healthzChecks...)
|
healthz.InstallHandler(s.Handler.PostGoRestfulMux, s.healthzChecks...)
|
||||||
}
|
}
|
||||||
|
@ -19,19 +19,12 @@ go_test(
|
|||||||
go_library(
|
go_library(
|
||||||
name = "go_default_library",
|
name = "go_default_library",
|
||||||
srcs = [
|
srcs = [
|
||||||
"container.go",
|
|
||||||
"doc.go",
|
"doc.go",
|
||||||
"pathrecorder.go",
|
"pathrecorder.go",
|
||||||
],
|
],
|
||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
deps = [
|
deps = [
|
||||||
"//vendor/github.com/emicklei/go-restful:go_default_library",
|
|
||||||
"//vendor/github.com/golang/glog:go_default_library",
|
|
||||||
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
|
||||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
|
||||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
|
||||||
"//vendor/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/util/runtime: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/apiserver/pkg/endpoints/handlers/responsewriters:go_default_library",
|
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
@ -1,102 +0,0 @@
|
|||||||
/*
|
|
||||||
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 mux
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
rt "runtime"
|
|
||||||
"sort"
|
|
||||||
|
|
||||||
"github.com/emicklei/go-restful"
|
|
||||||
"github.com/golang/glog"
|
|
||||||
|
|
||||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
|
||||||
"k8s.io/apiserver/pkg/endpoints/handlers/responsewriters"
|
|
||||||
)
|
|
||||||
|
|
||||||
// APIContainer is a restful container which in addition support registering
|
|
||||||
// handlers that do not show up in swagger or in /
|
|
||||||
type APIContainer struct {
|
|
||||||
*restful.Container
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewAPIContainer constructs a new container for APIs
|
|
||||||
func NewAPIContainer(mux *http.ServeMux, s runtime.NegotiatedSerializer, defaultMux http.Handler) *APIContainer {
|
|
||||||
c := APIContainer{
|
|
||||||
Container: restful.NewContainer(),
|
|
||||||
}
|
|
||||||
c.Container.ServeMux = mux
|
|
||||||
c.Container.Router(restful.CurlyRouter{}) // e.g. for proxy/{kind}/{name}/{*}
|
|
||||||
c.Container.RecoverHandler(func(panicReason interface{}, httpWriter http.ResponseWriter) {
|
|
||||||
logStackOnRecover(s, panicReason, httpWriter)
|
|
||||||
})
|
|
||||||
c.Container.ServiceErrorHandler(func(serviceErr restful.ServiceError, request *restful.Request, response *restful.Response) {
|
|
||||||
serviceErrorHandler(s, serviceErr, request, response)
|
|
||||||
})
|
|
||||||
|
|
||||||
// register the defaultHandler for everything. This will allow an unhandled request to fall through to another handler instead of
|
|
||||||
// ending up with a forced 404
|
|
||||||
c.Container.Handle("/", defaultMux)
|
|
||||||
|
|
||||||
return &c
|
|
||||||
}
|
|
||||||
|
|
||||||
// ListedPaths returns the paths of the webservices for listing on /.
|
|
||||||
func (c *APIContainer) ListedPaths() []string {
|
|
||||||
var handledPaths []string
|
|
||||||
// Extract the paths handled using restful.WebService
|
|
||||||
for _, ws := range c.RegisteredWebServices() {
|
|
||||||
handledPaths = append(handledPaths, ws.RootPath())
|
|
||||||
}
|
|
||||||
sort.Strings(handledPaths)
|
|
||||||
|
|
||||||
return handledPaths
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO: Unify with RecoverPanics?
|
|
||||||
func logStackOnRecover(s runtime.NegotiatedSerializer, panicReason interface{}, w http.ResponseWriter) {
|
|
||||||
var buffer bytes.Buffer
|
|
||||||
buffer.WriteString(fmt.Sprintf("recover from panic situation: - %v\r\n", panicReason))
|
|
||||||
for i := 2; ; i++ {
|
|
||||||
_, file, line, ok := rt.Caller(i)
|
|
||||||
if !ok {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
buffer.WriteString(fmt.Sprintf(" %s:%d\r\n", file, line))
|
|
||||||
}
|
|
||||||
glog.Errorln(buffer.String())
|
|
||||||
|
|
||||||
headers := http.Header{}
|
|
||||||
if ct := w.Header().Get("Content-Type"); len(ct) > 0 {
|
|
||||||
headers.Set("Accept", ct)
|
|
||||||
}
|
|
||||||
responsewriters.ErrorNegotiated(apierrors.NewGenericServerResponse(http.StatusInternalServerError, "", schema.GroupResource{}, "", "", 0, false), s, schema.GroupVersion{}, w, &http.Request{Header: headers})
|
|
||||||
}
|
|
||||||
|
|
||||||
func serviceErrorHandler(s runtime.NegotiatedSerializer, serviceErr restful.ServiceError, request *restful.Request, resp *restful.Response) {
|
|
||||||
responsewriters.ErrorNegotiated(
|
|
||||||
apierrors.NewGenericServerResponse(serviceErr.Code, "", schema.GroupResource{}, "", serviceErr.Message, 0, false),
|
|
||||||
s,
|
|
||||||
schema.GroupVersion{},
|
|
||||||
resp,
|
|
||||||
request.Request,
|
|
||||||
)
|
|
||||||
}
|
|
@ -475,7 +475,7 @@ NextTest:
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
s, err := config.Complete().New()
|
s, err := config.Complete().New(server.EmptyDelegate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("%q - failed creating the server: %v", title, err)
|
t.Errorf("%q - failed creating the server: %v", title, err)
|
||||||
return
|
return
|
||||||
|
@ -17,6 +17,8 @@ limitations under the License.
|
|||||||
package routes
|
package routes
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/emicklei/go-restful"
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/openapi"
|
"k8s.io/apimachinery/pkg/openapi"
|
||||||
"k8s.io/apiserver/pkg/server/mux"
|
"k8s.io/apiserver/pkg/server/mux"
|
||||||
apiserveropenapi "k8s.io/apiserver/pkg/server/openapi"
|
apiserveropenapi "k8s.io/apiserver/pkg/server/openapi"
|
||||||
@ -30,7 +32,7 @@ type OpenAPI struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Install adds the SwaggerUI webservice to the given mux.
|
// Install adds the SwaggerUI webservice to the given mux.
|
||||||
func (oa OpenAPI) Install(c *mux.APIContainer, mux *mux.PathRecorderMux) {
|
func (oa OpenAPI) Install(c *restful.Container, mux *mux.PathRecorderMux) {
|
||||||
err := apiserveropenapi.RegisterOpenAPIService("/swagger.json", c.RegisteredWebServices(), oa.Config, mux)
|
err := apiserveropenapi.RegisterOpenAPIService("/swagger.json", c.RegisteredWebServices(), oa.Config, mux)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Fatalf("Failed to register open api spec for root: %v", err)
|
glog.Fatalf("Failed to register open api spec for root: %v", err)
|
||||||
|
@ -17,8 +17,7 @@ limitations under the License.
|
|||||||
package routes
|
package routes
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"k8s.io/apiserver/pkg/server/mux"
|
"github.com/emicklei/go-restful"
|
||||||
|
|
||||||
"github.com/emicklei/go-restful-swagger12"
|
"github.com/emicklei/go-restful-swagger12"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -31,7 +30,7 @@ type Swagger struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Install adds the SwaggerUI webservice to the given mux.
|
// Install adds the SwaggerUI webservice to the given mux.
|
||||||
func (s Swagger) Install(c *mux.APIContainer) {
|
func (s Swagger) Install(c *restful.Container) {
|
||||||
s.Config.WebServices = c.RegisteredWebServices()
|
s.Config.WebServices = c.RegisteredWebServices()
|
||||||
swagger.RegisterSwaggerService(*s.Config, c.Container)
|
swagger.RegisterSwaggerService(*s.Config, c)
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,6 @@ import (
|
|||||||
|
|
||||||
"k8s.io/apimachinery/pkg/version"
|
"k8s.io/apimachinery/pkg/version"
|
||||||
"k8s.io/apiserver/pkg/endpoints/handlers/responsewriters"
|
"k8s.io/apiserver/pkg/endpoints/handlers/responsewriters"
|
||||||
"k8s.io/apiserver/pkg/server/mux"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Version provides a webservice with version information.
|
// Version provides a webservice with version information.
|
||||||
@ -32,7 +31,7 @@ type Version struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Install registers the APIServer's `/version` handler.
|
// Install registers the APIServer's `/version` handler.
|
||||||
func (v Version) Install(c *mux.APIContainer) {
|
func (v Version) Install(c *restful.Container) {
|
||||||
if v.Version == nil {
|
if v.Version == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -135,7 +135,7 @@ func (c *Config) SkipComplete() completedConfig {
|
|||||||
|
|
||||||
// New returns a new instance of APIAggregator from the given config.
|
// New returns a new instance of APIAggregator from the given config.
|
||||||
func (c completedConfig) NewWithDelegate(delegationTarget genericapiserver.DelegationTarget, stopCh <-chan struct{}) (*APIAggregator, error) {
|
func (c completedConfig) NewWithDelegate(delegationTarget genericapiserver.DelegationTarget, stopCh <-chan struct{}) (*APIAggregator, error) {
|
||||||
genericServer, err := c.Config.GenericConfig.SkipComplete().NewWithDelegate(delegationTarget) // completion is done in Complete, no need for a second time
|
genericServer, err := c.Config.GenericConfig.SkipComplete().New(delegationTarget) // completion is done in Complete, no need for a second time
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -176,8 +176,8 @@ func (c completedConfig) NewWithDelegate(delegationTarget genericapiserver.Deleg
|
|||||||
serviceLister: s.serviceLister,
|
serviceLister: s.serviceLister,
|
||||||
endpointsLister: s.endpointsLister,
|
endpointsLister: s.endpointsLister,
|
||||||
}
|
}
|
||||||
s.GenericAPIServer.FallThroughHandler.Handle("/apis", apisHandler)
|
s.GenericAPIServer.Handler.PostGoRestfulMux.Handle("/apis", apisHandler)
|
||||||
s.GenericAPIServer.FallThroughHandler.UnlistedHandle("/apis/", apisHandler)
|
s.GenericAPIServer.Handler.PostGoRestfulMux.UnlistedHandle("/apis/", apisHandler)
|
||||||
|
|
||||||
apiserviceRegistrationController := NewAPIServiceRegistrationController(informerFactory.Apiregistration().InternalVersion().APIServices(), kubeInformers.Core().V1().Services(), s)
|
apiserviceRegistrationController := NewAPIServiceRegistrationController(informerFactory.Apiregistration().InternalVersion().APIServices(), kubeInformers.Core().V1().Services(), s)
|
||||||
|
|
||||||
@ -219,8 +219,8 @@ func (s *APIAggregator) AddAPIService(apiService *apiregistration.APIService, de
|
|||||||
}
|
}
|
||||||
proxyHandler.updateAPIService(apiService, destinationHost)
|
proxyHandler.updateAPIService(apiService, destinationHost)
|
||||||
s.proxyHandlers[apiService.Name] = proxyHandler
|
s.proxyHandlers[apiService.Name] = proxyHandler
|
||||||
s.GenericAPIServer.FallThroughHandler.Handle(proxyPath, proxyHandler)
|
s.GenericAPIServer.Handler.PostGoRestfulMux.Handle(proxyPath, proxyHandler)
|
||||||
s.GenericAPIServer.FallThroughHandler.UnlistedHandle(proxyPath+"/", proxyHandler)
|
s.GenericAPIServer.Handler.PostGoRestfulMux.UnlistedHandlePrefix(proxyPath+"/", proxyHandler)
|
||||||
|
|
||||||
// if we're dealing with the legacy group, we're done here
|
// if we're dealing with the legacy group, we're done here
|
||||||
if apiService.Name == legacyAPIServiceName {
|
if apiService.Name == legacyAPIServiceName {
|
||||||
@ -243,8 +243,8 @@ func (s *APIAggregator) AddAPIService(apiService *apiregistration.APIService, de
|
|||||||
delegate: s.delegateHandler,
|
delegate: s.delegateHandler,
|
||||||
}
|
}
|
||||||
// aggregation is protected
|
// aggregation is protected
|
||||||
s.GenericAPIServer.FallThroughHandler.Handle(groupPath, groupDiscoveryHandler)
|
s.GenericAPIServer.Handler.PostGoRestfulMux.Handle(groupPath, groupDiscoveryHandler)
|
||||||
s.GenericAPIServer.FallThroughHandler.UnlistedHandle(groupPath+"/", groupDiscoveryHandler)
|
s.GenericAPIServer.Handler.PostGoRestfulMux.UnlistedHandle(groupPath+"/", groupDiscoveryHandler)
|
||||||
s.handledGroups.Insert(apiService.Spec.Group)
|
s.handledGroups.Insert(apiService.Spec.Group)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -258,8 +258,8 @@ func (s *APIAggregator) RemoveAPIService(apiServiceName string) {
|
|||||||
if apiServiceName == legacyAPIServiceName {
|
if apiServiceName == legacyAPIServiceName {
|
||||||
proxyPath = "/api"
|
proxyPath = "/api"
|
||||||
}
|
}
|
||||||
s.GenericAPIServer.FallThroughHandler.Unregister(proxyPath)
|
s.GenericAPIServer.Handler.PostGoRestfulMux.Unregister(proxyPath)
|
||||||
s.GenericAPIServer.FallThroughHandler.Unregister(proxyPath + "/")
|
s.GenericAPIServer.Handler.PostGoRestfulMux.Unregister(proxyPath + "/")
|
||||||
delete(s.proxyHandlers, apiServiceName)
|
delete(s.proxyHandlers, apiServiceName)
|
||||||
|
|
||||||
// TODO unregister group level discovery when there are no more versions for the group
|
// TODO unregister group level discovery when there are no more versions for the group
|
||||||
|
@ -102,7 +102,7 @@ func (c *Config) SkipComplete() completedConfig {
|
|||||||
|
|
||||||
// New returns a new instance of CustomResources from the given config.
|
// New returns a new instance of CustomResources from the given config.
|
||||||
func (c completedConfig) New(delegationTarget genericapiserver.DelegationTarget, stopCh <-chan struct{}) (*CustomResources, error) {
|
func (c completedConfig) New(delegationTarget genericapiserver.DelegationTarget, stopCh <-chan struct{}) (*CustomResources, error) {
|
||||||
genericServer, err := c.Config.GenericConfig.SkipComplete().New() // completion is done in Complete, no need for a second time
|
genericServer, err := c.Config.GenericConfig.SkipComplete().New(genericapiserver.EmptyDelegate) // completion is done in Complete, no need for a second time
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -149,8 +149,8 @@ func (c completedConfig) New(delegationTarget genericapiserver.DelegationTarget,
|
|||||||
c.CustomResourceRESTOptionsGetter,
|
c.CustomResourceRESTOptionsGetter,
|
||||||
c.GenericConfig.AdmissionControl,
|
c.GenericConfig.AdmissionControl,
|
||||||
)
|
)
|
||||||
s.GenericAPIServer.FallThroughHandler.Handle("/apis", customResourceHandler)
|
s.GenericAPIServer.Handler.PostGoRestfulMux.Handle("/apis", customResourceHandler)
|
||||||
s.GenericAPIServer.FallThroughHandler.HandlePrefix("/apis/", customResourceHandler)
|
s.GenericAPIServer.Handler.PostGoRestfulMux.HandlePrefix("/apis/", customResourceHandler)
|
||||||
|
|
||||||
customResourceController := NewDiscoveryController(customResourceInformers.Apiextensions().InternalVersion().CustomResources(), versionDiscoveryHandler, groupDiscoveryHandler)
|
customResourceController := NewDiscoveryController(customResourceInformers.Apiextensions().InternalVersion().CustomResources(), versionDiscoveryHandler, groupDiscoveryHandler)
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ func (c *Config) SkipComplete() completedConfig {
|
|||||||
|
|
||||||
// New returns a new instance of WardleServer from the given config.
|
// New returns a new instance of WardleServer from the given config.
|
||||||
func (c completedConfig) New() (*WardleServer, error) {
|
func (c completedConfig) New() (*WardleServer, error) {
|
||||||
genericServer, err := c.Config.GenericConfig.SkipComplete().New() // completion is done in Complete, no need for a second time
|
genericServer, err := c.Config.GenericConfig.SkipComplete().New(genericapiserver.EmptyDelegate) // completion is done in Complete, no need for a second time
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -236,7 +236,7 @@ func startMasterOrDie(masterConfig *master.Config, incomingServer *httptest.Serv
|
|||||||
|
|
||||||
masterConfig.GenericConfig.LoopbackClientConfig.BearerToken = privilegedLoopbackToken
|
masterConfig.GenericConfig.LoopbackClientConfig.BearerToken = privilegedLoopbackToken
|
||||||
|
|
||||||
m, err := masterConfig.Complete().New()
|
m, err := masterConfig.Complete().New(genericapiserver.EmptyDelegate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Fatalf("error in bringing up the master: %v", err)
|
glog.Fatalf("error in bringing up the master: %v", err)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user