Replace godep with dep
This commit is contained in:
parent
1e7489927c
commit
bf5616c65b
14883 changed files with 3937406 additions and 361781 deletions
52
vendor/k8s.io/kubernetes/cmd/kube-apiserver/BUILD
generated
vendored
Normal file
52
vendor/k8s.io/kubernetes/cmd/kube-apiserver/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_binary",
|
||||
"go_library",
|
||||
)
|
||||
load("//pkg/version:def.bzl", "version_x_defs")
|
||||
|
||||
go_binary(
|
||||
name = "kube-apiserver",
|
||||
gc_linkopts = [
|
||||
"-linkmode",
|
||||
"external",
|
||||
"-extldflags",
|
||||
"-static",
|
||||
],
|
||||
library = ":go_default_library",
|
||||
x_defs = version_x_defs(),
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["apiserver.go"],
|
||||
deps = [
|
||||
"//cmd/kube-apiserver/app:go_default_library",
|
||||
"//cmd/kube-apiserver/app/options:go_default_library",
|
||||
"//pkg/client/metrics/prometheus:go_default_library",
|
||||
"//pkg/version/prometheus:go_default_library",
|
||||
"//pkg/version/verflag:go_default_library",
|
||||
"//vendor/github.com/spf13/pflag:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/server:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/util/flag:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/util/logs: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:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
21
vendor/k8s.io/kubernetes/cmd/kube-apiserver/OWNERS
generated
vendored
Normal file
21
vendor/k8s.io/kubernetes/cmd/kube-apiserver/OWNERS
generated
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
approvers:
|
||||
- caesarxuchao
|
||||
- deads2k
|
||||
- lavalamp
|
||||
- liggitt
|
||||
- mml
|
||||
- nikhiljindal
|
||||
- smarterclayton
|
||||
- sttts
|
||||
reviewers:
|
||||
- lavalamp
|
||||
- smarterclayton
|
||||
- wojtek-t
|
||||
- deads2k
|
||||
- derekwaynecarr
|
||||
- caesarxuchao
|
||||
- mikedanese
|
||||
- liggitt
|
||||
- nikhiljindal
|
||||
- ncdc
|
||||
- sttts
|
||||
56
vendor/k8s.io/kubernetes/cmd/kube-apiserver/apiserver.go
generated
vendored
Normal file
56
vendor/k8s.io/kubernetes/cmd/kube-apiserver/apiserver.go
generated
vendored
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
// apiserver is the main api server and master for the cluster.
|
||||
// it is responsible for serving the cluster management API.
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
|
||||
"k8s.io/apiserver/pkg/server"
|
||||
"k8s.io/apiserver/pkg/util/flag"
|
||||
"k8s.io/apiserver/pkg/util/logs"
|
||||
"k8s.io/kubernetes/cmd/kube-apiserver/app"
|
||||
"k8s.io/kubernetes/cmd/kube-apiserver/app/options"
|
||||
_ "k8s.io/kubernetes/pkg/client/metrics/prometheus" // for client metric registration
|
||||
_ "k8s.io/kubernetes/pkg/version/prometheus" // for version metric registration
|
||||
"k8s.io/kubernetes/pkg/version/verflag"
|
||||
)
|
||||
|
||||
func main() {
|
||||
rand.Seed(time.Now().UTC().UnixNano())
|
||||
|
||||
s := options.NewServerRunOptions()
|
||||
s.AddFlags(pflag.CommandLine)
|
||||
|
||||
flag.InitFlags()
|
||||
logs.InitLogs()
|
||||
defer logs.FlushLogs()
|
||||
|
||||
verflag.PrintAndExitIfRequested()
|
||||
|
||||
stopCh := server.SetupSignalHandler()
|
||||
if err := app.Run(s, stopCh); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "%v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
96
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/BUILD
generated
vendored
Normal file
96
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
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",
|
||||
],
|
||||
deps = [
|
||||
"//cmd/kube-apiserver/app/options:go_default_library",
|
||||
"//pkg/api:go_default_library",
|
||||
"//pkg/apis/apps:go_default_library",
|
||||
"//pkg/apis/batch:go_default_library",
|
||||
"//pkg/apis/extensions:go_default_library",
|
||||
"//pkg/apis/networking: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/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/tunneler:go_default_library",
|
||||
"//pkg/quota/install:go_default_library",
|
||||
"//pkg/registry/cachesize:go_default_library",
|
||||
"//pkg/registry/rbac/rest:go_default_library",
|
||||
"//pkg/util/reflector/prometheus:go_default_library",
|
||||
"//pkg/util/workqueue/prometheus:go_default_library",
|
||||
"//pkg/version: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/github.com/spf13/pflag: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/authentication/authenticator:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authorization/authorizer: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/client-go/informers:go_default_library",
|
||||
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
|
||||
"//vendor/k8s.io/client-go/tools/cache:go_default_library",
|
||||
"//vendor/k8s.io/kube-aggregator/pkg/apis/apiregistration: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/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"],
|
||||
)
|
||||
259
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/aggregator.go
generated
vendored
Normal file
259
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/aggregator.go
generated
vendored
Normal file
|
|
@ -0,0 +1,259 @@
|
|||
/*
|
||||
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"
|
||||
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/v1beta1"
|
||||
aggregatorapiserver "k8s.io/kube-aggregator/pkg/apiserver"
|
||||
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) (*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
|
||||
|
||||
// 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 = aggregatorapiserver.Codecs.LegacyCodec(v1beta1.SchemeGroupVersion)
|
||||
etcdOptions.StorageConfig.Copier = aggregatorapiserver.Scheme
|
||||
genericConfig.RESTOptionsGetter = &genericoptions.SimpleRestOptionsFactory{Options: etcdOptions}
|
||||
|
||||
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.
|
||||
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
|
||||
})
|
||||
}
|
||||
|
||||
type priority struct {
|
||||
group int32
|
||||
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: 1},
|
||||
{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: "apiextensions.k8s.io", Version: "v1beta1"}: {group: 16700, version: 9},
|
||||
{Group: "admissionregistration.k8s.io", Version: "v1alpha1"}: {group: 16700, version: 9},
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
63
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/apiextensions.go
generated
vendored
Normal file
63
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/apiextensions.go
generated
vendored
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
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"
|
||||
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, commandOptions *options.ServerRunOptions) (*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
|
||||
|
||||
// copy the etcd options so we don't mutate originals.
|
||||
etcdOptions := *commandOptions.Etcd
|
||||
etcdOptions.StorageConfig.Codec = apiextensionsapiserver.Codecs.LegacyCodec(v1beta1.SchemeGroupVersion)
|
||||
etcdOptions.StorageConfig.Copier = apiextensionsapiserver.Scheme
|
||||
genericConfig.RESTOptionsGetter = &genericoptions.SimpleRestOptionsFactory{Options: etcdOptions}
|
||||
|
||||
apiextensionsConfig := &apiextensionsapiserver.Config{
|
||||
GenericConfig: &genericapiserver.RecommendedConfig{
|
||||
Config: genericConfig,
|
||||
SharedInformerFactory: externalInformers,
|
||||
},
|
||||
ExtraConfig: apiextensionsapiserver.ExtraConfig{
|
||||
CRDRESTOptionsGetter: apiextensionscmd.NewCRDRESTOptionsGetter(etcdOptions),
|
||||
},
|
||||
}
|
||||
|
||||
return apiextensionsConfig, nil
|
||||
}
|
||||
|
||||
func createAPIExtensionsServer(apiextensionsConfig *apiextensionsapiserver.Config, delegateAPIServer genericapiserver.DelegationTarget) (*apiextensionsapiserver.CustomResourceDefinitions, error) {
|
||||
apiextensionsServer, err := apiextensionsConfig.Complete().New(delegateAPIServer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return apiextensionsServer, nil
|
||||
}
|
||||
87
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/options/BUILD
generated
vendored
Normal file
87
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/options/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
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",
|
||||
"plugins.go",
|
||||
"validation.go",
|
||||
],
|
||||
deps = [
|
||||
"//pkg/api:go_default_library",
|
||||
"//pkg/api/validation:go_default_library",
|
||||
"//pkg/cloudprovider/providers: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",
|
||||
"//plugin/pkg/admission/admit:go_default_library",
|
||||
"//plugin/pkg/admission/alwayspullimages:go_default_library",
|
||||
"//plugin/pkg/admission/antiaffinity:go_default_library",
|
||||
"//plugin/pkg/admission/defaulttolerationseconds:go_default_library",
|
||||
"//plugin/pkg/admission/deny:go_default_library",
|
||||
"//plugin/pkg/admission/eventratelimit:go_default_library",
|
||||
"//plugin/pkg/admission/exec:go_default_library",
|
||||
"//plugin/pkg/admission/gc:go_default_library",
|
||||
"//plugin/pkg/admission/imagepolicy:go_default_library",
|
||||
"//plugin/pkg/admission/initialization:go_default_library",
|
||||
"//plugin/pkg/admission/initialresources:go_default_library",
|
||||
"//plugin/pkg/admission/limitranger:go_default_library",
|
||||
"//plugin/pkg/admission/namespace/autoprovision:go_default_library",
|
||||
"//plugin/pkg/admission/namespace/exists:go_default_library",
|
||||
"//plugin/pkg/admission/noderestriction:go_default_library",
|
||||
"//plugin/pkg/admission/persistentvolume/label:go_default_library",
|
||||
"//plugin/pkg/admission/persistentvolume/resize:go_default_library",
|
||||
"//plugin/pkg/admission/podnodeselector:go_default_library",
|
||||
"//plugin/pkg/admission/podpreset:go_default_library",
|
||||
"//plugin/pkg/admission/podtolerationrestriction:go_default_library",
|
||||
"//plugin/pkg/admission/priority:go_default_library",
|
||||
"//plugin/pkg/admission/resourcequota:go_default_library",
|
||||
"//plugin/pkg/admission/security/podsecuritypolicy:go_default_library",
|
||||
"//plugin/pkg/admission/securitycontext/scdeny:go_default_library",
|
||||
"//plugin/pkg/admission/serviceaccount:go_default_library",
|
||||
"//plugin/pkg/admission/storageclass/setdefault:go_default_library",
|
||||
"//plugin/pkg/admission/webhook:go_default_library",
|
||||
"//vendor/github.com/spf13/pflag:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/net:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/server/options:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/storage/storagebackend:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["options_test.go"],
|
||||
library = ":go_default_library",
|
||||
deps = [
|
||||
"//pkg/api:go_default_library",
|
||||
"//pkg/kubeapiserver/options:go_default_library",
|
||||
"//pkg/kubelet/client: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/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"],
|
||||
)
|
||||
236
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/options/options.go
generated
vendored
Normal file
236
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/options/options.go
generated
vendored
Normal file
|
|
@ -0,0 +1,236 @@
|
|||
/*
|
||||
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"
|
||||
"time"
|
||||
|
||||
utilnet "k8s.io/apimachinery/pkg/util/net"
|
||||
genericoptions "k8s.io/apiserver/pkg/server/options"
|
||||
"k8s.io/apiserver/pkg/storage/storagebackend"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/validation"
|
||||
kubeoptions "k8s.io/kubernetes/pkg/kubeapiserver/options"
|
||||
kubeletclient "k8s.io/kubernetes/pkg/kubelet/client"
|
||||
"k8s.io/kubernetes/pkg/master/ports"
|
||||
|
||||
// add the kubernetes feature gates
|
||||
_ "k8s.io/kubernetes/pkg/features"
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
// DefaultServiceNodePortRange is the default port range for NodePort services.
|
||||
var DefaultServiceNodePortRange = utilnet.PortRange{Base: 30000, Size: 2768}
|
||||
|
||||
// ServerRunOptions runs a kubernetes api server.
|
||||
type ServerRunOptions struct {
|
||||
GenericServerRunOptions *genericoptions.ServerRunOptions
|
||||
Etcd *genericoptions.EtcdOptions
|
||||
SecureServing *genericoptions.SecureServingOptions
|
||||
InsecureServing *kubeoptions.InsecureServingOptions
|
||||
Audit *genericoptions.AuditOptions
|
||||
Features *genericoptions.FeatureOptions
|
||||
Admission *genericoptions.AdmissionOptions
|
||||
Authentication *kubeoptions.BuiltInAuthenticationOptions
|
||||
Authorization *kubeoptions.BuiltInAuthorizationOptions
|
||||
CloudProvider *kubeoptions.CloudProviderOptions
|
||||
StorageSerialization *kubeoptions.StorageSerializationOptions
|
||||
APIEnablement *kubeoptions.APIEnablementOptions
|
||||
|
||||
AllowPrivileged bool
|
||||
EnableLogsHandler bool
|
||||
EventTTL time.Duration
|
||||
KubeletConfig kubeletclient.KubeletClientConfig
|
||||
KubernetesServiceNodePort int
|
||||
MasterCount int
|
||||
MaxConnectionBytesPerSec int64
|
||||
ServiceClusterIPRange net.IPNet // TODO: make this a list
|
||||
ServiceNodePortRange utilnet.PortRange
|
||||
SSHKeyfile string
|
||||
SSHUser string
|
||||
|
||||
ProxyClientCertFile string
|
||||
ProxyClientKeyFile string
|
||||
|
||||
EnableAggregatorRouting bool
|
||||
}
|
||||
|
||||
// NewServerRunOptions creates a new ServerRunOptions object with default parameters
|
||||
func NewServerRunOptions() *ServerRunOptions {
|
||||
s := ServerRunOptions{
|
||||
GenericServerRunOptions: genericoptions.NewServerRunOptions(),
|
||||
Etcd: genericoptions.NewEtcdOptions(storagebackend.NewDefaultConfig(kubeoptions.DefaultEtcdPathPrefix, api.Scheme, nil)),
|
||||
SecureServing: kubeoptions.NewSecureServingOptions(),
|
||||
InsecureServing: kubeoptions.NewInsecureServingOptions(),
|
||||
Audit: genericoptions.NewAuditOptions(),
|
||||
Features: genericoptions.NewFeatureOptions(),
|
||||
Admission: genericoptions.NewAdmissionOptions(),
|
||||
Authentication: kubeoptions.NewBuiltInAuthenticationOptions().WithAll(),
|
||||
Authorization: kubeoptions.NewBuiltInAuthorizationOptions(),
|
||||
CloudProvider: kubeoptions.NewCloudProviderOptions(),
|
||||
StorageSerialization: kubeoptions.NewStorageSerializationOptions(),
|
||||
APIEnablement: kubeoptions.NewAPIEnablementOptions(),
|
||||
|
||||
EnableLogsHandler: true,
|
||||
EventTTL: 1 * time.Hour,
|
||||
MasterCount: 1,
|
||||
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: DefaultServiceNodePortRange,
|
||||
}
|
||||
// Overwrite the default for storage data format.
|
||||
s.Etcd.DefaultStorageMediaType = "application/vnd.kubernetes.protobuf"
|
||||
|
||||
// register all admission plugins
|
||||
RegisterAllAdmissionPlugins(s.Admission.Plugins)
|
||||
// Set the default for admission plugins names
|
||||
s.Admission.PluginNames = []string{"AlwaysAdmit"}
|
||||
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.SecureServing.AddDeprecatedFlags(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.")
|
||||
|
||||
fs.StringVar(&s.SSHUser, "ssh-user", s.SSHUser,
|
||||
"If non-empty, use secure SSH proxy to the nodes, using this user name")
|
||||
|
||||
fs.StringVar(&s.SSHKeyfile, "ssh-keyfile", s.SSHKeyfile,
|
||||
"If non-empty, use secure SSH proxy to the nodes, using this user keyfile")
|
||||
|
||||
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.")
|
||||
|
||||
// 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.IPNetVar(&s.ServiceClusterIPRange, "portal-net", s.ServiceClusterIPRange,
|
||||
"DEPRECATED: see --service-cluster-ip-range instead.")
|
||||
fs.MarkDeprecated("portal-net", "see --service-cluster-ip-range instead")
|
||||
|
||||
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.")
|
||||
fs.Var(&s.ServiceNodePortRange, "service-node-ports", "DEPRECATED: see --service-node-port-range instead")
|
||||
fs.MarkDeprecated("service-node-ports", "see --service-node-port-range instead")
|
||||
|
||||
// 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 as soon as we identify and fix all clients that send malformed updates, like #14126.
|
||||
fs.BoolVar(&validation.RepairMalformedUpdates, "repair-malformed-updates", validation.RepairMalformedUpdates, ""+
|
||||
"If true, server will do its best to fix the update request to pass the validation, "+
|
||||
"e.g., setting empty UID in update request to its existing value. This flag can be turned off "+
|
||||
"after we fix all the clients that send malformed updates.")
|
||||
|
||||
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 recieving 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.")
|
||||
|
||||
}
|
||||
227
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/options/options_test.go
generated
vendored
Normal file
227
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/options/options_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,227 @@
|
|||
/*
|
||||
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"
|
||||
"k8s.io/apiserver/pkg/storage/storagebackend"
|
||||
utilconfig "k8s.io/apiserver/pkg/util/flag"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
kapi "k8s.io/kubernetes/pkg/api"
|
||||
kubeoptions "k8s.io/kubernetes/pkg/kubeapiserver/options"
|
||||
kubeletclient "k8s.io/kubernetes/pkg/kubelet/client"
|
||||
)
|
||||
|
||||
func TestAddFlags(t *testing.T) {
|
||||
f := pflag.NewFlagSet("addflagstest", pflag.ContinueOnError)
|
||||
s := NewServerRunOptions()
|
||||
s.AddFlags(f)
|
||||
|
||||
args := []string{
|
||||
"--admission-control=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-policy-file=/policy",
|
||||
"--audit-webhook-config-file=/webhook-config",
|
||||
"--audit-webhook-mode=blocking",
|
||||
"--authentication-token-webhook-cache-ttl=3m",
|
||||
"--authentication-token-webhook-config-file=/token-webhook-config",
|
||||
"--authorization-mode=AlwaysDeny",
|
||||
"--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",
|
||||
"--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",
|
||||
"--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: DefaultServiceNodePortRange,
|
||||
MasterCount: 5,
|
||||
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: &apiserveroptions.AdmissionOptions{
|
||||
PluginNames: []string{"AlwaysDeny"},
|
||||
ConfigFile: "/admission-control-config",
|
||||
Plugins: s.Admission.Plugins,
|
||||
},
|
||||
Etcd: &apiserveroptions.EtcdOptions{
|
||||
StorageConfig: storagebackend.Config{
|
||||
Type: "etcd2",
|
||||
ServerList: nil,
|
||||
Prefix: "/registry",
|
||||
DeserializationCacheSize: 0,
|
||||
Copier: kapi.Scheme,
|
||||
Quorum: false,
|
||||
KeyFile: "/var/run/kubernetes/etcd.key",
|
||||
CAFile: "/var/run/kubernetes/etcdca.crt",
|
||||
CertFile: "/var/run/kubernetes/etcdce.crt",
|
||||
},
|
||||
DefaultStorageMediaType: "application/vnd.kubernetes.protobuf",
|
||||
DeleteCollectionWorkers: 1,
|
||||
EnableGarbageCollection: true,
|
||||
EnableWatchCache: true,
|
||||
DefaultWatchCacheSize: 100,
|
||||
},
|
||||
SecureServing: &apiserveroptions.SecureServingOptions{
|
||||
BindAddress: net.ParseIP("192.168.10.20"),
|
||||
BindPort: 6443,
|
||||
ServerCert: apiserveroptions.GeneratableKeyCert{
|
||||
CertDirectory: "/var/run/kubernetes",
|
||||
PairName: "apiserver",
|
||||
},
|
||||
},
|
||||
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",
|
||||
},
|
||||
WebhookOptions: apiserveroptions.AuditWebhookOptions{
|
||||
Mode: "blocking",
|
||||
ConfigFile: "/webhook-config",
|
||||
},
|
||||
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{},
|
||||
Keystone: &kubeoptions.KeystoneAuthenticationOptions{},
|
||||
OIDC: &kubeoptions.OIDCAuthenticationOptions{
|
||||
UsernameClaim: "sub",
|
||||
},
|
||||
PasswordFile: &kubeoptions.PasswordFileAuthenticationOptions{},
|
||||
RequestHeader: &apiserveroptions.RequestHeaderAuthenticationOptions{},
|
||||
ServiceAccounts: &kubeoptions.ServiceAccountAuthenticationOptions{
|
||||
Lookup: true,
|
||||
},
|
||||
TokenFile: &kubeoptions.TokenFileAuthenticationOptions{},
|
||||
TokenSuccessCacheTTL: 10 * time.Second,
|
||||
TokenFailureCacheTTL: 0,
|
||||
},
|
||||
Authorization: &kubeoptions.BuiltInAuthorizationOptions{
|
||||
Mode: "AlwaysDeny",
|
||||
PolicyFile: "/policy",
|
||||
WebhookConfigFile: "/webhook-config",
|
||||
WebhookCacheAuthorizedTTL: 180000000000,
|
||||
WebhookCacheUnauthorizedTTL: 60000000000,
|
||||
},
|
||||
CloudProvider: &kubeoptions.CloudProviderOptions{
|
||||
CloudConfigFile: "/cloud-config",
|
||||
CloudProvider: "azure",
|
||||
},
|
||||
StorageSerialization: &kubeoptions.StorageSerializationOptions{
|
||||
StorageVersions: kapi.Registry.AllPreferredGroupVersions(),
|
||||
DefaultStorageVersions: kapi.Registry.AllPreferredGroupVersions(),
|
||||
},
|
||||
APIEnablement: &kubeoptions.APIEnablementOptions{
|
||||
RuntimeConfig: utilconfig.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))
|
||||
}
|
||||
}
|
||||
86
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/options/plugins.go
generated
vendored
Normal file
86
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/options/plugins.go
generated
vendored
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
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
|
||||
|
||||
// This file exists to force the desired plugin implementations to be linked.
|
||||
// This should probably be part of some configuration fed into the build for a
|
||||
// given binary target.
|
||||
import (
|
||||
// Cloud providers
|
||||
_ "k8s.io/kubernetes/pkg/cloudprovider/providers"
|
||||
|
||||
// Admission policies
|
||||
"k8s.io/apiserver/pkg/admission"
|
||||
"k8s.io/kubernetes/plugin/pkg/admission/admit"
|
||||
"k8s.io/kubernetes/plugin/pkg/admission/alwayspullimages"
|
||||
"k8s.io/kubernetes/plugin/pkg/admission/antiaffinity"
|
||||
"k8s.io/kubernetes/plugin/pkg/admission/defaulttolerationseconds"
|
||||
"k8s.io/kubernetes/plugin/pkg/admission/deny"
|
||||
"k8s.io/kubernetes/plugin/pkg/admission/eventratelimit"
|
||||
"k8s.io/kubernetes/plugin/pkg/admission/exec"
|
||||
"k8s.io/kubernetes/plugin/pkg/admission/gc"
|
||||
"k8s.io/kubernetes/plugin/pkg/admission/imagepolicy"
|
||||
"k8s.io/kubernetes/plugin/pkg/admission/initialization"
|
||||
"k8s.io/kubernetes/plugin/pkg/admission/initialresources"
|
||||
"k8s.io/kubernetes/plugin/pkg/admission/limitranger"
|
||||
"k8s.io/kubernetes/plugin/pkg/admission/namespace/autoprovision"
|
||||
"k8s.io/kubernetes/plugin/pkg/admission/namespace/exists"
|
||||
"k8s.io/kubernetes/plugin/pkg/admission/noderestriction"
|
||||
"k8s.io/kubernetes/plugin/pkg/admission/persistentvolume/label"
|
||||
"k8s.io/kubernetes/plugin/pkg/admission/persistentvolume/resize"
|
||||
"k8s.io/kubernetes/plugin/pkg/admission/podnodeselector"
|
||||
"k8s.io/kubernetes/plugin/pkg/admission/podpreset"
|
||||
"k8s.io/kubernetes/plugin/pkg/admission/podtolerationrestriction"
|
||||
podpriority "k8s.io/kubernetes/plugin/pkg/admission/priority"
|
||||
"k8s.io/kubernetes/plugin/pkg/admission/resourcequota"
|
||||
"k8s.io/kubernetes/plugin/pkg/admission/security/podsecuritypolicy"
|
||||
"k8s.io/kubernetes/plugin/pkg/admission/securitycontext/scdeny"
|
||||
"k8s.io/kubernetes/plugin/pkg/admission/serviceaccount"
|
||||
"k8s.io/kubernetes/plugin/pkg/admission/storageclass/setdefault"
|
||||
"k8s.io/kubernetes/plugin/pkg/admission/webhook"
|
||||
)
|
||||
|
||||
// RegisterAllAdmissionPlugins registers all admission plugins
|
||||
func RegisterAllAdmissionPlugins(plugins *admission.Plugins) {
|
||||
admit.Register(plugins)
|
||||
alwayspullimages.Register(plugins)
|
||||
antiaffinity.Register(plugins)
|
||||
defaulttolerationseconds.Register(plugins)
|
||||
deny.Register(plugins)
|
||||
eventratelimit.Register(plugins)
|
||||
exec.Register(plugins)
|
||||
gc.Register(plugins)
|
||||
imagepolicy.Register(plugins)
|
||||
initialization.Register(plugins)
|
||||
initialresources.Register(plugins)
|
||||
limitranger.Register(plugins)
|
||||
autoprovision.Register(plugins)
|
||||
exists.Register(plugins)
|
||||
noderestriction.Register(plugins)
|
||||
label.Register(plugins) // DEPRECATED in favor of NewPersistentVolumeLabelController in CCM
|
||||
podnodeselector.Register(plugins)
|
||||
podpreset.Register(plugins)
|
||||
podtolerationrestriction.Register(plugins)
|
||||
resourcequota.Register(plugins)
|
||||
podsecuritypolicy.Register(plugins)
|
||||
podpriority.Register(plugins)
|
||||
scdeny.Register(plugins)
|
||||
serviceaccount.Register(plugins)
|
||||
setdefault.Register(plugins)
|
||||
webhook.Register(plugins)
|
||||
resize.Register(plugins)
|
||||
}
|
||||
76
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/options/validation.go
generated
vendored
Normal file
76
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/options/validation.go
generated
vendored
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
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"
|
||||
)
|
||||
|
||||
// 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 (options *ServerRunOptions) Validate() []error {
|
||||
var errors []error
|
||||
if errs := options.Etcd.Validate(); len(errs) > 0 {
|
||||
errors = append(errors, errs...)
|
||||
}
|
||||
if errs := validateClusterIPFlags(options); len(errs) > 0 {
|
||||
errors = append(errors, errs...)
|
||||
}
|
||||
if errs := validateServiceNodePort(options); len(errs) > 0 {
|
||||
errors = append(errors, errs...)
|
||||
}
|
||||
if errs := options.SecureServing.Validate(); len(errs) > 0 {
|
||||
errors = append(errors, errs...)
|
||||
}
|
||||
if errs := options.Authentication.Validate(); len(errs) > 0 {
|
||||
errors = append(errors, errs...)
|
||||
}
|
||||
if errs := options.Audit.Validate(); len(errs) > 0 {
|
||||
errors = append(errors, errs...)
|
||||
}
|
||||
if errs := options.InsecureServing.Validate("insecure-port"); len(errs) > 0 {
|
||||
errors = append(errors, errs...)
|
||||
}
|
||||
if options.MasterCount <= 0 {
|
||||
errors = append(errors, fmt.Errorf("--apiserver-count should be a positive number, but value '%d' provided", options.MasterCount))
|
||||
}
|
||||
return errors
|
||||
}
|
||||
1030
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/server.go
generated
vendored
Normal file
1030
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/server.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
58
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/testing/BUILD
generated
vendored
Normal file
58
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/testing/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["server_test.go"],
|
||||
library = ":go_default_library",
|
||||
deps = [
|
||||
"//vendor/k8s.io/api/admissionregistration/v1alpha1:go_default_library",
|
||||
"//vendor/k8s.io/api/apps/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/api/networking/v1:go_default_library",
|
||||
"//vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/features:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/util/feature/testing:go_default_library",
|
||||
"//vendor/k8s.io/client-go/dynamic:go_default_library",
|
||||
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["testserver.go"],
|
||||
deps = [
|
||||
"//cmd/kube-apiserver/app:go_default_library",
|
||||
"//cmd/kube-apiserver/app/options:go_default_library",
|
||||
"//pkg/api:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/storage/etcd/testing: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"],
|
||||
)
|
||||
391
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/testing/server_test.go
generated
vendored
Normal file
391
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/testing/server_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,391 @@
|
|||
/*
|
||||
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 (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
admissionregistrationv1alpha1 "k8s.io/api/admissionregistration/v1alpha1"
|
||||
appsv1beta1 "k8s.io/api/apps/v1beta1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
networkingv1 "k8s.io/api/networking/v1"
|
||||
apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
|
||||
apiextensionsclientset "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/apiserver/pkg/features"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
|
||||
"k8s.io/client-go/dynamic"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
)
|
||||
|
||||
func TestRun(t *testing.T) {
|
||||
config, tearDown := StartTestServerOrDie(t)
|
||||
defer tearDown()
|
||||
|
||||
client, err := kubernetes.NewForConfig(config)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
// test whether the server is really healthy after /healthz told us so
|
||||
t.Logf("Creating Deployment directly after being healthy")
|
||||
var replicas int32 = 1
|
||||
_, err = client.AppsV1beta1().Deployments("default").Create(&appsv1beta1.Deployment{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "Deployment",
|
||||
APIVersion: "apps/v1beta1",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: "default",
|
||||
Name: "test",
|
||||
},
|
||||
Spec: appsv1beta1.DeploymentSpec{
|
||||
Replicas: &replicas,
|
||||
Strategy: appsv1beta1.DeploymentStrategy{
|
||||
Type: appsv1beta1.RollingUpdateDeploymentStrategyType,
|
||||
},
|
||||
Template: corev1.PodTemplateSpec{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Labels: map[string]string{"foo": "bar"},
|
||||
},
|
||||
Spec: corev1.PodSpec{
|
||||
Containers: []corev1.Container{
|
||||
{
|
||||
Name: "foo",
|
||||
Image: "foo",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create deployment: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCRDShadowGroup(t *testing.T) {
|
||||
config, tearDown := StartTestServerOrDie(t)
|
||||
defer tearDown()
|
||||
|
||||
kubeclient, err := kubernetes.NewForConfig(config)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
|
||||
apiextensionsclient, err := apiextensionsclientset.NewForConfig(config)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
|
||||
t.Logf("Creating a NetworkPolicy")
|
||||
nwPolicy, err := kubeclient.NetworkingV1().NetworkPolicies("default").Create(&networkingv1.NetworkPolicy{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault},
|
||||
Spec: networkingv1.NetworkPolicySpec{
|
||||
PodSelector: metav1.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}},
|
||||
Ingress: []networkingv1.NetworkPolicyIngressRule{},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create NetworkPolicy: %v", err)
|
||||
}
|
||||
|
||||
t.Logf("Trying to shadow networking group")
|
||||
crd := &apiextensionsv1beta1.CustomResourceDefinition{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foos." + networkingv1.GroupName,
|
||||
},
|
||||
Spec: apiextensionsv1beta1.CustomResourceDefinitionSpec{
|
||||
Group: networkingv1.GroupName,
|
||||
Version: networkingv1.SchemeGroupVersion.Version,
|
||||
Scope: apiextensionsv1beta1.ClusterScoped,
|
||||
Names: apiextensionsv1beta1.CustomResourceDefinitionNames{
|
||||
Plural: "foos",
|
||||
Kind: "Foo",
|
||||
},
|
||||
},
|
||||
}
|
||||
if _, err = apiextensionsclient.ApiextensionsV1beta1().CustomResourceDefinitions().Create(crd); err != nil {
|
||||
t.Fatalf("Failed to create networking group CRD: %v", err)
|
||||
}
|
||||
if err := waitForEstablishedCRD(apiextensionsclient, crd.Name); err != nil {
|
||||
t.Fatalf("Failed to establish networking group CRD: %v", err)
|
||||
}
|
||||
// wait to give aggregator time to update
|
||||
time.Sleep(2 * time.Second)
|
||||
|
||||
t.Logf("Checking that we still see the NetworkPolicy")
|
||||
_, err = kubeclient.NetworkingV1().NetworkPolicies(nwPolicy.Namespace).Get(nwPolicy.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
t.Errorf("Failed to get NetworkPolocy: %v", err)
|
||||
}
|
||||
|
||||
t.Logf("Checking that crd resource does not show up in networking group")
|
||||
found, err := crdExistsInDiscovery(apiextensionsclient, crd)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected discovery error: %v", err)
|
||||
}
|
||||
if found {
|
||||
t.Errorf("CRD resource shows up in discovery, but shouldn't.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCRD(t *testing.T) {
|
||||
defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.Initializers, true)()
|
||||
|
||||
config, tearDown := StartTestServerOrDie(t)
|
||||
defer tearDown()
|
||||
|
||||
kubeclient, err := kubernetes.NewForConfig(config)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
|
||||
apiextensionsclient, err := apiextensionsclientset.NewForConfig(config)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
|
||||
t.Logf("Trying to create a custom resource without conflict")
|
||||
crd := &apiextensionsv1beta1.CustomResourceDefinition{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foos.cr.bar.com",
|
||||
},
|
||||
Spec: apiextensionsv1beta1.CustomResourceDefinitionSpec{
|
||||
Group: "cr.bar.com",
|
||||
Version: "v1",
|
||||
Scope: apiextensionsv1beta1.NamespaceScoped,
|
||||
Names: apiextensionsv1beta1.CustomResourceDefinitionNames{
|
||||
Plural: "foos",
|
||||
Kind: "Foo",
|
||||
},
|
||||
},
|
||||
}
|
||||
if _, err = apiextensionsclient.ApiextensionsV1beta1().CustomResourceDefinitions().Create(crd); err != nil {
|
||||
t.Fatalf("Failed to create foos.cr.bar.com CRD; %v", err)
|
||||
}
|
||||
if err := waitForEstablishedCRD(apiextensionsclient, crd.Name); err != nil {
|
||||
t.Fatalf("Failed to establish foos.cr.bar.com CRD: %v", err)
|
||||
}
|
||||
if err := wait.PollImmediate(500*time.Millisecond, 30*time.Second, func() (bool, error) {
|
||||
return crdExistsInDiscovery(apiextensionsclient, crd)
|
||||
}); err != nil {
|
||||
t.Fatalf("Failed to see foos.cr.bar.com in discovery: %v", err)
|
||||
}
|
||||
|
||||
t.Logf("Trying to access foos.cr.bar.com with dynamic client")
|
||||
barComConfig := *config
|
||||
barComConfig.GroupVersion = &schema.GroupVersion{Group: "cr.bar.com", Version: "v1"}
|
||||
barComConfig.APIPath = "/apis"
|
||||
barComClient, err := dynamic.NewClient(&barComConfig)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
_, err = barComClient.Resource(&metav1.APIResource{Name: "foos", Namespaced: true}, "default").List(metav1.ListOptions{})
|
||||
if err != nil {
|
||||
t.Errorf("Failed to list foos.cr.bar.com instances: %v", err)
|
||||
}
|
||||
|
||||
t.Logf("Creating InitializerConfiguration")
|
||||
_, err = kubeclient.AdmissionregistrationV1alpha1().InitializerConfigurations().Create(&admissionregistrationv1alpha1.InitializerConfiguration{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foos.cr.bar.com",
|
||||
},
|
||||
Initializers: []admissionregistrationv1alpha1.Initializer{
|
||||
{
|
||||
Name: "cr.bar.com",
|
||||
Rules: []admissionregistrationv1alpha1.Rule{
|
||||
{
|
||||
APIGroups: []string{"cr.bar.com"},
|
||||
APIVersions: []string{"*"},
|
||||
Resources: []string{"*"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create InitializerConfiguration: %v", err)
|
||||
}
|
||||
|
||||
// TODO DO NOT MERGE THIS
|
||||
time.Sleep(5 * time.Second)
|
||||
|
||||
t.Logf("Creating Foo instance")
|
||||
foo := &Foo{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
APIVersion: "cr.bar.com/v1",
|
||||
Kind: "Foo",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
|
||||
}
|
||||
unstructuredFoo, err := unstructuredFoo(foo)
|
||||
if err != nil {
|
||||
t.Fatalf("Unable to create Foo: %v", err)
|
||||
}
|
||||
createErr := make(chan error, 1)
|
||||
go func() {
|
||||
_, err = barComClient.Resource(&metav1.APIResource{Name: "foos", Namespaced: true}, "default").Create(unstructuredFoo)
|
||||
t.Logf("Foo instance create returned: %v", err)
|
||||
if err != nil {
|
||||
createErr <- err
|
||||
}
|
||||
}()
|
||||
|
||||
err = wait.PollImmediate(100*time.Millisecond, wait.ForeverTestTimeout, func() (bool, error) {
|
||||
select {
|
||||
case createErr := <-createErr:
|
||||
return true, createErr
|
||||
default:
|
||||
}
|
||||
|
||||
t.Logf("Checking that Foo instance is visible with IncludeUninitialized=true")
|
||||
_, err := barComClient.Resource(&metav1.APIResource{Name: "foos", Namespaced: true}, "default").Get(foo.ObjectMeta.Name, metav1.GetOptions{
|
||||
IncludeUninitialized: true,
|
||||
})
|
||||
switch {
|
||||
case err == nil:
|
||||
return true, nil
|
||||
case errors.IsNotFound(err):
|
||||
return false, nil
|
||||
default:
|
||||
return false, err
|
||||
}
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
|
||||
t.Logf("Removing initializer from Foo instance")
|
||||
success := false
|
||||
for i := 0; i < 10; i++ {
|
||||
// would love to replace the following with a patch, but removing strings from the intitializer array
|
||||
// is not what JSON (Merge) patch authors had in mind.
|
||||
fooUnstructured, err := barComClient.Resource(&metav1.APIResource{Name: "foos", Namespaced: true}, "default").Get(foo.ObjectMeta.Name, metav1.GetOptions{
|
||||
IncludeUninitialized: true,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Error getting Foo instance: %v", err)
|
||||
}
|
||||
bs, _ := fooUnstructured.MarshalJSON()
|
||||
t.Logf("Got Foo instance: %v", string(bs))
|
||||
foo := Foo{}
|
||||
if err := json.Unmarshal(bs, &foo); err != nil {
|
||||
t.Fatalf("Error parsing Foo instance: %v", err)
|
||||
}
|
||||
|
||||
// remove initialize
|
||||
if foo.ObjectMeta.Initializers == nil {
|
||||
t.Fatalf("Expected initializers to be set in Foo instance")
|
||||
}
|
||||
found := false
|
||||
for i := range foo.ObjectMeta.Initializers.Pending {
|
||||
if foo.ObjectMeta.Initializers.Pending[i].Name == "cr.bar.com" {
|
||||
foo.ObjectMeta.Initializers.Pending = append(foo.ObjectMeta.Initializers.Pending[:i], foo.ObjectMeta.Initializers.Pending[i+1:]...)
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
t.Fatalf("Expected cr.bar.com as initializer on Foo instance")
|
||||
}
|
||||
if len(foo.ObjectMeta.Initializers.Pending) == 0 && foo.ObjectMeta.Initializers.Result == nil {
|
||||
foo.ObjectMeta.Initializers = nil
|
||||
}
|
||||
bs, err = json.Marshal(&foo)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
fooUnstructured.UnmarshalJSON(bs)
|
||||
|
||||
_, err = barComClient.Resource(&metav1.APIResource{Name: "foos", Namespaced: true}, "default").Update(fooUnstructured)
|
||||
if err != nil && !errors.IsConflict(err) {
|
||||
t.Fatalf("Failed to update Foo instance: %v", err)
|
||||
} else if err == nil {
|
||||
success = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !success {
|
||||
t.Fatalf("Failed to remove initializer from Foo object")
|
||||
}
|
||||
|
||||
t.Logf("Checking that Foo instance is visible after removing the initializer")
|
||||
if _, err := barComClient.Resource(&metav1.APIResource{Name: "foos", Namespaced: true}, "default").Get(foo.ObjectMeta.Name, metav1.GetOptions{}); err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
type Foo struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
|
||||
}
|
||||
|
||||
func unstructuredFoo(foo *Foo) (*unstructured.Unstructured, error) {
|
||||
bs, err := json.Marshal(foo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret := &unstructured.Unstructured{}
|
||||
if err = ret.UnmarshalJSON(bs); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func waitForEstablishedCRD(client apiextensionsclientset.Interface, name string) error {
|
||||
return wait.PollImmediate(500*time.Millisecond, wait.ForeverTestTimeout, func() (bool, error) {
|
||||
crd, err := client.ApiextensionsV1beta1().CustomResourceDefinitions().Get(name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
for _, cond := range crd.Status.Conditions {
|
||||
switch cond.Type {
|
||||
case apiextensionsv1beta1.Established:
|
||||
if cond.Status == apiextensionsv1beta1.ConditionTrue {
|
||||
return true, err
|
||||
}
|
||||
case apiextensionsv1beta1.NamesAccepted:
|
||||
if cond.Status == apiextensionsv1beta1.ConditionFalse {
|
||||
fmt.Printf("Name conflict: %v\n", cond.Reason)
|
||||
}
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
})
|
||||
}
|
||||
|
||||
func crdExistsInDiscovery(client apiextensionsclientset.Interface, crd *apiextensionsv1beta1.CustomResourceDefinition) (bool, error) {
|
||||
resourceList, err := client.Discovery().ServerResourcesForGroupVersion(crd.Spec.Group + "/" + crd.Spec.Version)
|
||||
if err != nil {
|
||||
return false, nil
|
||||
}
|
||||
for _, resource := range resourceList.APIResources {
|
||||
if resource.Name == crd.Spec.Names.Plural {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
164
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/testing/testserver.go
generated
vendored
Normal file
164
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/testing/testserver.go
generated
vendored
Normal file
|
|
@ -0,0 +1,164 @@
|
|||
/*
|
||||
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"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
etcdtesting "k8s.io/apiserver/pkg/storage/etcd/testing"
|
||||
"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"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
)
|
||||
|
||||
// TearDownFunc is to be called to tear down a test server.
|
||||
type TearDownFunc func()
|
||||
|
||||
// StartTestServer starts a etcd server and kube-apiserver. A rest client config and a tear-down func
|
||||
// are returned.
|
||||
//
|
||||
// Note: we return a tear-down func instead of a stop channel because the later will leak temporariy
|
||||
// files that becaues Golang testing's call to os.Exit will not give a stop channel go routine
|
||||
// enough time to remove temporariy files.
|
||||
func StartTestServer(t *testing.T) (result *restclient.Config, tearDownForCaller TearDownFunc, err error) {
|
||||
var tmpDir string
|
||||
var etcdServer *etcdtesting.EtcdTestServer
|
||||
stopCh := make(chan struct{})
|
||||
tearDown := func() {
|
||||
close(stopCh)
|
||||
if etcdServer != nil {
|
||||
etcdServer.Terminate(t)
|
||||
}
|
||||
if len(tmpDir) != 0 {
|
||||
os.RemoveAll(tmpDir)
|
||||
}
|
||||
}
|
||||
defer func() {
|
||||
if tearDownForCaller == nil {
|
||||
tearDown()
|
||||
}
|
||||
}()
|
||||
|
||||
t.Logf("Starting etcd...")
|
||||
etcdServer, storageConfig := etcdtesting.NewUnsecuredEtcd3TestClientServer(t, api.Scheme)
|
||||
|
||||
tmpDir, err = ioutil.TempDir("", "kubernetes-kube-apiserver")
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("Failed to create temp dir: %v", err)
|
||||
}
|
||||
|
||||
s := options.NewServerRunOptions()
|
||||
s.InsecureServing.BindPort = 0
|
||||
s.SecureServing.BindPort = freePort()
|
||||
s.SecureServing.ServerCert.CertDirectory = tmpDir
|
||||
s.ServiceClusterIPRange.IP = net.IPv4(10, 0, 0, 0)
|
||||
s.ServiceClusterIPRange.Mask = net.CIDRMask(16, 32)
|
||||
s.Etcd.StorageConfig = *storageConfig
|
||||
s.Etcd.DefaultStorageMediaType = "application/json"
|
||||
s.Admission.PluginNames = strings.Split("Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,ResourceQuota,DefaultTolerationSeconds", ",")
|
||||
s.APIEnablement.RuntimeConfig.Set("api/all=true")
|
||||
|
||||
t.Logf("Starting kube-apiserver...")
|
||||
runErrCh := make(chan error, 1)
|
||||
server, err := app.CreateServerChain(s, stopCh)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("Failed to create server chain: %v", err)
|
||||
}
|
||||
go func(stopCh <-chan struct{}) {
|
||||
if err := server.PrepareRun().Run(stopCh); err != nil {
|
||||
t.Logf("kube-apiserver exited uncleanly: %v", err)
|
||||
runErrCh <- err
|
||||
}
|
||||
}(stopCh)
|
||||
|
||||
t.Logf("Waiting for /healthz to be ok...")
|
||||
client, err := kubernetes.NewForConfig(server.LoopbackClientConfig)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("Failed to create a client: %v", err)
|
||||
}
|
||||
err = wait.Poll(100*time.Millisecond, 30*time.Second, func() (bool, error) {
|
||||
select {
|
||||
case err := <-runErrCh:
|
||||
return false, err
|
||||
default:
|
||||
}
|
||||
|
||||
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 nil, nil, fmt.Errorf("Failed to wait for /healthz to return ok: %v", err)
|
||||
}
|
||||
|
||||
// from here the caller must call tearDown
|
||||
return server.LoopbackClientConfig, tearDown, nil
|
||||
}
|
||||
|
||||
// StartTestServerOrDie calls StartTestServer with up to 5 retries on bind error and dies with
|
||||
// t.Fatal if it does not succeed.
|
||||
func StartTestServerOrDie(t *testing.T) (*restclient.Config, TearDownFunc) {
|
||||
// retry test because the bind might fail due to a race with another process
|
||||
// binding to the port. We cannot listen to :0 (then the kernel would give us
|
||||
// a port which is free for sure), so we need this workaround.
|
||||
|
||||
var err error
|
||||
|
||||
for retry := 0; retry < 5 && !t.Failed(); retry++ {
|
||||
var config *restclient.Config
|
||||
var td TearDownFunc
|
||||
|
||||
config, td, err = StartTestServer(t)
|
||||
if err == nil {
|
||||
return config, td
|
||||
}
|
||||
if err != nil && !strings.Contains(err.Error(), "bind") {
|
||||
break
|
||||
}
|
||||
t.Logf("Bind error, retrying...")
|
||||
}
|
||||
|
||||
t.Fatalf("Failed to launch server: %v", err)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func freePort() int {
|
||||
addr, err := net.ResolveTCPAddr("tcp", "localhost:0")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
l, err := net.ListenTCP("tcp", addr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer l.Close()
|
||||
return l.Addr().(*net.TCPAddr).Port
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue