Add generated file
This PR adds generated files under pkg/client and vendor folder.
This commit is contained in:
116
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/BUILD
generated
vendored
Normal file
116
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/BUILD
generated
vendored
Normal file
@@ -0,0 +1,116 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"aggregator.go",
|
||||
"apiextensions.go",
|
||||
"server.go",
|
||||
],
|
||||
importpath = "k8s.io/kubernetes/cmd/kube-apiserver/app",
|
||||
deps = [
|
||||
"//cmd/kube-apiserver/app/options:go_default_library",
|
||||
"//pkg/api/legacyscheme:go_default_library",
|
||||
"//pkg/apis/admissionregistration:go_default_library",
|
||||
"//pkg/apis/apps:go_default_library",
|
||||
"//pkg/apis/batch:go_default_library",
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/apis/events:go_default_library",
|
||||
"//pkg/apis/extensions:go_default_library",
|
||||
"//pkg/apis/networking:go_default_library",
|
||||
"//pkg/apis/policy:go_default_library",
|
||||
"//pkg/apis/storage:go_default_library",
|
||||
"//pkg/capabilities:go_default_library",
|
||||
"//pkg/client/clientset_generated/internalclientset:go_default_library",
|
||||
"//pkg/client/informers/informers_generated/internalversion:go_default_library",
|
||||
"//pkg/cloudprovider:go_default_library",
|
||||
"//pkg/controller/serviceaccount:go_default_library",
|
||||
"//pkg/features:go_default_library",
|
||||
"//pkg/generated/openapi:go_default_library",
|
||||
"//pkg/kubeapiserver:go_default_library",
|
||||
"//pkg/kubeapiserver/admission:go_default_library",
|
||||
"//pkg/kubeapiserver/authenticator:go_default_library",
|
||||
"//pkg/kubeapiserver/authorizer/modes:go_default_library",
|
||||
"//pkg/kubeapiserver/options:go_default_library",
|
||||
"//pkg/kubeapiserver/server:go_default_library",
|
||||
"//pkg/master:go_default_library",
|
||||
"//pkg/master/controller/crdregistration:go_default_library",
|
||||
"//pkg/master/reconcilers:go_default_library",
|
||||
"//pkg/master/tunneler:go_default_library",
|
||||
"//pkg/quota/install:go_default_library",
|
||||
"//pkg/registry/cachesize:go_default_library",
|
||||
"//pkg/registry/rbac/rest:go_default_library",
|
||||
"//pkg/serviceaccount:go_default_library",
|
||||
"//pkg/util/flag:go_default_library",
|
||||
"//pkg/util/reflector/prometheus:go_default_library",
|
||||
"//pkg/util/workqueue/prometheus:go_default_library",
|
||||
"//pkg/version:go_default_library",
|
||||
"//pkg/version/verflag:go_default_library",
|
||||
"//plugin/pkg/auth/authenticator/token/bootstrap:go_default_library",
|
||||
"//vendor/github.com/go-openapi/spec:go_default_library",
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/github.com/spf13/cobra:go_default_library",
|
||||
"//vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/apiextensions-apiserver/pkg/apiserver:go_default_library",
|
||||
"//vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion:go_default_library",
|
||||
"//vendor/k8s.io/apiextensions-apiserver/pkg/cmd/server:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/net:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/config:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/initializer:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authentication/authenticator:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/endpoints/openapi: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/healthz:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/server/options:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/server/options/encryptionconfig:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/server/storage:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/storage/etcd3/preflight:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||
"//vendor/k8s.io/client-go/discovery/cached:go_default_library",
|
||||
"//vendor/k8s.io/client-go/informers:go_default_library",
|
||||
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
|
||||
"//vendor/k8s.io/client-go/rest:go_default_library",
|
||||
"//vendor/k8s.io/client-go/restmapper:go_default_library",
|
||||
"//vendor/k8s.io/client-go/tools/cache:go_default_library",
|
||||
"//vendor/k8s.io/client-go/util/cert:go_default_library",
|
||||
"//vendor/k8s.io/kube-aggregator/pkg/apis/apiregistration:go_default_library",
|
||||
"//vendor/k8s.io/kube-aggregator/pkg/apis/apiregistration/v1:go_default_library",
|
||||
"//vendor/k8s.io/kube-aggregator/pkg/apis/apiregistration/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/kube-aggregator/pkg/apiserver:go_default_library",
|
||||
"//vendor/k8s.io/kube-aggregator/pkg/apiserver/scheme:go_default_library",
|
||||
"//vendor/k8s.io/kube-aggregator/pkg/client/clientset_generated/internalclientset/typed/apiregistration/internalversion:go_default_library",
|
||||
"//vendor/k8s.io/kube-aggregator/pkg/client/informers/internalversion/apiregistration/internalversion:go_default_library",
|
||||
"//vendor/k8s.io/kube-aggregator/pkg/controllers/autoregister:go_default_library",
|
||||
"//vendor/k8s.io/kube-openapi/pkg/common:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//cmd/kube-apiserver/app/options:all-srcs",
|
||||
"//cmd/kube-apiserver/app/testing:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
)
|
302
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/aggregator.go
generated
vendored
Normal file
302
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/aggregator.go
generated
vendored
Normal file
@@ -0,0 +1,302 @@
|
||||
/*
|
||||
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 app does all of the work necessary to create a Kubernetes
|
||||
// APIServer by binding together the API, master and APIServer infrastructure.
|
||||
// It can be configured and called directly or via the hyperkube framework.
|
||||
package app
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/golang/glog"
|
||||
|
||||
apiextensionsinformers "k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/apiserver/pkg/admission"
|
||||
genericapiserver "k8s.io/apiserver/pkg/server"
|
||||
"k8s.io/apiserver/pkg/server/healthz"
|
||||
genericoptions "k8s.io/apiserver/pkg/server/options"
|
||||
kubeexternalinformers "k8s.io/client-go/informers"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"k8s.io/kube-aggregator/pkg/apis/apiregistration"
|
||||
"k8s.io/kube-aggregator/pkg/apis/apiregistration/v1"
|
||||
"k8s.io/kube-aggregator/pkg/apis/apiregistration/v1beta1"
|
||||
aggregatorapiserver "k8s.io/kube-aggregator/pkg/apiserver"
|
||||
aggregatorscheme "k8s.io/kube-aggregator/pkg/apiserver/scheme"
|
||||
apiregistrationclient "k8s.io/kube-aggregator/pkg/client/clientset_generated/internalclientset/typed/apiregistration/internalversion"
|
||||
informers "k8s.io/kube-aggregator/pkg/client/informers/internalversion/apiregistration/internalversion"
|
||||
"k8s.io/kube-aggregator/pkg/controllers/autoregister"
|
||||
"k8s.io/kubernetes/cmd/kube-apiserver/app/options"
|
||||
"k8s.io/kubernetes/pkg/master/controller/crdregistration"
|
||||
)
|
||||
|
||||
func createAggregatorConfig(
|
||||
kubeAPIServerConfig genericapiserver.Config,
|
||||
commandOptions *options.ServerRunOptions,
|
||||
externalInformers kubeexternalinformers.SharedInformerFactory,
|
||||
serviceResolver aggregatorapiserver.ServiceResolver,
|
||||
proxyTransport *http.Transport,
|
||||
pluginInitializers []admission.PluginInitializer,
|
||||
) (*aggregatorapiserver.Config, error) {
|
||||
// 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
|
||||
genericConfig := kubeAPIServerConfig
|
||||
|
||||
// override genericConfig.AdmissionControl with kube-aggregator's scheme,
|
||||
// because aggregator apiserver should use its own scheme to convert its own resources.
|
||||
commandOptions.Admission.ApplyTo(
|
||||
&genericConfig,
|
||||
externalInformers,
|
||||
genericConfig.LoopbackClientConfig,
|
||||
aggregatorscheme.Scheme,
|
||||
pluginInitializers...)
|
||||
|
||||
// the aggregator doesn't wire these up. It just delegates them to the kubeapiserver
|
||||
genericConfig.EnableSwaggerUI = false
|
||||
genericConfig.SwaggerConfig = nil
|
||||
|
||||
// copy the etcd options so we don't mutate originals.
|
||||
etcdOptions := *commandOptions.Etcd
|
||||
etcdOptions.StorageConfig.Codec = aggregatorscheme.Codecs.LegacyCodec(v1beta1.SchemeGroupVersion, v1.SchemeGroupVersion)
|
||||
genericConfig.RESTOptionsGetter = &genericoptions.SimpleRestOptionsFactory{Options: etcdOptions}
|
||||
|
||||
// override MergedResourceConfig with aggregator defaults and registry
|
||||
if err := commandOptions.APIEnablement.ApplyTo(
|
||||
&genericConfig,
|
||||
aggregatorapiserver.DefaultAPIResourceConfigSource(),
|
||||
aggregatorscheme.Scheme); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var err error
|
||||
var certBytes, keyBytes []byte
|
||||
if len(commandOptions.ProxyClientCertFile) > 0 && len(commandOptions.ProxyClientKeyFile) > 0 {
|
||||
certBytes, err = ioutil.ReadFile(commandOptions.ProxyClientCertFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
keyBytes, err = ioutil.ReadFile(commandOptions.ProxyClientKeyFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
aggregatorConfig := &aggregatorapiserver.Config{
|
||||
GenericConfig: &genericapiserver.RecommendedConfig{
|
||||
Config: genericConfig,
|
||||
SharedInformerFactory: externalInformers,
|
||||
},
|
||||
ExtraConfig: aggregatorapiserver.ExtraConfig{
|
||||
ProxyClientCert: certBytes,
|
||||
ProxyClientKey: keyBytes,
|
||||
ServiceResolver: serviceResolver,
|
||||
ProxyTransport: proxyTransport,
|
||||
},
|
||||
}
|
||||
|
||||
return aggregatorConfig, nil
|
||||
}
|
||||
|
||||
func createAggregatorServer(aggregatorConfig *aggregatorapiserver.Config, delegateAPIServer genericapiserver.DelegationTarget, apiExtensionInformers apiextensionsinformers.SharedInformerFactory) (*aggregatorapiserver.APIAggregator, error) {
|
||||
aggregatorServer, err := aggregatorConfig.Complete().NewWithDelegate(delegateAPIServer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// create controllers for auto-registration
|
||||
apiRegistrationClient, err := apiregistrationclient.NewForConfig(aggregatorConfig.GenericConfig.LoopbackClientConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
autoRegistrationController := autoregister.NewAutoRegisterController(aggregatorServer.APIRegistrationInformers.Apiregistration().InternalVersion().APIServices(), apiRegistrationClient)
|
||||
apiServices := apiServicesToRegister(delegateAPIServer, autoRegistrationController)
|
||||
crdRegistrationController := crdregistration.NewAutoRegistrationController(
|
||||
apiExtensionInformers.Apiextensions().InternalVersion().CustomResourceDefinitions(),
|
||||
autoRegistrationController)
|
||||
|
||||
aggregatorServer.GenericAPIServer.AddPostStartHook("kube-apiserver-autoregistration", func(context genericapiserver.PostStartHookContext) error {
|
||||
go crdRegistrationController.Run(5, context.StopCh)
|
||||
go func() {
|
||||
// let the CRD controller process the initial set of CRDs before starting the autoregistration controller.
|
||||
// this prevents the autoregistration controller's initial sync from deleting APIServices for CRDs that still exist.
|
||||
// we only need to do this if CRDs are enabled on this server. We can't use discovery because we are the source for discovery.
|
||||
if aggregatorConfig.GenericConfig.MergedResourceConfig.AnyVersionForGroupEnabled("apiextensions.k8s.io") {
|
||||
crdRegistrationController.WaitForInitialSync()
|
||||
}
|
||||
autoRegistrationController.Run(5, context.StopCh)
|
||||
}()
|
||||
return nil
|
||||
})
|
||||
|
||||
aggregatorServer.GenericAPIServer.AddHealthzChecks(
|
||||
makeAPIServiceAvailableHealthzCheck(
|
||||
"autoregister-completion",
|
||||
apiServices,
|
||||
aggregatorServer.APIRegistrationInformers.Apiregistration().InternalVersion().APIServices(),
|
||||
),
|
||||
)
|
||||
|
||||
return aggregatorServer, nil
|
||||
}
|
||||
|
||||
func makeAPIService(gv schema.GroupVersion) *apiregistration.APIService {
|
||||
apiServicePriority, ok := apiVersionPriorities[gv]
|
||||
if !ok {
|
||||
// if we aren't found, then we shouldn't register ourselves because it could result in a CRD group version
|
||||
// being permanently stuck in the APIServices list.
|
||||
glog.Infof("Skipping APIService creation for %v", gv)
|
||||
return nil
|
||||
}
|
||||
return &apiregistration.APIService{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: gv.Version + "." + gv.Group},
|
||||
Spec: apiregistration.APIServiceSpec{
|
||||
Group: gv.Group,
|
||||
Version: gv.Version,
|
||||
GroupPriorityMinimum: apiServicePriority.group,
|
||||
VersionPriority: apiServicePriority.version,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// makeAPIServiceAvailableHealthzCheck returns a healthz check that returns healthy
|
||||
// once all of the specified services have been observed to be available at least once.
|
||||
func makeAPIServiceAvailableHealthzCheck(name string, apiServices []*apiregistration.APIService, apiServiceInformer informers.APIServiceInformer) healthz.HealthzChecker {
|
||||
// Track the auto-registered API services that have not been observed to be available yet
|
||||
pendingServiceNamesLock := &sync.RWMutex{}
|
||||
pendingServiceNames := sets.NewString()
|
||||
for _, service := range apiServices {
|
||||
pendingServiceNames.Insert(service.Name)
|
||||
}
|
||||
|
||||
// When an APIService in the list is seen as available, remove it from the pending list
|
||||
handleAPIServiceChange := func(service *apiregistration.APIService) {
|
||||
pendingServiceNamesLock.Lock()
|
||||
defer pendingServiceNamesLock.Unlock()
|
||||
if !pendingServiceNames.Has(service.Name) {
|
||||
return
|
||||
}
|
||||
if apiregistration.IsAPIServiceConditionTrue(service, apiregistration.Available) {
|
||||
pendingServiceNames.Delete(service.Name)
|
||||
}
|
||||
}
|
||||
|
||||
// Watch add/update events for APIServices
|
||||
apiServiceInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
|
||||
AddFunc: func(obj interface{}) { handleAPIServiceChange(obj.(*apiregistration.APIService)) },
|
||||
UpdateFunc: func(old, new interface{}) { handleAPIServiceChange(new.(*apiregistration.APIService)) },
|
||||
})
|
||||
|
||||
// Don't return healthy until the pending list is empty
|
||||
return healthz.NamedCheck(name, func(r *http.Request) error {
|
||||
pendingServiceNamesLock.RLock()
|
||||
defer pendingServiceNamesLock.RUnlock()
|
||||
if pendingServiceNames.Len() > 0 {
|
||||
return fmt.Errorf("missing APIService: %v", pendingServiceNames.List())
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// priority defines group priority that is used in discovery. This controls
|
||||
// group position in the kubectl output.
|
||||
type priority struct {
|
||||
// group indicates the order of the group relative to other groups.
|
||||
group int32
|
||||
// version indicates the relative order of the version inside of its group.
|
||||
version int32
|
||||
}
|
||||
|
||||
// The proper way to resolve this letting the aggregator know the desired group and version-within-group order of the underlying servers
|
||||
// is to refactor the genericapiserver.DelegationTarget to include a list of priorities based on which APIs were installed.
|
||||
// This requires the APIGroupInfo struct to evolve and include the concept of priorities and to avoid mistakes, the core storage map there needs to be updated.
|
||||
// That ripples out every bit as far as you'd expect, so for 1.7 we'll include the list here instead of being built up during storage.
|
||||
var apiVersionPriorities = map[schema.GroupVersion]priority{
|
||||
{Group: "", Version: "v1"}: {group: 18000, version: 1},
|
||||
// extensions is above the rest for CLI compatibility, though the level of unqalified resource compatibility we
|
||||
// can reasonably expect seems questionable.
|
||||
{Group: "extensions", Version: "v1beta1"}: {group: 17900, version: 1},
|
||||
// to my knowledge, nothing below here collides
|
||||
{Group: "apps", Version: "v1beta1"}: {group: 17800, version: 1},
|
||||
{Group: "apps", Version: "v1beta2"}: {group: 17800, version: 9},
|
||||
{Group: "apps", Version: "v1"}: {group: 17800, version: 15},
|
||||
{Group: "events.k8s.io", Version: "v1beta1"}: {group: 17750, version: 5},
|
||||
{Group: "authentication.k8s.io", Version: "v1"}: {group: 17700, version: 15},
|
||||
{Group: "authentication.k8s.io", Version: "v1beta1"}: {group: 17700, version: 9},
|
||||
{Group: "authorization.k8s.io", Version: "v1"}: {group: 17600, version: 15},
|
||||
{Group: "authorization.k8s.io", Version: "v1beta1"}: {group: 17600, version: 9},
|
||||
{Group: "autoscaling", Version: "v1"}: {group: 17500, version: 15},
|
||||
{Group: "autoscaling", Version: "v2beta1"}: {group: 17500, version: 9},
|
||||
{Group: "batch", Version: "v1"}: {group: 17400, version: 15},
|
||||
{Group: "batch", Version: "v1beta1"}: {group: 17400, version: 9},
|
||||
{Group: "batch", Version: "v2alpha1"}: {group: 17400, version: 9},
|
||||
{Group: "certificates.k8s.io", Version: "v1beta1"}: {group: 17300, version: 9},
|
||||
{Group: "networking.k8s.io", Version: "v1"}: {group: 17200, version: 15},
|
||||
{Group: "policy", Version: "v1beta1"}: {group: 17100, version: 9},
|
||||
{Group: "rbac.authorization.k8s.io", Version: "v1"}: {group: 17000, version: 15},
|
||||
{Group: "rbac.authorization.k8s.io", Version: "v1beta1"}: {group: 17000, version: 12},
|
||||
{Group: "rbac.authorization.k8s.io", Version: "v1alpha1"}: {group: 17000, version: 9},
|
||||
{Group: "settings.k8s.io", Version: "v1alpha1"}: {group: 16900, version: 9},
|
||||
{Group: "storage.k8s.io", Version: "v1"}: {group: 16800, version: 15},
|
||||
{Group: "storage.k8s.io", Version: "v1beta1"}: {group: 16800, version: 9},
|
||||
{Group: "storage.k8s.io", Version: "v1alpha1"}: {group: 16800, version: 1},
|
||||
{Group: "apiextensions.k8s.io", Version: "v1beta1"}: {group: 16700, version: 9},
|
||||
{Group: "admissionregistration.k8s.io", Version: "v1"}: {group: 16700, version: 15},
|
||||
{Group: "admissionregistration.k8s.io", Version: "v1beta1"}: {group: 16700, version: 12},
|
||||
{Group: "admissionregistration.k8s.io", Version: "v1alpha1"}: {group: 16700, version: 9},
|
||||
{Group: "scheduling.k8s.io", Version: "v1beta1"}: {group: 16600, version: 12},
|
||||
{Group: "scheduling.k8s.io", Version: "v1alpha1"}: {group: 16600, version: 9},
|
||||
// Append a new group to the end of the list if unsure.
|
||||
// You can use min(existing group)-100 as the initial value for a group.
|
||||
// Version can be set to 9 (to have space around) for a new group.
|
||||
}
|
||||
|
||||
func apiServicesToRegister(delegateAPIServer genericapiserver.DelegationTarget, registration autoregister.AutoAPIServiceRegistration) []*apiregistration.APIService {
|
||||
apiServices := []*apiregistration.APIService{}
|
||||
|
||||
for _, curr := range delegateAPIServer.ListedPaths() {
|
||||
if curr == "/api/v1" {
|
||||
apiService := makeAPIService(schema.GroupVersion{Group: "", Version: "v1"})
|
||||
registration.AddAPIServiceToSyncOnStart(apiService)
|
||||
apiServices = append(apiServices, apiService)
|
||||
continue
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(curr, "/apis/") {
|
||||
continue
|
||||
}
|
||||
// this comes back in a list that looks like /apis/rbac.authorization.k8s.io/v1alpha1
|
||||
tokens := strings.Split(curr, "/")
|
||||
if len(tokens) != 4 {
|
||||
continue
|
||||
}
|
||||
|
||||
apiService := makeAPIService(schema.GroupVersion{Group: tokens[2], Version: tokens[3]})
|
||||
if apiService == nil {
|
||||
continue
|
||||
}
|
||||
registration.AddAPIServiceToSyncOnStart(apiService)
|
||||
apiServices = append(apiServices, apiService)
|
||||
}
|
||||
|
||||
return apiServices
|
||||
}
|
82
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/apiextensions.go
generated
vendored
Normal file
82
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/apiextensions.go
generated
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
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 app does all of the work necessary to create a Kubernetes
|
||||
// APIServer by binding together the API, master and APIServer infrastructure.
|
||||
// It can be configured and called directly or via the hyperkube framework.
|
||||
package app
|
||||
|
||||
import (
|
||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
|
||||
apiextensionsapiserver "k8s.io/apiextensions-apiserver/pkg/apiserver"
|
||||
apiextensionscmd "k8s.io/apiextensions-apiserver/pkg/cmd/server"
|
||||
"k8s.io/apiserver/pkg/admission"
|
||||
genericapiserver "k8s.io/apiserver/pkg/server"
|
||||
genericoptions "k8s.io/apiserver/pkg/server/options"
|
||||
kubeexternalinformers "k8s.io/client-go/informers"
|
||||
"k8s.io/kubernetes/cmd/kube-apiserver/app/options"
|
||||
)
|
||||
|
||||
func createAPIExtensionsConfig(
|
||||
kubeAPIServerConfig genericapiserver.Config,
|
||||
externalInformers kubeexternalinformers.SharedInformerFactory,
|
||||
pluginInitializers []admission.PluginInitializer,
|
||||
commandOptions *options.ServerRunOptions,
|
||||
masterCount int,
|
||||
) (*apiextensionsapiserver.Config, error) {
|
||||
// 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 apiextensions
|
||||
genericConfig := kubeAPIServerConfig
|
||||
|
||||
// override genericConfig.AdmissionControl with apiextensions' scheme,
|
||||
// because apiextentions apiserver should use its own scheme to convert resources.
|
||||
commandOptions.Admission.ApplyTo(
|
||||
&genericConfig,
|
||||
externalInformers,
|
||||
genericConfig.LoopbackClientConfig,
|
||||
apiextensionsapiserver.Scheme,
|
||||
pluginInitializers...)
|
||||
|
||||
// copy the etcd options so we don't mutate originals.
|
||||
etcdOptions := *commandOptions.Etcd
|
||||
etcdOptions.StorageConfig.Codec = apiextensionsapiserver.Codecs.LegacyCodec(v1beta1.SchemeGroupVersion)
|
||||
genericConfig.RESTOptionsGetter = &genericoptions.SimpleRestOptionsFactory{Options: etcdOptions}
|
||||
|
||||
// override MergedResourceConfig with apiextensions defaults and registry
|
||||
if err := commandOptions.APIEnablement.ApplyTo(
|
||||
&genericConfig,
|
||||
apiextensionsapiserver.DefaultAPIResourceConfigSource(),
|
||||
apiextensionsapiserver.Scheme); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
apiextensionsConfig := &apiextensionsapiserver.Config{
|
||||
GenericConfig: &genericapiserver.RecommendedConfig{
|
||||
Config: genericConfig,
|
||||
SharedInformerFactory: externalInformers,
|
||||
},
|
||||
ExtraConfig: apiextensionsapiserver.ExtraConfig{
|
||||
CRDRESTOptionsGetter: apiextensionscmd.NewCRDRESTOptionsGetter(etcdOptions),
|
||||
MasterCount: masterCount,
|
||||
},
|
||||
}
|
||||
|
||||
return apiextensionsConfig, nil
|
||||
}
|
||||
|
||||
func createAPIExtensionsServer(apiextensionsConfig *apiextensionsapiserver.Config, delegateAPIServer genericapiserver.DelegationTarget) (*apiextensionsapiserver.CustomResourceDefinitions, error) {
|
||||
return apiextensionsConfig.Complete().New(delegateAPIServer)
|
||||
}
|
65
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/options/BUILD
generated
vendored
Normal file
65
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/options/BUILD
generated
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"options.go",
|
||||
"validation.go",
|
||||
],
|
||||
importpath = "k8s.io/kubernetes/cmd/kube-apiserver/app/options",
|
||||
deps = [
|
||||
"//pkg/api/legacyscheme:go_default_library",
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/features:go_default_library",
|
||||
"//pkg/kubeapiserver/options:go_default_library",
|
||||
"//pkg/kubelet/client:go_default_library",
|
||||
"//pkg/master/ports:go_default_library",
|
||||
"//pkg/master/reconcilers:go_default_library",
|
||||
"//vendor/github.com/spf13/pflag:go_default_library",
|
||||
"//vendor/k8s.io/apiextensions-apiserver/pkg/apiserver:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/net:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/server/options:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/storage/storagebackend:go_default_library",
|
||||
"//vendor/k8s.io/kube-aggregator/pkg/apiserver/scheme:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["options_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//pkg/api/legacyscheme:go_default_library",
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/kubeapiserver/options:go_default_library",
|
||||
"//pkg/kubelet/client:go_default_library",
|
||||
"//pkg/master/reconcilers:go_default_library",
|
||||
"//vendor/github.com/spf13/pflag:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/diff:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/server/options:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/storage/storagebackend:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/util/flag:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/plugin/pkg/audit/buffered:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/plugin/pkg/audit/truncate:go_default_library",
|
||||
"//vendor/k8s.io/client-go/rest:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
238
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/options/options.go
generated
vendored
Normal file
238
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/options/options.go
generated
vendored
Normal file
@@ -0,0 +1,238 @@
|
||||
/*
|
||||
Copyright 2014 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 options contains flags and options for initializing an apiserver
|
||||
package options
|
||||
|
||||
import (
|
||||
"net"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
utilnet "k8s.io/apimachinery/pkg/util/net"
|
||||
genericoptions "k8s.io/apiserver/pkg/server/options"
|
||||
"k8s.io/apiserver/pkg/storage/storagebackend"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
kubeoptions "k8s.io/kubernetes/pkg/kubeapiserver/options"
|
||||
kubeletclient "k8s.io/kubernetes/pkg/kubelet/client"
|
||||
"k8s.io/kubernetes/pkg/master/ports"
|
||||
"k8s.io/kubernetes/pkg/master/reconcilers"
|
||||
|
||||
// add the kubernetes feature gates
|
||||
_ "k8s.io/kubernetes/pkg/features"
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
// ServerRunOptions runs a kubernetes api server.
|
||||
type ServerRunOptions struct {
|
||||
GenericServerRunOptions *genericoptions.ServerRunOptions
|
||||
Etcd *genericoptions.EtcdOptions
|
||||
SecureServing *genericoptions.SecureServingOptionsWithLoopback
|
||||
InsecureServing *kubeoptions.InsecureServingOptions
|
||||
Audit *genericoptions.AuditOptions
|
||||
Features *genericoptions.FeatureOptions
|
||||
Admission *kubeoptions.AdmissionOptions
|
||||
Authentication *kubeoptions.BuiltInAuthenticationOptions
|
||||
Authorization *kubeoptions.BuiltInAuthorizationOptions
|
||||
CloudProvider *kubeoptions.CloudProviderOptions
|
||||
StorageSerialization *kubeoptions.StorageSerializationOptions
|
||||
APIEnablement *genericoptions.APIEnablementOptions
|
||||
|
||||
AllowPrivileged bool
|
||||
EnableLogsHandler bool
|
||||
EventTTL time.Duration
|
||||
KubeletConfig kubeletclient.KubeletClientConfig
|
||||
KubernetesServiceNodePort int
|
||||
MaxConnectionBytesPerSec int64
|
||||
ServiceClusterIPRange net.IPNet // TODO: make this a list
|
||||
ServiceNodePortRange utilnet.PortRange
|
||||
SSHKeyfile string
|
||||
SSHUser string
|
||||
|
||||
ProxyClientCertFile string
|
||||
ProxyClientKeyFile string
|
||||
|
||||
EnableAggregatorRouting bool
|
||||
|
||||
MasterCount int
|
||||
EndpointReconcilerType string
|
||||
|
||||
ServiceAccountSigningKeyFile string
|
||||
}
|
||||
|
||||
// NewServerRunOptions creates a new ServerRunOptions object with default parameters
|
||||
func NewServerRunOptions() *ServerRunOptions {
|
||||
s := ServerRunOptions{
|
||||
GenericServerRunOptions: genericoptions.NewServerRunOptions(),
|
||||
Etcd: genericoptions.NewEtcdOptions(storagebackend.NewDefaultConfig(kubeoptions.DefaultEtcdPathPrefix, nil)),
|
||||
SecureServing: kubeoptions.NewSecureServingOptions(),
|
||||
InsecureServing: kubeoptions.NewInsecureServingOptions(),
|
||||
Audit: genericoptions.NewAuditOptions(),
|
||||
Features: genericoptions.NewFeatureOptions(),
|
||||
Admission: kubeoptions.NewAdmissionOptions(),
|
||||
Authentication: kubeoptions.NewBuiltInAuthenticationOptions().WithAll(),
|
||||
Authorization: kubeoptions.NewBuiltInAuthorizationOptions(),
|
||||
CloudProvider: kubeoptions.NewCloudProviderOptions(),
|
||||
StorageSerialization: kubeoptions.NewStorageSerializationOptions(),
|
||||
APIEnablement: genericoptions.NewAPIEnablementOptions(),
|
||||
|
||||
EnableLogsHandler: true,
|
||||
EventTTL: 1 * time.Hour,
|
||||
MasterCount: 1,
|
||||
EndpointReconcilerType: string(reconcilers.LeaseEndpointReconcilerType),
|
||||
KubeletConfig: kubeletclient.KubeletClientConfig{
|
||||
Port: ports.KubeletPort,
|
||||
ReadOnlyPort: ports.KubeletReadOnlyPort,
|
||||
PreferredAddressTypes: []string{
|
||||
// --override-hostname
|
||||
string(api.NodeHostName),
|
||||
|
||||
// internal, preferring DNS if reported
|
||||
string(api.NodeInternalDNS),
|
||||
string(api.NodeInternalIP),
|
||||
|
||||
// external, preferring DNS if reported
|
||||
string(api.NodeExternalDNS),
|
||||
string(api.NodeExternalIP),
|
||||
},
|
||||
EnableHttps: true,
|
||||
HTTPTimeout: time.Duration(5) * time.Second,
|
||||
},
|
||||
ServiceNodePortRange: kubeoptions.DefaultServiceNodePortRange,
|
||||
}
|
||||
s.ServiceClusterIPRange = kubeoptions.DefaultServiceIPCIDR
|
||||
|
||||
// Overwrite the default for storage data format.
|
||||
s.Etcd.DefaultStorageMediaType = "application/vnd.kubernetes.protobuf"
|
||||
|
||||
return &s
|
||||
}
|
||||
|
||||
// AddFlags adds flags for a specific APIServer to the specified FlagSet
|
||||
func (s *ServerRunOptions) AddFlags(fs *pflag.FlagSet) {
|
||||
// Add the generic flags.
|
||||
s.GenericServerRunOptions.AddUniversalFlags(fs)
|
||||
s.Etcd.AddFlags(fs)
|
||||
s.SecureServing.AddFlags(fs)
|
||||
s.InsecureServing.AddFlags(fs)
|
||||
s.InsecureServing.AddDeprecatedFlags(fs)
|
||||
s.Audit.AddFlags(fs)
|
||||
s.Features.AddFlags(fs)
|
||||
s.Authentication.AddFlags(fs)
|
||||
s.Authorization.AddFlags(fs)
|
||||
s.CloudProvider.AddFlags(fs)
|
||||
s.StorageSerialization.AddFlags(fs)
|
||||
s.APIEnablement.AddFlags(fs)
|
||||
s.Admission.AddFlags(fs)
|
||||
|
||||
// Note: the weird ""+ in below lines seems to be the only way to get gofmt to
|
||||
// arrange these text blocks sensibly. Grrr.
|
||||
|
||||
fs.DurationVar(&s.EventTTL, "event-ttl", s.EventTTL,
|
||||
"Amount of time to retain events.")
|
||||
|
||||
fs.BoolVar(&s.AllowPrivileged, "allow-privileged", s.AllowPrivileged,
|
||||
"If true, allow privileged containers. [default=false]")
|
||||
|
||||
fs.BoolVar(&s.EnableLogsHandler, "enable-logs-handler", s.EnableLogsHandler,
|
||||
"If true, install a /logs handler for the apiserver logs.")
|
||||
|
||||
// Deprecated in release 1.9
|
||||
fs.StringVar(&s.SSHUser, "ssh-user", s.SSHUser,
|
||||
"If non-empty, use secure SSH proxy to the nodes, using this user name")
|
||||
fs.MarkDeprecated("ssh-user", "This flag will be removed in a future version.")
|
||||
|
||||
// Deprecated in release 1.9
|
||||
fs.StringVar(&s.SSHKeyfile, "ssh-keyfile", s.SSHKeyfile,
|
||||
"If non-empty, use secure SSH proxy to the nodes, using this user keyfile")
|
||||
fs.MarkDeprecated("ssh-keyfile", "This flag will be removed in a future version.")
|
||||
|
||||
fs.Int64Var(&s.MaxConnectionBytesPerSec, "max-connection-bytes-per-sec", s.MaxConnectionBytesPerSec, ""+
|
||||
"If non-zero, throttle each user connection to this number of bytes/sec. "+
|
||||
"Currently only applies to long-running requests.")
|
||||
|
||||
fs.IntVar(&s.MasterCount, "apiserver-count", s.MasterCount,
|
||||
"The number of apiservers running in the cluster, must be a positive number. (In use when --endpoint-reconciler-type=master-count is enabled.)")
|
||||
|
||||
fs.StringVar(&s.EndpointReconcilerType, "endpoint-reconciler-type", string(s.EndpointReconcilerType),
|
||||
"Use an endpoint reconciler ("+strings.Join(reconcilers.AllTypes.Names(), ", ")+")")
|
||||
|
||||
// See #14282 for details on how to test/try this option out.
|
||||
// TODO: remove this comment once this option is tested in CI.
|
||||
fs.IntVar(&s.KubernetesServiceNodePort, "kubernetes-service-node-port", s.KubernetesServiceNodePort, ""+
|
||||
"If non-zero, the Kubernetes master service (which apiserver creates/maintains) will be "+
|
||||
"of type NodePort, using this as the value of the port. If zero, the Kubernetes master "+
|
||||
"service will be of type ClusterIP.")
|
||||
|
||||
fs.IPNetVar(&s.ServiceClusterIPRange, "service-cluster-ip-range", s.ServiceClusterIPRange, ""+
|
||||
"A CIDR notation IP range from which to assign service cluster IPs. This must not "+
|
||||
"overlap with any IP ranges assigned to nodes for pods.")
|
||||
|
||||
fs.Var(&s.ServiceNodePortRange, "service-node-port-range", ""+
|
||||
"A port range to reserve for services with NodePort visibility. "+
|
||||
"Example: '30000-32767'. Inclusive at both ends of the range.")
|
||||
|
||||
// Kubelet related flags:
|
||||
fs.BoolVar(&s.KubeletConfig.EnableHttps, "kubelet-https", s.KubeletConfig.EnableHttps,
|
||||
"Use https for kubelet connections.")
|
||||
|
||||
fs.StringSliceVar(&s.KubeletConfig.PreferredAddressTypes, "kubelet-preferred-address-types", s.KubeletConfig.PreferredAddressTypes,
|
||||
"List of the preferred NodeAddressTypes to use for kubelet connections.")
|
||||
|
||||
fs.UintVar(&s.KubeletConfig.Port, "kubelet-port", s.KubeletConfig.Port,
|
||||
"DEPRECATED: kubelet port.")
|
||||
fs.MarkDeprecated("kubelet-port", "kubelet-port is deprecated and will be removed.")
|
||||
|
||||
fs.UintVar(&s.KubeletConfig.ReadOnlyPort, "kubelet-read-only-port", s.KubeletConfig.ReadOnlyPort,
|
||||
"DEPRECATED: kubelet port.")
|
||||
|
||||
fs.DurationVar(&s.KubeletConfig.HTTPTimeout, "kubelet-timeout", s.KubeletConfig.HTTPTimeout,
|
||||
"Timeout for kubelet operations.")
|
||||
|
||||
fs.StringVar(&s.KubeletConfig.CertFile, "kubelet-client-certificate", s.KubeletConfig.CertFile,
|
||||
"Path to a client cert file for TLS.")
|
||||
|
||||
fs.StringVar(&s.KubeletConfig.KeyFile, "kubelet-client-key", s.KubeletConfig.KeyFile,
|
||||
"Path to a client key file for TLS.")
|
||||
|
||||
fs.StringVar(&s.KubeletConfig.CAFile, "kubelet-certificate-authority", s.KubeletConfig.CAFile,
|
||||
"Path to a cert file for the certificate authority.")
|
||||
|
||||
// TODO: delete this flag in 1.13
|
||||
repair := false
|
||||
fs.BoolVar(&repair, "repair-malformed-updates", false, "deprecated")
|
||||
fs.MarkDeprecated("repair-malformed-updates", "This flag will be removed in a future version")
|
||||
|
||||
fs.StringVar(&s.ProxyClientCertFile, "proxy-client-cert-file", s.ProxyClientCertFile, ""+
|
||||
"Client certificate used to prove the identity of the aggregator or kube-apiserver "+
|
||||
"when it must call out during a request. This includes proxying requests to a user "+
|
||||
"api-server and calling out to webhook admission plugins. It is expected that this "+
|
||||
"cert includes a signature from the CA in the --requestheader-client-ca-file flag. "+
|
||||
"That CA is published in the 'extension-apiserver-authentication' configmap in "+
|
||||
"the kube-system namespace. Components receiving calls from kube-aggregator should "+
|
||||
"use that CA to perform their half of the mutual TLS verification.")
|
||||
fs.StringVar(&s.ProxyClientKeyFile, "proxy-client-key-file", s.ProxyClientKeyFile, ""+
|
||||
"Private key for the client certificate used to prove the identity of the aggregator or kube-apiserver "+
|
||||
"when it must call out during a request. This includes proxying requests to a user "+
|
||||
"api-server and calling out to webhook admission plugins.")
|
||||
|
||||
fs.BoolVar(&s.EnableAggregatorRouting, "enable-aggregator-routing", s.EnableAggregatorRouting,
|
||||
"Turns on aggregator routing requests to endoints IP rather than cluster IP.")
|
||||
|
||||
fs.StringVar(&s.ServiceAccountSigningKeyFile, "service-account-signing-key-file", s.ServiceAccountSigningKeyFile, ""+
|
||||
"Path to the file that contains the current private key of the service account token issuer. The issuer will sign issued ID tokens with this private key. (Requires the 'TokenRequest' feature gate.)")
|
||||
}
|
302
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/options/options_test.go
generated
vendored
Normal file
302
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/options/options_test.go
generated
vendored
Normal file
@@ -0,0 +1,302 @@
|
||||
/*
|
||||
Copyright 2014 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 options
|
||||
|
||||
import (
|
||||
"net"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/diff"
|
||||
apiserveroptions "k8s.io/apiserver/pkg/server/options"
|
||||
genericoptions "k8s.io/apiserver/pkg/server/options"
|
||||
"k8s.io/apiserver/pkg/storage/storagebackend"
|
||||
utilflag "k8s.io/apiserver/pkg/util/flag"
|
||||
auditbuffered "k8s.io/apiserver/plugin/pkg/audit/buffered"
|
||||
audittruncate "k8s.io/apiserver/plugin/pkg/audit/truncate"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||
kapi "k8s.io/kubernetes/pkg/apis/core"
|
||||
kubeoptions "k8s.io/kubernetes/pkg/kubeapiserver/options"
|
||||
kubeletclient "k8s.io/kubernetes/pkg/kubelet/client"
|
||||
"k8s.io/kubernetes/pkg/master/reconcilers"
|
||||
)
|
||||
|
||||
func TestAddFlags(t *testing.T) {
|
||||
f := pflag.NewFlagSet("addflagstest", pflag.ContinueOnError)
|
||||
s := NewServerRunOptions()
|
||||
s.AddFlags(f)
|
||||
|
||||
args := []string{
|
||||
"--enable-admission-plugins=AlwaysDeny",
|
||||
"--admission-control-config-file=/admission-control-config",
|
||||
"--advertise-address=192.168.10.10",
|
||||
"--allow-privileged=false",
|
||||
"--anonymous-auth=false",
|
||||
"--apiserver-count=5",
|
||||
"--audit-log-maxage=11",
|
||||
"--audit-log-maxbackup=12",
|
||||
"--audit-log-maxsize=13",
|
||||
"--audit-log-path=/var/log",
|
||||
"--audit-log-mode=blocking",
|
||||
"--audit-log-batch-buffer-size=46",
|
||||
"--audit-log-batch-max-size=47",
|
||||
"--audit-log-batch-max-wait=48s",
|
||||
"--audit-log-batch-throttle-enable=true",
|
||||
"--audit-log-batch-throttle-qps=49.5",
|
||||
"--audit-log-batch-throttle-burst=50",
|
||||
"--audit-log-truncate-enabled=true",
|
||||
"--audit-log-truncate-max-batch-size=45",
|
||||
"--audit-log-truncate-max-event-size=44",
|
||||
"--audit-log-version=audit.k8s.io/v1alpha1",
|
||||
"--audit-policy-file=/policy",
|
||||
"--audit-webhook-config-file=/webhook-config",
|
||||
"--audit-webhook-mode=blocking",
|
||||
"--audit-webhook-batch-buffer-size=42",
|
||||
"--audit-webhook-batch-max-size=43",
|
||||
"--audit-webhook-batch-max-wait=1s",
|
||||
"--audit-webhook-batch-throttle-enable=false",
|
||||
"--audit-webhook-batch-throttle-qps=43.5",
|
||||
"--audit-webhook-batch-throttle-burst=44",
|
||||
"--audit-webhook-truncate-enabled=true",
|
||||
"--audit-webhook-truncate-max-batch-size=43",
|
||||
"--audit-webhook-truncate-max-event-size=42",
|
||||
"--audit-webhook-initial-backoff=2s",
|
||||
"--audit-webhook-version=audit.k8s.io/v1alpha1",
|
||||
"--authentication-token-webhook-cache-ttl=3m",
|
||||
"--authentication-token-webhook-config-file=/token-webhook-config",
|
||||
"--authorization-mode=AlwaysDeny,RBAC",
|
||||
"--authorization-policy-file=/policy",
|
||||
"--authorization-webhook-cache-authorized-ttl=3m",
|
||||
"--authorization-webhook-cache-unauthorized-ttl=1m",
|
||||
"--authorization-webhook-config-file=/webhook-config",
|
||||
"--bind-address=192.168.10.20",
|
||||
"--client-ca-file=/client-ca",
|
||||
"--cloud-config=/cloud-config",
|
||||
"--cloud-provider=azure",
|
||||
"--cors-allowed-origins=10.10.10.100,10.10.10.200",
|
||||
"--contention-profiling=true",
|
||||
"--enable-aggregator-routing=true",
|
||||
"--enable-logs-handler=false",
|
||||
"--enable-swagger-ui=true",
|
||||
"--endpoint-reconciler-type=" + string(reconcilers.LeaseEndpointReconcilerType),
|
||||
"--etcd-quorum-read=false",
|
||||
"--etcd-keyfile=/var/run/kubernetes/etcd.key",
|
||||
"--etcd-certfile=/var/run/kubernetes/etcdce.crt",
|
||||
"--etcd-cafile=/var/run/kubernetes/etcdca.crt",
|
||||
"--http2-max-streams-per-connection=42",
|
||||
"--kubelet-https=true",
|
||||
"--kubelet-read-only-port=10255",
|
||||
"--kubelet-timeout=5s",
|
||||
"--kubelet-client-certificate=/var/run/kubernetes/ceserver.crt",
|
||||
"--kubelet-client-key=/var/run/kubernetes/server.key",
|
||||
"--kubelet-certificate-authority=/var/run/kubernetes/caserver.crt",
|
||||
"--proxy-client-cert-file=/var/run/kubernetes/proxy.crt",
|
||||
"--proxy-client-key-file=/var/run/kubernetes/proxy.key",
|
||||
"--request-timeout=2m",
|
||||
"--storage-backend=etcd2",
|
||||
}
|
||||
f.Parse(args)
|
||||
|
||||
// This is a snapshot of expected options parsed by args.
|
||||
expected := &ServerRunOptions{
|
||||
ServiceNodePortRange: kubeoptions.DefaultServiceNodePortRange,
|
||||
ServiceClusterIPRange: kubeoptions.DefaultServiceIPCIDR,
|
||||
MasterCount: 5,
|
||||
EndpointReconcilerType: string(reconcilers.LeaseEndpointReconcilerType),
|
||||
AllowPrivileged: false,
|
||||
GenericServerRunOptions: &apiserveroptions.ServerRunOptions{
|
||||
AdvertiseAddress: net.ParseIP("192.168.10.10"),
|
||||
CorsAllowedOriginList: []string{"10.10.10.100", "10.10.10.200"},
|
||||
MaxRequestsInFlight: 400,
|
||||
MaxMutatingRequestsInFlight: 200,
|
||||
RequestTimeout: time.Duration(2) * time.Minute,
|
||||
MinRequestTimeout: 1800,
|
||||
},
|
||||
Admission: &kubeoptions.AdmissionOptions{
|
||||
GenericAdmission: &apiserveroptions.AdmissionOptions{
|
||||
RecommendedPluginOrder: s.Admission.GenericAdmission.RecommendedPluginOrder,
|
||||
DefaultOffPlugins: s.Admission.GenericAdmission.DefaultOffPlugins,
|
||||
EnablePlugins: []string{"AlwaysDeny"},
|
||||
ConfigFile: "/admission-control-config",
|
||||
Plugins: s.Admission.GenericAdmission.Plugins,
|
||||
},
|
||||
},
|
||||
Etcd: &apiserveroptions.EtcdOptions{
|
||||
StorageConfig: storagebackend.Config{
|
||||
Type: "etcd2",
|
||||
ServerList: nil,
|
||||
Prefix: "/registry",
|
||||
DeserializationCacheSize: 0,
|
||||
Quorum: false,
|
||||
KeyFile: "/var/run/kubernetes/etcd.key",
|
||||
CAFile: "/var/run/kubernetes/etcdca.crt",
|
||||
CertFile: "/var/run/kubernetes/etcdce.crt",
|
||||
CompactionInterval: storagebackend.DefaultCompactInterval,
|
||||
CountMetricPollPeriod: time.Minute,
|
||||
},
|
||||
DefaultStorageMediaType: "application/vnd.kubernetes.protobuf",
|
||||
DeleteCollectionWorkers: 1,
|
||||
EnableGarbageCollection: true,
|
||||
EnableWatchCache: true,
|
||||
DefaultWatchCacheSize: 100,
|
||||
},
|
||||
SecureServing: genericoptions.WithLoopback(&apiserveroptions.SecureServingOptions{
|
||||
BindAddress: net.ParseIP("192.168.10.20"),
|
||||
BindPort: 6443,
|
||||
ServerCert: apiserveroptions.GeneratableKeyCert{
|
||||
CertDirectory: "/var/run/kubernetes",
|
||||
PairName: "apiserver",
|
||||
},
|
||||
HTTP2MaxStreamsPerConnection: 42,
|
||||
}),
|
||||
InsecureServing: &kubeoptions.InsecureServingOptions{
|
||||
BindAddress: net.ParseIP("127.0.0.1"),
|
||||
BindPort: 8080,
|
||||
},
|
||||
EventTTL: 1 * time.Hour,
|
||||
KubeletConfig: kubeletclient.KubeletClientConfig{
|
||||
Port: 10250,
|
||||
ReadOnlyPort: 10255,
|
||||
PreferredAddressTypes: []string{
|
||||
string(kapi.NodeHostName),
|
||||
string(kapi.NodeInternalDNS),
|
||||
string(kapi.NodeInternalIP),
|
||||
string(kapi.NodeExternalDNS),
|
||||
string(kapi.NodeExternalIP),
|
||||
},
|
||||
EnableHttps: true,
|
||||
HTTPTimeout: time.Duration(5) * time.Second,
|
||||
TLSClientConfig: restclient.TLSClientConfig{
|
||||
CertFile: "/var/run/kubernetes/ceserver.crt",
|
||||
KeyFile: "/var/run/kubernetes/server.key",
|
||||
CAFile: "/var/run/kubernetes/caserver.crt",
|
||||
},
|
||||
},
|
||||
Audit: &apiserveroptions.AuditOptions{
|
||||
LogOptions: apiserveroptions.AuditLogOptions{
|
||||
Path: "/var/log",
|
||||
MaxAge: 11,
|
||||
MaxBackups: 12,
|
||||
MaxSize: 13,
|
||||
Format: "json",
|
||||
BatchOptions: apiserveroptions.AuditBatchOptions{
|
||||
Mode: "blocking",
|
||||
BatchConfig: auditbuffered.BatchConfig{
|
||||
BufferSize: 46,
|
||||
MaxBatchSize: 47,
|
||||
MaxBatchWait: 48 * time.Second,
|
||||
ThrottleEnable: true,
|
||||
ThrottleQPS: 49.5,
|
||||
ThrottleBurst: 50,
|
||||
},
|
||||
},
|
||||
TruncateOptions: apiserveroptions.AuditTruncateOptions{
|
||||
Enabled: true,
|
||||
TruncateConfig: audittruncate.Config{
|
||||
MaxBatchSize: 45,
|
||||
MaxEventSize: 44,
|
||||
},
|
||||
},
|
||||
GroupVersionString: "audit.k8s.io/v1alpha1",
|
||||
},
|
||||
WebhookOptions: apiserveroptions.AuditWebhookOptions{
|
||||
ConfigFile: "/webhook-config",
|
||||
BatchOptions: apiserveroptions.AuditBatchOptions{
|
||||
Mode: "blocking",
|
||||
BatchConfig: auditbuffered.BatchConfig{
|
||||
BufferSize: 42,
|
||||
MaxBatchSize: 43,
|
||||
MaxBatchWait: 1 * time.Second,
|
||||
ThrottleEnable: false,
|
||||
ThrottleQPS: 43.5,
|
||||
ThrottleBurst: 44,
|
||||
},
|
||||
},
|
||||
TruncateOptions: apiserveroptions.AuditTruncateOptions{
|
||||
Enabled: true,
|
||||
TruncateConfig: audittruncate.Config{
|
||||
MaxBatchSize: 43,
|
||||
MaxEventSize: 42,
|
||||
},
|
||||
},
|
||||
InitialBackoff: 2 * time.Second,
|
||||
GroupVersionString: "audit.k8s.io/v1alpha1",
|
||||
},
|
||||
PolicyFile: "/policy",
|
||||
},
|
||||
Features: &apiserveroptions.FeatureOptions{
|
||||
EnableSwaggerUI: true,
|
||||
EnableProfiling: true,
|
||||
EnableContentionProfiling: true,
|
||||
},
|
||||
Authentication: &kubeoptions.BuiltInAuthenticationOptions{
|
||||
Anonymous: &kubeoptions.AnonymousAuthenticationOptions{
|
||||
Allow: false,
|
||||
},
|
||||
ClientCert: &apiserveroptions.ClientCertAuthenticationOptions{
|
||||
ClientCA: "/client-ca",
|
||||
},
|
||||
WebHook: &kubeoptions.WebHookAuthenticationOptions{
|
||||
CacheTTL: 180000000000,
|
||||
ConfigFile: "/token-webhook-config",
|
||||
},
|
||||
BootstrapToken: &kubeoptions.BootstrapTokenAuthenticationOptions{},
|
||||
OIDC: &kubeoptions.OIDCAuthenticationOptions{
|
||||
UsernameClaim: "sub",
|
||||
SigningAlgs: []string{"RS256"},
|
||||
},
|
||||
PasswordFile: &kubeoptions.PasswordFileAuthenticationOptions{},
|
||||
RequestHeader: &apiserveroptions.RequestHeaderAuthenticationOptions{},
|
||||
ServiceAccounts: &kubeoptions.ServiceAccountAuthenticationOptions{
|
||||
Lookup: true,
|
||||
},
|
||||
TokenFile: &kubeoptions.TokenFileAuthenticationOptions{},
|
||||
TokenSuccessCacheTTL: 10 * time.Second,
|
||||
TokenFailureCacheTTL: 0,
|
||||
},
|
||||
Authorization: &kubeoptions.BuiltInAuthorizationOptions{
|
||||
Modes: []string{"AlwaysDeny", "RBAC"},
|
||||
PolicyFile: "/policy",
|
||||
WebhookConfigFile: "/webhook-config",
|
||||
WebhookCacheAuthorizedTTL: 180000000000,
|
||||
WebhookCacheUnauthorizedTTL: 60000000000,
|
||||
},
|
||||
CloudProvider: &kubeoptions.CloudProviderOptions{
|
||||
CloudConfigFile: "/cloud-config",
|
||||
CloudProvider: "azure",
|
||||
},
|
||||
StorageSerialization: &kubeoptions.StorageSerializationOptions{
|
||||
StorageVersions: kubeoptions.ToPreferredVersionString(legacyscheme.Scheme.PreferredVersionAllGroups()),
|
||||
DefaultStorageVersions: kubeoptions.ToPreferredVersionString(legacyscheme.Scheme.PreferredVersionAllGroups()),
|
||||
},
|
||||
APIEnablement: &apiserveroptions.APIEnablementOptions{
|
||||
RuntimeConfig: utilflag.ConfigurationMap{},
|
||||
},
|
||||
EnableLogsHandler: false,
|
||||
EnableAggregatorRouting: true,
|
||||
ProxyClientKeyFile: "/var/run/kubernetes/proxy.key",
|
||||
ProxyClientCertFile: "/var/run/kubernetes/proxy.crt",
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(expected, s) {
|
||||
t.Errorf("Got different run options than expected.\nDifference detected on:\n%s", diff.ObjectReflectDiff(expected, s))
|
||||
}
|
||||
}
|
90
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/options/validation.go
generated
vendored
Normal file
90
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/options/validation.go
generated
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
Copyright 2014 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 options
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
apiextensionsapiserver "k8s.io/apiextensions-apiserver/pkg/apiserver"
|
||||
aggregatorscheme "k8s.io/kube-aggregator/pkg/apiserver/scheme"
|
||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||
)
|
||||
|
||||
// TODO: Longer term we should read this from some config store, rather than a flag.
|
||||
func validateClusterIPFlags(options *ServerRunOptions) []error {
|
||||
errors := []error{}
|
||||
if options.ServiceClusterIPRange.IP == nil {
|
||||
errors = append(errors, fmt.Errorf("no --service-cluster-ip-range specified"))
|
||||
}
|
||||
var ones, bits = options.ServiceClusterIPRange.Mask.Size()
|
||||
if bits-ones > 20 {
|
||||
errors = append(errors, fmt.Errorf("specified --service-cluster-ip-range is too large"))
|
||||
}
|
||||
return errors
|
||||
}
|
||||
|
||||
func validateServiceNodePort(options *ServerRunOptions) []error {
|
||||
errors := []error{}
|
||||
if options.KubernetesServiceNodePort < 0 || options.KubernetesServiceNodePort > 65535 {
|
||||
errors = append(errors, fmt.Errorf("--kubernetes-service-node-port %v must be between 0 and 65535, inclusive. If 0, the Kubernetes master service will be of type ClusterIP", options.KubernetesServiceNodePort))
|
||||
}
|
||||
|
||||
if options.KubernetesServiceNodePort > 0 && !options.ServiceNodePortRange.Contains(options.KubernetesServiceNodePort) {
|
||||
errors = append(errors, fmt.Errorf("kubernetes service port range %v doesn't contain %v", options.ServiceNodePortRange, (options.KubernetesServiceNodePort)))
|
||||
}
|
||||
return errors
|
||||
}
|
||||
|
||||
// Validate checks ServerRunOptions and return a slice of found errors.
|
||||
func (s *ServerRunOptions) Validate() []error {
|
||||
var errors []error
|
||||
if errs := s.Etcd.Validate(); len(errs) > 0 {
|
||||
errors = append(errors, errs...)
|
||||
}
|
||||
if errs := validateClusterIPFlags(s); len(errs) > 0 {
|
||||
errors = append(errors, errs...)
|
||||
}
|
||||
if errs := validateServiceNodePort(s); len(errs) > 0 {
|
||||
errors = append(errors, errs...)
|
||||
}
|
||||
if errs := s.SecureServing.Validate(); len(errs) > 0 {
|
||||
errors = append(errors, errs...)
|
||||
}
|
||||
if errs := s.Authentication.Validate(); len(errs) > 0 {
|
||||
errors = append(errors, errs...)
|
||||
}
|
||||
if errs := s.Authorization.Validate(); len(errs) > 0 {
|
||||
errors = append(errors, errs...)
|
||||
}
|
||||
if errs := s.Audit.Validate(); len(errs) > 0 {
|
||||
errors = append(errors, errs...)
|
||||
}
|
||||
if errs := s.Admission.Validate(); len(errs) > 0 {
|
||||
errors = append(errors, errs...)
|
||||
}
|
||||
if errs := s.InsecureServing.Validate(); len(errs) > 0 {
|
||||
errors = append(errors, errs...)
|
||||
}
|
||||
if s.MasterCount <= 0 {
|
||||
errors = append(errors, fmt.Errorf("--apiserver-count should be a positive number, but value '%d' provided", s.MasterCount))
|
||||
}
|
||||
if errs := s.APIEnablement.Validate(legacyscheme.Scheme, apiextensionsapiserver.Scheme, aggregatorscheme.Scheme); len(errs) > 0 {
|
||||
errors = append(errors, errs...)
|
||||
}
|
||||
|
||||
return errors
|
||||
}
|
1127
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/server.go
generated
vendored
Normal file
1127
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/server.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
35
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/testing/BUILD
generated
vendored
Normal file
35
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/testing/BUILD
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["testserver.go"],
|
||||
importpath = "k8s.io/kubernetes/cmd/kube-apiserver/app/testing",
|
||||
deps = [
|
||||
"//cmd/kube-apiserver/app:go_default_library",
|
||||
"//cmd/kube-apiserver/app/options:go_default_library",
|
||||
"//vendor/github.com/spf13/pflag:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/registry/generic/registry:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/storage/storagebackend:go_default_library",
|
||||
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
|
||||
"//vendor/k8s.io/client-go/rest:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
195
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/testing/testserver.go
generated
vendored
Normal file
195
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/testing/testserver.go
generated
vendored
Normal file
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
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 testing
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
pflag "github.com/spf13/pflag"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/apiserver/pkg/registry/generic/registry"
|
||||
"k8s.io/apiserver/pkg/storage/storagebackend"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
"k8s.io/kubernetes/cmd/kube-apiserver/app"
|
||||
"k8s.io/kubernetes/cmd/kube-apiserver/app/options"
|
||||
)
|
||||
|
||||
// TearDownFunc is to be called to tear down a test server.
|
||||
type TearDownFunc func()
|
||||
|
||||
// TestServerInstanceOptions Instance options the TestServer
|
||||
type TestServerInstanceOptions struct {
|
||||
// DisableStorageCleanup Disable the automatic storage cleanup
|
||||
DisableStorageCleanup bool
|
||||
}
|
||||
|
||||
// TestServer return values supplied by kube-test-ApiServer
|
||||
type TestServer struct {
|
||||
ClientConfig *restclient.Config // Rest client config
|
||||
ServerOpts *options.ServerRunOptions // ServerOpts
|
||||
TearDownFn TearDownFunc // TearDown function
|
||||
TmpDir string // Temp Dir used, by the apiserver
|
||||
}
|
||||
|
||||
// Logger allows t.Testing and b.Testing to be passed to StartTestServer and StartTestServerOrDie
|
||||
type Logger interface {
|
||||
Errorf(format string, args ...interface{})
|
||||
Fatalf(format string, args ...interface{})
|
||||
Logf(format string, args ...interface{})
|
||||
}
|
||||
|
||||
// NewDefaultTestServerOptions Default options for TestServer instances
|
||||
func NewDefaultTestServerOptions() *TestServerInstanceOptions {
|
||||
return &TestServerInstanceOptions{
|
||||
DisableStorageCleanup: false,
|
||||
}
|
||||
}
|
||||
|
||||
// StartTestServer starts a etcd server and kube-apiserver. A rest client config and a tear-down func,
|
||||
// and location of the tmpdir are returned.
|
||||
//
|
||||
// Note: we return a tear-down func instead of a stop channel because the later will leak temporary
|
||||
// files that because Golang testing's call to os.Exit will not give a stop channel go routine
|
||||
// enough time to remove temporary files.
|
||||
func StartTestServer(t Logger, instanceOptions *TestServerInstanceOptions, customFlags []string, storageConfig *storagebackend.Config) (result TestServer, err error) {
|
||||
if instanceOptions == nil {
|
||||
instanceOptions = NewDefaultTestServerOptions()
|
||||
}
|
||||
|
||||
// TODO : Remove TrackStorageCleanup below when PR
|
||||
// https://github.com/kubernetes/kubernetes/pull/50690
|
||||
// merges as that shuts down storage properly
|
||||
if !instanceOptions.DisableStorageCleanup {
|
||||
registry.TrackStorageCleanup()
|
||||
}
|
||||
|
||||
stopCh := make(chan struct{})
|
||||
tearDown := func() {
|
||||
if !instanceOptions.DisableStorageCleanup {
|
||||
registry.CleanupStorage()
|
||||
}
|
||||
close(stopCh)
|
||||
if len(result.TmpDir) != 0 {
|
||||
os.RemoveAll(result.TmpDir)
|
||||
}
|
||||
}
|
||||
defer func() {
|
||||
if result.TearDownFn == nil {
|
||||
tearDown()
|
||||
}
|
||||
}()
|
||||
|
||||
result.TmpDir, err = ioutil.TempDir("", "kubernetes-kube-apiserver")
|
||||
if err != nil {
|
||||
return result, fmt.Errorf("failed to create temp dir: %v", err)
|
||||
}
|
||||
|
||||
fs := pflag.NewFlagSet("test", pflag.PanicOnError)
|
||||
|
||||
s := options.NewServerRunOptions()
|
||||
s.AddFlags(fs)
|
||||
|
||||
s.InsecureServing.BindPort = 0
|
||||
|
||||
s.SecureServing.Listener, s.SecureServing.BindPort, err = createListenerOnFreePort()
|
||||
if err != nil {
|
||||
return result, fmt.Errorf("failed to create listener: %v", err)
|
||||
}
|
||||
s.SecureServing.ServerCert.CertDirectory = result.TmpDir
|
||||
s.ServiceClusterIPRange.IP = net.IPv4(10, 0, 0, 0)
|
||||
s.ServiceClusterIPRange.Mask = net.CIDRMask(16, 32)
|
||||
s.Etcd.StorageConfig = *storageConfig
|
||||
s.APIEnablement.RuntimeConfig.Set("api/all=true")
|
||||
|
||||
fs.Parse(customFlags)
|
||||
completedOptions, err := app.Complete(s)
|
||||
if err != nil {
|
||||
return result, fmt.Errorf("failed to set default ServerRunOptions: %v", err)
|
||||
}
|
||||
|
||||
t.Logf("runtime-config=%v", completedOptions.APIEnablement.RuntimeConfig)
|
||||
t.Logf("Starting kube-apiserver on port %d...", s.SecureServing.BindPort)
|
||||
server, err := app.CreateServerChain(completedOptions, stopCh)
|
||||
if err != nil {
|
||||
return result, fmt.Errorf("failed to create server chain: %v", err)
|
||||
|
||||
}
|
||||
go func(stopCh <-chan struct{}) {
|
||||
if err := server.PrepareRun().Run(stopCh); err != nil {
|
||||
t.Errorf("kube-apiserver failed run: %v", err)
|
||||
}
|
||||
}(stopCh)
|
||||
|
||||
t.Logf("Waiting for /healthz to be ok...")
|
||||
|
||||
client, err := kubernetes.NewForConfig(server.LoopbackClientConfig)
|
||||
if err != nil {
|
||||
return result, fmt.Errorf("failed to create a client: %v", err)
|
||||
}
|
||||
err = wait.Poll(100*time.Millisecond, 30*time.Second, func() (bool, error) {
|
||||
result := client.CoreV1().RESTClient().Get().AbsPath("/healthz").Do()
|
||||
status := 0
|
||||
result.StatusCode(&status)
|
||||
if status == 200 {
|
||||
return true, nil
|
||||
}
|
||||
return false, nil
|
||||
})
|
||||
if err != nil {
|
||||
return result, fmt.Errorf("failed to wait for /healthz to return ok: %v", err)
|
||||
}
|
||||
|
||||
// from here the caller must call tearDown
|
||||
result.ClientConfig = server.LoopbackClientConfig
|
||||
result.ServerOpts = s
|
||||
result.TearDownFn = tearDown
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// StartTestServerOrDie calls StartTestServer t.Fatal if it does not succeed.
|
||||
func StartTestServerOrDie(t Logger, instanceOptions *TestServerInstanceOptions, flags []string, storageConfig *storagebackend.Config) *TestServer {
|
||||
result, err := StartTestServer(t, instanceOptions, flags, storageConfig)
|
||||
if err == nil {
|
||||
return &result
|
||||
}
|
||||
|
||||
t.Fatalf("failed to launch server: %v", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
func createListenerOnFreePort() (net.Listener, int, error) {
|
||||
ln, err := net.Listen("tcp", ":0")
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
// get port
|
||||
tcpAddr, ok := ln.Addr().(*net.TCPAddr)
|
||||
if !ok {
|
||||
ln.Close()
|
||||
return nil, 0, fmt.Errorf("invalid listen address: %q", ln.Addr().String())
|
||||
}
|
||||
|
||||
return ln, tcpAddr.Port, nil
|
||||
}
|
Reference in New Issue
Block a user