// 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.ClusterIP = net.IPv4(10, 10, 10, 10) 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 (c *MasterConfig) RunHealth() { apiContainer := genericmux.NewAPIContainer(http.NewServeMux(), kapi.Codecs) healthz.InstallHandler(&apiContainer.NonSwaggerRoutes, healthz.PingHealthz) initReadinessCheckRoute(apiContainer, "/healthz/ready", func() bool { return true }) initMetricsRoute(apiContainer, "/metrics") c.serve(apiContainer.ServeMux, []string{"Started health checks at %s"}) }
// 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()) } }
// New returns a new instance of GenericAPIServer from the given config. // Certain config fields will be set to a default value if unset, // including: // 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) { if c.Serializer == nil { return nil, fmt.Errorf("Genericapiserver.New() called with config.Serializer == nil") } s := &GenericAPIServer{ ServiceClusterIPRange: c.ServiceClusterIPRange, ServiceNodePortRange: c.ServiceNodePortRange, LoopbackClientConfig: c.LoopbackClientConfig, legacyAPIPrefix: c.APIPrefix, apiPrefix: c.APIGroupPrefix, admissionControl: c.AdmissionControl, requestContextMapper: c.RequestContextMapper, Serializer: c.Serializer, minRequestTimeout: time.Duration(c.MinRequestTimeout) * time.Second, enableSwaggerSupport: c.EnableSwaggerSupport, MasterCount: c.MasterCount, SecureServingInfo: c.SecureServingInfo, InsecureServingInfo: c.InsecureServingInfo, ExternalAddress: c.ExternalHost, ClusterIP: c.PublicAddress, PublicReadWritePort: c.ReadWritePort, ServiceReadWriteIP: c.ServiceReadWriteIP, ServiceReadWritePort: c.ServiceReadWritePort, ExtraServicePorts: c.ExtraServicePorts, ExtraEndpointPorts: c.ExtraEndpointPorts, KubernetesServiceNodePort: c.KubernetesServiceNodePort, apiGroupsForDiscovery: map[string]unversioned.APIGroup{}, enableOpenAPISupport: c.EnableOpenAPISupport, openAPIInfo: c.OpenAPIInfo, openAPIDefaultResponse: c.OpenAPIDefaultResponse, openAPIDefinitions: c.OpenAPIDefinitions, } s.HandlerContainer = mux.NewAPIContainer(http.NewServeMux(), c.Serializer) if c.ProxyDialer != nil || c.ProxyTLSClientConfig != nil { s.ProxyTransport = utilnet.SetTransportDefaults(&http.Transport{ Dial: c.ProxyDialer, TLSClientConfig: c.ProxyTLSClientConfig, }) } s.installAPI(c.Config) s.Handler, s.InsecureHandler = c.BuildHandlerChainsFunc(s.HandlerContainer.ServeMux, c.Config) return s, nil }
func (c *MasterConfig) RunInProxyMode(proxy *kubernetes.ProxyConfig, assetConfig *AssetConfig) { handlerChain, messages, err := c.buildHandlerChain(assetConfig) if err != nil { glog.Fatalf("Failed to launch master: %v", err) } // TODO(sttts): create a genericapiserver here container := genericmux.NewAPIContainer(http.NewServeMux(), kapi.Codecs) // install /api proxy forwarder proxyMessages, err := proxy.InstallAPI(container.Container) if err != nil { glog.Fatalf("Failed to launch master: %v", err) } messages = append(messages, proxyMessages...) // install GenericAPIServer handlers manually, usually done by GenericAPIServer.PrepareRun() healthz.InstallHandler(&container.NonSwaggerRoutes, healthz.PingHealthz) swaggerConfig := genericapiserver.DefaultSwaggerConfig() swaggerConfig.WebServicesUrl = c.Options.MasterPublicURL genericroutes.Swagger{Config: swaggerConfig}.Install(container) messages = append(messages, fmt.Sprintf("Started Swagger Schema API at %%s%s", swaggerConfig.ApiPath)) genericroutes.OpenAPI{Config: kubernetes.DefaultOpenAPIConfig()}.Install(container) messages = append(messages, fmt.Sprintf("Started OpenAPI Schema at %%s%s", openAPIServePath)) // install origin handlers c.InstallProtectedAPI(container) // TODO(sttts): split cmd/server/kubernetes config generation into generic and master-specific // until then: create ad-hoc config genericConfig := genericapiserver.NewConfig() genericConfig.RequestContextMapper = c.RequestContextMapper genericConfig.LegacyAPIGroupPrefixes = kubernetes.LegacyAPIGroupPrefixes genericConfig.MaxRequestsInFlight = c.Options.ServingInfo.MaxRequestsInFlight secureHandler, _ := handlerChain(container.ServeMux, genericConfig) c.serve(secureHandler, messages) // Attempt to verify the server came up for 20 seconds (100 tries * 100ms, 100ms timeout per try) cmdutil.WaitForSuccessfulDial(c.TLS, c.Options.ServingInfo.BindNetwork, c.Options.ServingInfo.BindAddress, 100*time.Millisecond, 100*time.Millisecond, 100) }
// New returns a new instance of GenericAPIServer from the given config. // Certain config fields will be set to a default value if unset, // including: // 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) { if c.Serializer == nil { return nil, fmt.Errorf("Genericapiserver.New() called with config.Serializer == nil") } s := &GenericAPIServer{ ServiceClusterIPRange: c.ServiceClusterIPRange, LoopbackClientConfig: c.LoopbackClientConfig, legacyAPIGroupPrefixes: c.LegacyAPIGroupPrefixes, admissionControl: c.AdmissionControl, requestContextMapper: c.RequestContextMapper, Serializer: c.Serializer, minRequestTimeout: time.Duration(c.MinRequestTimeout) * time.Second, enableSwaggerSupport: c.EnableSwaggerSupport, MasterCount: c.MasterCount, SecureServingInfo: c.SecureServingInfo, InsecureServingInfo: c.InsecureServingInfo, ExternalAddress: c.ExternalHost, ServiceReadWriteIP: c.ServiceReadWriteIP, ServiceReadWritePort: c.ServiceReadWritePort, KubernetesServiceNodePort: c.KubernetesServiceNodePort, apiGroupsForDiscovery: map[string]unversioned.APIGroup{}, enableOpenAPISupport: c.EnableOpenAPISupport, openAPIConfig: c.OpenAPIConfig, } s.HandlerContainer = mux.NewAPIContainer(http.NewServeMux(), c.Serializer) s.installAPI(c.Config) s.Handler, s.InsecureHandler = c.BuildHandlerChainsFunc(s.HandlerContainer.ServeMux, c.Config) return s, nil }
// New returns a new instance of GenericAPIServer from the given config. // Certain config fields will be set to a default value if unset, // including: // 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) { if c.Serializer == nil { return nil, fmt.Errorf("Genericapiserver.New() called with config.Serializer == nil") } s := &GenericAPIServer{ discoveryAddresses: c.DiscoveryAddresses, LoopbackClientConfig: c.LoopbackClientConfig, legacyAPIGroupPrefixes: c.LegacyAPIGroupPrefixes, admissionControl: c.AdmissionControl, requestContextMapper: c.RequestContextMapper, Serializer: c.Serializer, minRequestTimeout: time.Duration(c.MinRequestTimeout) * time.Second, enableSwaggerSupport: c.EnableSwaggerSupport, SecureServingInfo: c.SecureServingInfo, InsecureServingInfo: c.InsecureServingInfo, ExternalAddress: c.ExternalAddress, apiGroupsForDiscovery: map[string]metav1.APIGroup{}, enableOpenAPISupport: c.EnableOpenAPISupport, openAPIConfig: c.OpenAPIConfig, postStartHooks: map[string]postStartHookEntry{}, healthzChecks: c.HealthzChecks, } s.HandlerContainer = mux.NewAPIContainer(http.NewServeMux(), c.Serializer) s.installAPI(c.Config) s.Handler, s.InsecureHandler = c.BuildHandlerChainsFunc(s.HandlerContainer.ServeMux, c.Config) return s, nil }