Make genericapiserver handler chain customizable

This commit is contained in:
Dr. Stefan Schimanski
2016-09-28 11:26:50 +02:00
committed by deads2k
parent 7cfd0150e4
commit 68cee1d9ac
18 changed files with 269 additions and 171 deletions

View File

@@ -42,6 +42,7 @@ import (
"k8s.io/kubernetes/pkg/apimachinery/registered"
"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/runtime"
@@ -118,9 +119,8 @@ type GenericAPIServer struct {
// requestContextMapper provides a way to get the context for a request. It may be nil.
requestContextMapper api.RequestContextMapper
Mux *apiserver.PathRecorderMux
HandlerContainer *restful.Container
MasterCount int
// The registered APIs
HandlerContainer *genericmux.APIContainer
SecureServingInfo *ServingInfo
InsecureServingInfo *ServingInfo
@@ -128,13 +128,9 @@ type GenericAPIServer struct {
// ExternalAddress is the address (hostname or IP and port) that should be used in
// external (public internet) URLs for this GenericAPIServer.
ExternalAddress string
// ClusterIP is the IP address of the GenericAPIServer within the cluster.
ClusterIP net.IP
PublicReadWritePort int
ServiceReadWriteIP net.IP
ServiceReadWritePort int
ExtraServicePorts []api.ServicePort
ExtraEndpointPorts []api.EndpointPort
ClusterIP net.IP
// storage contains the RESTful endpoints exposed by this GenericAPIServer
storage map[string]rest.Storage
@@ -150,26 +146,31 @@ type GenericAPIServer struct {
// Used for custom proxy dialing, and proxy TLS options
ProxyTransport http.RoundTripper
KubernetesServiceNodePort int
// Map storing information about all groups to be exposed in discovery response.
// The map is from name to the group.
apiGroupsForDiscoveryLock sync.RWMutex
apiGroupsForDiscovery map[string]unversioned.APIGroup
// See Config.$name for documentation of these flags
enableOpenAPISupport bool
openAPIInfo spec.Info
openAPIDefaultResponse spec.Response
openAPIDefinitions *common.OpenAPIDefinitions
// PostStartHooks are each called after the server has started listening, in a separate go func for each
// with no guaranteee of ordering between them. The map key is a name used for error reporting.
// It may kill the process with a panic if it wishes to by returning an error
postStartHooks map[string]PostStartHookFunc
postStartHookLock sync.Mutex
postStartHooksCalled bool
// See Config.$name for documentation of these flags:
enableOpenAPISupport bool
openAPIInfo spec.Info
openAPIDefaultResponse spec.Response
openAPIDefinitions *common.OpenAPIDefinitions
MasterCount int
KubernetesServiceNodePort int // TODO(sttts): move into master
PublicReadWritePort int
ServiceReadWriteIP net.IP
ServiceReadWritePort int
ExtraServicePorts []api.ServicePort
ExtraEndpointPorts []api.EndpointPort
}
func init() {
@@ -191,33 +192,6 @@ func (s *GenericAPIServer) MinRequestTimeout() time.Duration {
return s.minRequestTimeout
}
// HandleWithAuth adds an http.Handler for pattern to an http.ServeMux
// Applies the same authentication and authorization (if any is configured)
// to the request is used for the GenericAPIServer's built-in endpoints.
func (s *GenericAPIServer) HandleWithAuth(pattern string, handler http.Handler) {
// TODO: Add a way for plugged-in endpoints to translate their
// URLs into attributes that an Authorizer can understand, and have
// sensible policy defaults for plugged-in endpoints. This will be different
// for generic endpoints versus REST object endpoints.
// TODO: convert to go-restful
s.Mux.Handle(pattern, handler)
}
// HandleFuncWithAuth adds an http.Handler for pattern to an http.ServeMux
// Applies the same authentication and authorization (if any is configured)
// to the request is used for the GenericAPIServer's built-in endpoints.
func (s *GenericAPIServer) HandleFuncWithAuth(pattern string, handler func(http.ResponseWriter, *http.Request)) {
// TODO: convert to go-restful
s.Mux.HandleFunc(pattern, handler)
}
func NewHandlerContainer(mux *http.ServeMux, s runtime.NegotiatedSerializer) *restful.Container {
container := restful.NewContainer()
container.ServeMux = mux
apiserver.InstallRecoverHandler(s, container)
return container
}
func (s *GenericAPIServer) Run() {
// install APIs which depend on other APIs to be installed
if s.enableSwaggerSupport {
@@ -227,7 +201,7 @@ func (s *GenericAPIServer) Run() {
s.InstallOpenAPI()
}
if s.SecureServingInfo != nil {
if s.SecureServingInfo != nil && s.Handler != nil {
secureServer := &http.Server{
Addr: s.SecureServingInfo.BindAddress,
Handler: s.Handler,
@@ -282,7 +256,7 @@ func (s *GenericAPIServer) Run() {
}()
}
if s.InsecureServingInfo != nil {
if s.InsecureServingInfo != nil && s.InsecureHandler != nil {
insecureServer := &http.Server{
Addr: s.InsecureServingInfo.BindAddress,
Handler: s.InsecureHandler,
@@ -343,14 +317,14 @@ func (s *GenericAPIServer) InstallAPIGroup(apiGroupInfo *APIGroupInfo) error {
apiGroupVersion.OptionsExternalVersion = apiGroupInfo.OptionsExternalVersion
}
if err := apiGroupVersion.InstallREST(s.HandlerContainer); err != nil {
if err := apiGroupVersion.InstallREST(s.HandlerContainer.Container); err != nil {
return fmt.Errorf("Unable to setup API %v: %v", apiGroupInfo, err)
}
}
// Install the version handler.
if apiGroupInfo.IsLegacyGroup {
// Add a handler at /api to enumerate the supported api versions.
apiserver.AddApiWebService(s.Serializer, s.HandlerContainer, apiPrefix, func(req *restful.Request) *unversioned.APIVersions {
apiserver.AddApiWebService(s.Serializer, s.HandlerContainer.Container, apiPrefix, func(req *restful.Request) *unversioned.APIVersions {
apiVersionsForDiscovery := unversioned.APIVersions{
ServerAddressByClientCIDRs: s.getServerAddressByClientCIDRs(req.Request),
Versions: apiVersions,
@@ -487,7 +461,7 @@ func (s *GenericAPIServer) getSwaggerConfig() *swagger.Config {
// 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)
swagger.RegisterSwaggerService(*s.getSwaggerConfig(), s.HandlerContainer.Container)
}
// InstallOpenAPI installs spec endpoints for each web service.
@@ -508,7 +482,7 @@ func (s *GenericAPIServer) InstallOpenAPI() {
Info: &info,
DefaultResponse: &s.openAPIDefaultResponse,
OpenAPIDefinitions: s.openAPIDefinitions,
}, s.HandlerContainer)
}, s.HandlerContainer.Container)
if err != nil {
glog.Fatalf("Failed to register open api spec for %v: %v", w.RootPath(), err)
}
@@ -521,7 +495,7 @@ func (s *GenericAPIServer) InstallOpenAPI() {
Info: &s.openAPIInfo,
DefaultResponse: &s.openAPIDefaultResponse,
OpenAPIDefinitions: s.openAPIDefinitions,
}, s.HandlerContainer)
}, s.HandlerContainer.Container)
if err != nil {
glog.Fatalf("Failed to register open api spec for root: %v", err)
}