mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-06-13 10:33:35 +00:00
vendor files
This commit is contained in:
35
vendor/k8s.io/kubernetes/cmd/BUILD
generated
vendored
Normal file
35
vendor/k8s.io/kubernetes/cmd/BUILD
generated
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//cmd/clicheck:all-srcs",
|
||||
"//cmd/cloud-controller-manager:all-srcs",
|
||||
"//cmd/gendocs:all-srcs",
|
||||
"//cmd/genkubedocs:all-srcs",
|
||||
"//cmd/genman:all-srcs",
|
||||
"//cmd/genswaggertypedocs:all-srcs",
|
||||
"//cmd/genutils:all-srcs",
|
||||
"//cmd/genyaml:all-srcs",
|
||||
"//cmd/gke-certificates-controller:all-srcs",
|
||||
"//cmd/hyperkube:all-srcs",
|
||||
"//cmd/importverifier:all-srcs",
|
||||
"//cmd/kube-apiserver:all-srcs",
|
||||
"//cmd/kube-controller-manager:all-srcs",
|
||||
"//cmd/kube-proxy:all-srcs",
|
||||
"//cmd/kubeadm:all-srcs",
|
||||
"//cmd/kubectl:all-srcs",
|
||||
"//cmd/kubelet:all-srcs",
|
||||
"//cmd/kubemark:all-srcs",
|
||||
"//cmd/linkcheck:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
)
|
10
vendor/k8s.io/kubernetes/cmd/OWNERS
generated
vendored
Normal file
10
vendor/k8s.io/kubernetes/cmd/OWNERS
generated
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
reviewers:
|
||||
- dchen1107
|
||||
- lavalamp
|
||||
- mikedanese
|
||||
- thockin
|
||||
approvers:
|
||||
- dchen1107
|
||||
- lavalamp
|
||||
- mikedanese
|
||||
- thockin
|
37
vendor/k8s.io/kubernetes/cmd/clicheck/BUILD
generated
vendored
Normal file
37
vendor/k8s.io/kubernetes/cmd/clicheck/BUILD
generated
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_binary",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_binary(
|
||||
name = "clicheck",
|
||||
importpath = "k8s.io/kubernetes/cmd/clicheck",
|
||||
library = ":go_default_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["check_cli_conventions.go"],
|
||||
importpath = "k8s.io/kubernetes/cmd/clicheck",
|
||||
deps = [
|
||||
"//pkg/kubectl/cmd:go_default_library",
|
||||
"//pkg/kubectl/cmd/util:go_default_library",
|
||||
"//pkg/kubectl/cmd/util/sanity:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
4
vendor/k8s.io/kubernetes/cmd/clicheck/OWNERS
generated
vendored
Normal file
4
vendor/k8s.io/kubernetes/cmd/clicheck/OWNERS
generated
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
approvers:
|
||||
- sig-cli-maintainers
|
||||
reviewers:
|
||||
- sig-cli
|
55
vendor/k8s.io/kubernetes/cmd/clicheck/check_cli_conventions.go
generated
vendored
Normal file
55
vendor/k8s.io/kubernetes/cmd/clicheck/check_cli_conventions.go
generated
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd"
|
||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||
cmdsanity "k8s.io/kubernetes/pkg/kubectl/cmd/util/sanity"
|
||||
)
|
||||
|
||||
var (
|
||||
skip = []string{}
|
||||
)
|
||||
|
||||
func main() {
|
||||
var errorCount int
|
||||
|
||||
kubectl := cmd.NewKubectlCommand(cmdutil.NewFactory(nil), os.Stdin, ioutil.Discard, ioutil.Discard)
|
||||
errors := cmdsanity.RunCmdChecks(kubectl, cmdsanity.AllCmdChecks, []string{})
|
||||
for _, err := range errors {
|
||||
errorCount++
|
||||
fmt.Fprintf(os.Stderr, " %d. %s\n", errorCount, err)
|
||||
}
|
||||
|
||||
errors = cmdsanity.RunGlobalChecks(cmdsanity.AllGlobalChecks)
|
||||
for _, err := range errors {
|
||||
errorCount++
|
||||
fmt.Fprintf(os.Stderr, " %d. %s\n", errorCount, err)
|
||||
}
|
||||
|
||||
if errorCount > 0 {
|
||||
fmt.Fprintf(os.Stdout, "Found %d errors.\n", errorCount)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
fmt.Fprintln(os.Stdout, "Congrats, CLI looks good!")
|
||||
}
|
54
vendor/k8s.io/kubernetes/cmd/cloud-controller-manager/BUILD
generated
vendored
Normal file
54
vendor/k8s.io/kubernetes/cmd/cloud-controller-manager/BUILD
generated
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
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 = "cloud-controller-manager",
|
||||
gc_linkopts = [
|
||||
"-linkmode",
|
||||
"external",
|
||||
"-extldflags",
|
||||
"-static",
|
||||
],
|
||||
importpath = "k8s.io/kubernetes/cmd/cloud-controller-manager",
|
||||
library = ":go_default_library",
|
||||
x_defs = version_x_defs(),
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["controller-manager.go"],
|
||||
importpath = "k8s.io/kubernetes/cmd/cloud-controller-manager",
|
||||
deps = [
|
||||
"//cmd/cloud-controller-manager/app:go_default_library",
|
||||
"//cmd/cloud-controller-manager/app/options:go_default_library",
|
||||
"//pkg/client/metrics/prometheus:go_default_library",
|
||||
"//pkg/cloudprovider/providers: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/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/cloud-controller-manager/app:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
)
|
8
vendor/k8s.io/kubernetes/cmd/cloud-controller-manager/OWNERS
generated
vendored
Normal file
8
vendor/k8s.io/kubernetes/cmd/cloud-controller-manager/OWNERS
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
approvers:
|
||||
- thockin
|
||||
- luxas
|
||||
- wlan0
|
||||
reviewers:
|
||||
- thockin
|
||||
- luxas
|
||||
- wlan0
|
53
vendor/k8s.io/kubernetes/cmd/cloud-controller-manager/app/BUILD
generated
vendored
Normal file
53
vendor/k8s.io/kubernetes/cmd/cloud-controller-manager/app/BUILD
generated
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["controllermanager.go"],
|
||||
importpath = "k8s.io/kubernetes/cmd/cloud-controller-manager/app",
|
||||
deps = [
|
||||
"//cmd/cloud-controller-manager/app/options:go_default_library",
|
||||
"//pkg/api/legacyscheme:go_default_library",
|
||||
"//pkg/cloudprovider:go_default_library",
|
||||
"//pkg/controller:go_default_library",
|
||||
"//pkg/controller/cloud:go_default_library",
|
||||
"//pkg/controller/route:go_default_library",
|
||||
"//pkg/controller/service:go_default_library",
|
||||
"//pkg/util/configz:go_default_library",
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/github.com/prometheus/client_golang/prometheus:go_default_library",
|
||||
"//vendor/github.com/spf13/cobra:go_default_library",
|
||||
"//vendor/github.com/spf13/pflag:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/server/healthz: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/kubernetes/typed/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/client-go/rest:go_default_library",
|
||||
"//vendor/k8s.io/client-go/tools/clientcmd:go_default_library",
|
||||
"//vendor/k8s.io/client-go/tools/leaderelection:go_default_library",
|
||||
"//vendor/k8s.io/client-go/tools/leaderelection/resourcelock:go_default_library",
|
||||
"//vendor/k8s.io/client-go/tools/record:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//cmd/cloud-controller-manager/app/options:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
)
|
303
vendor/k8s.io/kubernetes/cmd/cloud-controller-manager/app/controllermanager.go
generated
vendored
Normal file
303
vendor/k8s.io/kubernetes/cmd/cloud-controller-manager/app/controllermanager.go
generated
vendored
Normal file
@ -0,0 +1,303 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package app
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/pprof"
|
||||
"os"
|
||||
goruntime "runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/apiserver/pkg/server/healthz"
|
||||
"k8s.io/client-go/informers"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
v1core "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
"k8s.io/client-go/tools/leaderelection"
|
||||
"k8s.io/client-go/tools/leaderelection/resourcelock"
|
||||
"k8s.io/client-go/tools/record"
|
||||
"k8s.io/kubernetes/cmd/cloud-controller-manager/app/options"
|
||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||
"k8s.io/kubernetes/pkg/cloudprovider"
|
||||
"k8s.io/kubernetes/pkg/controller"
|
||||
cloudcontrollers "k8s.io/kubernetes/pkg/controller/cloud"
|
||||
routecontroller "k8s.io/kubernetes/pkg/controller/route"
|
||||
servicecontroller "k8s.io/kubernetes/pkg/controller/service"
|
||||
"k8s.io/kubernetes/pkg/util/configz"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
const (
|
||||
// ControllerStartJitter is the jitter value used when starting controller managers.
|
||||
ControllerStartJitter = 1.0
|
||||
)
|
||||
|
||||
// NewCloudControllerManagerCommand creates a *cobra.Command object with default parameters
|
||||
func NewCloudControllerManagerCommand() *cobra.Command {
|
||||
s := options.NewCloudControllerManagerServer()
|
||||
s.AddFlags(pflag.CommandLine)
|
||||
cmd := &cobra.Command{
|
||||
Use: "cloud-controller-manager",
|
||||
Long: `The Cloud controller manager is a daemon that embeds
|
||||
the cloud specific control loops shipped with Kubernetes.`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
},
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
// resyncPeriod computes the time interval a shared informer waits before resyncing with the api server
|
||||
func resyncPeriod(s *options.CloudControllerManagerServer) func() time.Duration {
|
||||
return func() time.Duration {
|
||||
factor := rand.Float64() + 1
|
||||
return time.Duration(float64(s.MinResyncPeriod.Nanoseconds()) * factor)
|
||||
}
|
||||
}
|
||||
|
||||
// Run runs the ExternalCMServer. This should never exit.
|
||||
func Run(s *options.CloudControllerManagerServer) error {
|
||||
if s.CloudProvider == "" {
|
||||
glog.Fatalf("--cloud-provider cannot be empty")
|
||||
}
|
||||
|
||||
cloud, err := cloudprovider.InitCloudProvider(s.CloudProvider, s.CloudConfigFile)
|
||||
if err != nil {
|
||||
glog.Fatalf("Cloud provider could not be initialized: %v", err)
|
||||
}
|
||||
|
||||
if cloud.HasClusterID() == false {
|
||||
if s.AllowUntaggedCloud == true {
|
||||
glog.Warning("detected a cluster without a ClusterID. A ClusterID will be required in the future. Please tag your cluster to avoid any future issues")
|
||||
} else {
|
||||
glog.Fatalf("no ClusterID found. A ClusterID is required for the cloud provider to function properly. This check can be bypassed by setting the allow-untagged-cloud option")
|
||||
}
|
||||
}
|
||||
|
||||
if c, err := configz.New("componentconfig"); err == nil {
|
||||
c.Set(s.KubeControllerManagerConfiguration)
|
||||
} else {
|
||||
glog.Errorf("unable to register configz: %s", err)
|
||||
}
|
||||
kubeconfig, err := clientcmd.BuildConfigFromFlags(s.Master, s.Kubeconfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Set the ContentType of the requests from kube client
|
||||
kubeconfig.ContentConfig.ContentType = s.ContentType
|
||||
// Override kubeconfig qps/burst settings from flags
|
||||
kubeconfig.QPS = s.KubeAPIQPS
|
||||
kubeconfig.Burst = int(s.KubeAPIBurst)
|
||||
kubeClient, err := clientset.NewForConfig(restclient.AddUserAgent(kubeconfig, "cloud-controller-manager"))
|
||||
if err != nil {
|
||||
glog.Fatalf("Invalid API configuration: %v", err)
|
||||
}
|
||||
leaderElectionClient := kubernetes.NewForConfigOrDie(restclient.AddUserAgent(kubeconfig, "leader-election"))
|
||||
|
||||
// Start the external controller manager server
|
||||
go startHTTP(s)
|
||||
|
||||
recorder := createRecorder(kubeClient)
|
||||
|
||||
run := func(stop <-chan struct{}) {
|
||||
rootClientBuilder := controller.SimpleControllerClientBuilder{
|
||||
ClientConfig: kubeconfig,
|
||||
}
|
||||
var clientBuilder controller.ControllerClientBuilder
|
||||
if s.UseServiceAccountCredentials {
|
||||
clientBuilder = controller.SAControllerClientBuilder{
|
||||
ClientConfig: restclient.AnonymousClientConfig(kubeconfig),
|
||||
CoreClient: kubeClient.CoreV1(),
|
||||
AuthenticationClient: kubeClient.Authentication(),
|
||||
Namespace: "kube-system",
|
||||
}
|
||||
} else {
|
||||
clientBuilder = rootClientBuilder
|
||||
}
|
||||
|
||||
err := StartControllers(s, kubeconfig, clientBuilder, stop, recorder, cloud)
|
||||
glog.Fatalf("error running controllers: %v", err)
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
if !s.LeaderElection.LeaderElect {
|
||||
run(nil)
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
// Identity used to distinguish between multiple cloud controller manager instances
|
||||
id, err := os.Hostname()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Lock required for leader election
|
||||
rl, err := resourcelock.New(s.LeaderElection.ResourceLock,
|
||||
"kube-system",
|
||||
"cloud-controller-manager",
|
||||
leaderElectionClient.CoreV1(),
|
||||
resourcelock.ResourceLockConfig{
|
||||
Identity: id + "-external-cloud-controller",
|
||||
EventRecorder: recorder,
|
||||
})
|
||||
if err != nil {
|
||||
glog.Fatalf("error creating lock: %v", err)
|
||||
}
|
||||
|
||||
// Try and become the leader and start cloud controller manager loops
|
||||
leaderelection.RunOrDie(leaderelection.LeaderElectionConfig{
|
||||
Lock: rl,
|
||||
LeaseDuration: s.LeaderElection.LeaseDuration.Duration,
|
||||
RenewDeadline: s.LeaderElection.RenewDeadline.Duration,
|
||||
RetryPeriod: s.LeaderElection.RetryPeriod.Duration,
|
||||
Callbacks: leaderelection.LeaderCallbacks{
|
||||
OnStartedLeading: run,
|
||||
OnStoppedLeading: func() {
|
||||
glog.Fatalf("leaderelection lost")
|
||||
},
|
||||
},
|
||||
})
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
// StartControllers starts the cloud specific controller loops.
|
||||
func StartControllers(s *options.CloudControllerManagerServer, kubeconfig *restclient.Config, clientBuilder controller.ControllerClientBuilder, stop <-chan struct{}, recorder record.EventRecorder, cloud cloudprovider.Interface) error {
|
||||
// Function to build the kube client object
|
||||
client := func(serviceAccountName string) clientset.Interface {
|
||||
return clientBuilder.ClientOrDie(serviceAccountName)
|
||||
}
|
||||
|
||||
if cloud != nil {
|
||||
// Initialize the cloud provider with a reference to the clientBuilder
|
||||
cloud.Initialize(clientBuilder)
|
||||
}
|
||||
|
||||
versionedClient := client("shared-informers")
|
||||
sharedInformers := informers.NewSharedInformerFactory(versionedClient, resyncPeriod(s)())
|
||||
|
||||
// Start the CloudNodeController
|
||||
nodeController := cloudcontrollers.NewCloudNodeController(
|
||||
sharedInformers.Core().V1().Nodes(),
|
||||
client("cloud-node-controller"), cloud,
|
||||
s.NodeMonitorPeriod.Duration,
|
||||
s.NodeStatusUpdateFrequency.Duration)
|
||||
|
||||
nodeController.Run()
|
||||
time.Sleep(wait.Jitter(s.ControllerStartInterval.Duration, ControllerStartJitter))
|
||||
|
||||
// Start the PersistentVolumeLabelController
|
||||
pvlController := cloudcontrollers.NewPersistentVolumeLabelController(client("pvl-controller"), cloud)
|
||||
threads := 5
|
||||
go pvlController.Run(threads, stop)
|
||||
time.Sleep(wait.Jitter(s.ControllerStartInterval.Duration, ControllerStartJitter))
|
||||
|
||||
// Start the service controller
|
||||
serviceController, err := servicecontroller.New(
|
||||
cloud,
|
||||
client("service-controller"),
|
||||
sharedInformers.Core().V1().Services(),
|
||||
sharedInformers.Core().V1().Nodes(),
|
||||
s.ClusterName,
|
||||
)
|
||||
if err != nil {
|
||||
glog.Errorf("Failed to start service controller: %v", err)
|
||||
} else {
|
||||
go serviceController.Run(stop, int(s.ConcurrentServiceSyncs))
|
||||
time.Sleep(wait.Jitter(s.ControllerStartInterval.Duration, ControllerStartJitter))
|
||||
}
|
||||
|
||||
// If CIDRs should be allocated for pods and set on the CloudProvider, then start the route controller
|
||||
if s.AllocateNodeCIDRs && s.ConfigureCloudRoutes {
|
||||
if routes, ok := cloud.Routes(); !ok {
|
||||
glog.Warning("configure-cloud-routes is set, but cloud provider does not support routes. Will not configure cloud provider routes.")
|
||||
} else {
|
||||
var clusterCIDR *net.IPNet
|
||||
if len(strings.TrimSpace(s.ClusterCIDR)) != 0 {
|
||||
_, clusterCIDR, err = net.ParseCIDR(s.ClusterCIDR)
|
||||
if err != nil {
|
||||
glog.Warningf("Unsuccessful parsing of cluster CIDR %v: %v", s.ClusterCIDR, err)
|
||||
}
|
||||
}
|
||||
|
||||
routeController := routecontroller.New(routes, client("route-controller"), sharedInformers.Core().V1().Nodes(), s.ClusterName, clusterCIDR)
|
||||
go routeController.Run(stop, s.RouteReconciliationPeriod.Duration)
|
||||
time.Sleep(wait.Jitter(s.ControllerStartInterval.Duration, ControllerStartJitter))
|
||||
}
|
||||
} else {
|
||||
glog.Infof("Will not configure cloud provider routes for allocate-node-cidrs: %v, configure-cloud-routes: %v.", s.AllocateNodeCIDRs, s.ConfigureCloudRoutes)
|
||||
}
|
||||
|
||||
// If apiserver is not running we should wait for some time and fail only then. This is particularly
|
||||
// important when we start apiserver and controller manager at the same time.
|
||||
err = wait.PollImmediate(time.Second, 10*time.Second, func() (bool, error) {
|
||||
if _, err = restclient.ServerAPIVersions(kubeconfig); err == nil {
|
||||
return true, nil
|
||||
}
|
||||
glog.Errorf("Failed to get api versions from server: %v", err)
|
||||
return false, nil
|
||||
})
|
||||
if err != nil {
|
||||
glog.Fatalf("Failed to get api versions from server: %v", err)
|
||||
}
|
||||
|
||||
sharedInformers.Start(stop)
|
||||
|
||||
select {}
|
||||
}
|
||||
|
||||
func startHTTP(s *options.CloudControllerManagerServer) {
|
||||
mux := http.NewServeMux()
|
||||
healthz.InstallHandler(mux)
|
||||
if s.EnableProfiling {
|
||||
mux.HandleFunc("/debug/pprof/", pprof.Index)
|
||||
mux.HandleFunc("/debug/pprof/profile", pprof.Profile)
|
||||
mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
|
||||
mux.HandleFunc("/debug/pprof/trace", pprof.Trace)
|
||||
if s.EnableContentionProfiling {
|
||||
goruntime.SetBlockProfileRate(1)
|
||||
}
|
||||
}
|
||||
configz.InstallHandler(mux)
|
||||
mux.Handle("/metrics", prometheus.Handler())
|
||||
|
||||
server := &http.Server{
|
||||
Addr: net.JoinHostPort(s.Address, strconv.Itoa(int(s.Port))),
|
||||
Handler: mux,
|
||||
}
|
||||
glog.Fatal(server.ListenAndServe())
|
||||
}
|
||||
|
||||
func createRecorder(kubeClient *clientset.Clientset) record.EventRecorder {
|
||||
eventBroadcaster := record.NewBroadcaster()
|
||||
eventBroadcaster.StartLogging(glog.Infof)
|
||||
eventBroadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: v1core.New(kubeClient.CoreV1().RESTClient()).Events("")})
|
||||
return eventBroadcaster.NewRecorder(legacyscheme.Scheme, v1.EventSource{Component: "cloud-controller-manager"})
|
||||
}
|
48
vendor/k8s.io/kubernetes/cmd/cloud-controller-manager/app/options/BUILD
generated
vendored
Normal file
48
vendor/k8s.io/kubernetes/cmd/cloud-controller-manager/app/options/BUILD
generated
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
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"],
|
||||
importpath = "k8s.io/kubernetes/cmd/cloud-controller-manager/app/options",
|
||||
deps = [
|
||||
"//pkg/apis/componentconfig:go_default_library",
|
||||
"//pkg/client/leaderelectionconfig:go_default_library",
|
||||
"//pkg/features:go_default_library",
|
||||
"//pkg/master/ports:go_default_library",
|
||||
"//vendor/github.com/spf13/pflag:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["options_test.go"],
|
||||
importpath = "k8s.io/kubernetes/cmd/cloud-controller-manager/app/options",
|
||||
library = ":go_default_library",
|
||||
deps = [
|
||||
"//pkg/apis/componentconfig:go_default_library",
|
||||
"//vendor/github.com/spf13/pflag:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/diff:go_default_library",
|
||||
],
|
||||
)
|
104
vendor/k8s.io/kubernetes/cmd/cloud-controller-manager/app/options/options.go
generated
vendored
Normal file
104
vendor/k8s.io/kubernetes/cmd/cloud-controller-manager/app/options/options.go
generated
vendored
Normal file
@ -0,0 +1,104 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package options
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
"k8s.io/kubernetes/pkg/apis/componentconfig"
|
||||
"k8s.io/kubernetes/pkg/client/leaderelectionconfig"
|
||||
"k8s.io/kubernetes/pkg/master/ports"
|
||||
|
||||
// add the kubernetes feature gates
|
||||
_ "k8s.io/kubernetes/pkg/features"
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
// CloudControllerManagerServer is the main context object for the controller manager.
|
||||
type CloudControllerManagerServer struct {
|
||||
componentconfig.KubeControllerManagerConfiguration
|
||||
|
||||
Master string
|
||||
Kubeconfig string
|
||||
|
||||
// NodeStatusUpdateFrequency is the frequency at which the controller updates nodes' status
|
||||
NodeStatusUpdateFrequency metav1.Duration
|
||||
}
|
||||
|
||||
// NewCloudControllerManagerServer creates a new ExternalCMServer with a default config.
|
||||
func NewCloudControllerManagerServer() *CloudControllerManagerServer {
|
||||
s := CloudControllerManagerServer{
|
||||
// Part of these default values also present in 'cmd/kube-controller-manager/app/options/options.go'.
|
||||
// Please keep them in sync when doing update.
|
||||
KubeControllerManagerConfiguration: componentconfig.KubeControllerManagerConfiguration{
|
||||
Port: ports.CloudControllerManagerPort,
|
||||
Address: "0.0.0.0",
|
||||
ConcurrentServiceSyncs: 1,
|
||||
MinResyncPeriod: metav1.Duration{Duration: 12 * time.Hour},
|
||||
NodeMonitorPeriod: metav1.Duration{Duration: 5 * time.Second},
|
||||
ClusterName: "kubernetes",
|
||||
ConfigureCloudRoutes: true,
|
||||
ContentType: "application/vnd.kubernetes.protobuf",
|
||||
KubeAPIQPS: 20.0,
|
||||
KubeAPIBurst: 30,
|
||||
LeaderElection: leaderelectionconfig.DefaultLeaderElectionConfiguration(),
|
||||
ControllerStartInterval: metav1.Duration{Duration: 0 * time.Second},
|
||||
RouteReconciliationPeriod: metav1.Duration{Duration: 10 * time.Second},
|
||||
},
|
||||
NodeStatusUpdateFrequency: metav1.Duration{Duration: 5 * time.Minute},
|
||||
}
|
||||
s.LeaderElection.LeaderElect = true
|
||||
return &s
|
||||
}
|
||||
|
||||
// AddFlags adds flags for a specific ExternalCMServer to the specified FlagSet
|
||||
func (s *CloudControllerManagerServer) AddFlags(fs *pflag.FlagSet) {
|
||||
fs.Int32Var(&s.Port, "port", s.Port, "The port that the cloud-controller-manager's http service runs on.")
|
||||
fs.Var(componentconfig.IPVar{Val: &s.Address}, "address", "The IP address to serve on (set to 0.0.0.0 for all interfaces).")
|
||||
fs.StringVar(&s.CloudProvider, "cloud-provider", s.CloudProvider, "The provider of cloud services. Cannot be empty.")
|
||||
fs.StringVar(&s.CloudConfigFile, "cloud-config", s.CloudConfigFile, "The path to the cloud provider configuration file. Empty string for no configuration file.")
|
||||
fs.BoolVar(&s.AllowUntaggedCloud, "allow-untagged-cloud", false, "Allow the cluster to run without the cluster-id on cloud instances. This is a legacy mode of operation and a cluster-id will be required in the future.")
|
||||
fs.MarkDeprecated("allow-untagged-cloud", "This flag is deprecated and will be removed in a future release. A cluster-id will be required on cloud instances.")
|
||||
fs.DurationVar(&s.MinResyncPeriod.Duration, "min-resync-period", s.MinResyncPeriod.Duration, "The resync period in reflectors will be random between MinResyncPeriod and 2*MinResyncPeriod.")
|
||||
fs.DurationVar(&s.NodeMonitorPeriod.Duration, "node-monitor-period", s.NodeMonitorPeriod.Duration,
|
||||
"The period for syncing NodeStatus in NodeController.")
|
||||
fs.DurationVar(&s.NodeStatusUpdateFrequency.Duration, "node-status-update-frequency", s.NodeStatusUpdateFrequency.Duration, "Specifies how often the controller updates nodes' status.")
|
||||
// TODO: remove --service-account-private-key-file 6 months after 1.8 is released (~1.10)
|
||||
fs.StringVar(&s.ServiceAccountKeyFile, "service-account-private-key-file", s.ServiceAccountKeyFile, "Filename containing a PEM-encoded private RSA or ECDSA key used to sign service account tokens.")
|
||||
fs.MarkDeprecated("service-account-private-key-file", "This flag is currently no-op and will be deleted.")
|
||||
fs.BoolVar(&s.UseServiceAccountCredentials, "use-service-account-credentials", s.UseServiceAccountCredentials, "If true, use individual service account credentials for each controller.")
|
||||
fs.DurationVar(&s.RouteReconciliationPeriod.Duration, "route-reconciliation-period", s.RouteReconciliationPeriod.Duration, "The period for reconciling routes created for Nodes by cloud provider.")
|
||||
fs.BoolVar(&s.ConfigureCloudRoutes, "configure-cloud-routes", true, "Should CIDRs allocated by allocate-node-cidrs be configured on the cloud provider.")
|
||||
fs.BoolVar(&s.EnableProfiling, "profiling", true, "Enable profiling via web interface host:port/debug/pprof/.")
|
||||
fs.BoolVar(&s.EnableContentionProfiling, "contention-profiling", false, "Enable lock contention profiling, if profiling is enabled.")
|
||||
fs.StringVar(&s.ClusterCIDR, "cluster-cidr", s.ClusterCIDR, "CIDR Range for Pods in cluster.")
|
||||
fs.StringVar(&s.ClusterName, "cluster-name", s.ClusterName, "The instance prefix for the cluster.")
|
||||
fs.BoolVar(&s.AllocateNodeCIDRs, "allocate-node-cidrs", false, "Should CIDRs for Pods be allocated and set on the cloud provider.")
|
||||
fs.StringVar(&s.Master, "master", s.Master, "The address of the Kubernetes API server (overrides any value in kubeconfig).")
|
||||
fs.StringVar(&s.Kubeconfig, "kubeconfig", s.Kubeconfig, "Path to kubeconfig file with authorization and master location information.")
|
||||
fs.StringVar(&s.ContentType, "kube-api-content-type", s.ContentType, "Content type of requests sent to apiserver.")
|
||||
fs.Float32Var(&s.KubeAPIQPS, "kube-api-qps", s.KubeAPIQPS, "QPS to use while talking with kubernetes apiserver.")
|
||||
fs.Int32Var(&s.KubeAPIBurst, "kube-api-burst", s.KubeAPIBurst, "Burst to use while talking with kubernetes apiserver.")
|
||||
fs.DurationVar(&s.ControllerStartInterval.Duration, "controller-start-interval", s.ControllerStartInterval.Duration, "Interval between starting controller managers.")
|
||||
fs.Int32Var(&s.ConcurrentServiceSyncs, "concurrent-service-syncs", s.ConcurrentServiceSyncs, "The number of services that are allowed to sync concurrently. Larger number = more responsive service management, but more CPU (and network) load")
|
||||
leaderelectionconfig.BindFlags(&s.LeaderElection, fs)
|
||||
|
||||
utilfeature.DefaultFeatureGate.AddFlag(fs)
|
||||
}
|
101
vendor/k8s.io/kubernetes/cmd/cloud-controller-manager/app/options/options_test.go
generated
vendored
Normal file
101
vendor/k8s.io/kubernetes/cmd/cloud-controller-manager/app/options/options_test.go
generated
vendored
Normal file
@ -0,0 +1,101 @@
|
||||
/*
|
||||
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 options
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/diff"
|
||||
"k8s.io/kubernetes/pkg/apis/componentconfig"
|
||||
)
|
||||
|
||||
func TestAddFlags(t *testing.T) {
|
||||
f := pflag.NewFlagSet("addflagstest", pflag.ContinueOnError)
|
||||
s := NewCloudControllerManagerServer()
|
||||
s.AddFlags(f)
|
||||
|
||||
args := []string{
|
||||
"--address=192.168.4.10",
|
||||
"--allocate-node-cidrs=true",
|
||||
"--cloud-config=/cloud-config",
|
||||
"--cloud-provider=gce",
|
||||
"--cluster-cidr=1.2.3.4/24",
|
||||
"--cluster-name=k8s",
|
||||
"--configure-cloud-routes=false",
|
||||
"--contention-profiling=true",
|
||||
"--controller-start-interval=2m",
|
||||
"--min-resync-period=5m",
|
||||
"--kube-api-burst=100",
|
||||
"--kube-api-content-type=application/vnd.kubernetes.protobuf",
|
||||
"--kube-api-qps=50.0",
|
||||
"--kubeconfig=/kubeconfig",
|
||||
"--leader-elect=false",
|
||||
"--leader-elect-lease-duration=30s",
|
||||
"--leader-elect-renew-deadline=15s",
|
||||
"--leader-elect-resource-lock=configmap",
|
||||
"--leader-elect-retry-period=5s",
|
||||
"--master=192.168.4.20",
|
||||
"--min-resync-period=8h",
|
||||
"--port=10000",
|
||||
"--profiling=false",
|
||||
"--node-status-update-frequency=10m",
|
||||
"--route-reconciliation-period=30s",
|
||||
"--min-resync-period=100m",
|
||||
"--use-service-account-credentials=false",
|
||||
}
|
||||
f.Parse(args)
|
||||
|
||||
expected := &CloudControllerManagerServer{
|
||||
KubeControllerManagerConfiguration: componentconfig.KubeControllerManagerConfiguration{
|
||||
CloudProvider: "gce",
|
||||
CloudConfigFile: "/cloud-config",
|
||||
Port: 10000,
|
||||
Address: "192.168.4.10",
|
||||
ConcurrentServiceSyncs: 1,
|
||||
MinResyncPeriod: metav1.Duration{Duration: 100 * time.Minute},
|
||||
NodeMonitorPeriod: metav1.Duration{Duration: 5 * time.Second},
|
||||
ClusterName: "k8s",
|
||||
ConfigureCloudRoutes: false,
|
||||
AllocateNodeCIDRs: true,
|
||||
ContentType: "application/vnd.kubernetes.protobuf",
|
||||
EnableContentionProfiling: true,
|
||||
KubeAPIQPS: 50.0,
|
||||
KubeAPIBurst: 100,
|
||||
LeaderElection: componentconfig.LeaderElectionConfiguration{
|
||||
ResourceLock: "configmap",
|
||||
LeaderElect: false,
|
||||
LeaseDuration: metav1.Duration{Duration: 30 * time.Second},
|
||||
RenewDeadline: metav1.Duration{Duration: 15 * time.Second},
|
||||
RetryPeriod: metav1.Duration{Duration: 5 * time.Second},
|
||||
},
|
||||
ControllerStartInterval: metav1.Duration{Duration: 2 * time.Minute},
|
||||
RouteReconciliationPeriod: metav1.Duration{Duration: 30 * time.Second},
|
||||
ClusterCIDR: "1.2.3.4/24",
|
||||
},
|
||||
Kubeconfig: "/kubeconfig",
|
||||
Master: "192.168.4.20",
|
||||
NodeStatusUpdateFrequency: metav1.Duration{Duration: 10 * time.Minute},
|
||||
}
|
||||
if !reflect.DeepEqual(expected, s) {
|
||||
t.Errorf("Got different run options than expected.\nDifference detected on:\n%s", diff.ObjectReflectDiff(expected, s))
|
||||
}
|
||||
}
|
54
vendor/k8s.io/kubernetes/cmd/cloud-controller-manager/controller-manager.go
generated
vendored
Normal file
54
vendor/k8s.io/kubernetes/cmd/cloud-controller-manager/controller-manager.go
generated
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// The external controller manager is responsible for running controller loops that
|
||||
// are cloud provider dependent. It uses the API to listen to new events on resources.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"k8s.io/apiserver/pkg/util/flag"
|
||||
"k8s.io/apiserver/pkg/util/logs"
|
||||
"k8s.io/kubernetes/cmd/cloud-controller-manager/app"
|
||||
"k8s.io/kubernetes/cmd/cloud-controller-manager/app/options"
|
||||
_ "k8s.io/kubernetes/pkg/client/metrics/prometheus" // for client metric registration
|
||||
// NOTE: Importing all in-tree cloud-providers is not required when
|
||||
// implementing an out-of-tree cloud-provider.
|
||||
_ "k8s.io/kubernetes/pkg/cloudprovider/providers"
|
||||
_ "k8s.io/kubernetes/pkg/version/prometheus" // for version metric registration
|
||||
"k8s.io/kubernetes/pkg/version/verflag"
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
func main() {
|
||||
s := options.NewCloudControllerManagerServer()
|
||||
s.AddFlags(pflag.CommandLine)
|
||||
|
||||
flag.InitFlags()
|
||||
logs.InitLogs()
|
||||
defer logs.FlushLogs()
|
||||
|
||||
verflag.PrintAndExitIfRequested()
|
||||
|
||||
if err := app.Run(s); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "%v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
38
vendor/k8s.io/kubernetes/cmd/gendocs/BUILD
generated
vendored
Normal file
38
vendor/k8s.io/kubernetes/cmd/gendocs/BUILD
generated
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_binary",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_binary(
|
||||
name = "gendocs",
|
||||
importpath = "k8s.io/kubernetes/cmd/gendocs",
|
||||
library = ":go_default_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["gen_kubectl_docs.go"],
|
||||
importpath = "k8s.io/kubernetes/cmd/gendocs",
|
||||
deps = [
|
||||
"//cmd/genutils:go_default_library",
|
||||
"//pkg/kubectl/cmd:go_default_library",
|
||||
"//pkg/kubectl/cmd/util:go_default_library",
|
||||
"//vendor/github.com/spf13/cobra/doc:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
52
vendor/k8s.io/kubernetes/cmd/gendocs/gen_kubectl_docs.go
generated
vendored
Normal file
52
vendor/k8s.io/kubernetes/cmd/gendocs/gen_kubectl_docs.go
generated
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
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 main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"github.com/spf13/cobra/doc"
|
||||
"k8s.io/kubernetes/cmd/genutils"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd"
|
||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// use os.Args instead of "flags" because "flags" will mess up the man pages!
|
||||
path := "docs/"
|
||||
if len(os.Args) == 2 {
|
||||
path = os.Args[1]
|
||||
} else if len(os.Args) > 2 {
|
||||
fmt.Fprintf(os.Stderr, "usage: %s [output directory]\n", os.Args[0])
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
outDir, err := genutils.OutDir(path)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "failed to get output directory: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Set environment variables used by kubectl so the output is consistent,
|
||||
// regardless of where we run.
|
||||
os.Setenv("HOME", "/home/username")
|
||||
// TODO os.Stdin should really be something like ioutil.Discard, but a Reader
|
||||
kubectl := cmd.NewKubectlCommand(cmdutil.NewFactory(nil), os.Stdin, ioutil.Discard, ioutil.Discard)
|
||||
doc.GenMarkdownTree(kubectl, outDir)
|
||||
}
|
56
vendor/k8s.io/kubernetes/cmd/genkubedocs/BUILD
generated
vendored
Normal file
56
vendor/k8s.io/kubernetes/cmd/genkubedocs/BUILD
generated
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_binary",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_binary(
|
||||
name = "genkubedocs",
|
||||
importpath = "k8s.io/kubernetes/cmd/genkubedocs",
|
||||
library = ":go_default_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"gen_kube_docs.go",
|
||||
"postprocessing.go",
|
||||
],
|
||||
importpath = "k8s.io/kubernetes/cmd/genkubedocs",
|
||||
deps = [
|
||||
"//cmd/cloud-controller-manager/app:go_default_library",
|
||||
"//cmd/genutils:go_default_library",
|
||||
"//cmd/kube-apiserver/app:go_default_library",
|
||||
"//cmd/kube-controller-manager/app:go_default_library",
|
||||
"//cmd/kube-proxy/app:go_default_library",
|
||||
"//cmd/kubeadm/app/cmd:go_default_library",
|
||||
"//cmd/kubelet/app:go_default_library",
|
||||
"//plugin/cmd/kube-scheduler/app:go_default_library",
|
||||
"//vendor/github.com/spf13/cobra:go_default_library",
|
||||
"//vendor/github.com/spf13/cobra/doc:go_default_library",
|
||||
"//vendor/github.com/spf13/pflag:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["postprocessing_test.go"],
|
||||
importpath = "k8s.io/kubernetes/cmd/genkubedocs",
|
||||
library = ":go_default_library",
|
||||
)
|
95
vendor/k8s.io/kubernetes/cmd/genkubedocs/gen_kube_docs.go
generated
vendored
Normal file
95
vendor/k8s.io/kubernetes/cmd/genkubedocs/gen_kube_docs.go
generated
vendored
Normal file
@ -0,0 +1,95 @@
|
||||
/*
|
||||
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 main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/spf13/cobra/doc"
|
||||
"github.com/spf13/pflag"
|
||||
ccmapp "k8s.io/kubernetes/cmd/cloud-controller-manager/app"
|
||||
"k8s.io/kubernetes/cmd/genutils"
|
||||
apiservapp "k8s.io/kubernetes/cmd/kube-apiserver/app"
|
||||
cmapp "k8s.io/kubernetes/cmd/kube-controller-manager/app"
|
||||
proxyapp "k8s.io/kubernetes/cmd/kube-proxy/app"
|
||||
kubeadmapp "k8s.io/kubernetes/cmd/kubeadm/app/cmd"
|
||||
kubeletapp "k8s.io/kubernetes/cmd/kubelet/app"
|
||||
schapp "k8s.io/kubernetes/plugin/cmd/kube-scheduler/app"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// use os.Args instead of "flags" because "flags" will mess up the man pages!
|
||||
path := ""
|
||||
module := ""
|
||||
if len(os.Args) == 3 {
|
||||
path = os.Args[1]
|
||||
module = os.Args[2]
|
||||
} else {
|
||||
fmt.Fprintf(os.Stderr, "usage: %s [output directory] [module] \n", os.Args[0])
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
outDir, err := genutils.OutDir(path)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "failed to get output directory: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
switch module {
|
||||
case "kube-apiserver":
|
||||
// generate docs for kube-apiserver
|
||||
apiserver := apiservapp.NewAPIServerCommand()
|
||||
doc.GenMarkdownTree(apiserver, outDir)
|
||||
case "kube-controller-manager":
|
||||
// generate docs for kube-controller-manager
|
||||
controllermanager := cmapp.NewControllerManagerCommand()
|
||||
doc.GenMarkdownTree(controllermanager, outDir)
|
||||
case "cloud-controller-manager":
|
||||
// generate docs for cloud-controller-manager
|
||||
cloudcontrollermanager := ccmapp.NewCloudControllerManagerCommand()
|
||||
doc.GenMarkdownTree(cloudcontrollermanager, outDir)
|
||||
case "kube-proxy":
|
||||
// generate docs for kube-proxy
|
||||
proxy := proxyapp.NewProxyCommand()
|
||||
doc.GenMarkdownTree(proxy, outDir)
|
||||
case "kube-scheduler":
|
||||
// generate docs for kube-scheduler
|
||||
scheduler := schapp.NewSchedulerCommand()
|
||||
doc.GenMarkdownTree(scheduler, outDir)
|
||||
case "kubelet":
|
||||
// generate docs for kubelet
|
||||
kubelet := kubeletapp.NewKubeletCommand()
|
||||
doc.GenMarkdownTree(kubelet, outDir)
|
||||
case "kubeadm":
|
||||
// resets global flags created by kubelet or other commands e.g.
|
||||
// --azure-container-registry-config from pkg/credentialprovider/azure
|
||||
// --google-json-key from pkg/credentialprovider/gcp
|
||||
// --version pkg/version/verflag
|
||||
pflag.CommandLine = pflag.NewFlagSet(os.Args[0], pflag.ExitOnError)
|
||||
|
||||
// generate docs for kubeadm
|
||||
kubeadm := kubeadmapp.NewKubeadmCommand(os.Stdin, os.Stdout, os.Stderr)
|
||||
doc.GenMarkdownTree(kubeadm, outDir)
|
||||
|
||||
// cleanup generated code for usage as include in the website
|
||||
MarkdownPostProcessing(kubeadm, outDir, cleanupForInclude)
|
||||
default:
|
||||
fmt.Fprintf(os.Stderr, "Module %s is not supported", module)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
73
vendor/k8s.io/kubernetes/cmd/genkubedocs/postprocessing.go
generated
vendored
Normal file
73
vendor/k8s.io/kubernetes/cmd/genkubedocs/postprocessing.go
generated
vendored
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
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 main
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// MarkdownPostProcessing goes though the generated files
|
||||
func MarkdownPostProcessing(cmd *cobra.Command, dir string, processor func(string) string) error {
|
||||
for _, c := range cmd.Commands() {
|
||||
if !c.IsAvailableCommand() || c.IsHelpCommand() {
|
||||
continue
|
||||
}
|
||||
if err := MarkdownPostProcessing(c, dir, processor); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
basename := strings.Replace(cmd.CommandPath(), " ", "_", -1) + ".md"
|
||||
filename := filepath.Join(dir, basename)
|
||||
|
||||
markdownBytes, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
processedMarkDown := processor(string(markdownBytes))
|
||||
|
||||
return ioutil.WriteFile(filename, []byte(processedMarkDown), 0644)
|
||||
}
|
||||
|
||||
// cleanupForInclude parts of markdown that will make difficult to use it as include in the website:
|
||||
// - The title of the document (this allow more flexibility for include, e.g. include in tabs)
|
||||
// - The sections see also, that assumes file will be used as a main page
|
||||
func cleanupForInclude(md string) string {
|
||||
lines := strings.Split(md, "\n")
|
||||
|
||||
cleanMd := ""
|
||||
for i, line := range lines {
|
||||
if i == 0 {
|
||||
continue
|
||||
}
|
||||
if line == "### SEE ALSO" {
|
||||
break
|
||||
}
|
||||
|
||||
cleanMd += line
|
||||
if i < len(lines)-1 {
|
||||
cleanMd += "\n"
|
||||
}
|
||||
}
|
||||
|
||||
return cleanMd
|
||||
}
|
57
vendor/k8s.io/kubernetes/cmd/genkubedocs/postprocessing_test.go
generated
vendored
Normal file
57
vendor/k8s.io/kubernetes/cmd/genkubedocs/postprocessing_test.go
generated
vendored
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
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 main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestCleanupForInclude(t *testing.T) {
|
||||
|
||||
var tests = []struct {
|
||||
markdown, expectedMarkdown string
|
||||
}{
|
||||
{ // first line is removed
|
||||
// Nb. fist line is the title of the document, and by removing it you get
|
||||
// more flexibility for include, e.g. include in tabs
|
||||
markdown: "line 1\n" +
|
||||
"line 2\n" +
|
||||
"line 3",
|
||||
expectedMarkdown: "line 2\n" +
|
||||
"line 3",
|
||||
},
|
||||
{ // evething after ###SEE ALSO is removed
|
||||
// Nb. see also, that assumes file will be used as a main page (does not apply to includes)
|
||||
markdown: "line 1\n" +
|
||||
"line 2\n" +
|
||||
"### SEE ALSO\n" +
|
||||
"line 3",
|
||||
expectedMarkdown: "line 2\n",
|
||||
},
|
||||
}
|
||||
for _, rt := range tests {
|
||||
actual := cleanupForInclude(rt.markdown)
|
||||
if actual != rt.expectedMarkdown {
|
||||
t.Errorf(
|
||||
"failed cleanupForInclude:\n\texpected: %s\n\t actual: %s",
|
||||
rt.expectedMarkdown,
|
||||
actual,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
47
vendor/k8s.io/kubernetes/cmd/genman/BUILD
generated
vendored
Normal file
47
vendor/k8s.io/kubernetes/cmd/genman/BUILD
generated
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_binary",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_binary(
|
||||
name = "genman",
|
||||
importpath = "k8s.io/kubernetes/cmd/genman",
|
||||
library = ":go_default_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["gen_kube_man.go"],
|
||||
importpath = "k8s.io/kubernetes/cmd/genman",
|
||||
deps = [
|
||||
"//cmd/cloud-controller-manager/app:go_default_library",
|
||||
"//cmd/genutils:go_default_library",
|
||||
"//cmd/kube-apiserver/app:go_default_library",
|
||||
"//cmd/kube-controller-manager/app:go_default_library",
|
||||
"//cmd/kube-proxy/app:go_default_library",
|
||||
"//cmd/kubeadm/app/cmd:go_default_library",
|
||||
"//cmd/kubelet/app:go_default_library",
|
||||
"//pkg/kubectl/cmd:go_default_library",
|
||||
"//pkg/kubectl/cmd/util:go_default_library",
|
||||
"//plugin/cmd/kube-scheduler/app:go_default_library",
|
||||
"//vendor/github.com/cpuguy83/go-md2man/md2man:go_default_library",
|
||||
"//vendor/github.com/spf13/cobra:go_default_library",
|
||||
"//vendor/github.com/spf13/pflag:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
231
vendor/k8s.io/kubernetes/cmd/genman/gen_kube_man.go
generated
vendored
Normal file
231
vendor/k8s.io/kubernetes/cmd/genman/gen_kube_man.go
generated
vendored
Normal file
@ -0,0 +1,231 @@
|
||||
/*
|
||||
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 main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
mangen "github.com/cpuguy83/go-md2man/md2man"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
ccmapp "k8s.io/kubernetes/cmd/cloud-controller-manager/app"
|
||||
"k8s.io/kubernetes/cmd/genutils"
|
||||
apiservapp "k8s.io/kubernetes/cmd/kube-apiserver/app"
|
||||
cmapp "k8s.io/kubernetes/cmd/kube-controller-manager/app"
|
||||
proxyapp "k8s.io/kubernetes/cmd/kube-proxy/app"
|
||||
kubeadmapp "k8s.io/kubernetes/cmd/kubeadm/app/cmd"
|
||||
kubeletapp "k8s.io/kubernetes/cmd/kubelet/app"
|
||||
kubectlcmd "k8s.io/kubernetes/pkg/kubectl/cmd"
|
||||
kubectlcmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||
schapp "k8s.io/kubernetes/plugin/cmd/kube-scheduler/app"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// use os.Args instead of "flags" because "flags" will mess up the man pages!
|
||||
path := "docs/man/man1"
|
||||
module := ""
|
||||
if len(os.Args) == 3 {
|
||||
path = os.Args[1]
|
||||
module = os.Args[2]
|
||||
} else {
|
||||
fmt.Fprintf(os.Stderr, "usage: %s [output directory] [module] \n", os.Args[0])
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
outDir, err := genutils.OutDir(path)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "failed to get output directory: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Set environment variables used by command so the output is consistent,
|
||||
// regardless of where we run.
|
||||
os.Setenv("HOME", "/home/username")
|
||||
|
||||
switch module {
|
||||
case "kube-apiserver":
|
||||
// generate manpage for kube-apiserver
|
||||
apiserver := apiservapp.NewAPIServerCommand()
|
||||
genMarkdown(apiserver, "", outDir)
|
||||
for _, c := range apiserver.Commands() {
|
||||
genMarkdown(c, "kube-apiserver", outDir)
|
||||
}
|
||||
case "kube-controller-manager":
|
||||
// generate manpage for kube-controller-manager
|
||||
controllermanager := cmapp.NewControllerManagerCommand()
|
||||
genMarkdown(controllermanager, "", outDir)
|
||||
for _, c := range controllermanager.Commands() {
|
||||
genMarkdown(c, "kube-controller-manager", outDir)
|
||||
}
|
||||
case "cloud-controller-manager":
|
||||
//generate manpage for cloud-controller-manager
|
||||
controllermanager := ccmapp.NewCloudControllerManagerCommand()
|
||||
genMarkdown(controllermanager, "", outDir)
|
||||
for _, c := range controllermanager.Commands() {
|
||||
genMarkdown(c, "cloud-controller-manager", outDir)
|
||||
}
|
||||
case "kube-proxy":
|
||||
// generate manpage for kube-proxy
|
||||
proxy := proxyapp.NewProxyCommand()
|
||||
genMarkdown(proxy, "", outDir)
|
||||
for _, c := range proxy.Commands() {
|
||||
genMarkdown(c, "kube-proxy", outDir)
|
||||
}
|
||||
case "kube-scheduler":
|
||||
// generate manpage for kube-scheduler
|
||||
scheduler := schapp.NewSchedulerCommand()
|
||||
genMarkdown(scheduler, "", outDir)
|
||||
for _, c := range scheduler.Commands() {
|
||||
genMarkdown(c, "kube-scheduler", outDir)
|
||||
}
|
||||
case "kubelet":
|
||||
// generate manpage for kubelet
|
||||
kubelet := kubeletapp.NewKubeletCommand()
|
||||
genMarkdown(kubelet, "", outDir)
|
||||
for _, c := range kubelet.Commands() {
|
||||
genMarkdown(c, "kubelet", outDir)
|
||||
}
|
||||
case "kubectl":
|
||||
// generate manpage for kubectl
|
||||
// TODO os.Stdin should really be something like ioutil.Discard, but a Reader
|
||||
kubectl := kubectlcmd.NewKubectlCommand(kubectlcmdutil.NewFactory(nil), os.Stdin, ioutil.Discard, ioutil.Discard)
|
||||
genMarkdown(kubectl, "", outDir)
|
||||
for _, c := range kubectl.Commands() {
|
||||
genMarkdown(c, "kubectl", outDir)
|
||||
}
|
||||
case "kubeadm":
|
||||
// generate manpage for kubelet
|
||||
kubeadm := kubeadmapp.NewKubeadmCommand(os.Stdin, os.Stdout, os.Stderr)
|
||||
genMarkdown(kubeadm, "", outDir)
|
||||
for _, c := range kubeadm.Commands() {
|
||||
genMarkdown(c, "kubeadm", outDir)
|
||||
}
|
||||
default:
|
||||
fmt.Fprintf(os.Stderr, "Module %s is not supported", module)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func preamble(out *bytes.Buffer, name, short, long string) {
|
||||
out.WriteString(`% KUBERNETES(1) kubernetes User Manuals
|
||||
% Eric Paris
|
||||
% Jan 2015
|
||||
# NAME
|
||||
`)
|
||||
fmt.Fprintf(out, "%s \\- %s\n\n", name, short)
|
||||
fmt.Fprintf(out, "# SYNOPSIS\n")
|
||||
fmt.Fprintf(out, "**%s** [OPTIONS]\n\n", name)
|
||||
fmt.Fprintf(out, "# DESCRIPTION\n")
|
||||
fmt.Fprintf(out, "%s\n\n", long)
|
||||
}
|
||||
|
||||
func printFlags(out *bytes.Buffer, flags *pflag.FlagSet) {
|
||||
flags.VisitAll(func(flag *pflag.Flag) {
|
||||
format := "**--%s**=%s\n\t%s\n\n"
|
||||
if flag.Value.Type() == "string" {
|
||||
// put quotes on the value
|
||||
format = "**--%s**=%q\n\t%s\n\n"
|
||||
}
|
||||
|
||||
// Todo, when we mark a shorthand is deprecated, but specify an empty message.
|
||||
// The flag.ShorthandDeprecated is empty as the shorthand is deprecated.
|
||||
// Using len(flag.ShorthandDeprecated) > 0 can't handle this, others are ok.
|
||||
if !(len(flag.ShorthandDeprecated) > 0) && len(flag.Shorthand) > 0 {
|
||||
format = "**-%s**, " + format
|
||||
fmt.Fprintf(out, format, flag.Shorthand, flag.Name, flag.DefValue, flag.Usage)
|
||||
} else {
|
||||
fmt.Fprintf(out, format, flag.Name, flag.DefValue, flag.Usage)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func printOptions(out *bytes.Buffer, command *cobra.Command) {
|
||||
flags := command.NonInheritedFlags()
|
||||
if flags.HasFlags() {
|
||||
fmt.Fprintf(out, "# OPTIONS\n")
|
||||
printFlags(out, flags)
|
||||
fmt.Fprintf(out, "\n")
|
||||
}
|
||||
flags = command.InheritedFlags()
|
||||
if flags.HasFlags() {
|
||||
fmt.Fprintf(out, "# OPTIONS INHERITED FROM PARENT COMMANDS\n")
|
||||
printFlags(out, flags)
|
||||
fmt.Fprintf(out, "\n")
|
||||
}
|
||||
}
|
||||
|
||||
func genMarkdown(command *cobra.Command, parent, docsDir string) {
|
||||
dparent := strings.Replace(parent, " ", "-", -1)
|
||||
name := command.Name()
|
||||
dname := name
|
||||
if len(parent) > 0 {
|
||||
dname = dparent + "-" + name
|
||||
name = parent + " " + name
|
||||
}
|
||||
|
||||
out := new(bytes.Buffer)
|
||||
short := command.Short
|
||||
long := command.Long
|
||||
if len(long) == 0 {
|
||||
long = short
|
||||
}
|
||||
|
||||
preamble(out, name, short, long)
|
||||
printOptions(out, command)
|
||||
|
||||
if len(command.Example) > 0 {
|
||||
fmt.Fprintf(out, "# EXAMPLE\n")
|
||||
fmt.Fprintf(out, "```\n%s\n```\n", command.Example)
|
||||
}
|
||||
|
||||
if len(command.Commands()) > 0 || len(parent) > 0 {
|
||||
fmt.Fprintf(out, "# SEE ALSO\n")
|
||||
if len(parent) > 0 {
|
||||
fmt.Fprintf(out, "**%s(1)**, ", dparent)
|
||||
}
|
||||
for _, c := range command.Commands() {
|
||||
fmt.Fprintf(out, "**%s-%s(1)**, ", dname, c.Name())
|
||||
genMarkdown(c, name, docsDir)
|
||||
}
|
||||
fmt.Fprintf(out, "\n")
|
||||
}
|
||||
|
||||
out.WriteString(`
|
||||
# HISTORY
|
||||
January 2015, Originally compiled by Eric Paris (eparis at redhat dot com) based on the kubernetes source material, but hopefully they have been automatically generated since!
|
||||
`)
|
||||
|
||||
final := mangen.Render(out.Bytes())
|
||||
|
||||
filename := docsDir + dname + ".1"
|
||||
outFile, err := os.Create(filename)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
defer outFile.Close()
|
||||
_, err = outFile.Write(final)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
}
|
37
vendor/k8s.io/kubernetes/cmd/genswaggertypedocs/BUILD
generated
vendored
Normal file
37
vendor/k8s.io/kubernetes/cmd/genswaggertypedocs/BUILD
generated
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_binary",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_binary(
|
||||
name = "genswaggertypedocs",
|
||||
importpath = "k8s.io/kubernetes/cmd/genswaggertypedocs",
|
||||
library = ":go_default_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["swagger_type_docs.go"],
|
||||
importpath = "k8s.io/kubernetes/cmd/genswaggertypedocs",
|
||||
deps = [
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/github.com/spf13/pflag:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
71
vendor/k8s.io/kubernetes/cmd/genswaggertypedocs/swagger_type_docs.go
generated
vendored
Normal file
71
vendor/k8s.io/kubernetes/cmd/genswaggertypedocs/swagger_type_docs.go
generated
vendored
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
Copyright 2015 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 main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
kruntime "k8s.io/apimachinery/pkg/runtime"
|
||||
|
||||
"github.com/golang/glog"
|
||||
flag "github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
var (
|
||||
functionDest = flag.StringP("func-dest", "f", "-", "Output for swagger functions; '-' means stdout (default)")
|
||||
typeSrc = flag.StringP("type-src", "s", "", "From where we are going to read the types")
|
||||
verify = flag.BoolP("verify", "v", false, "Verifies if the given type-src file has documentation for every type")
|
||||
)
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
|
||||
if *typeSrc == "" {
|
||||
glog.Fatalf("Please define -s flag as it is the source file")
|
||||
}
|
||||
|
||||
var funcOut io.Writer
|
||||
if *functionDest == "-" {
|
||||
funcOut = os.Stdout
|
||||
} else {
|
||||
file, err := os.Create(*functionDest)
|
||||
if err != nil {
|
||||
glog.Fatalf("Couldn't open %v: %v", *functionDest, err)
|
||||
}
|
||||
defer file.Close()
|
||||
funcOut = file
|
||||
}
|
||||
|
||||
docsForTypes := kruntime.ParseDocumentationFrom(*typeSrc)
|
||||
|
||||
if *verify == true {
|
||||
rc, err := kruntime.VerifySwaggerDocsExist(docsForTypes, funcOut)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error in verification process: %s\n", err)
|
||||
}
|
||||
os.Exit(rc)
|
||||
}
|
||||
|
||||
if docsForTypes != nil && len(docsForTypes) > 0 {
|
||||
if err := kruntime.WriteSwaggerDocFunc(docsForTypes, funcOut); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error when writing swagger documentation functions: %s\n", err)
|
||||
os.Exit(-1)
|
||||
}
|
||||
}
|
||||
}
|
33
vendor/k8s.io/kubernetes/cmd/genutils/BUILD
generated
vendored
Normal file
33
vendor/k8s.io/kubernetes/cmd/genutils/BUILD
generated
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["genutils.go"],
|
||||
importpath = "k8s.io/kubernetes/cmd/genutils",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["genutils_test.go"],
|
||||
importpath = "k8s.io/kubernetes/cmd/genutils",
|
||||
library = ":go_default_library",
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
43
vendor/k8s.io/kubernetes/cmd/genutils/genutils.go
generated
vendored
Normal file
43
vendor/k8s.io/kubernetes/cmd/genutils/genutils.go
generated
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
Copyright 2015 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 genutils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
// OutDir creates the absolute path name from path and checks path exists.
|
||||
// Returns absolute path including trailing '/' or error if path does not exist.
|
||||
func OutDir(path string) (string, error) {
|
||||
outDir, err := filepath.Abs(path)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
stat, err := os.Stat(outDir)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if !stat.IsDir() {
|
||||
return "", fmt.Errorf("output directory %s is not a directory", outDir)
|
||||
}
|
||||
outDir = outDir + "/"
|
||||
return outDir, nil
|
||||
}
|
42
vendor/k8s.io/kubernetes/cmd/genutils/genutils_test.go
generated
vendored
Normal file
42
vendor/k8s.io/kubernetes/cmd/genutils/genutils_test.go
generated
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
Copyright 2015 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 genutils
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestValidDir(t *testing.T) {
|
||||
_, err := OutDir("./")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInvalidDir(t *testing.T) {
|
||||
_, err := OutDir("./nondir")
|
||||
if err == nil {
|
||||
t.Fatal("expected an error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNotDir(t *testing.T) {
|
||||
_, err := OutDir("./genutils_test.go")
|
||||
if err == nil {
|
||||
t.Fatal("expected an error")
|
||||
}
|
||||
}
|
40
vendor/k8s.io/kubernetes/cmd/genyaml/BUILD
generated
vendored
Normal file
40
vendor/k8s.io/kubernetes/cmd/genyaml/BUILD
generated
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_binary",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_binary(
|
||||
name = "genyaml",
|
||||
importpath = "k8s.io/kubernetes/cmd/genyaml",
|
||||
library = ":go_default_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["gen_kubectl_yaml.go"],
|
||||
importpath = "k8s.io/kubernetes/cmd/genyaml",
|
||||
deps = [
|
||||
"//cmd/genutils:go_default_library",
|
||||
"//pkg/kubectl/cmd:go_default_library",
|
||||
"//pkg/kubectl/cmd/util:go_default_library",
|
||||
"//vendor/github.com/spf13/cobra:go_default_library",
|
||||
"//vendor/github.com/spf13/pflag:go_default_library",
|
||||
"//vendor/gopkg.in/yaml.v2:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
169
vendor/k8s.io/kubernetes/cmd/genyaml/gen_kubectl_yaml.go
generated
vendored
Normal file
169
vendor/k8s.io/kubernetes/cmd/genyaml/gen_kubectl_yaml.go
generated
vendored
Normal file
@ -0,0 +1,169 @@
|
||||
/*
|
||||
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 main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
"gopkg.in/yaml.v2"
|
||||
"k8s.io/kubernetes/cmd/genutils"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd"
|
||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||
)
|
||||
|
||||
type cmdOption struct {
|
||||
Name string
|
||||
Shorthand string `yaml:",omitempty"`
|
||||
DefaultValue string `yaml:"default_value,omitempty"`
|
||||
Usage string `yaml:",omitempty"`
|
||||
}
|
||||
|
||||
type cmdDoc struct {
|
||||
Name string
|
||||
Synopsis string `yaml:",omitempty"`
|
||||
Description string `yaml:",omitempty"`
|
||||
Options []cmdOption `yaml:",omitempty"`
|
||||
InheritedOptions []cmdOption `yaml:"inherited_options,omitempty"`
|
||||
Example string `yaml:",omitempty"`
|
||||
SeeAlso []string `yaml:"see_also,omitempty"`
|
||||
}
|
||||
|
||||
func main() {
|
||||
path := "docs/yaml/kubectl"
|
||||
if len(os.Args) == 2 {
|
||||
path = os.Args[1]
|
||||
} else if len(os.Args) > 2 {
|
||||
fmt.Fprintf(os.Stderr, "usage: %s [output directory]\n", os.Args[0])
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
outDir, err := genutils.OutDir(path)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "failed to get output directory: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Set environment variables used by kubectl so the output is consistent,
|
||||
// regardless of where we run.
|
||||
os.Setenv("HOME", "/home/username")
|
||||
// TODO os.Stdin should really be something like ioutil.Discard, but a Reader
|
||||
kubectl := cmd.NewKubectlCommand(cmdutil.NewFactory(nil), os.Stdin, ioutil.Discard, ioutil.Discard)
|
||||
genYaml(kubectl, "", outDir)
|
||||
for _, c := range kubectl.Commands() {
|
||||
genYaml(c, "kubectl", outDir)
|
||||
}
|
||||
}
|
||||
|
||||
// Temporary workaround for yaml lib generating incorrect yaml with long strings
|
||||
// that do not contain \n.
|
||||
func forceMultiLine(s string) string {
|
||||
if len(s) > 60 && !strings.Contains(s, "\n") {
|
||||
s = s + "\n"
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func genFlagResult(flags *pflag.FlagSet) []cmdOption {
|
||||
result := []cmdOption{}
|
||||
|
||||
flags.VisitAll(func(flag *pflag.Flag) {
|
||||
// Todo, when we mark a shorthand is deprecated, but specify an empty message.
|
||||
// The flag.ShorthandDeprecated is empty as the shorthand is deprecated.
|
||||
// Using len(flag.ShorthandDeprecated) > 0 can't handle this, others are ok.
|
||||
if !(len(flag.ShorthandDeprecated) > 0) && len(flag.Shorthand) > 0 {
|
||||
opt := cmdOption{
|
||||
flag.Name,
|
||||
flag.Shorthand,
|
||||
flag.DefValue,
|
||||
forceMultiLine(flag.Usage),
|
||||
}
|
||||
result = append(result, opt)
|
||||
} else {
|
||||
opt := cmdOption{
|
||||
Name: flag.Name,
|
||||
DefaultValue: forceMultiLine(flag.DefValue),
|
||||
Usage: forceMultiLine(flag.Usage),
|
||||
}
|
||||
result = append(result, opt)
|
||||
}
|
||||
})
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func genYaml(command *cobra.Command, parent, docsDir string) {
|
||||
doc := cmdDoc{}
|
||||
|
||||
doc.Name = command.Name()
|
||||
doc.Synopsis = forceMultiLine(command.Short)
|
||||
doc.Description = forceMultiLine(command.Long)
|
||||
|
||||
flags := command.NonInheritedFlags()
|
||||
if flags.HasFlags() {
|
||||
doc.Options = genFlagResult(flags)
|
||||
}
|
||||
flags = command.InheritedFlags()
|
||||
if flags.HasFlags() {
|
||||
doc.InheritedOptions = genFlagResult(flags)
|
||||
}
|
||||
|
||||
if len(command.Example) > 0 {
|
||||
doc.Example = command.Example
|
||||
}
|
||||
|
||||
if len(command.Commands()) > 0 || len(parent) > 0 {
|
||||
result := []string{}
|
||||
if len(parent) > 0 {
|
||||
result = append(result, parent)
|
||||
}
|
||||
for _, c := range command.Commands() {
|
||||
result = append(result, c.Name())
|
||||
}
|
||||
doc.SeeAlso = result
|
||||
}
|
||||
|
||||
final, err := yaml.Marshal(&doc)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
var filename string
|
||||
|
||||
if parent == "" {
|
||||
filename = docsDir + doc.Name + ".yaml"
|
||||
} else {
|
||||
filename = docsDir + parent + "_" + doc.Name + ".yaml"
|
||||
}
|
||||
|
||||
outFile, err := os.Create(filename)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
defer outFile.Close()
|
||||
_, err = outFile.Write(final)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
42
vendor/k8s.io/kubernetes/cmd/gke-certificates-controller/BUILD
generated
vendored
Normal file
42
vendor/k8s.io/kubernetes/cmd/gke-certificates-controller/BUILD
generated
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_binary",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["main.go"],
|
||||
importpath = "k8s.io/kubernetes/cmd/gke-certificates-controller",
|
||||
deps = [
|
||||
"//cmd/gke-certificates-controller/app:go_default_library",
|
||||
"//pkg/kubectl/util/logs:go_default_library",
|
||||
"//pkg/version/verflag:go_default_library",
|
||||
"//vendor/github.com/spf13/pflag:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/util/flag:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//cmd/gke-certificates-controller/app:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
|
||||
go_binary(
|
||||
name = "gke-certificates-controller",
|
||||
importpath = "k8s.io/kubernetes/cmd/gke-certificates-controller",
|
||||
library = ":go_default_library",
|
||||
)
|
8
vendor/k8s.io/kubernetes/cmd/gke-certificates-controller/OWNERS
generated
vendored
Normal file
8
vendor/k8s.io/kubernetes/cmd/gke-certificates-controller/OWNERS
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
approvers:
|
||||
- pipejakob
|
||||
- mikedanese
|
||||
- roberthbailey
|
||||
reviewers:
|
||||
- pipejakob
|
||||
- mikedanese
|
||||
- roberthbailey
|
62
vendor/k8s.io/kubernetes/cmd/gke-certificates-controller/app/BUILD
generated
vendored
Normal file
62
vendor/k8s.io/kubernetes/cmd/gke-certificates-controller/app/BUILD
generated
vendored
Normal file
@ -0,0 +1,62 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"gke_certificates_controller.go",
|
||||
"gke_signer.go",
|
||||
"options.go",
|
||||
],
|
||||
importpath = "k8s.io/kubernetes/cmd/gke-certificates-controller/app",
|
||||
deps = [
|
||||
"//pkg/api/legacyscheme:go_default_library",
|
||||
"//pkg/apis/certificates/install:go_default_library",
|
||||
"//pkg/controller:go_default_library",
|
||||
"//pkg/controller/certificates: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/api/certificates/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1: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/apiserver/pkg/util/webhook: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/kubernetes/typed/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/client-go/plugin/pkg/client/auth:go_default_library",
|
||||
"//vendor/k8s.io/client-go/rest:go_default_library",
|
||||
"//vendor/k8s.io/client-go/tools/clientcmd:go_default_library",
|
||||
"//vendor/k8s.io/client-go/tools/record:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["gke_signer_test.go"],
|
||||
importpath = "k8s.io/kubernetes/cmd/gke-certificates-controller/app",
|
||||
library = ":go_default_library",
|
||||
deps = [
|
||||
"//vendor/k8s.io/api/certificates/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/client-go/tools/record:go_default_library",
|
||||
],
|
||||
)
|
89
vendor/k8s.io/kubernetes/cmd/gke-certificates-controller/app/gke_certificates_controller.go
generated
vendored
Normal file
89
vendor/k8s.io/kubernetes/cmd/gke-certificates-controller/app/gke_certificates_controller.go
generated
vendored
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
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 implements a server that runs a stand-alone version of the
|
||||
// certificates controller for GKE clusters.
|
||||
package app
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/client-go/informers"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
v1core "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
"k8s.io/client-go/tools/record"
|
||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||
"k8s.io/kubernetes/pkg/controller"
|
||||
"k8s.io/kubernetes/pkg/controller/certificates"
|
||||
|
||||
// Install all auth plugins
|
||||
_ "k8s.io/client-go/plugin/pkg/client/auth"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// NewGKECertificatesControllerCommand creates a new *cobra.Command with default parameters.
|
||||
func NewGKECertificatesControllerCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "gke-certificates-controller",
|
||||
Long: `The Kubernetes GKE certificates controller is a daemon that
|
||||
handles auto-approving and signing certificates for GKE clusters.`,
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
// Run runs the GKECertificatesController. This should never exit.
|
||||
func Run(s *GKECertificatesController) error {
|
||||
kubeconfig, err := clientcmd.BuildConfigFromFlags("", s.Kubeconfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
kubeClient, err := clientset.NewForConfig(restclient.AddUserAgent(kubeconfig, "gke-certificates-controller"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
eventBroadcaster := record.NewBroadcaster()
|
||||
eventBroadcaster.StartLogging(glog.Infof)
|
||||
eventBroadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: v1core.New(kubeClient.CoreV1().RESTClient()).Events("")})
|
||||
recorder := eventBroadcaster.NewRecorder(legacyscheme.Scheme, v1.EventSource{Component: "gke-certificates-controller"})
|
||||
|
||||
clientBuilder := controller.SimpleControllerClientBuilder{ClientConfig: kubeconfig}
|
||||
client := clientBuilder.ClientOrDie("certificate-controller")
|
||||
|
||||
sharedInformers := informers.NewSharedInformerFactory(client, time.Duration(12)*time.Hour)
|
||||
|
||||
signer, err := NewGKESigner(s.ClusterSigningGKEKubeconfig, s.ClusterSigningGKERetryBackoff.Duration, recorder, client)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
controller := certificates.NewCertificateController(
|
||||
client,
|
||||
sharedInformers.Certificates().V1beta1().CertificateSigningRequests(),
|
||||
signer.handle,
|
||||
)
|
||||
|
||||
sharedInformers.Start(nil)
|
||||
controller.Run(5, nil) // runs forever
|
||||
panic("unreachable")
|
||||
}
|
137
vendor/k8s.io/kubernetes/cmd/gke-certificates-controller/app/gke_signer.go
generated
vendored
Normal file
137
vendor/k8s.io/kubernetes/cmd/gke-certificates-controller/app/gke_signer.go
generated
vendored
Normal file
@ -0,0 +1,137 @@
|
||||
/*
|
||||
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
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/golang/glog"
|
||||
|
||||
capi "k8s.io/api/certificates/v1beta1"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apiserver/pkg/util/webhook"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/tools/record"
|
||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||
_ "k8s.io/kubernetes/pkg/apis/certificates/install"
|
||||
"k8s.io/kubernetes/pkg/controller/certificates"
|
||||
)
|
||||
|
||||
var (
|
||||
groupVersions = []schema.GroupVersion{capi.SchemeGroupVersion}
|
||||
)
|
||||
|
||||
// GKESigner uses external calls to GKE in order to sign certificate signing
|
||||
// requests.
|
||||
type GKESigner struct {
|
||||
webhook *webhook.GenericWebhook
|
||||
kubeConfigFile string
|
||||
retryBackoff time.Duration
|
||||
recorder record.EventRecorder
|
||||
client clientset.Interface
|
||||
}
|
||||
|
||||
// NewGKESigner will create a new instance of a GKESigner.
|
||||
func NewGKESigner(kubeConfigFile string, retryBackoff time.Duration, recorder record.EventRecorder, client clientset.Interface) (*GKESigner, error) {
|
||||
webhook, err := webhook.NewGenericWebhook(legacyscheme.Registry, legacyscheme.Codecs, kubeConfigFile, groupVersions, retryBackoff)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &GKESigner{
|
||||
webhook: webhook,
|
||||
kubeConfigFile: kubeConfigFile,
|
||||
retryBackoff: retryBackoff,
|
||||
recorder: recorder,
|
||||
client: client,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *GKESigner) handle(csr *capi.CertificateSigningRequest) error {
|
||||
if !certificates.IsCertificateRequestApproved(csr) {
|
||||
return nil
|
||||
}
|
||||
csr, err := s.sign(csr)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error auto signing csr: %v", err)
|
||||
}
|
||||
_, err = s.client.CertificatesV1beta1().CertificateSigningRequests().UpdateStatus(csr)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error updating signature for csr: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Sign will make an external call to GKE order to sign the given
|
||||
// *capi.CertificateSigningRequest, using the GKESigner's
|
||||
// kubeConfigFile.
|
||||
func (s *GKESigner) sign(csr *capi.CertificateSigningRequest) (*capi.CertificateSigningRequest, error) {
|
||||
result := s.webhook.WithExponentialBackoff(func() rest.Result {
|
||||
return s.webhook.RestClient.Post().Body(csr).Do()
|
||||
})
|
||||
|
||||
if err := result.Error(); err != nil {
|
||||
if bodyErr := s.resultBodyError(result); bodyErr != nil {
|
||||
return nil, s.webhookError(csr, bodyErr)
|
||||
}
|
||||
return nil, s.webhookError(csr, err)
|
||||
}
|
||||
|
||||
var statusCode int
|
||||
if result.StatusCode(&statusCode); statusCode < 200 || statusCode >= 300 {
|
||||
return nil, s.webhookError(csr, fmt.Errorf("received unsuccessful response code from webhook: %d", statusCode))
|
||||
}
|
||||
|
||||
result_csr := &capi.CertificateSigningRequest{}
|
||||
|
||||
if err := result.Into(result_csr); err != nil {
|
||||
return nil, s.webhookError(result_csr, err)
|
||||
}
|
||||
|
||||
// Keep the original CSR intact, and only update fields we expect to change.
|
||||
csr.Status.Certificate = result_csr.Status.Certificate
|
||||
return csr, nil
|
||||
}
|
||||
|
||||
func (s *GKESigner) webhookError(csr *capi.CertificateSigningRequest, err error) error {
|
||||
glog.V(2).Infof("error contacting webhook backend: %s", err)
|
||||
s.recorder.Eventf(csr, "Warning", "SigningError", "error while calling GKE: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
// signResultError represents the structured response body of a failed call to
|
||||
// GKE's SignCertificate API.
|
||||
type signResultError struct {
|
||||
Error struct {
|
||||
Code int
|
||||
Message string
|
||||
Status string
|
||||
}
|
||||
}
|
||||
|
||||
// resultBodyError attempts to extract an error out of a response body.
|
||||
func (s *GKESigner) resultBodyError(result rest.Result) error {
|
||||
body, _ := result.Raw()
|
||||
var sre signResultError
|
||||
if err := json.Unmarshal(body, &sre); err == nil {
|
||||
return fmt.Errorf("server responded with error: %s", sre.Error.Message)
|
||||
}
|
||||
return nil
|
||||
}
|
154
vendor/k8s.io/kubernetes/cmd/gke-certificates-controller/app/gke_signer_test.go
generated
vendored
Normal file
154
vendor/k8s.io/kubernetes/cmd/gke-certificates-controller/app/gke_signer_test.go
generated
vendored
Normal file
@ -0,0 +1,154 @@
|
||||
/*
|
||||
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
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
"text/template"
|
||||
"time"
|
||||
|
||||
certificates "k8s.io/api/certificates/v1beta1"
|
||||
"k8s.io/client-go/tools/record"
|
||||
)
|
||||
|
||||
const kubeConfigTmpl = `
|
||||
clusters:
|
||||
- cluster:
|
||||
server: {{ .Server }}
|
||||
name: testcluster
|
||||
users:
|
||||
- user:
|
||||
username: admin
|
||||
password: mypass
|
||||
`
|
||||
|
||||
func TestGKESigner(t *testing.T) {
|
||||
goodResponse := &certificates.CertificateSigningRequest{
|
||||
Status: certificates.CertificateSigningRequestStatus{
|
||||
Certificate: []byte("fake certificate"),
|
||||
},
|
||||
}
|
||||
|
||||
invalidResponse := "{ \"status\": \"Not a properly formatted CSR response\" }"
|
||||
|
||||
cases := []struct {
|
||||
mockResponse interface{}
|
||||
expected []byte
|
||||
failCalls int
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
mockResponse: goodResponse,
|
||||
expected: goodResponse.Status.Certificate,
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
mockResponse: goodResponse,
|
||||
expected: goodResponse.Status.Certificate,
|
||||
failCalls: 3,
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
mockResponse: goodResponse,
|
||||
failCalls: 20,
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
mockResponse: invalidResponse,
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
server, err := newTestServer(c.mockResponse, c.failCalls)
|
||||
if err != nil {
|
||||
t.Fatalf("error creating test server")
|
||||
}
|
||||
|
||||
kubeConfig, err := ioutil.TempFile("", "kubeconfig")
|
||||
if err != nil {
|
||||
t.Fatalf("error creating kubeconfig tempfile: %v", err)
|
||||
}
|
||||
|
||||
tmpl, err := template.New("kubeconfig").Parse(kubeConfigTmpl)
|
||||
if err != nil {
|
||||
t.Fatalf("error creating kubeconfig template: %v", err)
|
||||
}
|
||||
|
||||
data := struct{ Server string }{server.httpserver.URL}
|
||||
|
||||
if err := tmpl.Execute(kubeConfig, data); err != nil {
|
||||
t.Fatalf("error executing kubeconfig template: %v", err)
|
||||
}
|
||||
|
||||
if err := kubeConfig.Close(); err != nil {
|
||||
t.Fatalf("error closing kubeconfig template: %v", err)
|
||||
}
|
||||
|
||||
signer, err := NewGKESigner(kubeConfig.Name(), time.Duration(500)*time.Millisecond, record.NewFakeRecorder(10), nil)
|
||||
if err != nil {
|
||||
t.Fatalf("error creating GKESigner: %v", err)
|
||||
}
|
||||
|
||||
cert, err := signer.sign(&certificates.CertificateSigningRequest{})
|
||||
|
||||
if c.wantErr {
|
||||
if err == nil {
|
||||
t.Errorf("wanted error during GKE.Sign() call, got not none")
|
||||
}
|
||||
} else {
|
||||
if err != nil {
|
||||
t.Errorf("error while signing: %v", err)
|
||||
}
|
||||
|
||||
if !bytes.Equal(cert.Status.Certificate, c.expected) {
|
||||
t.Errorf("response certificate didn't match expected %v: %v", c.expected, cert)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type testServer struct {
|
||||
httpserver *httptest.Server
|
||||
failCalls int
|
||||
response interface{}
|
||||
}
|
||||
|
||||
func newTestServer(response interface{}, failCalls int) (*testServer, error) {
|
||||
server := &testServer{
|
||||
response: response,
|
||||
failCalls: failCalls,
|
||||
}
|
||||
|
||||
server.httpserver = httptest.NewServer(server)
|
||||
return server, nil
|
||||
}
|
||||
|
||||
func (s *testServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
if s.failCalls > 0 {
|
||||
http.Error(w, "Service unavailable", 500)
|
||||
s.failCalls--
|
||||
} else {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(s.response)
|
||||
}
|
||||
}
|
54
vendor/k8s.io/kubernetes/cmd/gke-certificates-controller/app/options.go
generated
vendored
Normal file
54
vendor/k8s.io/kubernetes/cmd/gke-certificates-controller/app/options.go
generated
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
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 app implements a server that runs a stand-alone version of the
|
||||
// certificates controller.
|
||||
package app
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
// GKECertificatesController is the main context object for the package.
|
||||
type GKECertificatesController struct {
|
||||
Kubeconfig string
|
||||
ClusterSigningGKEKubeconfig string
|
||||
ClusterSigningGKERetryBackoff metav1.Duration
|
||||
ApproveAllKubeletCSRsForGroup string
|
||||
}
|
||||
|
||||
// Create a new instance of a GKECertificatesController with default parameters.
|
||||
func NewGKECertificatesController() *GKECertificatesController {
|
||||
s := &GKECertificatesController{
|
||||
ClusterSigningGKERetryBackoff: metav1.Duration{Duration: 500 * time.Millisecond},
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// AddFlags adds flags for a specific GKECertificatesController to the
|
||||
// specified FlagSet.
|
||||
func (s *GKECertificatesController) AddFlags(fs *pflag.FlagSet) {
|
||||
fs.StringVar(&s.Kubeconfig, "kubeconfig", s.Kubeconfig, "Path to kubeconfig file with authorization and master location information.")
|
||||
|
||||
fs.StringVar(&s.ClusterSigningGKEKubeconfig, "cluster-signing-gke-kubeconfig", s.ClusterSigningGKEKubeconfig, "If set, use the kubeconfig file to call GKE to sign cluster-scoped certificates instead of using a local private key.")
|
||||
fs.DurationVar(&s.ClusterSigningGKERetryBackoff.Duration, "cluster-signing-gke-retry-backoff", s.ClusterSigningGKERetryBackoff.Duration, "The initial backoff to use when retrying requests to GKE. Additional attempts will use exponential backoff.")
|
||||
|
||||
fs.StringVar(&s.ApproveAllKubeletCSRsForGroup, "insecure-experimental-approve-all-kubelet-csrs-for-group", s.ApproveAllKubeletCSRsForGroup, "The group for which the controller-manager will auto approve all CSRs for kubelet client certificates.")
|
||||
}
|
49
vendor/k8s.io/kubernetes/cmd/gke-certificates-controller/main.go
generated
vendored
Normal file
49
vendor/k8s.io/kubernetes/cmd/gke-certificates-controller/main.go
generated
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
// The GKE certificates controller is responsible for monitoring certificate
|
||||
// signing requests and (potentially) auto-approving and signing them within
|
||||
// GKE.
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"k8s.io/apiserver/pkg/util/flag"
|
||||
"k8s.io/kubernetes/cmd/gke-certificates-controller/app"
|
||||
"k8s.io/kubernetes/pkg/kubectl/util/logs"
|
||||
"k8s.io/kubernetes/pkg/version/verflag"
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
// TODO(pipejakob): Move this entire cmd directory into its own repo
|
||||
func main() {
|
||||
s := app.NewGKECertificatesController()
|
||||
s.AddFlags(pflag.CommandLine)
|
||||
|
||||
flag.InitFlags()
|
||||
logs.InitLogs()
|
||||
defer logs.FlushLogs()
|
||||
|
||||
verflag.PrintAndExitIfRequested()
|
||||
|
||||
if err := app.Run(s); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "%v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
84
vendor/k8s.io/kubernetes/cmd/hyperkube/BUILD
generated
vendored
Normal file
84
vendor/k8s.io/kubernetes/cmd/hyperkube/BUILD
generated
vendored
Normal file
@ -0,0 +1,84 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_binary",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
load("//pkg/version:def.bzl", "version_x_defs")
|
||||
|
||||
go_binary(
|
||||
name = "hyperkube",
|
||||
importpath = "k8s.io/kubernetes/cmd/hyperkube",
|
||||
library = ":go_default_library",
|
||||
x_defs = version_x_defs(),
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["hyperkube_test.go"],
|
||||
importpath = "k8s.io/kubernetes/cmd/hyperkube",
|
||||
library = ":go_default_library",
|
||||
deps = [
|
||||
"//vendor/github.com/spf13/cobra:go_default_library",
|
||||
"//vendor/github.com/stretchr/testify/assert:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"cloud-controller-manager.go",
|
||||
"hyperkube.go",
|
||||
"kube-aggregator.go",
|
||||
"kube-apiserver.go",
|
||||
"kube-controller-manager.go",
|
||||
"kube-proxy.go",
|
||||
"kube-scheduler.go",
|
||||
"kubectl.go",
|
||||
"kubelet.go",
|
||||
"main.go",
|
||||
"server.go",
|
||||
],
|
||||
importpath = "k8s.io/kubernetes/cmd/hyperkube",
|
||||
deps = [
|
||||
"//cmd/cloud-controller-manager/app:go_default_library",
|
||||
"//cmd/cloud-controller-manager/app/options:go_default_library",
|
||||
"//cmd/kube-apiserver/app:go_default_library",
|
||||
"//cmd/kube-apiserver/app/options:go_default_library",
|
||||
"//cmd/kube-controller-manager/app:go_default_library",
|
||||
"//cmd/kube-controller-manager/app/options:go_default_library",
|
||||
"//cmd/kube-proxy/app:go_default_library",
|
||||
"//cmd/kubelet/app:go_default_library",
|
||||
"//cmd/kubelet/app/options:go_default_library",
|
||||
"//pkg/client/metrics/prometheus:go_default_library",
|
||||
"//pkg/kubectl/cmd:go_default_library",
|
||||
"//pkg/kubectl/cmd/util:go_default_library",
|
||||
"//pkg/util/template:go_default_library",
|
||||
"//pkg/version/prometheus:go_default_library",
|
||||
"//pkg/version/verflag:go_default_library",
|
||||
"//plugin/cmd/kube-scheduler/app: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/server:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/server/healthz:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/util/flag:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/util/logs:go_default_library",
|
||||
"//vendor/k8s.io/kube-aggregator/pkg/cmd/server:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
39
vendor/k8s.io/kubernetes/cmd/hyperkube/cloud-controller-manager.go
generated
vendored
Normal file
39
vendor/k8s.io/kubernetes/cmd/hyperkube/cloud-controller-manager.go
generated
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
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 main
|
||||
|
||||
import (
|
||||
"k8s.io/kubernetes/cmd/cloud-controller-manager/app"
|
||||
"k8s.io/kubernetes/cmd/cloud-controller-manager/app/options"
|
||||
)
|
||||
|
||||
// NewCloudControllerManager creates a new hyperkube Server object that includes the
|
||||
// description and flags.
|
||||
func NewCloudControllerManager() *Server {
|
||||
s := options.NewCloudControllerManagerServer()
|
||||
|
||||
hks := Server{
|
||||
name: "cloud-controller-manager",
|
||||
SimpleUsage: "cloud-controller-manager",
|
||||
Long: "A server that acts as an external cloud provider.",
|
||||
Run: func(_ *Server, args []string, stopCh <-chan struct{}) error {
|
||||
return app.Run(s)
|
||||
},
|
||||
}
|
||||
s.AddFlags(hks.Flags())
|
||||
return &hks
|
||||
}
|
281
vendor/k8s.io/kubernetes/cmd/hyperkube/hyperkube.go
generated
vendored
Normal file
281
vendor/k8s.io/kubernetes/cmd/hyperkube/hyperkube.go
generated
vendored
Normal file
@ -0,0 +1,281 @@
|
||||
/*
|
||||
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 main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/apiserver/pkg/server"
|
||||
utilflag "k8s.io/apiserver/pkg/util/flag"
|
||||
"k8s.io/apiserver/pkg/util/logs"
|
||||
utiltemplate "k8s.io/kubernetes/pkg/util/template"
|
||||
"k8s.io/kubernetes/pkg/version/verflag"
|
||||
)
|
||||
|
||||
// HyperKube represents a single binary that can morph/manage into multiple
|
||||
// servers.
|
||||
type HyperKube struct {
|
||||
Name string // The executable name, used for help and soft-link invocation
|
||||
Long string // A long description of the binary. It will be world wrapped before output.
|
||||
|
||||
servers []Server
|
||||
alphaServers []Server
|
||||
baseFlags *pflag.FlagSet
|
||||
out io.Writer
|
||||
helpFlagVal bool
|
||||
makeSymlinksFlagVal bool
|
||||
}
|
||||
|
||||
// AddServer adds a server to the HyperKube object.
|
||||
func (hk *HyperKube) AddServer(s *Server) {
|
||||
hk.servers = append(hk.servers, *s)
|
||||
hk.servers[len(hk.servers)-1].hk = hk
|
||||
}
|
||||
|
||||
// AddServer adds an alpha server to the HyperKube object.
|
||||
func (hk *HyperKube) AddAlphaServer(s *Server) {
|
||||
hk.alphaServers = append(hk.alphaServers, *s)
|
||||
hk.alphaServers[len(hk.alphaServers)-1].hk = hk
|
||||
}
|
||||
|
||||
// FindServer will find a specific server named name.
|
||||
func (hk *HyperKube) FindServer(name string) (*Server, error) {
|
||||
return findServer(name, hk.servers)
|
||||
}
|
||||
|
||||
// FindServer will find a specific alpha server named name.
|
||||
func (hk *HyperKube) FindAlphaServer(name string) (*Server, error) {
|
||||
return findServer(name, hk.alphaServers)
|
||||
}
|
||||
|
||||
func findServer(name string, servers []Server) (*Server, error) {
|
||||
for _, s := range servers {
|
||||
if s.Name() == name || s.AlternativeName == name {
|
||||
return &s, nil
|
||||
}
|
||||
}
|
||||
return nil, fmt.Errorf("Server not found: %s", name)
|
||||
}
|
||||
|
||||
// Servers returns a list of all of the registered servers
|
||||
func (hk *HyperKube) Servers() []Server {
|
||||
return hk.servers
|
||||
}
|
||||
|
||||
// Flags returns a flagset for "global" flags.
|
||||
func (hk *HyperKube) Flags() *pflag.FlagSet {
|
||||
if hk.baseFlags == nil {
|
||||
hk.baseFlags = pflag.NewFlagSet(hk.Name, pflag.ContinueOnError)
|
||||
hk.baseFlags.SetOutput(ioutil.Discard)
|
||||
hk.baseFlags.SetNormalizeFunc(utilflag.WordSepNormalizeFunc)
|
||||
hk.baseFlags.BoolVarP(&hk.helpFlagVal, "help", "h", false, "help for "+hk.Name)
|
||||
hk.baseFlags.BoolVar(&hk.makeSymlinksFlagVal, "make-symlinks", false, "create a symlink for each server in current directory")
|
||||
hk.baseFlags.MarkHidden("make-symlinks") // hide this flag from appearing in servers' usage output
|
||||
|
||||
// These will add all of the "global" flags (defined with both the
|
||||
// flag and pflag packages) to the new flag set we have.
|
||||
hk.baseFlags.AddGoFlagSet(flag.CommandLine)
|
||||
hk.baseFlags.AddFlagSet(pflag.CommandLine)
|
||||
|
||||
}
|
||||
return hk.baseFlags
|
||||
}
|
||||
|
||||
// Out returns the io.Writer that is used for all usage/error information
|
||||
func (hk *HyperKube) Out() io.Writer {
|
||||
if hk.out == nil {
|
||||
hk.out = os.Stderr
|
||||
}
|
||||
return hk.out
|
||||
}
|
||||
|
||||
// SetOut sets the output writer for all usage/error information
|
||||
func (hk *HyperKube) SetOut(w io.Writer) {
|
||||
hk.out = w
|
||||
}
|
||||
|
||||
// Print is a convenience method to Print to the defined output
|
||||
func (hk *HyperKube) Print(i ...interface{}) {
|
||||
fmt.Fprint(hk.Out(), i...)
|
||||
}
|
||||
|
||||
// Println is a convenience method to Println to the defined output
|
||||
func (hk *HyperKube) Println(i ...interface{}) {
|
||||
fmt.Fprintln(hk.Out(), i...)
|
||||
}
|
||||
|
||||
// Printf is a convenience method to Printf to the defined output
|
||||
func (hk *HyperKube) Printf(format string, i ...interface{}) {
|
||||
fmt.Fprintf(hk.Out(), format, i...)
|
||||
}
|
||||
|
||||
// Run the server. This will pick the appropriate server and run it.
|
||||
func (hk *HyperKube) Run(args []string, stopCh <-chan struct{}) error {
|
||||
// If we are called directly, parse all flags up to the first real
|
||||
// argument. That should be the server to run.
|
||||
command := args[0]
|
||||
serverName := path.Base(command)
|
||||
args = args[1:]
|
||||
if serverName == hk.Name {
|
||||
|
||||
baseFlags := hk.Flags()
|
||||
baseFlags.SetInterspersed(false) // Only parse flags up to the next real command
|
||||
err := baseFlags.Parse(args)
|
||||
if err != nil || hk.helpFlagVal {
|
||||
if err != nil {
|
||||
hk.Println("Error:", err)
|
||||
}
|
||||
hk.Usage()
|
||||
return err
|
||||
}
|
||||
|
||||
if hk.makeSymlinksFlagVal {
|
||||
return hk.MakeSymlinks(command)
|
||||
}
|
||||
|
||||
verflag.PrintAndExitIfRequested()
|
||||
|
||||
args = baseFlags.Args()
|
||||
if len(args) > 0 && len(args[0]) > 0 {
|
||||
serverName = args[0]
|
||||
args = args[1:]
|
||||
} else {
|
||||
err = errors.New("no server specified")
|
||||
hk.Printf("Error: %v\n\n", err)
|
||||
hk.Usage()
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
var s *Server
|
||||
var err error
|
||||
if serverName == "alpha" {
|
||||
if len(args) > 0 && len(args[0]) > 0 {
|
||||
serverName = args[0]
|
||||
args = args[1:]
|
||||
hk.Printf("Warning: alpha command syntax is unstable!\n\n")
|
||||
} else {
|
||||
err = errors.New("no alpha server specified")
|
||||
hk.Printf("Error: %v\n\n", err)
|
||||
hk.Usage()
|
||||
return err
|
||||
}
|
||||
s, err = hk.FindAlphaServer(serverName)
|
||||
} else {
|
||||
s, err = hk.FindServer(serverName)
|
||||
}
|
||||
if err != nil {
|
||||
hk.Printf("Error: %v\n\n", err)
|
||||
hk.Usage()
|
||||
return err
|
||||
}
|
||||
|
||||
s.Flags().AddFlagSet(hk.Flags())
|
||||
err = s.Flags().Parse(args)
|
||||
if err != nil || hk.helpFlagVal {
|
||||
if err != nil {
|
||||
hk.Printf("Error: %v\n\n", err)
|
||||
}
|
||||
s.Usage()
|
||||
return err
|
||||
}
|
||||
|
||||
verflag.PrintAndExitIfRequested()
|
||||
|
||||
logs.InitLogs()
|
||||
defer logs.FlushLogs()
|
||||
|
||||
if !s.RespectsStopCh {
|
||||
// For commands that do not respect the stopCh, we run them in a go
|
||||
// routine and leave them running when stopCh is closed.
|
||||
errCh := make(chan error)
|
||||
go func() {
|
||||
errCh <- s.Run(s, s.Flags().Args(), wait.NeverStop)
|
||||
}()
|
||||
select {
|
||||
case <-stopCh:
|
||||
return errors.New("interrupted") // This error text is ignored.
|
||||
case err = <-errCh:
|
||||
// fall-through
|
||||
}
|
||||
} else {
|
||||
err = s.Run(s, s.Flags().Args(), stopCh)
|
||||
}
|
||||
if err != nil {
|
||||
hk.Println("Error:", err)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// RunToExit will run the hyperkube and then call os.Exit with an appropriate exit code.
|
||||
func (hk *HyperKube) RunToExit(args []string) {
|
||||
stopCh := server.SetupSignalHandler()
|
||||
if err := hk.Run(args, stopCh); err != nil {
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
// Usage will write out a summary for all servers that this binary supports.
|
||||
func (hk *HyperKube) Usage() {
|
||||
tt := `{{if .Long}}{{.Long | trim | wrap ""}}
|
||||
{{end}}Usage
|
||||
|
||||
{{.Name}} <server> [flags]
|
||||
|
||||
Servers
|
||||
{{range .Servers}}
|
||||
{{.Name}}
|
||||
{{.Long | trim | wrap " "}}{{end}}
|
||||
Call '{{.Name}} --make-symlinks' to create symlinks for each server in the local directory.
|
||||
Call '{{.Name}} <server> --help' for help on a specific server.
|
||||
`
|
||||
utiltemplate.ExecuteTemplate(hk.Out(), tt, hk)
|
||||
}
|
||||
|
||||
// MakeSymlinks will create a symlink for each registered hyperkube server in the local directory.
|
||||
func (hk *HyperKube) MakeSymlinks(command string) error {
|
||||
wd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var errs bool
|
||||
for _, s := range hk.servers {
|
||||
link := path.Join(wd, s.Name())
|
||||
|
||||
err := os.Symlink(command, link)
|
||||
if err != nil {
|
||||
errs = true
|
||||
hk.Println(err)
|
||||
}
|
||||
}
|
||||
|
||||
if errs {
|
||||
return errors.New("Error creating one or more symlinks.")
|
||||
}
|
||||
return nil
|
||||
}
|
338
vendor/k8s.io/kubernetes/cmd/hyperkube/hyperkube_test.go
generated
vendored
Normal file
338
vendor/k8s.io/kubernetes/cmd/hyperkube/hyperkube_test.go
generated
vendored
Normal file
@ -0,0 +1,338 @@
|
||||
/*
|
||||
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 main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
)
|
||||
|
||||
type result struct {
|
||||
err error
|
||||
output string
|
||||
}
|
||||
|
||||
func testServer(n string) *Server {
|
||||
return &Server{
|
||||
SimpleUsage: n,
|
||||
Long: fmt.Sprintf("A simple server named %s", n),
|
||||
Run: func(s *Server, args []string, stopCh <-chan struct{}) error {
|
||||
s.hk.Printf("%s Run\n", s.Name())
|
||||
return nil
|
||||
},
|
||||
}
|
||||
}
|
||||
func testServerError(n string) *Server {
|
||||
return &Server{
|
||||
SimpleUsage: n,
|
||||
Long: fmt.Sprintf("A simple server named %s that returns an error", n),
|
||||
Run: func(s *Server, args []string, stopCh <-chan struct{}) error {
|
||||
s.hk.Printf("%s Run\n", s.Name())
|
||||
return errors.New("server returning error")
|
||||
},
|
||||
}
|
||||
}
|
||||
func testStopChRespectingServer(n string) *Server {
|
||||
return &Server{
|
||||
SimpleUsage: n,
|
||||
Long: fmt.Sprintf("A simple server named %s", n),
|
||||
Run: func(s *Server, args []string, stopCh <-chan struct{}) error {
|
||||
s.hk.Printf("%s Run\n", s.Name())
|
||||
<-stopCh
|
||||
return nil
|
||||
},
|
||||
RespectsStopCh: true,
|
||||
}
|
||||
}
|
||||
func testStopChIgnoringServer(n string) *Server {
|
||||
return &Server{
|
||||
SimpleUsage: n,
|
||||
Long: fmt.Sprintf("A simple server named %s", n),
|
||||
Run: func(s *Server, args []string, stopCh <-chan struct{}) error {
|
||||
<-wait.NeverStop // this leaks obviously, but we don't care about one go routine more or less in test
|
||||
return nil
|
||||
},
|
||||
RespectsStopCh: false,
|
||||
}
|
||||
}
|
||||
func testStopChRespectingServerWithError(n string) *Server {
|
||||
return &Server{
|
||||
SimpleUsage: n,
|
||||
Long: fmt.Sprintf("A simple server named %s", n),
|
||||
Run: func(s *Server, args []string, stopCh <-chan struct{}) error {
|
||||
s.hk.Printf("%s Run\n", s.Name())
|
||||
<-stopCh
|
||||
return errors.New("server returning error")
|
||||
},
|
||||
RespectsStopCh: true,
|
||||
}
|
||||
}
|
||||
|
||||
const defaultCobraMessage = "default message from cobra command"
|
||||
const defaultCobraSubMessage = "default sub-message from cobra command"
|
||||
const cobraMessageDesc = "message to print"
|
||||
const cobraSubMessageDesc = "sub-message to print"
|
||||
|
||||
func testCobraCommand(n string) *Server {
|
||||
|
||||
var cobraServer *Server
|
||||
var msg string
|
||||
cmd := &cobra.Command{
|
||||
Use: n,
|
||||
Long: n,
|
||||
Short: n,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cobraServer.hk.Printf("msg: %s\n", msg)
|
||||
},
|
||||
}
|
||||
cmd.PersistentFlags().StringVar(&msg, "msg", defaultCobraMessage, cobraMessageDesc)
|
||||
|
||||
var subMsg string
|
||||
subCmdName := "subcommand"
|
||||
subCmd := &cobra.Command{
|
||||
Use: subCmdName,
|
||||
Long: subCmdName,
|
||||
Short: subCmdName,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cobraServer.hk.Printf("submsg: %s", subMsg)
|
||||
},
|
||||
}
|
||||
subCmd.PersistentFlags().StringVar(&subMsg, "submsg", defaultCobraSubMessage, cobraSubMessageDesc)
|
||||
|
||||
cmd.AddCommand(subCmd)
|
||||
|
||||
localFlags := cmd.LocalFlags()
|
||||
localFlags.SetInterspersed(false)
|
||||
s := &Server{
|
||||
SimpleUsage: n,
|
||||
Long: fmt.Sprintf("A server named %s which uses a cobra command", n),
|
||||
Run: func(s *Server, args []string, stopCh <-chan struct{}) error {
|
||||
cobraServer = s
|
||||
cmd.SetOutput(s.hk.Out())
|
||||
cmd.SetArgs(args)
|
||||
return cmd.Execute()
|
||||
},
|
||||
flags: localFlags,
|
||||
}
|
||||
|
||||
return s
|
||||
}
|
||||
func runFull(t *testing.T, args string, stopCh <-chan struct{}) *result {
|
||||
buf := new(bytes.Buffer)
|
||||
hk := HyperKube{
|
||||
Name: "hyperkube",
|
||||
Long: "hyperkube is an all-in-one server binary.",
|
||||
}
|
||||
hk.SetOut(buf)
|
||||
|
||||
hk.AddServer(testServer("test1"))
|
||||
hk.AddServer(testServer("test2"))
|
||||
hk.AddServer(testServer("test3"))
|
||||
hk.AddAlphaServer(testServer("testAlpha1"))
|
||||
hk.AddServer(testServerError("test-error"))
|
||||
hk.AddServer(testStopChIgnoringServer("test-stop-ch-ignoring"))
|
||||
hk.AddServer(testStopChRespectingServer("test-stop-ch-respecting"))
|
||||
hk.AddServer(testStopChRespectingServerWithError("test-error-stop-ch-respecting"))
|
||||
hk.AddServer(testCobraCommand("test-cobra-command"))
|
||||
|
||||
a := strings.Split(args, " ")
|
||||
t.Logf("Running full with args: %q", a)
|
||||
err := hk.Run(a, stopCh)
|
||||
|
||||
r := &result{err, buf.String()}
|
||||
t.Logf("Result err: %v, output: %q", r.err, r.output)
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
func TestRun(t *testing.T) {
|
||||
x := runFull(t, "hyperkube test1", wait.NeverStop)
|
||||
assert.Contains(t, x.output, "test1 Run")
|
||||
assert.NoError(t, x.err)
|
||||
}
|
||||
|
||||
func TestLinkRun(t *testing.T) {
|
||||
x := runFull(t, "test1", wait.NeverStop)
|
||||
assert.Contains(t, x.output, "test1 Run")
|
||||
assert.NoError(t, x.err)
|
||||
}
|
||||
|
||||
func TestTopNoArgs(t *testing.T) {
|
||||
x := runFull(t, "hyperkube", wait.NeverStop)
|
||||
assert.EqualError(t, x.err, "no server specified")
|
||||
}
|
||||
|
||||
func TestBadServer(t *testing.T) {
|
||||
x := runFull(t, "hyperkube bad-server", wait.NeverStop)
|
||||
assert.EqualError(t, x.err, "Server not found: bad-server")
|
||||
assert.Contains(t, x.output, "Usage")
|
||||
}
|
||||
|
||||
func TestTopHelp(t *testing.T) {
|
||||
x := runFull(t, "hyperkube --help", wait.NeverStop)
|
||||
assert.NoError(t, x.err)
|
||||
assert.Contains(t, x.output, "all-in-one")
|
||||
assert.Contains(t, x.output, "A simple server named test1")
|
||||
}
|
||||
|
||||
func TestTopFlags(t *testing.T) {
|
||||
x := runFull(t, "hyperkube --help test1", wait.NeverStop)
|
||||
assert.NoError(t, x.err)
|
||||
assert.Contains(t, x.output, "all-in-one")
|
||||
assert.Contains(t, x.output, "A simple server named test1")
|
||||
assert.NotContains(t, x.output, "test1 Run")
|
||||
}
|
||||
|
||||
func TestTopFlagsBad(t *testing.T) {
|
||||
x := runFull(t, "hyperkube --bad-flag", wait.NeverStop)
|
||||
assert.EqualError(t, x.err, "unknown flag: --bad-flag")
|
||||
assert.Contains(t, x.output, "all-in-one")
|
||||
assert.Contains(t, x.output, "A simple server named test1")
|
||||
}
|
||||
|
||||
func TestServerHelp(t *testing.T) {
|
||||
x := runFull(t, "hyperkube test1 --help", wait.NeverStop)
|
||||
assert.NoError(t, x.err)
|
||||
assert.Contains(t, x.output, "A simple server named test1")
|
||||
assert.Contains(t, x.output, "-h, --help")
|
||||
assert.Contains(t, x.output, "help for hyperkube")
|
||||
assert.NotContains(t, x.output, "test1 Run")
|
||||
}
|
||||
|
||||
func TestServerFlagsBad(t *testing.T) {
|
||||
x := runFull(t, "hyperkube test1 --bad-flag", wait.NeverStop)
|
||||
assert.EqualError(t, x.err, "unknown flag: --bad-flag")
|
||||
assert.Contains(t, x.output, "A simple server named test1")
|
||||
assert.Contains(t, x.output, "-h, --help")
|
||||
assert.Contains(t, x.output, "help for hyperkube")
|
||||
assert.NotContains(t, x.output, "test1 Run")
|
||||
}
|
||||
|
||||
func TestServerError(t *testing.T) {
|
||||
x := runFull(t, "hyperkube test-error", wait.NeverStop)
|
||||
assert.Contains(t, x.output, "test-error Run")
|
||||
assert.EqualError(t, x.err, "server returning error")
|
||||
}
|
||||
|
||||
func TestAlphaRun(t *testing.T) {
|
||||
x := runFull(t, "hyperkube alpha testAlpha1", wait.NeverStop)
|
||||
assert.NoError(t, x.err)
|
||||
}
|
||||
|
||||
func TestAlphaNoArgs(t *testing.T) {
|
||||
x := runFull(t, "hyperkube alpha", wait.NeverStop)
|
||||
assert.EqualError(t, x.err, "no alpha server specified")
|
||||
}
|
||||
|
||||
func TestAlphaBadServer(t *testing.T) {
|
||||
x := runFull(t, "hyperkube alpha bad-server", wait.NeverStop)
|
||||
assert.EqualError(t, x.err, "Server not found: bad-server")
|
||||
assert.Contains(t, x.output, "Usage")
|
||||
}
|
||||
|
||||
func TestStopChIgnoringServer(t *testing.T) {
|
||||
stopCh := make(chan struct{})
|
||||
returnedCh := make(chan struct{})
|
||||
var x *result
|
||||
go func() {
|
||||
defer close(returnedCh)
|
||||
x = runFull(t, "hyperkube test-stop-ch-ignoring", stopCh)
|
||||
}()
|
||||
close(stopCh)
|
||||
select {
|
||||
case <-time.After(wait.ForeverTestTimeout):
|
||||
t.Fatalf("%q never returned after stopCh was closed", "hyperkube test-stop-ch-ignoring")
|
||||
case <-returnedCh:
|
||||
}
|
||||
// we cannot be sure that the server had a chance to output anything
|
||||
// assert.Contains(t, x.output, "test-error-stop-ch-ignoring Run")
|
||||
assert.EqualError(t, x.err, "interrupted")
|
||||
}
|
||||
|
||||
func TestStopChRespectingServer(t *testing.T) {
|
||||
stopCh := make(chan struct{})
|
||||
returnedCh := make(chan struct{})
|
||||
var x *result
|
||||
go func() {
|
||||
defer close(returnedCh)
|
||||
x = runFull(t, "hyperkube test-stop-ch-respecting", stopCh)
|
||||
}()
|
||||
close(stopCh)
|
||||
select {
|
||||
case <-time.After(wait.ForeverTestTimeout):
|
||||
t.Fatalf("%q never returned after stopCh was closed", "hyperkube test-stop-ch-respecting")
|
||||
case <-returnedCh:
|
||||
}
|
||||
assert.Contains(t, x.output, "test-stop-ch-respecting Run")
|
||||
assert.Nil(t, x.err)
|
||||
}
|
||||
|
||||
func TestStopChRespectingServerWithError(t *testing.T) {
|
||||
stopCh := make(chan struct{})
|
||||
returnedCh := make(chan struct{})
|
||||
var x *result
|
||||
go func() {
|
||||
defer close(returnedCh)
|
||||
x = runFull(t, "hyperkube test-error-stop-ch-respecting", stopCh)
|
||||
}()
|
||||
close(stopCh)
|
||||
select {
|
||||
case <-time.After(wait.ForeverTestTimeout):
|
||||
t.Fatalf("%q never returned after stopCh was closed", "hyperkube test-error-stop-ch-respecting")
|
||||
case <-returnedCh:
|
||||
}
|
||||
assert.Contains(t, x.output, "test-error-stop-ch-respecting Run")
|
||||
assert.EqualError(t, x.err, "server returning error")
|
||||
}
|
||||
|
||||
func TestCobraCommandHelp(t *testing.T) {
|
||||
x := runFull(t, "hyperkube test-cobra-command --help", wait.NeverStop)
|
||||
assert.NoError(t, x.err)
|
||||
assert.Contains(t, x.output, "A server named test-cobra-command which uses a cobra command")
|
||||
assert.Contains(t, x.output, cobraMessageDesc)
|
||||
}
|
||||
func TestCobraCommandDefaultMessage(t *testing.T) {
|
||||
x := runFull(t, "hyperkube test-cobra-command", wait.NeverStop)
|
||||
assert.Contains(t, x.output, fmt.Sprintf("msg: %s", defaultCobraMessage))
|
||||
}
|
||||
func TestCobraCommandMessage(t *testing.T) {
|
||||
x := runFull(t, "hyperkube test-cobra-command --msg foobar", wait.NeverStop)
|
||||
assert.Contains(t, x.output, "msg: foobar")
|
||||
}
|
||||
|
||||
func TestCobraSubCommandHelp(t *testing.T) {
|
||||
x := runFull(t, "hyperkube test-cobra-command subcommand --help", wait.NeverStop)
|
||||
assert.NoError(t, x.err)
|
||||
assert.Contains(t, x.output, cobraSubMessageDesc)
|
||||
}
|
||||
func TestCobraSubCommandDefaultMessage(t *testing.T) {
|
||||
x := runFull(t, "hyperkube test-cobra-command subcommand", wait.NeverStop)
|
||||
assert.Contains(t, x.output, fmt.Sprintf("submsg: %s", defaultCobraSubMessage))
|
||||
}
|
||||
func TestCobraSubCommandMessage(t *testing.T) {
|
||||
x := runFull(t, "hyperkube test-cobra-command subcommand --submsg foobar", wait.NeverStop)
|
||||
assert.Contains(t, x.output, "submsg: foobar")
|
||||
}
|
52
vendor/k8s.io/kubernetes/cmd/hyperkube/kube-aggregator.go
generated
vendored
Normal file
52
vendor/k8s.io/kubernetes/cmd/hyperkube/kube-aggregator.go
generated
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
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 main
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"k8s.io/kube-aggregator/pkg/cmd/server"
|
||||
)
|
||||
|
||||
// NewKubeAggregator creates a new hyperkube Server object that includes the
|
||||
// description and flags.
|
||||
func NewKubeAggregator() *Server {
|
||||
o := server.NewDefaultOptions(os.Stdout, os.Stderr)
|
||||
|
||||
hks := Server{
|
||||
name: "aggregator",
|
||||
AlternativeName: "kube-aggregator",
|
||||
SimpleUsage: "aggregator",
|
||||
Long: "Aggregator for Kubernetes-style API servers: dynamic registration, discovery summarization, secure proxy.",
|
||||
Run: func(_ *Server, args []string, stopCh <-chan struct{}) error {
|
||||
if err := o.Complete(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := o.Validate(args); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := o.RunAggregator(stopCh); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
},
|
||||
RespectsStopCh: true,
|
||||
}
|
||||
|
||||
o.AddFlags(hks.Flags())
|
||||
return &hks
|
||||
}
|
41
vendor/k8s.io/kubernetes/cmd/hyperkube/kube-apiserver.go
generated
vendored
Normal file
41
vendor/k8s.io/kubernetes/cmd/hyperkube/kube-apiserver.go
generated
vendored
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
Copyright 2015 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 main
|
||||
|
||||
import (
|
||||
"k8s.io/kubernetes/cmd/kube-apiserver/app"
|
||||
"k8s.io/kubernetes/cmd/kube-apiserver/app/options"
|
||||
)
|
||||
|
||||
// NewKubeAPIServer creates a new hyperkube Server object that includes the
|
||||
// description and flags.
|
||||
func NewKubeAPIServer() *Server {
|
||||
s := options.NewServerRunOptions()
|
||||
|
||||
hks := Server{
|
||||
name: "apiserver",
|
||||
AlternativeName: "kube-apiserver",
|
||||
SimpleUsage: "apiserver",
|
||||
Long: "The main API entrypoint and interface to the storage system. The API server is also the focal point for all authorization decisions.",
|
||||
Run: func(_ *Server, args []string, stopCh <-chan struct{}) error {
|
||||
return app.Run(s, stopCh)
|
||||
},
|
||||
RespectsStopCh: true,
|
||||
}
|
||||
s.AddFlags(hks.Flags())
|
||||
return &hks
|
||||
}
|
40
vendor/k8s.io/kubernetes/cmd/hyperkube/kube-controller-manager.go
generated
vendored
Normal file
40
vendor/k8s.io/kubernetes/cmd/hyperkube/kube-controller-manager.go
generated
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
Copyright 2015 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 main
|
||||
|
||||
import (
|
||||
"k8s.io/kubernetes/cmd/kube-controller-manager/app"
|
||||
"k8s.io/kubernetes/cmd/kube-controller-manager/app/options"
|
||||
)
|
||||
|
||||
// NewKubeControllerManager creates a new hyperkube Server object that includes the
|
||||
// description and flags.
|
||||
func NewKubeControllerManager() *Server {
|
||||
s := options.NewCMServer()
|
||||
|
||||
hks := Server{
|
||||
name: "controller-manager",
|
||||
AlternativeName: "kube-controller-manager",
|
||||
SimpleUsage: "controller-manager",
|
||||
Long: "A server that runs a set of active components. This includes replication controllers, service endpoints and nodes.",
|
||||
Run: func(_ *Server, args []string, stopCh <-chan struct{}) error {
|
||||
return app.Run(s)
|
||||
},
|
||||
}
|
||||
s.AddFlags(hks.Flags(), app.KnownControllers(), app.ControllersDisabledByDefault.List())
|
||||
return &hks
|
||||
}
|
54
vendor/k8s.io/kubernetes/cmd/hyperkube/kube-proxy.go
generated
vendored
Normal file
54
vendor/k8s.io/kubernetes/cmd/hyperkube/kube-proxy.go
generated
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
Copyright 2015 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 main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
|
||||
"k8s.io/apiserver/pkg/server/healthz"
|
||||
"k8s.io/kubernetes/cmd/kube-proxy/app"
|
||||
)
|
||||
|
||||
// NewKubeProxy creates a new hyperkube Server object that includes the
|
||||
// description and flags.
|
||||
func NewKubeProxy() *Server {
|
||||
healthz.DefaultHealthz()
|
||||
|
||||
command := app.NewProxyCommand()
|
||||
|
||||
hks := Server{
|
||||
name: "proxy",
|
||||
AlternativeName: "kube-proxy",
|
||||
SimpleUsage: "proxy",
|
||||
Long: command.Long,
|
||||
}
|
||||
|
||||
serverFlags := hks.Flags()
|
||||
serverFlags.AddFlagSet(command.Flags())
|
||||
|
||||
// FIXME this is here because hyperkube does its own flag parsing, and we need
|
||||
// the command to know about the go flag set. Remove this once hyperkube is
|
||||
// refactored to use cobra throughout.
|
||||
command.Flags().AddGoFlagSet(flag.CommandLine)
|
||||
|
||||
hks.Run = func(_ *Server, args []string, stopCh <-chan struct{}) error {
|
||||
command.SetArgs(args)
|
||||
return command.Execute()
|
||||
}
|
||||
|
||||
return &hks
|
||||
}
|
54
vendor/k8s.io/kubernetes/cmd/hyperkube/kube-scheduler.go
generated
vendored
Normal file
54
vendor/k8s.io/kubernetes/cmd/hyperkube/kube-scheduler.go
generated
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
Copyright 2015 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 main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
|
||||
"k8s.io/apiserver/pkg/server/healthz"
|
||||
"k8s.io/kubernetes/plugin/cmd/kube-scheduler/app"
|
||||
)
|
||||
|
||||
// NewScheduler creates a new hyperkube Server object that includes the
|
||||
// description and flags.
|
||||
func NewScheduler() *Server {
|
||||
healthz.DefaultHealthz()
|
||||
|
||||
command := app.NewSchedulerCommand()
|
||||
|
||||
hks := Server{
|
||||
name: "scheduler",
|
||||
AlternativeName: "kube-scheduler",
|
||||
SimpleUsage: "scheduler",
|
||||
Long: command.Long,
|
||||
}
|
||||
|
||||
serverFlags := hks.Flags()
|
||||
serverFlags.AddFlagSet(command.Flags())
|
||||
|
||||
// FIXME this is here because hyperkube does its own flag parsing, and we need
|
||||
// the command to know about the go flag set. Remove this once hyperkube is
|
||||
// refactored to use cobra throughout.
|
||||
command.Flags().AddGoFlagSet(flag.CommandLine)
|
||||
|
||||
hks.Run = func(_ *Server, args []string, stopCh <-chan struct{}) error {
|
||||
command.SetArgs(args)
|
||||
return command.Execute()
|
||||
}
|
||||
|
||||
return &hks
|
||||
}
|
42
vendor/k8s.io/kubernetes/cmd/hyperkube/kubectl.go
generated
vendored
Normal file
42
vendor/k8s.io/kubernetes/cmd/hyperkube/kubectl.go
generated
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
Copyright 2015 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 main
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd"
|
||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||
)
|
||||
|
||||
// Create a Server that implements the kubectl command
|
||||
func NewKubectlServer() *Server {
|
||||
cmd := cmd.NewKubectlCommand(cmdutil.NewFactory(nil), os.Stdin, os.Stdout, os.Stderr)
|
||||
localFlags := cmd.LocalFlags()
|
||||
localFlags.SetInterspersed(false)
|
||||
|
||||
return &Server{
|
||||
name: "kubectl",
|
||||
SimpleUsage: "Kubernetes command line client",
|
||||
Long: "Kubernetes command line client",
|
||||
Run: func(s *Server, args []string, stopCh <-chan struct{}) error {
|
||||
cmd.SetArgs(args)
|
||||
return cmd.Execute()
|
||||
},
|
||||
flags: localFlags,
|
||||
}
|
||||
}
|
50
vendor/k8s.io/kubernetes/cmd/hyperkube/kubelet.go
generated
vendored
Normal file
50
vendor/k8s.io/kubernetes/cmd/hyperkube/kubelet.go
generated
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
Copyright 2015 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 main
|
||||
|
||||
import (
|
||||
"k8s.io/kubernetes/cmd/kubelet/app"
|
||||
"k8s.io/kubernetes/cmd/kubelet/app/options"
|
||||
)
|
||||
|
||||
// NewKubelet creates a new hyperkube Server object that includes the
|
||||
// description and flags.
|
||||
func NewKubelet() (*Server, error) {
|
||||
s, err := options.NewKubeletServer()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
hks := Server{
|
||||
name: "kubelet",
|
||||
SimpleUsage: "kubelet",
|
||||
Long: `The kubelet binary is responsible for maintaining a set of containers on a
|
||||
particular node. It syncs data from a variety of sources including a
|
||||
Kubernetes API server, an etcd cluster, HTTP endpoint or local file. It then
|
||||
queries Docker to see what is currently running. It synchronizes the
|
||||
configuration data, with the running set of containers by starting or stopping
|
||||
Docker containers.`,
|
||||
Run: func(_ *Server, _ []string, stopCh <-chan struct{}) error {
|
||||
if s.ExperimentalDockershim {
|
||||
return app.RunDockershim(&s.KubeletFlags, &s.KubeletConfiguration)
|
||||
}
|
||||
return app.Run(s, nil)
|
||||
},
|
||||
}
|
||||
s.AddFlags(hks.Flags())
|
||||
return &hks, nil
|
||||
}
|
53
vendor/k8s.io/kubernetes/cmd/hyperkube/main.go
generated
vendored
Normal file
53
vendor/k8s.io/kubernetes/cmd/hyperkube/main.go
generated
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
// A binary that can morph into all of the other kubernetes binaries. You can
|
||||
// also soft-link to it busybox style.
|
||||
//
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
_ "k8s.io/kubernetes/pkg/client/metrics/prometheus" // for client metric registration
|
||||
_ "k8s.io/kubernetes/pkg/version/prometheus" // for version metric registration
|
||||
)
|
||||
|
||||
func main() {
|
||||
hk := HyperKube{
|
||||
Name: "hyperkube",
|
||||
Long: "This is an all-in-one binary that can run any of the various Kubernetes servers.",
|
||||
}
|
||||
|
||||
hk.AddServer(NewKubectlServer())
|
||||
hk.AddServer(NewKubeAPIServer())
|
||||
hk.AddServer(NewKubeControllerManager())
|
||||
hk.AddServer(NewScheduler())
|
||||
if kubelet, err := NewKubelet(); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error: %v\n", err)
|
||||
os.Exit(1)
|
||||
} else {
|
||||
hk.AddServer(kubelet)
|
||||
}
|
||||
hk.AddServer(NewKubeProxy())
|
||||
hk.AddServer(NewKubeAggregator())
|
||||
|
||||
// Alpha servers
|
||||
hk.AddAlphaServer(NewCloudControllerManager())
|
||||
|
||||
hk.RunToExit(os.Args)
|
||||
}
|
77
vendor/k8s.io/kubernetes/cmd/hyperkube/server.go
generated
vendored
Normal file
77
vendor/k8s.io/kubernetes/cmd/hyperkube/server.go
generated
vendored
Normal file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
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 main
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
|
||||
"k8s.io/apiserver/pkg/util/flag"
|
||||
utiltemplate "k8s.io/kubernetes/pkg/util/template"
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
type serverRunFunc func(s *Server, args []string, stopCh <-chan struct{}) error
|
||||
|
||||
// Server describes a server that this binary can morph into.
|
||||
type Server struct {
|
||||
SimpleUsage string // One line description of the server.
|
||||
Long string // Longer free form description of the server
|
||||
Run serverRunFunc // Run the server. This is not expected to return.
|
||||
AlternativeName string
|
||||
RespectsStopCh bool
|
||||
|
||||
flags *pflag.FlagSet // Flags for the command (and all dependents)
|
||||
name string
|
||||
hk *HyperKube
|
||||
}
|
||||
|
||||
// Usage returns the full usage string including all of the flags.
|
||||
func (s *Server) Usage() error {
|
||||
tt := `{{if .Long}}{{.Long | trim | wrap ""}}
|
||||
{{end}}Usage:
|
||||
{{.SimpleUsage}} [flags]
|
||||
|
||||
Available Flags:
|
||||
{{.Flags.FlagUsages}}`
|
||||
|
||||
return utiltemplate.ExecuteTemplate(s.hk.Out(), tt, s)
|
||||
}
|
||||
|
||||
// Name returns the name of the command as derived from the usage line.
|
||||
func (s *Server) Name() string {
|
||||
if s.name != "" {
|
||||
return s.name
|
||||
}
|
||||
name := s.SimpleUsage
|
||||
i := strings.Index(name, " ")
|
||||
if i >= 0 {
|
||||
name = name[:i]
|
||||
}
|
||||
return name
|
||||
}
|
||||
|
||||
// Flags returns a flagset for this server
|
||||
func (s *Server) Flags() *pflag.FlagSet {
|
||||
if s.flags == nil {
|
||||
s.flags = pflag.NewFlagSet(s.Name(), pflag.ContinueOnError)
|
||||
s.flags.SetOutput(ioutil.Discard)
|
||||
s.flags.SetNormalizeFunc(flag.WordSepNormalizeFunc)
|
||||
}
|
||||
return s.flags
|
||||
}
|
33
vendor/k8s.io/kubernetes/cmd/importverifier/BUILD
generated
vendored
Normal file
33
vendor/k8s.io/kubernetes/cmd/importverifier/BUILD
generated
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_binary",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_binary(
|
||||
name = "importverifier",
|
||||
importpath = "k8s.io/kubernetes/cmd/importverifier",
|
||||
library = ":go_default_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["importverifier.go"],
|
||||
importpath = "k8s.io/kubernetes/cmd/importverifier",
|
||||
deps = ["//vendor/gopkg.in/yaml.v2:go_default_library"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
8
vendor/k8s.io/kubernetes/cmd/importverifier/OWNERS
generated
vendored
Normal file
8
vendor/k8s.io/kubernetes/cmd/importverifier/OWNERS
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
reviewers:
|
||||
- stevekuznetsov
|
||||
- deads2k
|
||||
- sttts
|
||||
approvers:
|
||||
- stevekuznetsov
|
||||
- deads2k
|
||||
- sttts
|
272
vendor/k8s.io/kubernetes/cmd/importverifier/importverifier.go
generated
vendored
Normal file
272
vendor/k8s.io/kubernetes/cmd/importverifier/importverifier.go
generated
vendored
Normal file
@ -0,0 +1,272 @@
|
||||
/*
|
||||
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 main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
// Package is a subset of cmd/go.Package
|
||||
type Package struct {
|
||||
Dir string `yaml:",omitempty"` // directory containing package sources
|
||||
ImportPath string `yaml:",omitempty"` // import path of package in dir
|
||||
Imports []string `yaml:",omitempty"` // import paths used by this package
|
||||
TestImports []string `yaml:",omitempty"` // imports from TestGoFiles
|
||||
XTestImports []string `yaml:",omitempty"` // imports from XTestGoFiles
|
||||
}
|
||||
|
||||
// ImportRestriction describes a set of allowable import
|
||||
// trees for a tree of source code
|
||||
type ImportRestriction struct {
|
||||
// BaseDir is the root of the package tree that is
|
||||
// restricted by this configuration, given as a
|
||||
// relative path from the root of the repository
|
||||
BaseDir string `yaml:"baseImportPath"`
|
||||
// IgnoredSubTrees are roots of sub-trees of the
|
||||
// BaseDir for which we do not want to enforce
|
||||
// any import restrictions whatsoever, given as
|
||||
// relative paths from the root of the repository
|
||||
IgnoredSubTrees []string `yaml:"ignoredSubTrees,omitempty"`
|
||||
// AllowedImports are roots of package trees that
|
||||
// are allowed to be imported from the BaseDir,
|
||||
// given as paths that would be used in a Go
|
||||
// import statement
|
||||
AllowedImports []string `yaml:"allowedImports"`
|
||||
}
|
||||
|
||||
// ForbiddenImportsFor determines all of the forbidden
|
||||
// imports for a package given the import restrictions
|
||||
func (i *ImportRestriction) ForbiddenImportsFor(pkg Package) ([]string, error) {
|
||||
if restricted, err := i.isRestrictedDir(pkg.Dir); err != nil {
|
||||
return []string{}, err
|
||||
} else if !restricted {
|
||||
return []string{}, nil
|
||||
}
|
||||
|
||||
return i.forbiddenImportsFor(pkg), nil
|
||||
}
|
||||
|
||||
// isRestrictedDir determines if the source directory has
|
||||
// any restrictions placed on it by this configuration.
|
||||
// A path will be restricted if:
|
||||
// - it falls under the base import path
|
||||
// - it does not fall under any of the ignored sub-trees
|
||||
func (i *ImportRestriction) isRestrictedDir(dir string) (bool, error) {
|
||||
if under, err := isPathUnder(i.BaseDir, dir); err != nil {
|
||||
return false, err
|
||||
} else if !under {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
for _, ignored := range i.IgnoredSubTrees {
|
||||
if under, err := isPathUnder(ignored, dir); err != nil {
|
||||
return false, err
|
||||
} else if under {
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// isPathUnder determines if path is under base
|
||||
func isPathUnder(base, path string) (bool, error) {
|
||||
absBase, err := filepath.Abs(base)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
absPath, err := filepath.Abs(path)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
relPath, err := filepath.Rel(absBase, absPath)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
// if path is below base, the relative path
|
||||
// from base to path will not start with `../`
|
||||
return !strings.HasPrefix(relPath, ".."), nil
|
||||
}
|
||||
|
||||
// forbiddenImportsFor determines all of the forbidden
|
||||
// imports for a package given the import restrictions
|
||||
// and returns a deduplicated list of them
|
||||
func (i *ImportRestriction) forbiddenImportsFor(pkg Package) []string {
|
||||
forbiddenImportSet := map[string]struct{}{}
|
||||
for _, imp := range append(pkg.Imports, append(pkg.TestImports, pkg.XTestImports...)...) {
|
||||
path := extractVendorPath(imp)
|
||||
if i.isForbidden(path) {
|
||||
forbiddenImportSet[path] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
var forbiddenImports []string
|
||||
for imp := range forbiddenImportSet {
|
||||
forbiddenImports = append(forbiddenImports, imp)
|
||||
}
|
||||
return forbiddenImports
|
||||
}
|
||||
|
||||
// extractVendorPath removes a vendor prefix if one exists
|
||||
func extractVendorPath(path string) string {
|
||||
vendorPath := "/vendor/"
|
||||
if !strings.Contains(path, vendorPath) {
|
||||
return path
|
||||
}
|
||||
|
||||
return path[strings.Index(path, vendorPath)+len(vendorPath):]
|
||||
}
|
||||
|
||||
// isForbidden determines if an import is forbidden,
|
||||
// which is true when the import is:
|
||||
// - of a package under the rootPackage
|
||||
// - is not of the base import path or a sub-package of it
|
||||
// - is not of an allowed path or a sub-package of one
|
||||
func (i *ImportRestriction) isForbidden(imp string) bool {
|
||||
importsBelowRoot := strings.HasPrefix(imp, rootPackage)
|
||||
importsBelowBase := strings.HasPrefix(imp, i.BaseDir)
|
||||
importsAllowed := false
|
||||
for _, allowed := range i.AllowedImports {
|
||||
exactlyImportsAllowed := imp == allowed
|
||||
importsBelowAllowed := strings.HasPrefix(imp, fmt.Sprintf("%s/", allowed))
|
||||
importsAllowed = importsAllowed || (importsBelowAllowed || exactlyImportsAllowed)
|
||||
}
|
||||
|
||||
return importsBelowRoot && !importsBelowBase && !importsAllowed
|
||||
}
|
||||
|
||||
var rootPackage string
|
||||
|
||||
func main() {
|
||||
if len(os.Args) != 3 {
|
||||
log.Fatalf("Usage: %s ROOT RESTRICTIONS.yaml", os.Args[0])
|
||||
}
|
||||
|
||||
rootPackage = os.Args[1]
|
||||
configFile := os.Args[2]
|
||||
importRestrictions, err := loadImportRestrictions(configFile)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to load import restrictions: %v", err)
|
||||
}
|
||||
|
||||
foundForbiddenImports := false
|
||||
for _, restriction := range importRestrictions {
|
||||
log.Printf("Inspecting imports under %s...\n", restriction.BaseDir)
|
||||
packages, err := resolvePackageTree(restriction.BaseDir)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to resolve package tree: %v", err)
|
||||
} else if len(packages) == 0 {
|
||||
log.Fatalf("Found no packages under tree %s", restriction.BaseDir)
|
||||
}
|
||||
|
||||
log.Printf("- validating imports for %d packages in the tree", len(packages))
|
||||
restrictionViolated := false
|
||||
for _, pkg := range packages {
|
||||
if forbidden, err := restriction.ForbiddenImportsFor(pkg); err != nil {
|
||||
log.Fatalf("-- failed to validate imports: %v", err)
|
||||
} else if len(forbidden) != 0 {
|
||||
logForbiddenPackages(pkg.ImportPath, forbidden)
|
||||
restrictionViolated = true
|
||||
}
|
||||
}
|
||||
if restrictionViolated {
|
||||
foundForbiddenImports = true
|
||||
log.Println("- FAIL")
|
||||
} else {
|
||||
log.Println("- OK")
|
||||
}
|
||||
}
|
||||
|
||||
if foundForbiddenImports {
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func loadImportRestrictions(configFile string) ([]ImportRestriction, error) {
|
||||
config, err := ioutil.ReadFile(configFile)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to load configuration from %s: %v", configFile, err)
|
||||
}
|
||||
|
||||
var importRestrictions []ImportRestriction
|
||||
if err := yaml.Unmarshal(config, &importRestrictions); err != nil {
|
||||
return nil, fmt.Errorf("failed to unmarshal from %s: %v", configFile, err)
|
||||
}
|
||||
|
||||
return importRestrictions, nil
|
||||
}
|
||||
|
||||
func resolvePackageTree(treeBase string) ([]Package, error) {
|
||||
cmd := "go"
|
||||
args := []string{"list", "-json", fmt.Sprintf("%s...", treeBase)}
|
||||
stdout, err := exec.Command(cmd, args...).Output()
|
||||
if err != nil {
|
||||
var message string
|
||||
if ee, ok := err.(*exec.ExitError); ok {
|
||||
message = fmt.Sprintf("%v\n%v", ee, ee.Stderr)
|
||||
} else {
|
||||
message = fmt.Sprintf("%v", err)
|
||||
}
|
||||
return nil, fmt.Errorf("failed to run `%s %s`: %v", cmd, strings.Join(args, " "), message)
|
||||
}
|
||||
|
||||
packages, err := decodePackages(bytes.NewReader(stdout))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to decode packages: %v", err)
|
||||
}
|
||||
|
||||
return packages, nil
|
||||
}
|
||||
|
||||
func decodePackages(r io.Reader) ([]Package, error) {
|
||||
// `go list -json` concatenates package definitions
|
||||
// instead of emitting a single valid JSON, so we
|
||||
// need to stream the output to decode it into the
|
||||
// data we are looking for instead of just using a
|
||||
// simple JSON decoder on stdout
|
||||
var packages []Package
|
||||
decoder := json.NewDecoder(r)
|
||||
for decoder.More() {
|
||||
var pkg Package
|
||||
if err := decoder.Decode(&pkg); err != nil {
|
||||
return nil, fmt.Errorf("invalid package: %v", err)
|
||||
}
|
||||
packages = append(packages, pkg)
|
||||
}
|
||||
|
||||
return packages, nil
|
||||
}
|
||||
|
||||
func logForbiddenPackages(base string, forbidden []string) {
|
||||
log.Printf("-- found forbidden imports for %s:\n", base)
|
||||
for _, forbiddenPackage := range forbidden {
|
||||
log.Printf("--- %s\n", forbiddenPackage)
|
||||
}
|
||||
}
|
54
vendor/k8s.io/kubernetes/cmd/kube-apiserver/BUILD
generated
vendored
Normal file
54
vendor/k8s.io/kubernetes/cmd/kube-apiserver/BUILD
generated
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
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",
|
||||
],
|
||||
importpath = "k8s.io/kubernetes/cmd/kube-apiserver",
|
||||
library = ":go_default_library",
|
||||
x_defs = version_x_defs(),
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["apiserver.go"],
|
||||
importpath = "k8s.io/kubernetes/cmd/kube-apiserver",
|
||||
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)
|
||||
}
|
||||
}
|
105
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/BUILD
generated
vendored
Normal file
105
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/BUILD
generated
vendored
Normal file
@ -0,0 +1,105 @@
|
||||
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/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/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/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/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/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/rest: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"],
|
||||
)
|
263
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/aggregator.go
generated
vendored
Normal file
263
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/aggregator.go
generated
vendored
Normal file
@ -0,0 +1,263 @@
|
||||
/*
|
||||
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)
|
||||
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: 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: "v1beta1"}: {group: 16700, version: 12},
|
||||
{Group: "admissionregistration.k8s.io", Version: "v1alpha1"}: {group: 16700, version: 9},
|
||||
{Group: "scheduling.k8s.io", Version: "v1alpha1"}: {group: 16600, 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
|
||||
}
|
62
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/apiextensions.go
generated
vendored
Normal file
62
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/apiextensions.go
generated
vendored
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
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)
|
||||
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
|
||||
}
|
93
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/options/BUILD
generated
vendored
Normal file
93
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/options/BUILD
generated
vendored
Normal file
@ -0,0 +1,93 @@
|
||||
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",
|
||||
],
|
||||
importpath = "k8s.io/kubernetes/cmd/kube-apiserver/app/options",
|
||||
deps = [
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/apis/core/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",
|
||||
"//pkg/master/reconcilers: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/extendedresourcetoleration:go_default_library",
|
||||
"//plugin/pkg/admission/gc:go_default_library",
|
||||
"//plugin/pkg/admission/imagepolicy: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/persistentvolumeclaim/pvcprotection: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",
|
||||
"//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"],
|
||||
importpath = "k8s.io/kubernetes/cmd/kube-apiserver/app/options",
|
||||
library = ":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/webhook: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"],
|
||||
)
|
239
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/options/options.go
generated
vendored
Normal file
239
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/options/options.go
generated
vendored
Normal file
@ -0,0 +1,239 @@
|
||||
/*
|
||||
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"
|
||||
"k8s.io/kubernetes/pkg/apis/core/validation"
|
||||
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.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
|
||||
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
|
||||
}
|
||||
|
||||
// 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: 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,
|
||||
EndpointReconcilerType: string(reconcilers.MasterCountReconcilerType),
|
||||
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,
|
||||
}
|
||||
// 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.")
|
||||
|
||||
// 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.")
|
||||
|
||||
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 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.")
|
||||
|
||||
}
|
248
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/options/options_test.go
generated
vendored
Normal file
248
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/options/options_test.go
generated
vendored
Normal file
@ -0,0 +1,248 @@
|
||||
/*
|
||||
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"
|
||||
auditwebhook "k8s.io/apiserver/plugin/pkg/audit/webhook"
|
||||
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{
|
||||
"--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",
|
||||
"--audit-webhook-batch-buffer-size=42",
|
||||
"--audit-webhook-batch-max-size=43",
|
||||
"--audit-webhook-batch-max-wait=1s",
|
||||
"--audit-webhook-batch-throttle-qps=43.5",
|
||||
"--audit-webhook-batch-throttle-burst=44",
|
||||
"--audit-webhook-batch-initial-backoff=2s",
|
||||
"--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",
|
||||
"--endpoint-reconciler-type=" + string(reconcilers.MasterCountReconcilerType),
|
||||
"--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: kubeoptions.DefaultServiceNodePortRange,
|
||||
MasterCount: 5,
|
||||
EndpointReconcilerType: string(reconcilers.MasterCountReconcilerType),
|
||||
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{
|
||||
RecommendedPluginOrder: []string{"NamespaceLifecycle", "Initializers", "MutatingAdmissionWebhook", "ValidatingAdmissionWebhook"},
|
||||
DefaultOffPlugins: []string{"Initializers", "MutatingAdmissionWebhook", "ValidatingAdmissionWebhook"},
|
||||
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,
|
||||
Quorum: false,
|
||||
KeyFile: "/var/run/kubernetes/etcd.key",
|
||||
CAFile: "/var/run/kubernetes/etcdca.crt",
|
||||
CertFile: "/var/run/kubernetes/etcdce.crt",
|
||||
CompactionInterval: storagebackend.DefaultCompactInterval,
|
||||
},
|
||||
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",
|
||||
BatchConfig: auditwebhook.BatchBackendConfig{
|
||||
BufferSize: 42,
|
||||
MaxBatchSize: 43,
|
||||
MaxBatchWait: 1 * time.Second,
|
||||
ThrottleQPS: 43.5,
|
||||
ThrottleBurst: 44,
|
||||
InitialBackoff: 2 * time.Second,
|
||||
},
|
||||
},
|
||||
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: legacyscheme.Registry.AllPreferredGroupVersions(),
|
||||
DefaultStorageVersions: legacyscheme.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/extendedresourcetoleration"
|
||||
"k8s.io/kubernetes/plugin/pkg/admission/gc"
|
||||
"k8s.io/kubernetes/plugin/pkg/admission/imagepolicy"
|
||||
"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/persistentvolumeclaim/pvcprotection"
|
||||
"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"
|
||||
)
|
||||
|
||||
// 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)
|
||||
extendedresourcetoleration.Register(plugins)
|
||||
gc.Register(plugins)
|
||||
imagepolicy.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)
|
||||
resize.Register(plugins)
|
||||
pvcprotection.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
|
||||
}
|
1037
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/server.go
generated
vendored
Normal file
1037
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"],
|
||||
)
|
165
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/testing/testserver.go
generated
vendored
Normal file
165
vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/testing/testserver.go
generated
vendored
Normal file
@ -0,0 +1,165 @@
|
||||
/*
|
||||
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"
|
||||
"testing"
|
||||
"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()
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// 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 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, customFlags []string, storageConfig *storagebackend.Config) (result TestServer, err error) {
|
||||
|
||||
// TODO : Remove TrackStorageCleanup below when PR
|
||||
// https://github.com/kubernetes/kubernetes/pull/50690
|
||||
// merges as that shuts down storage properly
|
||||
registry.TrackStorageCleanup()
|
||||
|
||||
stopCh := make(chan struct{})
|
||||
tearDown := func() {
|
||||
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)
|
||||
|
||||
t.Logf("Starting kube-apiserver on port %d...", s.SecureServing.BindPort)
|
||||
server, err := app.CreateServerChain(s, 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 *testing.T, flags []string, storageConfig *storagebackend.Config) *TestServer {
|
||||
|
||||
result, err := StartTestServer(t, 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
|
||||
}
|
55
vendor/k8s.io/kubernetes/cmd/kube-controller-manager/BUILD
generated
vendored
Normal file
55
vendor/k8s.io/kubernetes/cmd/kube-controller-manager/BUILD
generated
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
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-controller-manager",
|
||||
gc_linkopts = [
|
||||
"-linkmode",
|
||||
"external",
|
||||
"-extldflags",
|
||||
"-static",
|
||||
],
|
||||
importpath = "k8s.io/kubernetes/cmd/kube-controller-manager",
|
||||
library = ":go_default_library",
|
||||
x_defs = version_x_defs(),
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["controller-manager.go"],
|
||||
importpath = "k8s.io/kubernetes/cmd/kube-controller-manager",
|
||||
deps = [
|
||||
"//cmd/kube-controller-manager/app:go_default_library",
|
||||
"//cmd/kube-controller-manager/app/options:go_default_library",
|
||||
"//pkg/client/metrics/prometheus:go_default_library",
|
||||
"//pkg/util/reflector/prometheus:go_default_library",
|
||||
"//pkg/util/workqueue/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/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-controller-manager/app:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
)
|
65
vendor/k8s.io/kubernetes/cmd/kube-controller-manager/OWNERS
generated
vendored
Normal file
65
vendor/k8s.io/kubernetes/cmd/kube-controller-manager/OWNERS
generated
vendored
Normal file
@ -0,0 +1,65 @@
|
||||
approvers:
|
||||
- deads2k
|
||||
- lavalamp
|
||||
- mikedanese
|
||||
reviewers:
|
||||
- '249043822'
|
||||
- a-robinson
|
||||
- brendandburns
|
||||
- caesarxuchao
|
||||
- cjcullen
|
||||
- dalanlan
|
||||
- david-mcmahon
|
||||
- davidopp
|
||||
- ddysher
|
||||
- deads2k
|
||||
- derekwaynecarr
|
||||
- eparis
|
||||
- erictune
|
||||
- errordeveloper
|
||||
- feiskyer
|
||||
- fgrzadkowski
|
||||
- ghodss
|
||||
- girishkalele
|
||||
- gmarek
|
||||
- goltermann
|
||||
- humblec
|
||||
- ingvagabund
|
||||
- janetkuo
|
||||
- jayunit100
|
||||
- jbeda
|
||||
- jdef
|
||||
- jlowdermilk
|
||||
- johscheuer
|
||||
- jsafrane
|
||||
- jszczepkowski
|
||||
- justinsb
|
||||
- lavalamp
|
||||
- liggitt
|
||||
- luxas
|
||||
- madhusudancs
|
||||
- markturansky
|
||||
- mfanjie
|
||||
- mikedanese
|
||||
- mml
|
||||
- mqliang
|
||||
- mwielgus
|
||||
- nikhiljindal
|
||||
- ping035627
|
||||
- piosz
|
||||
- pmorie
|
||||
- quinton-hoole
|
||||
- resouer
|
||||
- roberthbailey
|
||||
- rootfs
|
||||
- rrati
|
||||
- saad-ali
|
||||
- screeley44
|
||||
- sjenning
|
||||
- smarterclayton
|
||||
- soltysh
|
||||
- spiffxp
|
||||
- sttts
|
||||
- thockin
|
||||
- timothysc
|
||||
- wojtek-t
|
162
vendor/k8s.io/kubernetes/cmd/kube-controller-manager/app/BUILD
generated
vendored
Normal file
162
vendor/k8s.io/kubernetes/cmd/kube-controller-manager/app/BUILD
generated
vendored
Normal file
@ -0,0 +1,162 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"apps.go",
|
||||
"autoscaling.go",
|
||||
"batch.go",
|
||||
"bootstrap.go",
|
||||
"certificates.go",
|
||||
"controllermanager.go",
|
||||
"core.go",
|
||||
"extensions.go",
|
||||
"import_known_versions.go",
|
||||
"plugins.go",
|
||||
"policy.go",
|
||||
"rbac.go",
|
||||
],
|
||||
importpath = "k8s.io/kubernetes/cmd/kube-controller-manager/app",
|
||||
deps = [
|
||||
"//cmd/kube-controller-manager/app/options:go_default_library",
|
||||
"//pkg/api/legacyscheme:go_default_library",
|
||||
"//pkg/apis/apps/install:go_default_library",
|
||||
"//pkg/apis/authentication/install:go_default_library",
|
||||
"//pkg/apis/authorization/install:go_default_library",
|
||||
"//pkg/apis/autoscaling/install:go_default_library",
|
||||
"//pkg/apis/batch/install:go_default_library",
|
||||
"//pkg/apis/certificates/install:go_default_library",
|
||||
"//pkg/apis/componentconfig:go_default_library",
|
||||
"//pkg/apis/core/install:go_default_library",
|
||||
"//pkg/apis/events/install:go_default_library",
|
||||
"//pkg/apis/extensions/install:go_default_library",
|
||||
"//pkg/apis/policy/install:go_default_library",
|
||||
"//pkg/apis/rbac/install:go_default_library",
|
||||
"//pkg/apis/scheduling/install:go_default_library",
|
||||
"//pkg/apis/settings/install:go_default_library",
|
||||
"//pkg/apis/storage/install:go_default_library",
|
||||
"//pkg/cloudprovider:go_default_library",
|
||||
"//pkg/cloudprovider/providers:go_default_library",
|
||||
"//pkg/controller:go_default_library",
|
||||
"//pkg/controller/bootstrap:go_default_library",
|
||||
"//pkg/controller/certificates/approver:go_default_library",
|
||||
"//pkg/controller/certificates/cleaner:go_default_library",
|
||||
"//pkg/controller/certificates/signer:go_default_library",
|
||||
"//pkg/controller/clusterroleaggregation:go_default_library",
|
||||
"//pkg/controller/cronjob:go_default_library",
|
||||
"//pkg/controller/daemon:go_default_library",
|
||||
"//pkg/controller/deployment:go_default_library",
|
||||
"//pkg/controller/disruption:go_default_library",
|
||||
"//pkg/controller/endpoint:go_default_library",
|
||||
"//pkg/controller/garbagecollector:go_default_library",
|
||||
"//pkg/controller/job:go_default_library",
|
||||
"//pkg/controller/namespace:go_default_library",
|
||||
"//pkg/controller/node:go_default_library",
|
||||
"//pkg/controller/node/ipam:go_default_library",
|
||||
"//pkg/controller/podautoscaler:go_default_library",
|
||||
"//pkg/controller/podautoscaler/metrics:go_default_library",
|
||||
"//pkg/controller/podgc:go_default_library",
|
||||
"//pkg/controller/replicaset:go_default_library",
|
||||
"//pkg/controller/replication:go_default_library",
|
||||
"//pkg/controller/resourcequota:go_default_library",
|
||||
"//pkg/controller/route:go_default_library",
|
||||
"//pkg/controller/service:go_default_library",
|
||||
"//pkg/controller/serviceaccount:go_default_library",
|
||||
"//pkg/controller/statefulset:go_default_library",
|
||||
"//pkg/controller/ttl:go_default_library",
|
||||
"//pkg/controller/volume/attachdetach:go_default_library",
|
||||
"//pkg/controller/volume/expand:go_default_library",
|
||||
"//pkg/controller/volume/persistentvolume:go_default_library",
|
||||
"//pkg/controller/volume/pvcprotection:go_default_library",
|
||||
"//pkg/features:go_default_library",
|
||||
"//pkg/quota/generic:go_default_library",
|
||||
"//pkg/quota/install:go_default_library",
|
||||
"//pkg/serviceaccount:go_default_library",
|
||||
"//pkg/util/configz:go_default_library",
|
||||
"//pkg/util/metrics:go_default_library",
|
||||
"//pkg/version:go_default_library",
|
||||
"//pkg/volume:go_default_library",
|
||||
"//pkg/volume/aws_ebs:go_default_library",
|
||||
"//pkg/volume/azure_dd:go_default_library",
|
||||
"//pkg/volume/azure_file:go_default_library",
|
||||
"//pkg/volume/cinder:go_default_library",
|
||||
"//pkg/volume/csi:go_default_library",
|
||||
"//pkg/volume/fc:go_default_library",
|
||||
"//pkg/volume/flexvolume:go_default_library",
|
||||
"//pkg/volume/flocker:go_default_library",
|
||||
"//pkg/volume/gce_pd:go_default_library",
|
||||
"//pkg/volume/glusterfs:go_default_library",
|
||||
"//pkg/volume/host_path:go_default_library",
|
||||
"//pkg/volume/iscsi:go_default_library",
|
||||
"//pkg/volume/local:go_default_library",
|
||||
"//pkg/volume/nfs:go_default_library",
|
||||
"//pkg/volume/photon_pd:go_default_library",
|
||||
"//pkg/volume/portworx:go_default_library",
|
||||
"//pkg/volume/quobyte:go_default_library",
|
||||
"//pkg/volume/rbd:go_default_library",
|
||||
"//pkg/volume/scaleio:go_default_library",
|
||||
"//pkg/volume/storageos:go_default_library",
|
||||
"//pkg/volume/util:go_default_library",
|
||||
"//pkg/volume/vsphere_volume:go_default_library",
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/github.com/prometheus/client_golang/prometheus:go_default_library",
|
||||
"//vendor/github.com/spf13/cobra:go_default_library",
|
||||
"//vendor/github.com/spf13/pflag:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/server/healthz:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||
"//vendor/k8s.io/client-go/discovery:go_default_library",
|
||||
"//vendor/k8s.io/client-go/discovery/cached:go_default_library",
|
||||
"//vendor/k8s.io/client-go/dynamic: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/kubernetes/typed/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/client-go/rest:go_default_library",
|
||||
"//vendor/k8s.io/client-go/scale:go_default_library",
|
||||
"//vendor/k8s.io/client-go/tools/clientcmd:go_default_library",
|
||||
"//vendor/k8s.io/client-go/tools/leaderelection:go_default_library",
|
||||
"//vendor/k8s.io/client-go/tools/leaderelection/resourcelock:go_default_library",
|
||||
"//vendor/k8s.io/client-go/tools/record:go_default_library",
|
||||
"//vendor/k8s.io/client-go/util/cert:go_default_library",
|
||||
"//vendor/k8s.io/metrics/pkg/client/clientset_generated/clientset/typed/metrics/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/metrics/pkg/client/custom_metrics:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//cmd/kube-controller-manager/app/options:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["controller_manager_test.go"],
|
||||
importpath = "k8s.io/kubernetes/cmd/kube-controller-manager/app",
|
||||
library = ":go_default_library",
|
||||
deps = [
|
||||
"//vendor/github.com/stretchr/testify/assert:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
],
|
||||
)
|
40
vendor/k8s.io/kubernetes/cmd/kube-controller-manager/app/apps.go
generated
vendored
Normal file
40
vendor/k8s.io/kubernetes/cmd/kube-controller-manager/app/apps.go
generated
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package app implements a server that runs a set of active
|
||||
// components. This includes replication controllers, service endpoints and
|
||||
// nodes.
|
||||
//
|
||||
package app
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/kubernetes/pkg/controller/statefulset"
|
||||
)
|
||||
|
||||
func startStatefulSetController(ctx ControllerContext) (bool, error) {
|
||||
if !ctx.AvailableResources[schema.GroupVersionResource{Group: "apps", Version: "v1beta1", Resource: "statefulsets"}] {
|
||||
return false, nil
|
||||
}
|
||||
go statefulset.NewStatefulSetController(
|
||||
ctx.InformerFactory.Core().V1().Pods(),
|
||||
ctx.InformerFactory.Apps().V1beta1().StatefulSets(),
|
||||
ctx.InformerFactory.Core().V1().PersistentVolumeClaims(),
|
||||
ctx.InformerFactory.Apps().V1beta1().ControllerRevisions(),
|
||||
ctx.ClientBuilder.ClientOrDie("statefulset-controller"),
|
||||
).Run(1, ctx.Stop)
|
||||
return true, nil
|
||||
}
|
105
vendor/k8s.io/kubernetes/cmd/kube-controller-manager/app/autoscaling.go
generated
vendored
Normal file
105
vendor/k8s.io/kubernetes/cmd/kube-controller-manager/app/autoscaling.go
generated
vendored
Normal file
@ -0,0 +1,105 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package app implements a server that runs a set of active
|
||||
// components. This includes replication controllers, service endpoints and
|
||||
// nodes.
|
||||
//
|
||||
package app
|
||||
|
||||
import (
|
||||
apimeta "k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/client-go/discovery"
|
||||
discocache "k8s.io/client-go/discovery/cached" // Saturday Night Fever
|
||||
"k8s.io/client-go/dynamic"
|
||||
"k8s.io/client-go/scale"
|
||||
"k8s.io/kubernetes/pkg/controller/podautoscaler"
|
||||
"k8s.io/kubernetes/pkg/controller/podautoscaler/metrics"
|
||||
resourceclient "k8s.io/metrics/pkg/client/clientset_generated/clientset/typed/metrics/v1beta1"
|
||||
"k8s.io/metrics/pkg/client/custom_metrics"
|
||||
)
|
||||
|
||||
func startHPAController(ctx ControllerContext) (bool, error) {
|
||||
if !ctx.AvailableResources[schema.GroupVersionResource{Group: "autoscaling", Version: "v1", Resource: "horizontalpodautoscalers"}] {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if ctx.Options.HorizontalPodAutoscalerUseRESTClients {
|
||||
// use the new-style clients if support for custom metrics is enabled
|
||||
return startHPAControllerWithRESTClient(ctx)
|
||||
}
|
||||
|
||||
return startHPAControllerWithLegacyClient(ctx)
|
||||
}
|
||||
|
||||
func startHPAControllerWithRESTClient(ctx ControllerContext) (bool, error) {
|
||||
clientConfig := ctx.ClientBuilder.ConfigOrDie("horizontal-pod-autoscaler")
|
||||
metricsClient := metrics.NewRESTMetricsClient(
|
||||
resourceclient.NewForConfigOrDie(clientConfig),
|
||||
custom_metrics.NewForConfigOrDie(clientConfig),
|
||||
)
|
||||
return startHPAControllerWithMetricsClient(ctx, metricsClient)
|
||||
}
|
||||
|
||||
func startHPAControllerWithLegacyClient(ctx ControllerContext) (bool, error) {
|
||||
hpaClient := ctx.ClientBuilder.ClientOrDie("horizontal-pod-autoscaler")
|
||||
metricsClient := metrics.NewHeapsterMetricsClient(
|
||||
hpaClient,
|
||||
metrics.DefaultHeapsterNamespace,
|
||||
metrics.DefaultHeapsterScheme,
|
||||
metrics.DefaultHeapsterService,
|
||||
metrics.DefaultHeapsterPort,
|
||||
)
|
||||
return startHPAControllerWithMetricsClient(ctx, metricsClient)
|
||||
}
|
||||
|
||||
func startHPAControllerWithMetricsClient(ctx ControllerContext, metricsClient metrics.MetricsClient) (bool, error) {
|
||||
hpaClientGoClient := ctx.ClientBuilder.ClientGoClientOrDie("horizontal-pod-autoscaler")
|
||||
hpaClient := ctx.ClientBuilder.ClientOrDie("horizontal-pod-autoscaler")
|
||||
hpaClientConfig := ctx.ClientBuilder.ConfigOrDie("horizontal-pod-autoscaler")
|
||||
|
||||
// TODO: we need something like deferred discovery REST mapper that calls invalidate
|
||||
// on cache misses.
|
||||
cachedDiscovery := discocache.NewMemCacheClient(hpaClientGoClient.Discovery())
|
||||
restMapper := discovery.NewDeferredDiscoveryRESTMapper(cachedDiscovery, apimeta.InterfacesForUnstructured)
|
||||
restMapper.Reset()
|
||||
// we don't use cached discovery because DiscoveryScaleKindResolver does its own caching,
|
||||
// so we want to re-fetch every time when we actually ask for it
|
||||
scaleKindResolver := scale.NewDiscoveryScaleKindResolver(hpaClientGoClient.Discovery())
|
||||
scaleClient, err := scale.NewForConfig(hpaClientConfig, restMapper, dynamic.LegacyAPIPathResolverFunc, scaleKindResolver)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
replicaCalc := podautoscaler.NewReplicaCalculator(
|
||||
metricsClient,
|
||||
hpaClient.CoreV1(),
|
||||
ctx.Options.HorizontalPodAutoscalerTolerance,
|
||||
)
|
||||
go podautoscaler.NewHorizontalController(
|
||||
hpaClientGoClient.CoreV1(),
|
||||
scaleClient,
|
||||
hpaClient.AutoscalingV1(),
|
||||
restMapper,
|
||||
replicaCalc,
|
||||
ctx.InformerFactory.Autoscaling().V1().HorizontalPodAutoscalers(),
|
||||
ctx.Options.HorizontalPodAutoscalerSyncPeriod.Duration,
|
||||
ctx.Options.HorizontalPodAutoscalerUpscaleForbiddenWindow.Duration,
|
||||
ctx.Options.HorizontalPodAutoscalerDownscaleForbiddenWindow.Duration,
|
||||
).Run(ctx.Stop)
|
||||
return true, nil
|
||||
}
|
55
vendor/k8s.io/kubernetes/cmd/kube-controller-manager/app/batch.go
generated
vendored
Normal file
55
vendor/k8s.io/kubernetes/cmd/kube-controller-manager/app/batch.go
generated
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package app implements a server that runs a set of active
|
||||
// components. This includes replication controllers, service endpoints and
|
||||
// nodes.
|
||||
//
|
||||
package app
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/kubernetes/pkg/controller/cronjob"
|
||||
"k8s.io/kubernetes/pkg/controller/job"
|
||||
)
|
||||
|
||||
func startJobController(ctx ControllerContext) (bool, error) {
|
||||
if !ctx.AvailableResources[schema.GroupVersionResource{Group: "batch", Version: "v1", Resource: "jobs"}] {
|
||||
return false, nil
|
||||
}
|
||||
go job.NewJobController(
|
||||
ctx.InformerFactory.Core().V1().Pods(),
|
||||
ctx.InformerFactory.Batch().V1().Jobs(),
|
||||
ctx.ClientBuilder.ClientOrDie("job-controller"),
|
||||
).Run(int(ctx.Options.ConcurrentJobSyncs), ctx.Stop)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func startCronJobController(ctx ControllerContext) (bool, error) {
|
||||
if !ctx.AvailableResources[schema.GroupVersionResource{Group: "batch", Version: "v1beta1", Resource: "cronjobs"}] {
|
||||
return false, nil
|
||||
}
|
||||
cjc, err := cronjob.NewCronJobController(
|
||||
ctx.ClientBuilder.ClientOrDie("cronjob-controller"),
|
||||
)
|
||||
if err != nil {
|
||||
return true, fmt.Errorf("error creating CronJob controller: %v", err)
|
||||
}
|
||||
go cjc.Run(ctx.Stop)
|
||||
return true, nil
|
||||
}
|
47
vendor/k8s.io/kubernetes/cmd/kube-controller-manager/app/bootstrap.go
generated
vendored
Normal file
47
vendor/k8s.io/kubernetes/cmd/kube-controller-manager/app/bootstrap.go
generated
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package app
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/kubernetes/pkg/controller/bootstrap"
|
||||
)
|
||||
|
||||
func startBootstrapSignerController(ctx ControllerContext) (bool, error) {
|
||||
bsc, err := bootstrap.NewBootstrapSigner(
|
||||
ctx.ClientBuilder.ClientGoClientOrDie("bootstrap-signer"),
|
||||
bootstrap.DefaultBootstrapSignerOptions(),
|
||||
)
|
||||
if err != nil {
|
||||
return true, fmt.Errorf("error creating BootstrapSigner controller: %v", err)
|
||||
}
|
||||
go bsc.Run(ctx.Stop)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func startTokenCleanerController(ctx ControllerContext) (bool, error) {
|
||||
tcc, err := bootstrap.NewTokenCleaner(
|
||||
ctx.ClientBuilder.ClientGoClientOrDie("token-cleaner"),
|
||||
bootstrap.DefaultTokenCleanerOptions(),
|
||||
)
|
||||
if err != nil {
|
||||
return true, fmt.Errorf("error creating TokenCleaner controller: %v", err)
|
||||
}
|
||||
go tcc.Run(ctx.Stop)
|
||||
return true, nil
|
||||
}
|
120
vendor/k8s.io/kubernetes/cmd/kube-controller-manager/app/certificates.go
generated
vendored
Normal file
120
vendor/k8s.io/kubernetes/cmd/kube-controller-manager/app/certificates.go
generated
vendored
Normal file
@ -0,0 +1,120 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package app implements a server that runs a set of active
|
||||
// components. This includes replication controllers, service endpoints and
|
||||
// nodes.
|
||||
//
|
||||
package app
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/golang/glog"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/kubernetes/cmd/kube-controller-manager/app/options"
|
||||
"k8s.io/kubernetes/pkg/controller/certificates/approver"
|
||||
"k8s.io/kubernetes/pkg/controller/certificates/cleaner"
|
||||
"k8s.io/kubernetes/pkg/controller/certificates/signer"
|
||||
)
|
||||
|
||||
func startCSRSigningController(ctx ControllerContext) (bool, error) {
|
||||
if !ctx.AvailableResources[schema.GroupVersionResource{Group: "certificates.k8s.io", Version: "v1beta1", Resource: "certificatesigningrequests"}] {
|
||||
return false, nil
|
||||
}
|
||||
if ctx.Options.ClusterSigningCertFile == "" || ctx.Options.ClusterSigningKeyFile == "" {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// Deprecation warning for old defaults.
|
||||
//
|
||||
// * If the signing cert and key are the default paths but the files
|
||||
// exist, warn that the paths need to be specified explicitly in a
|
||||
// later release and the defaults will be removed. We don't expect this
|
||||
// to be the case.
|
||||
//
|
||||
// * If the signing cert and key are default paths but the files don't exist,
|
||||
// bail out of startController without logging.
|
||||
var keyFileExists, keyUsesDefault, certFileExists, certUsesDefault bool
|
||||
|
||||
_, err := os.Stat(ctx.Options.ClusterSigningCertFile)
|
||||
certFileExists = !os.IsNotExist(err)
|
||||
|
||||
certUsesDefault = (ctx.Options.ClusterSigningCertFile == options.DefaultClusterSigningCertFile)
|
||||
|
||||
_, err = os.Stat(ctx.Options.ClusterSigningKeyFile)
|
||||
keyFileExists = !os.IsNotExist(err)
|
||||
|
||||
keyUsesDefault = (ctx.Options.ClusterSigningKeyFile == options.DefaultClusterSigningKeyFile)
|
||||
|
||||
switch {
|
||||
case (keyFileExists && keyUsesDefault) || (certFileExists && certUsesDefault):
|
||||
glog.Warningf("You might be using flag defaulting for --cluster-signing-cert-file and" +
|
||||
" --cluster-signing-key-file. These defaults are deprecated and will be removed" +
|
||||
" in a subsequent release. Please pass these options explicitly.")
|
||||
case (!keyFileExists && keyUsesDefault) && (!certFileExists && certUsesDefault):
|
||||
// This is what we expect right now if people aren't
|
||||
// setting up the signing controller. This isn't
|
||||
// actually a problem since the signer is not a
|
||||
// required controller.
|
||||
return false, nil
|
||||
default:
|
||||
// Note that '!filesExist && !usesDefaults' is obviously
|
||||
// operator error. We don't handle this case here and instead
|
||||
// allow it to be handled by NewCSR... below.
|
||||
}
|
||||
|
||||
c := ctx.ClientBuilder.ClientOrDie("certificate-controller")
|
||||
|
||||
signer, err := signer.NewCSRSigningController(
|
||||
c,
|
||||
ctx.InformerFactory.Certificates().V1beta1().CertificateSigningRequests(),
|
||||
ctx.Options.ClusterSigningCertFile,
|
||||
ctx.Options.ClusterSigningKeyFile,
|
||||
ctx.Options.ClusterSigningDuration.Duration,
|
||||
)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("failed to start certificate controller: %v", err)
|
||||
}
|
||||
go signer.Run(1, ctx.Stop)
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func startCSRApprovingController(ctx ControllerContext) (bool, error) {
|
||||
if !ctx.AvailableResources[schema.GroupVersionResource{Group: "certificates.k8s.io", Version: "v1beta1", Resource: "certificatesigningrequests"}] {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
approver := approver.NewCSRApprovingController(
|
||||
ctx.ClientBuilder.ClientOrDie("certificate-controller"),
|
||||
ctx.InformerFactory.Certificates().V1beta1().CertificateSigningRequests(),
|
||||
)
|
||||
go approver.Run(1, ctx.Stop)
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func startCSRCleanerController(ctx ControllerContext) (bool, error) {
|
||||
cleaner := cleaner.NewCSRCleanerController(
|
||||
ctx.ClientBuilder.ClientOrDie("certificate-controller").CertificatesV1beta1().CertificateSigningRequests(),
|
||||
ctx.InformerFactory.Certificates().V1beta1().CertificateSigningRequests(),
|
||||
)
|
||||
go cleaner.Run(1, ctx.Stop)
|
||||
return true, nil
|
||||
}
|
81
vendor/k8s.io/kubernetes/cmd/kube-controller-manager/app/controller_manager_test.go
generated
vendored
Normal file
81
vendor/k8s.io/kubernetes/cmd/kube-controller-manager/app/controller_manager_test.go
generated
vendored
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
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 implements a server that runs a set of active
|
||||
// components. This includes replication controllers, service endpoints and
|
||||
// nodes.
|
||||
//
|
||||
package app
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestIsControllerEnabled(t *testing.T) {
|
||||
tcs := []struct {
|
||||
name string
|
||||
controllerName string
|
||||
controllers []string
|
||||
disabledByDefaultControllers []string
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
name: "on by name",
|
||||
controllerName: "bravo",
|
||||
controllers: []string{"alpha", "bravo", "-charlie"},
|
||||
disabledByDefaultControllers: []string{"delta", "echo"},
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "off by name",
|
||||
controllerName: "charlie",
|
||||
controllers: []string{"alpha", "bravo", "-charlie"},
|
||||
disabledByDefaultControllers: []string{"delta", "echo"},
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "on by default",
|
||||
controllerName: "alpha",
|
||||
controllers: []string{"*"},
|
||||
disabledByDefaultControllers: []string{"delta", "echo"},
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "off by default",
|
||||
controllerName: "delta",
|
||||
controllers: []string{"*"},
|
||||
disabledByDefaultControllers: []string{"delta", "echo"},
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "off by default implicit, no star",
|
||||
controllerName: "foxtrot",
|
||||
controllers: []string{"alpha", "bravo", "-charlie"},
|
||||
disabledByDefaultControllers: []string{"delta", "echo"},
|
||||
expected: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tcs {
|
||||
actual := IsControllerEnabled(tc.controllerName, sets.NewString(tc.disabledByDefaultControllers...), tc.controllers...)
|
||||
assert.Equal(t, tc.expected, actual, "%v: expected %v, got %v", tc.name, tc.expected, actual)
|
||||
}
|
||||
|
||||
}
|
552
vendor/k8s.io/kubernetes/cmd/kube-controller-manager/app/controllermanager.go
generated
vendored
Normal file
552
vendor/k8s.io/kubernetes/cmd/kube-controller-manager/app/controllermanager.go
generated
vendored
Normal file
@ -0,0 +1,552 @@
|
||||
/*
|
||||
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 app implements a server that runs a set of active
|
||||
// components. This includes replication controllers, service endpoints and
|
||||
// nodes.
|
||||
//
|
||||
package app
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"math/rand"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/pprof"
|
||||
"os"
|
||||
goruntime "runtime"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
|
||||
"k8s.io/apiserver/pkg/server/healthz"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/client-go/discovery"
|
||||
v1core "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
"k8s.io/client-go/tools/record"
|
||||
certutil "k8s.io/client-go/util/cert"
|
||||
|
||||
"k8s.io/client-go/informers"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/tools/leaderelection"
|
||||
"k8s.io/client-go/tools/leaderelection/resourcelock"
|
||||
"k8s.io/kubernetes/cmd/kube-controller-manager/app/options"
|
||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||
"k8s.io/kubernetes/pkg/cloudprovider"
|
||||
"k8s.io/kubernetes/pkg/controller"
|
||||
serviceaccountcontroller "k8s.io/kubernetes/pkg/controller/serviceaccount"
|
||||
"k8s.io/kubernetes/pkg/serviceaccount"
|
||||
"k8s.io/kubernetes/pkg/util/configz"
|
||||
"k8s.io/kubernetes/pkg/version"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
const (
|
||||
// Jitter used when starting controller managers
|
||||
ControllerStartJitter = 1.0
|
||||
)
|
||||
|
||||
// NewControllerManagerCommand creates a *cobra.Command object with default parameters
|
||||
func NewControllerManagerCommand() *cobra.Command {
|
||||
s := options.NewCMServer()
|
||||
s.AddFlags(pflag.CommandLine, KnownControllers(), ControllersDisabledByDefault.List())
|
||||
cmd := &cobra.Command{
|
||||
Use: "kube-controller-manager",
|
||||
Long: `The Kubernetes controller manager is a daemon that embeds
|
||||
the core control loops shipped with Kubernetes. In applications of robotics and
|
||||
automation, a control loop is a non-terminating loop that regulates the state of
|
||||
the system. In Kubernetes, a controller is a control loop that watches the shared
|
||||
state of the cluster through the apiserver and makes changes attempting to move the
|
||||
current state towards the desired state. Examples of controllers that ship with
|
||||
Kubernetes today are the replication controller, endpoints controller, namespace
|
||||
controller, and serviceaccounts controller.`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
},
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
// ResyncPeriod returns a function which generates a duration each time it is
|
||||
// invoked; this is so that multiple controllers don't get into lock-step and all
|
||||
// hammer the apiserver with list requests simultaneously.
|
||||
func ResyncPeriod(s *options.CMServer) func() time.Duration {
|
||||
return func() time.Duration {
|
||||
factor := rand.Float64() + 1
|
||||
return time.Duration(float64(s.MinResyncPeriod.Nanoseconds()) * factor)
|
||||
}
|
||||
}
|
||||
|
||||
// Run runs the CMServer. This should never exit.
|
||||
func Run(s *options.CMServer) error {
|
||||
// To help debugging, immediately log version
|
||||
glog.Infof("Version: %+v", version.Get())
|
||||
if err := s.Validate(KnownControllers(), ControllersDisabledByDefault.List()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if c, err := configz.New("componentconfig"); err == nil {
|
||||
c.Set(s.KubeControllerManagerConfiguration)
|
||||
} else {
|
||||
glog.Errorf("unable to register configz: %s", err)
|
||||
}
|
||||
|
||||
kubeClient, leaderElectionClient, kubeconfig, err := createClients(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
go startHTTP(s)
|
||||
|
||||
recorder := createRecorder(kubeClient)
|
||||
|
||||
run := func(stop <-chan struct{}) {
|
||||
rootClientBuilder := controller.SimpleControllerClientBuilder{
|
||||
ClientConfig: kubeconfig,
|
||||
}
|
||||
var clientBuilder controller.ControllerClientBuilder
|
||||
if s.UseServiceAccountCredentials {
|
||||
if len(s.ServiceAccountKeyFile) == 0 {
|
||||
// It's possible another controller process is creating the tokens for us.
|
||||
// If one isn't, we'll timeout and exit when our client builder is unable to create the tokens.
|
||||
glog.Warningf("--use-service-account-credentials was specified without providing a --service-account-private-key-file")
|
||||
}
|
||||
clientBuilder = controller.SAControllerClientBuilder{
|
||||
ClientConfig: restclient.AnonymousClientConfig(kubeconfig),
|
||||
CoreClient: kubeClient.CoreV1(),
|
||||
AuthenticationClient: kubeClient.Authentication(),
|
||||
Namespace: "kube-system",
|
||||
}
|
||||
} else {
|
||||
clientBuilder = rootClientBuilder
|
||||
}
|
||||
ctx, err := CreateControllerContext(s, rootClientBuilder, clientBuilder, stop)
|
||||
if err != nil {
|
||||
glog.Fatalf("error building controller context: %v", err)
|
||||
}
|
||||
saTokenControllerInitFunc := serviceAccountTokenControllerStarter{rootClientBuilder: rootClientBuilder}.startServiceAccountTokenController
|
||||
|
||||
if err := StartControllers(ctx, saTokenControllerInitFunc, NewControllerInitializers()); err != nil {
|
||||
glog.Fatalf("error starting controllers: %v", err)
|
||||
}
|
||||
|
||||
ctx.InformerFactory.Start(ctx.Stop)
|
||||
close(ctx.InformersStarted)
|
||||
|
||||
select {}
|
||||
}
|
||||
|
||||
if !s.LeaderElection.LeaderElect {
|
||||
run(nil)
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
id, err := os.Hostname()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
rl, err := resourcelock.New(s.LeaderElection.ResourceLock,
|
||||
"kube-system",
|
||||
"kube-controller-manager",
|
||||
leaderElectionClient.CoreV1(),
|
||||
resourcelock.ResourceLockConfig{
|
||||
Identity: id,
|
||||
EventRecorder: recorder,
|
||||
})
|
||||
if err != nil {
|
||||
glog.Fatalf("error creating lock: %v", err)
|
||||
}
|
||||
|
||||
leaderelection.RunOrDie(leaderelection.LeaderElectionConfig{
|
||||
Lock: rl,
|
||||
LeaseDuration: s.LeaderElection.LeaseDuration.Duration,
|
||||
RenewDeadline: s.LeaderElection.RenewDeadline.Duration,
|
||||
RetryPeriod: s.LeaderElection.RetryPeriod.Duration,
|
||||
Callbacks: leaderelection.LeaderCallbacks{
|
||||
OnStartedLeading: run,
|
||||
OnStoppedLeading: func() {
|
||||
glog.Fatalf("leaderelection lost")
|
||||
},
|
||||
},
|
||||
})
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
func startHTTP(s *options.CMServer) {
|
||||
mux := http.NewServeMux()
|
||||
healthz.InstallHandler(mux)
|
||||
if s.EnableProfiling {
|
||||
mux.HandleFunc("/debug/pprof/", pprof.Index)
|
||||
mux.HandleFunc("/debug/pprof/profile", pprof.Profile)
|
||||
mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
|
||||
mux.HandleFunc("/debug/pprof/trace", pprof.Trace)
|
||||
if s.EnableContentionProfiling {
|
||||
goruntime.SetBlockProfileRate(1)
|
||||
}
|
||||
}
|
||||
configz.InstallHandler(mux)
|
||||
mux.Handle("/metrics", prometheus.Handler())
|
||||
|
||||
server := &http.Server{
|
||||
Addr: net.JoinHostPort(s.Address, strconv.Itoa(int(s.Port))),
|
||||
Handler: mux,
|
||||
}
|
||||
glog.Fatal(server.ListenAndServe())
|
||||
}
|
||||
|
||||
func createRecorder(kubeClient *clientset.Clientset) record.EventRecorder {
|
||||
eventBroadcaster := record.NewBroadcaster()
|
||||
eventBroadcaster.StartLogging(glog.Infof)
|
||||
eventBroadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: v1core.New(kubeClient.CoreV1().RESTClient()).Events("")})
|
||||
return eventBroadcaster.NewRecorder(legacyscheme.Scheme, v1.EventSource{Component: "controller-manager"})
|
||||
}
|
||||
|
||||
func createClients(s *options.CMServer) (*clientset.Clientset, *clientset.Clientset, *restclient.Config, error) {
|
||||
kubeconfig, err := clientcmd.BuildConfigFromFlags(s.Master, s.Kubeconfig)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
kubeconfig.ContentConfig.ContentType = s.ContentType
|
||||
// Override kubeconfig qps/burst settings from flags
|
||||
kubeconfig.QPS = s.KubeAPIQPS
|
||||
kubeconfig.Burst = int(s.KubeAPIBurst)
|
||||
kubeClient, err := clientset.NewForConfig(restclient.AddUserAgent(kubeconfig, "controller-manager"))
|
||||
if err != nil {
|
||||
glog.Fatalf("Invalid API configuration: %v", err)
|
||||
}
|
||||
leaderElectionClient := clientset.NewForConfigOrDie(restclient.AddUserAgent(kubeconfig, "leader-election"))
|
||||
return kubeClient, leaderElectionClient, kubeconfig, nil
|
||||
}
|
||||
|
||||
type ControllerContext struct {
|
||||
// ClientBuilder will provide a client for this controller to use
|
||||
ClientBuilder controller.ControllerClientBuilder
|
||||
|
||||
// InformerFactory gives access to informers for the controller.
|
||||
InformerFactory informers.SharedInformerFactory
|
||||
|
||||
// Options provides access to init options for a given controller
|
||||
Options options.CMServer
|
||||
|
||||
// AvailableResources is a map listing currently available resources
|
||||
AvailableResources map[schema.GroupVersionResource]bool
|
||||
|
||||
// Cloud is the cloud provider interface for the controllers to use.
|
||||
// It must be initialized and ready to use.
|
||||
Cloud cloudprovider.Interface
|
||||
|
||||
// Stop is the stop channel
|
||||
Stop <-chan struct{}
|
||||
|
||||
// InformersStarted is closed after all of the controllers have been initialized and are running. After this point it is safe,
|
||||
// for an individual controller to start the shared informers. Before it is closed, they should not.
|
||||
InformersStarted chan struct{}
|
||||
}
|
||||
|
||||
func (c ControllerContext) IsControllerEnabled(name string) bool {
|
||||
return IsControllerEnabled(name, ControllersDisabledByDefault, c.Options.Controllers...)
|
||||
}
|
||||
|
||||
func IsControllerEnabled(name string, disabledByDefaultControllers sets.String, controllers ...string) bool {
|
||||
hasStar := false
|
||||
for _, ctrl := range controllers {
|
||||
if ctrl == name {
|
||||
return true
|
||||
}
|
||||
if ctrl == "-"+name {
|
||||
return false
|
||||
}
|
||||
if ctrl == "*" {
|
||||
hasStar = true
|
||||
}
|
||||
}
|
||||
// if we get here, there was no explicit choice
|
||||
if !hasStar {
|
||||
// nothing on by default
|
||||
return false
|
||||
}
|
||||
if disabledByDefaultControllers.Has(name) {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// InitFunc is used to launch a particular controller. It may run additional "should I activate checks".
|
||||
// Any error returned will cause the controller process to `Fatal`
|
||||
// The bool indicates whether the controller was enabled.
|
||||
type InitFunc func(ctx ControllerContext) (bool, error)
|
||||
|
||||
func KnownControllers() []string {
|
||||
ret := sets.StringKeySet(NewControllerInitializers())
|
||||
|
||||
// add "special" controllers that aren't initialized normally. These controllers cannot be initialized
|
||||
// using a normal function. The only known special case is the SA token controller which *must* be started
|
||||
// first to ensure that the SA tokens for future controllers will exist. Think very carefully before adding
|
||||
// to this list.
|
||||
ret.Insert(
|
||||
saTokenControllerName,
|
||||
)
|
||||
|
||||
return ret.List()
|
||||
}
|
||||
|
||||
var ControllersDisabledByDefault = sets.NewString(
|
||||
"bootstrapsigner",
|
||||
"tokencleaner",
|
||||
)
|
||||
|
||||
const (
|
||||
saTokenControllerName = "serviceaccount-token"
|
||||
)
|
||||
|
||||
// NewControllerInitializers is a public map of named controller groups (you can start more than one in an init func)
|
||||
// paired to their InitFunc. This allows for structured downstream composition and subdivision.
|
||||
func NewControllerInitializers() map[string]InitFunc {
|
||||
controllers := map[string]InitFunc{}
|
||||
controllers["endpoint"] = startEndpointController
|
||||
controllers["replicationcontroller"] = startReplicationController
|
||||
controllers["podgc"] = startPodGCController
|
||||
controllers["resourcequota"] = startResourceQuotaController
|
||||
controllers["namespace"] = startNamespaceController
|
||||
controllers["serviceaccount"] = startServiceAccountController
|
||||
controllers["garbagecollector"] = startGarbageCollectorController
|
||||
controllers["daemonset"] = startDaemonSetController
|
||||
controllers["job"] = startJobController
|
||||
controllers["deployment"] = startDeploymentController
|
||||
controllers["replicaset"] = startReplicaSetController
|
||||
controllers["horizontalpodautoscaling"] = startHPAController
|
||||
controllers["disruption"] = startDisruptionController
|
||||
controllers["statefulset"] = startStatefulSetController
|
||||
controllers["cronjob"] = startCronJobController
|
||||
controllers["csrsigning"] = startCSRSigningController
|
||||
controllers["csrapproving"] = startCSRApprovingController
|
||||
controllers["csrcleaner"] = startCSRCleanerController
|
||||
controllers["ttl"] = startTTLController
|
||||
controllers["bootstrapsigner"] = startBootstrapSignerController
|
||||
controllers["tokencleaner"] = startTokenCleanerController
|
||||
controllers["service"] = startServiceController
|
||||
controllers["node"] = startNodeController
|
||||
controllers["route"] = startRouteController
|
||||
controllers["persistentvolume-binder"] = startPersistentVolumeBinderController
|
||||
controllers["attachdetach"] = startAttachDetachController
|
||||
controllers["persistentvolume-expander"] = startVolumeExpandController
|
||||
controllers["clusterrole-aggregation"] = startClusterRoleAggregrationController
|
||||
controllers["pvc-protection"] = startPVCProtectionController
|
||||
|
||||
return controllers
|
||||
}
|
||||
|
||||
// TODO: In general, any controller checking this needs to be dynamic so
|
||||
// users don't have to restart their controller manager if they change the apiserver.
|
||||
// Until we get there, the structure here needs to be exposed for the construction of a proper ControllerContext.
|
||||
func GetAvailableResources(clientBuilder controller.ControllerClientBuilder) (map[schema.GroupVersionResource]bool, error) {
|
||||
var discoveryClient discovery.DiscoveryInterface
|
||||
|
||||
var healthzContent string
|
||||
// If apiserver is not running we should wait for some time and fail only then. This is particularly
|
||||
// important when we start apiserver and controller manager at the same time.
|
||||
err := wait.PollImmediate(time.Second, 10*time.Second, func() (bool, error) {
|
||||
client, err := clientBuilder.Client("controller-discovery")
|
||||
if err != nil {
|
||||
glog.Errorf("Failed to get api versions from server: %v", err)
|
||||
return false, nil
|
||||
}
|
||||
|
||||
healthStatus := 0
|
||||
resp := client.Discovery().RESTClient().Get().AbsPath("/healthz").Do().StatusCode(&healthStatus)
|
||||
if healthStatus != http.StatusOK {
|
||||
glog.Errorf("Server isn't healthy yet. Waiting a little while.")
|
||||
return false, nil
|
||||
}
|
||||
content, _ := resp.Raw()
|
||||
healthzContent = string(content)
|
||||
|
||||
discoveryClient = client.Discovery()
|
||||
return true, nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get api versions from server: %v: %v", healthzContent, err)
|
||||
}
|
||||
|
||||
resourceMap, err := discoveryClient.ServerResources()
|
||||
if err != nil {
|
||||
utilruntime.HandleError(fmt.Errorf("unable to get all supported resources from server: %v", err))
|
||||
}
|
||||
if len(resourceMap) == 0 {
|
||||
return nil, fmt.Errorf("unable to get any supported resources from server")
|
||||
}
|
||||
|
||||
allResources := map[schema.GroupVersionResource]bool{}
|
||||
for _, apiResourceList := range resourceMap {
|
||||
version, err := schema.ParseGroupVersion(apiResourceList.GroupVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, apiResource := range apiResourceList.APIResources {
|
||||
allResources[version.WithResource(apiResource.Name)] = true
|
||||
}
|
||||
}
|
||||
|
||||
return allResources, nil
|
||||
}
|
||||
|
||||
// CreateControllerContext creates a context struct containing references to resources needed by the
|
||||
// controllers such as the cloud provider and clientBuilder. rootClientBuilder is only used for
|
||||
// the shared-informers client and token controller.
|
||||
func CreateControllerContext(s *options.CMServer, rootClientBuilder, clientBuilder controller.ControllerClientBuilder, stop <-chan struct{}) (ControllerContext, error) {
|
||||
versionedClient := rootClientBuilder.ClientOrDie("shared-informers")
|
||||
sharedInformers := informers.NewSharedInformerFactory(versionedClient, ResyncPeriod(s)())
|
||||
|
||||
availableResources, err := GetAvailableResources(rootClientBuilder)
|
||||
if err != nil {
|
||||
return ControllerContext{}, err
|
||||
}
|
||||
|
||||
cloud, err := cloudprovider.InitCloudProvider(s.CloudProvider, s.CloudConfigFile)
|
||||
if err != nil {
|
||||
return ControllerContext{}, fmt.Errorf("cloud provider could not be initialized: %v", err)
|
||||
}
|
||||
|
||||
if cloud != nil && cloud.HasClusterID() == false {
|
||||
if s.AllowUntaggedCloud == true {
|
||||
glog.Warning("detected a cluster without a ClusterID. A ClusterID will be required in the future. Please tag your cluster to avoid any future issues")
|
||||
} else {
|
||||
return ControllerContext{}, fmt.Errorf("no ClusterID Found. A ClusterID is required for the cloud provider to function properly. This check can be bypassed by setting the allow-untagged-cloud option")
|
||||
}
|
||||
}
|
||||
|
||||
if informerUserCloud, ok := cloud.(cloudprovider.InformerUser); ok {
|
||||
informerUserCloud.SetInformers(sharedInformers)
|
||||
}
|
||||
|
||||
ctx := ControllerContext{
|
||||
ClientBuilder: clientBuilder,
|
||||
InformerFactory: sharedInformers,
|
||||
Options: *s,
|
||||
AvailableResources: availableResources,
|
||||
Cloud: cloud,
|
||||
Stop: stop,
|
||||
InformersStarted: make(chan struct{}),
|
||||
}
|
||||
return ctx, nil
|
||||
}
|
||||
|
||||
func StartControllers(ctx ControllerContext, startSATokenController InitFunc, controllers map[string]InitFunc) error {
|
||||
// Always start the SA token controller first using a full-power client, since it needs to mint tokens for the rest
|
||||
// If this fails, just return here and fail since other controllers won't be able to get credentials.
|
||||
if _, err := startSATokenController(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Initialize the cloud provider with a reference to the clientBuilder only after token controller
|
||||
// has started in case the cloud provider uses the client builder.
|
||||
if ctx.Cloud != nil {
|
||||
ctx.Cloud.Initialize(ctx.ClientBuilder)
|
||||
}
|
||||
|
||||
for controllerName, initFn := range controllers {
|
||||
if !ctx.IsControllerEnabled(controllerName) {
|
||||
glog.Warningf("%q is disabled", controllerName)
|
||||
continue
|
||||
}
|
||||
|
||||
time.Sleep(wait.Jitter(ctx.Options.ControllerStartInterval.Duration, ControllerStartJitter))
|
||||
|
||||
glog.V(1).Infof("Starting %q", controllerName)
|
||||
started, err := initFn(ctx)
|
||||
if err != nil {
|
||||
glog.Errorf("Error starting %q", controllerName)
|
||||
return err
|
||||
}
|
||||
if !started {
|
||||
glog.Warningf("Skipping %q", controllerName)
|
||||
continue
|
||||
}
|
||||
glog.Infof("Started %q", controllerName)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// serviceAccountTokenControllerStarter is special because it must run first to set up permissions for other controllers.
|
||||
// It cannot use the "normal" client builder, so it tracks its own. It must also avoid being included in the "normal"
|
||||
// init map so that it can always run first.
|
||||
type serviceAccountTokenControllerStarter struct {
|
||||
rootClientBuilder controller.ControllerClientBuilder
|
||||
}
|
||||
|
||||
func (c serviceAccountTokenControllerStarter) startServiceAccountTokenController(ctx ControllerContext) (bool, error) {
|
||||
if !ctx.IsControllerEnabled(saTokenControllerName) {
|
||||
glog.Warningf("%q is disabled", saTokenControllerName)
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if len(ctx.Options.ServiceAccountKeyFile) == 0 {
|
||||
glog.Warningf("%q is disabled because there is no private key", saTokenControllerName)
|
||||
return false, nil
|
||||
}
|
||||
privateKey, err := certutil.PrivateKeyFromFile(ctx.Options.ServiceAccountKeyFile)
|
||||
if err != nil {
|
||||
return true, fmt.Errorf("error reading key for service account token controller: %v", err)
|
||||
}
|
||||
|
||||
var rootCA []byte
|
||||
if ctx.Options.RootCAFile != "" {
|
||||
rootCA, err = ioutil.ReadFile(ctx.Options.RootCAFile)
|
||||
if err != nil {
|
||||
return true, fmt.Errorf("error reading root-ca-file at %s: %v", ctx.Options.RootCAFile, err)
|
||||
}
|
||||
if _, err := certutil.ParseCertsPEM(rootCA); err != nil {
|
||||
return true, fmt.Errorf("error parsing root-ca-file at %s: %v", ctx.Options.RootCAFile, err)
|
||||
}
|
||||
} else {
|
||||
rootCA = c.rootClientBuilder.ConfigOrDie("tokens-controller").CAData
|
||||
}
|
||||
|
||||
controller, err := serviceaccountcontroller.NewTokensController(
|
||||
ctx.InformerFactory.Core().V1().ServiceAccounts(),
|
||||
ctx.InformerFactory.Core().V1().Secrets(),
|
||||
c.rootClientBuilder.ClientOrDie("tokens-controller"),
|
||||
serviceaccountcontroller.TokensControllerOptions{
|
||||
TokenGenerator: serviceaccount.JWTTokenGenerator(privateKey),
|
||||
RootCA: rootCA,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return true, fmt.Errorf("error creating Tokens controller: %v", err)
|
||||
}
|
||||
go controller.Run(int(ctx.Options.ConcurrentSATokenSyncs), ctx.Stop)
|
||||
|
||||
// start the first set of informers now so that other controllers can start
|
||||
ctx.InformerFactory.Start(ctx.Stop)
|
||||
|
||||
return true, nil
|
||||
}
|
391
vendor/k8s.io/kubernetes/cmd/kube-controller-manager/app/core.go
generated
vendored
Normal file
391
vendor/k8s.io/kubernetes/cmd/kube-controller-manager/app/core.go
generated
vendored
Normal file
@ -0,0 +1,391 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package app implements a server that runs a set of active
|
||||
// components. This includes replication controllers, service endpoints and
|
||||
// nodes.
|
||||
//
|
||||
package app
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/golang/glog"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
"k8s.io/client-go/discovery"
|
||||
cacheddiscovery "k8s.io/client-go/discovery/cached"
|
||||
"k8s.io/client-go/dynamic"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||
"k8s.io/kubernetes/pkg/controller"
|
||||
endpointcontroller "k8s.io/kubernetes/pkg/controller/endpoint"
|
||||
"k8s.io/kubernetes/pkg/controller/garbagecollector"
|
||||
namespacecontroller "k8s.io/kubernetes/pkg/controller/namespace"
|
||||
nodecontroller "k8s.io/kubernetes/pkg/controller/node"
|
||||
"k8s.io/kubernetes/pkg/controller/node/ipam"
|
||||
"k8s.io/kubernetes/pkg/controller/podgc"
|
||||
replicationcontroller "k8s.io/kubernetes/pkg/controller/replication"
|
||||
resourcequotacontroller "k8s.io/kubernetes/pkg/controller/resourcequota"
|
||||
routecontroller "k8s.io/kubernetes/pkg/controller/route"
|
||||
servicecontroller "k8s.io/kubernetes/pkg/controller/service"
|
||||
serviceaccountcontroller "k8s.io/kubernetes/pkg/controller/serviceaccount"
|
||||
ttlcontroller "k8s.io/kubernetes/pkg/controller/ttl"
|
||||
"k8s.io/kubernetes/pkg/controller/volume/attachdetach"
|
||||
"k8s.io/kubernetes/pkg/controller/volume/expand"
|
||||
persistentvolumecontroller "k8s.io/kubernetes/pkg/controller/volume/persistentvolume"
|
||||
"k8s.io/kubernetes/pkg/controller/volume/pvcprotection"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
"k8s.io/kubernetes/pkg/quota/generic"
|
||||
quotainstall "k8s.io/kubernetes/pkg/quota/install"
|
||||
"k8s.io/kubernetes/pkg/util/metrics"
|
||||
)
|
||||
|
||||
func startServiceController(ctx ControllerContext) (bool, error) {
|
||||
serviceController, err := servicecontroller.New(
|
||||
ctx.Cloud,
|
||||
ctx.ClientBuilder.ClientOrDie("service-controller"),
|
||||
ctx.InformerFactory.Core().V1().Services(),
|
||||
ctx.InformerFactory.Core().V1().Nodes(),
|
||||
ctx.Options.ClusterName,
|
||||
)
|
||||
if err != nil {
|
||||
// This error shouldn't fail. It lives like this as a legacy.
|
||||
glog.Errorf("Failed to start service controller: %v", err)
|
||||
return false, nil
|
||||
}
|
||||
go serviceController.Run(ctx.Stop, int(ctx.Options.ConcurrentServiceSyncs))
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func startNodeController(ctx ControllerContext) (bool, error) {
|
||||
var clusterCIDR *net.IPNet = nil
|
||||
var serviceCIDR *net.IPNet = nil
|
||||
if ctx.Options.AllocateNodeCIDRs {
|
||||
var err error
|
||||
if len(strings.TrimSpace(ctx.Options.ClusterCIDR)) != 0 {
|
||||
_, clusterCIDR, err = net.ParseCIDR(ctx.Options.ClusterCIDR)
|
||||
if err != nil {
|
||||
glog.Warningf("Unsuccessful parsing of cluster CIDR %v: %v", ctx.Options.ClusterCIDR, err)
|
||||
}
|
||||
}
|
||||
|
||||
if len(strings.TrimSpace(ctx.Options.ServiceCIDR)) != 0 {
|
||||
_, serviceCIDR, err = net.ParseCIDR(ctx.Options.ServiceCIDR)
|
||||
if err != nil {
|
||||
glog.Warningf("Unsuccessful parsing of service CIDR %v: %v", ctx.Options.ServiceCIDR, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nodeController, err := nodecontroller.NewNodeController(
|
||||
ctx.InformerFactory.Core().V1().Pods(),
|
||||
ctx.InformerFactory.Core().V1().Nodes(),
|
||||
ctx.InformerFactory.Extensions().V1beta1().DaemonSets(),
|
||||
ctx.Cloud,
|
||||
ctx.ClientBuilder.ClientOrDie("node-controller"),
|
||||
ctx.Options.PodEvictionTimeout.Duration,
|
||||
ctx.Options.NodeEvictionRate,
|
||||
ctx.Options.SecondaryNodeEvictionRate,
|
||||
ctx.Options.LargeClusterSizeThreshold,
|
||||
ctx.Options.UnhealthyZoneThreshold,
|
||||
ctx.Options.NodeMonitorGracePeriod.Duration,
|
||||
ctx.Options.NodeStartupGracePeriod.Duration,
|
||||
ctx.Options.NodeMonitorPeriod.Duration,
|
||||
clusterCIDR,
|
||||
serviceCIDR,
|
||||
int(ctx.Options.NodeCIDRMaskSize),
|
||||
ctx.Options.AllocateNodeCIDRs,
|
||||
ipam.CIDRAllocatorType(ctx.Options.CIDRAllocatorType),
|
||||
ctx.Options.EnableTaintManager,
|
||||
utilfeature.DefaultFeatureGate.Enabled(features.TaintBasedEvictions),
|
||||
utilfeature.DefaultFeatureGate.Enabled(features.TaintNodesByCondition),
|
||||
)
|
||||
if err != nil {
|
||||
return true, err
|
||||
}
|
||||
go nodeController.Run(ctx.Stop)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func startRouteController(ctx ControllerContext) (bool, error) {
|
||||
if !ctx.Options.AllocateNodeCIDRs || !ctx.Options.ConfigureCloudRoutes {
|
||||
glog.Infof("Will not configure cloud provider routes for allocate-node-cidrs: %v, configure-cloud-routes: %v.", ctx.Options.AllocateNodeCIDRs, ctx.Options.ConfigureCloudRoutes)
|
||||
return false, nil
|
||||
}
|
||||
if ctx.Cloud == nil {
|
||||
glog.Warning("configure-cloud-routes is set, but no cloud provider specified. Will not configure cloud provider routes.")
|
||||
return false, nil
|
||||
}
|
||||
routes, ok := ctx.Cloud.Routes()
|
||||
if !ok {
|
||||
glog.Warning("configure-cloud-routes is set, but cloud provider does not support routes. Will not configure cloud provider routes.")
|
||||
return false, nil
|
||||
}
|
||||
_, clusterCIDR, err := net.ParseCIDR(ctx.Options.ClusterCIDR)
|
||||
if err != nil {
|
||||
glog.Warningf("Unsuccessful parsing of cluster CIDR %v: %v", ctx.Options.ClusterCIDR, err)
|
||||
}
|
||||
routeController := routecontroller.New(routes, ctx.ClientBuilder.ClientOrDie("route-controller"), ctx.InformerFactory.Core().V1().Nodes(), ctx.Options.ClusterName, clusterCIDR)
|
||||
go routeController.Run(ctx.Stop, ctx.Options.RouteReconciliationPeriod.Duration)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func startPersistentVolumeBinderController(ctx ControllerContext) (bool, error) {
|
||||
params := persistentvolumecontroller.ControllerParameters{
|
||||
KubeClient: ctx.ClientBuilder.ClientOrDie("persistent-volume-binder"),
|
||||
SyncPeriod: ctx.Options.PVClaimBinderSyncPeriod.Duration,
|
||||
VolumePlugins: ProbeControllerVolumePlugins(ctx.Cloud, ctx.Options.VolumeConfiguration),
|
||||
Cloud: ctx.Cloud,
|
||||
ClusterName: ctx.Options.ClusterName,
|
||||
VolumeInformer: ctx.InformerFactory.Core().V1().PersistentVolumes(),
|
||||
ClaimInformer: ctx.InformerFactory.Core().V1().PersistentVolumeClaims(),
|
||||
ClassInformer: ctx.InformerFactory.Storage().V1().StorageClasses(),
|
||||
EnableDynamicProvisioning: ctx.Options.VolumeConfiguration.EnableDynamicProvisioning,
|
||||
}
|
||||
volumeController, volumeControllerErr := persistentvolumecontroller.NewController(params)
|
||||
if volumeControllerErr != nil {
|
||||
return true, fmt.Errorf("failed to construct persistentvolume controller: %v", volumeControllerErr)
|
||||
}
|
||||
go volumeController.Run(ctx.Stop)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func startAttachDetachController(ctx ControllerContext) (bool, error) {
|
||||
if ctx.Options.ReconcilerSyncLoopPeriod.Duration < time.Second {
|
||||
return true, fmt.Errorf("Duration time must be greater than one second as set via command line option reconcile-sync-loop-period.")
|
||||
}
|
||||
attachDetachController, attachDetachControllerErr :=
|
||||
attachdetach.NewAttachDetachController(
|
||||
ctx.ClientBuilder.ClientOrDie("attachdetach-controller"),
|
||||
ctx.InformerFactory.Core().V1().Pods(),
|
||||
ctx.InformerFactory.Core().V1().Nodes(),
|
||||
ctx.InformerFactory.Core().V1().PersistentVolumeClaims(),
|
||||
ctx.InformerFactory.Core().V1().PersistentVolumes(),
|
||||
ctx.Cloud,
|
||||
ProbeAttachableVolumePlugins(),
|
||||
GetDynamicPluginProber(ctx.Options.VolumeConfiguration),
|
||||
ctx.Options.DisableAttachDetachReconcilerSync,
|
||||
ctx.Options.ReconcilerSyncLoopPeriod.Duration,
|
||||
attachdetach.DefaultTimerConfig,
|
||||
)
|
||||
if attachDetachControllerErr != nil {
|
||||
return true, fmt.Errorf("failed to start attach/detach controller: %v", attachDetachControllerErr)
|
||||
}
|
||||
go attachDetachController.Run(ctx.Stop)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func startVolumeExpandController(ctx ControllerContext) (bool, error) {
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.ExpandPersistentVolumes) {
|
||||
expandController, expandControllerErr := expand.NewExpandController(
|
||||
ctx.ClientBuilder.ClientOrDie("expand-controller"),
|
||||
ctx.InformerFactory.Core().V1().PersistentVolumeClaims(),
|
||||
ctx.InformerFactory.Core().V1().PersistentVolumes(),
|
||||
ctx.Cloud,
|
||||
ProbeExpandableVolumePlugins(ctx.Options.VolumeConfiguration))
|
||||
|
||||
if expandControllerErr != nil {
|
||||
return true, fmt.Errorf("Failed to start volume expand controller : %v", expandControllerErr)
|
||||
}
|
||||
go expandController.Run(ctx.Stop)
|
||||
return true, nil
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func startEndpointController(ctx ControllerContext) (bool, error) {
|
||||
go endpointcontroller.NewEndpointController(
|
||||
ctx.InformerFactory.Core().V1().Pods(),
|
||||
ctx.InformerFactory.Core().V1().Services(),
|
||||
ctx.InformerFactory.Core().V1().Endpoints(),
|
||||
ctx.ClientBuilder.ClientOrDie("endpoint-controller"),
|
||||
).Run(int(ctx.Options.ConcurrentEndpointSyncs), ctx.Stop)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func startReplicationController(ctx ControllerContext) (bool, error) {
|
||||
go replicationcontroller.NewReplicationManager(
|
||||
ctx.InformerFactory.Core().V1().Pods(),
|
||||
ctx.InformerFactory.Core().V1().ReplicationControllers(),
|
||||
ctx.ClientBuilder.ClientOrDie("replication-controller"),
|
||||
replicationcontroller.BurstReplicas,
|
||||
).Run(int(ctx.Options.ConcurrentRCSyncs), ctx.Stop)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func startPodGCController(ctx ControllerContext) (bool, error) {
|
||||
go podgc.NewPodGC(
|
||||
ctx.ClientBuilder.ClientOrDie("pod-garbage-collector"),
|
||||
ctx.InformerFactory.Core().V1().Pods(),
|
||||
int(ctx.Options.TerminatedPodGCThreshold),
|
||||
).Run(ctx.Stop)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func startResourceQuotaController(ctx ControllerContext) (bool, error) {
|
||||
resourceQuotaControllerClient := ctx.ClientBuilder.ClientOrDie("resourcequota-controller")
|
||||
discoveryFunc := resourceQuotaControllerClient.Discovery().ServerPreferredNamespacedResources
|
||||
listerFuncForResource := generic.ListerFuncForResourceFunc(ctx.InformerFactory.ForResource)
|
||||
quotaConfiguration := quotainstall.NewQuotaConfigurationForControllers(listerFuncForResource)
|
||||
|
||||
resourceQuotaControllerOptions := &resourcequotacontroller.ResourceQuotaControllerOptions{
|
||||
QuotaClient: resourceQuotaControllerClient.CoreV1(),
|
||||
ResourceQuotaInformer: ctx.InformerFactory.Core().V1().ResourceQuotas(),
|
||||
ResyncPeriod: controller.StaticResyncPeriodFunc(ctx.Options.ResourceQuotaSyncPeriod.Duration),
|
||||
InformerFactory: ctx.InformerFactory,
|
||||
ReplenishmentResyncPeriod: ResyncPeriod(&ctx.Options),
|
||||
DiscoveryFunc: discoveryFunc,
|
||||
IgnoredResourcesFunc: quotaConfiguration.IgnoredResources,
|
||||
InformersStarted: ctx.InformersStarted,
|
||||
Registry: generic.NewRegistry(quotaConfiguration.Evaluators()),
|
||||
}
|
||||
if resourceQuotaControllerClient.CoreV1().RESTClient().GetRateLimiter() != nil {
|
||||
if err := metrics.RegisterMetricAndTrackRateLimiterUsage("resource_quota_controller", resourceQuotaControllerClient.CoreV1().RESTClient().GetRateLimiter()); err != nil {
|
||||
return true, err
|
||||
}
|
||||
}
|
||||
|
||||
resourceQuotaController, err := resourcequotacontroller.NewResourceQuotaController(resourceQuotaControllerOptions)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
go resourceQuotaController.Run(int(ctx.Options.ConcurrentResourceQuotaSyncs), ctx.Stop)
|
||||
|
||||
// Periodically the quota controller to detect new resource types
|
||||
go resourceQuotaController.Sync(discoveryFunc, 30*time.Second, ctx.Stop)
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func startNamespaceController(ctx ControllerContext) (bool, error) {
|
||||
// TODO: should use a dynamic RESTMapper built from the discovery results.
|
||||
restMapper := legacyscheme.Registry.RESTMapper()
|
||||
|
||||
// the namespace cleanup controller is very chatty. It makes lots of discovery calls and then it makes lots of delete calls
|
||||
// the ratelimiter negatively affects its speed. Deleting 100 total items in a namespace (that's only a few of each resource
|
||||
// including events), takes ~10 seconds by default.
|
||||
nsKubeconfig := ctx.ClientBuilder.ConfigOrDie("namespace-controller")
|
||||
nsKubeconfig.QPS *= 10
|
||||
nsKubeconfig.Burst *= 10
|
||||
namespaceKubeClient := clientset.NewForConfigOrDie(nsKubeconfig)
|
||||
namespaceClientPool := dynamic.NewClientPool(nsKubeconfig, restMapper, dynamic.LegacyAPIPathResolverFunc)
|
||||
|
||||
discoverResourcesFn := namespaceKubeClient.Discovery().ServerPreferredNamespacedResources
|
||||
|
||||
namespaceController := namespacecontroller.NewNamespaceController(
|
||||
namespaceKubeClient,
|
||||
namespaceClientPool,
|
||||
discoverResourcesFn,
|
||||
ctx.InformerFactory.Core().V1().Namespaces(),
|
||||
ctx.Options.NamespaceSyncPeriod.Duration,
|
||||
v1.FinalizerKubernetes,
|
||||
)
|
||||
go namespaceController.Run(int(ctx.Options.ConcurrentNamespaceSyncs), ctx.Stop)
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func startServiceAccountController(ctx ControllerContext) (bool, error) {
|
||||
sac, err := serviceaccountcontroller.NewServiceAccountsController(
|
||||
ctx.InformerFactory.Core().V1().ServiceAccounts(),
|
||||
ctx.InformerFactory.Core().V1().Namespaces(),
|
||||
ctx.ClientBuilder.ClientOrDie("service-account-controller"),
|
||||
serviceaccountcontroller.DefaultServiceAccountsControllerOptions(),
|
||||
)
|
||||
if err != nil {
|
||||
return true, fmt.Errorf("error creating ServiceAccount controller: %v", err)
|
||||
}
|
||||
go sac.Run(1, ctx.Stop)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func startTTLController(ctx ControllerContext) (bool, error) {
|
||||
go ttlcontroller.NewTTLController(
|
||||
ctx.InformerFactory.Core().V1().Nodes(),
|
||||
ctx.ClientBuilder.ClientOrDie("ttl-controller"),
|
||||
).Run(5, ctx.Stop)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func startGarbageCollectorController(ctx ControllerContext) (bool, error) {
|
||||
if !ctx.Options.EnableGarbageCollector {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
gcClientset := ctx.ClientBuilder.ClientOrDie("generic-garbage-collector")
|
||||
|
||||
// Use a discovery client capable of being refreshed.
|
||||
discoveryClient := cacheddiscovery.NewMemCacheClient(gcClientset.Discovery())
|
||||
restMapper := discovery.NewDeferredDiscoveryRESTMapper(discoveryClient, meta.InterfacesForUnstructured)
|
||||
restMapper.Reset()
|
||||
|
||||
config := ctx.ClientBuilder.ConfigOrDie("generic-garbage-collector")
|
||||
config.ContentConfig = dynamic.ContentConfig()
|
||||
// TODO: Make NewMetadataCodecFactory support arbitrary (non-compiled)
|
||||
// resource types. Otherwise we'll be storing full Unstructured data in our
|
||||
// caches for custom resources. Consider porting it to work with
|
||||
// metav1alpha1.PartialObjectMetadata.
|
||||
metaOnlyClientPool := dynamic.NewClientPool(config, restMapper, dynamic.LegacyAPIPathResolverFunc)
|
||||
clientPool := dynamic.NewClientPool(config, restMapper, dynamic.LegacyAPIPathResolverFunc)
|
||||
|
||||
// Get an initial set of deletable resources to prime the garbage collector.
|
||||
deletableResources := garbagecollector.GetDeletableResources(discoveryClient)
|
||||
ignoredResources := make(map[schema.GroupResource]struct{})
|
||||
for _, r := range ctx.Options.GCIgnoredResources {
|
||||
ignoredResources[schema.GroupResource{Group: r.Group, Resource: r.Resource}] = struct{}{}
|
||||
}
|
||||
garbageCollector, err := garbagecollector.NewGarbageCollector(
|
||||
metaOnlyClientPool,
|
||||
clientPool,
|
||||
restMapper,
|
||||
deletableResources,
|
||||
ignoredResources,
|
||||
ctx.InformerFactory,
|
||||
ctx.InformersStarted,
|
||||
)
|
||||
if err != nil {
|
||||
return true, fmt.Errorf("Failed to start the generic garbage collector: %v", err)
|
||||
}
|
||||
|
||||
// Start the garbage collector.
|
||||
workers := int(ctx.Options.ConcurrentGCSyncs)
|
||||
go garbageCollector.Run(workers, ctx.Stop)
|
||||
|
||||
// Periodically refresh the RESTMapper with new discovery information and sync
|
||||
// the garbage collector.
|
||||
go garbageCollector.Sync(gcClientset.Discovery(), 30*time.Second, ctx.Stop)
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func startPVCProtectionController(ctx ControllerContext) (bool, error) {
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.PVCProtection) {
|
||||
go pvcprotection.NewPVCProtectionController(
|
||||
ctx.InformerFactory.Core().V1().PersistentVolumeClaims(),
|
||||
ctx.InformerFactory.Core().V1().Pods(),
|
||||
ctx.ClientBuilder.ClientOrDie("pvc-protection-controller"),
|
||||
).Run(1, ctx.Stop)
|
||||
return true, nil
|
||||
}
|
||||
return false, nil
|
||||
}
|
78
vendor/k8s.io/kubernetes/cmd/kube-controller-manager/app/extensions.go
generated
vendored
Normal file
78
vendor/k8s.io/kubernetes/cmd/kube-controller-manager/app/extensions.go
generated
vendored
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package app implements a server that runs a set of active
|
||||
// components. This includes replication controllers, service endpoints and
|
||||
// nodes.
|
||||
//
|
||||
package app
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/kubernetes/pkg/controller/daemon"
|
||||
"k8s.io/kubernetes/pkg/controller/deployment"
|
||||
"k8s.io/kubernetes/pkg/controller/replicaset"
|
||||
)
|
||||
|
||||
func startDaemonSetController(ctx ControllerContext) (bool, error) {
|
||||
if !ctx.AvailableResources[schema.GroupVersionResource{Group: "extensions", Version: "v1beta1", Resource: "daemonsets"}] {
|
||||
return false, nil
|
||||
}
|
||||
dsc, err := daemon.NewDaemonSetsController(
|
||||
ctx.InformerFactory.Extensions().V1beta1().DaemonSets(),
|
||||
ctx.InformerFactory.Apps().V1beta1().ControllerRevisions(),
|
||||
ctx.InformerFactory.Core().V1().Pods(),
|
||||
ctx.InformerFactory.Core().V1().Nodes(),
|
||||
ctx.ClientBuilder.ClientOrDie("daemon-set-controller"),
|
||||
)
|
||||
if err != nil {
|
||||
return true, fmt.Errorf("error creating DaemonSets controller: %v", err)
|
||||
}
|
||||
go dsc.Run(int(ctx.Options.ConcurrentDaemonSetSyncs), ctx.Stop)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func startDeploymentController(ctx ControllerContext) (bool, error) {
|
||||
if !ctx.AvailableResources[schema.GroupVersionResource{Group: "extensions", Version: "v1beta1", Resource: "deployments"}] {
|
||||
return false, nil
|
||||
}
|
||||
dc, err := deployment.NewDeploymentController(
|
||||
ctx.InformerFactory.Extensions().V1beta1().Deployments(),
|
||||
ctx.InformerFactory.Extensions().V1beta1().ReplicaSets(),
|
||||
ctx.InformerFactory.Core().V1().Pods(),
|
||||
ctx.ClientBuilder.ClientOrDie("deployment-controller"),
|
||||
)
|
||||
if err != nil {
|
||||
return true, fmt.Errorf("error creating Deployment controller: %v", err)
|
||||
}
|
||||
go dc.Run(int(ctx.Options.ConcurrentDeploymentSyncs), ctx.Stop)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func startReplicaSetController(ctx ControllerContext) (bool, error) {
|
||||
if !ctx.AvailableResources[schema.GroupVersionResource{Group: "extensions", Version: "v1beta1", Resource: "replicasets"}] {
|
||||
return false, nil
|
||||
}
|
||||
go replicaset.NewReplicaSetController(
|
||||
ctx.InformerFactory.Extensions().V1beta1().ReplicaSets(),
|
||||
ctx.InformerFactory.Core().V1().Pods(),
|
||||
ctx.ClientBuilder.ClientOrDie("replicaset-controller"),
|
||||
replicaset.BurstReplicas,
|
||||
).Run(int(ctx.Options.ConcurrentRSSyncs), ctx.Stop)
|
||||
return true, nil
|
||||
}
|
46
vendor/k8s.io/kubernetes/cmd/kube-controller-manager/app/import_known_versions.go
generated
vendored
Normal file
46
vendor/k8s.io/kubernetes/cmd/kube-controller-manager/app/import_known_versions.go
generated
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// TODO: Remove this file when namespace controller and garbage collector
|
||||
// stops using legacyscheme.Registry.RESTMapper()
|
||||
package app
|
||||
|
||||
// These imports are the API groups the client will support.
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||
_ "k8s.io/kubernetes/pkg/apis/apps/install"
|
||||
_ "k8s.io/kubernetes/pkg/apis/authentication/install"
|
||||
_ "k8s.io/kubernetes/pkg/apis/authorization/install"
|
||||
_ "k8s.io/kubernetes/pkg/apis/autoscaling/install"
|
||||
_ "k8s.io/kubernetes/pkg/apis/batch/install"
|
||||
_ "k8s.io/kubernetes/pkg/apis/certificates/install"
|
||||
_ "k8s.io/kubernetes/pkg/apis/core/install"
|
||||
_ "k8s.io/kubernetes/pkg/apis/events/install"
|
||||
_ "k8s.io/kubernetes/pkg/apis/extensions/install"
|
||||
_ "k8s.io/kubernetes/pkg/apis/policy/install"
|
||||
_ "k8s.io/kubernetes/pkg/apis/rbac/install"
|
||||
_ "k8s.io/kubernetes/pkg/apis/scheduling/install"
|
||||
_ "k8s.io/kubernetes/pkg/apis/settings/install"
|
||||
_ "k8s.io/kubernetes/pkg/apis/storage/install"
|
||||
)
|
||||
|
||||
func init() {
|
||||
if missingVersions := legacyscheme.Registry.ValidateEnvRequestedVersions(); len(missingVersions) != 0 {
|
||||
panic(fmt.Sprintf("KUBE_API_VERSIONS contains versions that are not installed: %q.", missingVersions))
|
||||
}
|
||||
}
|
53
vendor/k8s.io/kubernetes/cmd/kube-controller-manager/app/options/BUILD
generated
vendored
Normal file
53
vendor/k8s.io/kubernetes/cmd/kube-controller-manager/app/options/BUILD
generated
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
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"],
|
||||
importpath = "k8s.io/kubernetes/cmd/kube-controller-manager/app/options",
|
||||
deps = [
|
||||
"//pkg/apis/componentconfig:go_default_library",
|
||||
"//pkg/client/leaderelectionconfig:go_default_library",
|
||||
"//pkg/controller/garbagecollector:go_default_library",
|
||||
"//pkg/features:go_default_library",
|
||||
"//pkg/master/ports:go_default_library",
|
||||
"//vendor/github.com/cloudflare/cfssl/helpers:go_default_library",
|
||||
"//vendor/github.com/spf13/pflag:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["options_test.go"],
|
||||
importpath = "k8s.io/kubernetes/cmd/kube-controller-manager/app/options",
|
||||
library = ":go_default_library",
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//pkg/apis/componentconfig:go_default_library",
|
||||
"//vendor/github.com/spf13/pflag:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/diff:go_default_library",
|
||||
],
|
||||
)
|
258
vendor/k8s.io/kubernetes/cmd/kube-controller-manager/app/options/options.go
generated
vendored
Normal file
258
vendor/k8s.io/kubernetes/cmd/kube-controller-manager/app/options/options.go
generated
vendored
Normal file
@ -0,0 +1,258 @@
|
||||
/*
|
||||
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 provides the flags used for the controller manager.
|
||||
//
|
||||
package options
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
"k8s.io/kubernetes/pkg/apis/componentconfig"
|
||||
"k8s.io/kubernetes/pkg/client/leaderelectionconfig"
|
||||
"k8s.io/kubernetes/pkg/controller/garbagecollector"
|
||||
"k8s.io/kubernetes/pkg/master/ports"
|
||||
|
||||
// add the kubernetes feature gates
|
||||
_ "k8s.io/kubernetes/pkg/features"
|
||||
|
||||
"github.com/cloudflare/cfssl/helpers"
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
const (
|
||||
// These defaults are deprecated and exported so that we can warn if
|
||||
// they are being used.
|
||||
|
||||
// DefaultClusterSigningCertFile is deprecated. Do not use.
|
||||
DefaultClusterSigningCertFile = "/etc/kubernetes/ca/ca.pem"
|
||||
// DefaultClusterSigningKeyFile is deprecated. Do not use.
|
||||
DefaultClusterSigningKeyFile = "/etc/kubernetes/ca/ca.key"
|
||||
)
|
||||
|
||||
// CMServer is the main context object for the controller manager.
|
||||
type CMServer struct {
|
||||
componentconfig.KubeControllerManagerConfiguration
|
||||
|
||||
Master string
|
||||
Kubeconfig string
|
||||
}
|
||||
|
||||
// NewCMServer creates a new CMServer with a default config.
|
||||
func NewCMServer() *CMServer {
|
||||
gcIgnoredResources := make([]componentconfig.GroupResource, 0, len(garbagecollector.DefaultIgnoredResources()))
|
||||
for r := range garbagecollector.DefaultIgnoredResources() {
|
||||
gcIgnoredResources = append(gcIgnoredResources, componentconfig.GroupResource{Group: r.Group, Resource: r.Resource})
|
||||
}
|
||||
|
||||
s := CMServer{
|
||||
// Part of these default values also present in 'cmd/cloud-controller-manager/app/options/options.go'.
|
||||
// Please keep them in sync when doing update.
|
||||
KubeControllerManagerConfiguration: componentconfig.KubeControllerManagerConfiguration{
|
||||
Controllers: []string{"*"},
|
||||
Port: ports.ControllerManagerPort,
|
||||
Address: "0.0.0.0",
|
||||
ConcurrentEndpointSyncs: 5,
|
||||
ConcurrentServiceSyncs: 1,
|
||||
ConcurrentRCSyncs: 5,
|
||||
ConcurrentRSSyncs: 5,
|
||||
ConcurrentDaemonSetSyncs: 2,
|
||||
ConcurrentJobSyncs: 5,
|
||||
ConcurrentResourceQuotaSyncs: 5,
|
||||
ConcurrentDeploymentSyncs: 5,
|
||||
ConcurrentNamespaceSyncs: 10,
|
||||
ConcurrentSATokenSyncs: 5,
|
||||
ServiceSyncPeriod: metav1.Duration{Duration: 5 * time.Minute},
|
||||
RouteReconciliationPeriod: metav1.Duration{Duration: 10 * time.Second},
|
||||
ResourceQuotaSyncPeriod: metav1.Duration{Duration: 5 * time.Minute},
|
||||
NamespaceSyncPeriod: metav1.Duration{Duration: 5 * time.Minute},
|
||||
PVClaimBinderSyncPeriod: metav1.Duration{Duration: 15 * time.Second},
|
||||
HorizontalPodAutoscalerSyncPeriod: metav1.Duration{Duration: 30 * time.Second},
|
||||
HorizontalPodAutoscalerUpscaleForbiddenWindow: metav1.Duration{Duration: 3 * time.Minute},
|
||||
HorizontalPodAutoscalerDownscaleForbiddenWindow: metav1.Duration{Duration: 5 * time.Minute},
|
||||
HorizontalPodAutoscalerTolerance: 0.1,
|
||||
DeploymentControllerSyncPeriod: metav1.Duration{Duration: 30 * time.Second},
|
||||
MinResyncPeriod: metav1.Duration{Duration: 12 * time.Hour},
|
||||
RegisterRetryCount: 10,
|
||||
PodEvictionTimeout: metav1.Duration{Duration: 5 * time.Minute},
|
||||
NodeMonitorGracePeriod: metav1.Duration{Duration: 40 * time.Second},
|
||||
NodeStartupGracePeriod: metav1.Duration{Duration: 60 * time.Second},
|
||||
NodeMonitorPeriod: metav1.Duration{Duration: 5 * time.Second},
|
||||
ClusterName: "kubernetes",
|
||||
NodeCIDRMaskSize: 24,
|
||||
ConfigureCloudRoutes: true,
|
||||
TerminatedPodGCThreshold: 12500,
|
||||
VolumeConfiguration: componentconfig.VolumeConfiguration{
|
||||
EnableHostPathProvisioning: false,
|
||||
EnableDynamicProvisioning: true,
|
||||
PersistentVolumeRecyclerConfiguration: componentconfig.PersistentVolumeRecyclerConfiguration{
|
||||
MaximumRetry: 3,
|
||||
MinimumTimeoutNFS: 300,
|
||||
IncrementTimeoutNFS: 30,
|
||||
MinimumTimeoutHostPath: 60,
|
||||
IncrementTimeoutHostPath: 30,
|
||||
},
|
||||
FlexVolumePluginDir: "/usr/libexec/kubernetes/kubelet-plugins/volume/exec/",
|
||||
},
|
||||
ContentType: "application/vnd.kubernetes.protobuf",
|
||||
KubeAPIQPS: 20.0,
|
||||
KubeAPIBurst: 30,
|
||||
LeaderElection: leaderelectionconfig.DefaultLeaderElectionConfiguration(),
|
||||
ControllerStartInterval: metav1.Duration{Duration: 0 * time.Second},
|
||||
EnableGarbageCollector: true,
|
||||
ConcurrentGCSyncs: 20,
|
||||
GCIgnoredResources: gcIgnoredResources,
|
||||
ClusterSigningCertFile: DefaultClusterSigningCertFile,
|
||||
ClusterSigningKeyFile: DefaultClusterSigningKeyFile,
|
||||
ClusterSigningDuration: metav1.Duration{Duration: helpers.OneYear},
|
||||
ReconcilerSyncLoopPeriod: metav1.Duration{Duration: 60 * time.Second},
|
||||
EnableTaintManager: true,
|
||||
HorizontalPodAutoscalerUseRESTClients: true,
|
||||
},
|
||||
}
|
||||
s.LeaderElection.LeaderElect = true
|
||||
return &s
|
||||
}
|
||||
|
||||
// AddFlags adds flags for a specific CMServer to the specified FlagSet
|
||||
func (s *CMServer) AddFlags(fs *pflag.FlagSet, allControllers []string, disabledByDefaultControllers []string) {
|
||||
fs.StringSliceVar(&s.Controllers, "controllers", s.Controllers, fmt.Sprintf(""+
|
||||
"A list of controllers to enable. '*' enables all on-by-default controllers, 'foo' enables the controller "+
|
||||
"named 'foo', '-foo' disables the controller named 'foo'.\nAll controllers: %s\nDisabled-by-default controllers: %s",
|
||||
strings.Join(allControllers, ", "), strings.Join(disabledByDefaultControllers, ", ")))
|
||||
fs.Int32Var(&s.Port, "port", s.Port, "The port that the controller-manager's http service runs on")
|
||||
fs.Var(componentconfig.IPVar{Val: &s.Address}, "address", "The IP address to serve on (set to 0.0.0.0 for all interfaces)")
|
||||
fs.BoolVar(&s.UseServiceAccountCredentials, "use-service-account-credentials", s.UseServiceAccountCredentials, "If true, use individual service account credentials for each controller.")
|
||||
fs.StringVar(&s.CloudProvider, "cloud-provider", s.CloudProvider, "The provider for cloud services. Empty string for no provider.")
|
||||
fs.StringVar(&s.CloudConfigFile, "cloud-config", s.CloudConfigFile, "The path to the cloud provider configuration file. Empty string for no configuration file.")
|
||||
fs.BoolVar(&s.AllowUntaggedCloud, "allow-untagged-cloud", false, "Allow the cluster to run without the cluster-id on cloud instances. This is a legacy mode of operation and a cluster-id will be required in the future.")
|
||||
fs.MarkDeprecated("allow-untagged-cloud", "This flag is deprecated and will be removed in a future release. A cluster-id will be required on cloud instances")
|
||||
fs.Int32Var(&s.ConcurrentEndpointSyncs, "concurrent-endpoint-syncs", s.ConcurrentEndpointSyncs, "The number of endpoint syncing operations that will be done concurrently. Larger number = faster endpoint updating, but more CPU (and network) load")
|
||||
fs.Int32Var(&s.ConcurrentServiceSyncs, "concurrent-service-syncs", s.ConcurrentServiceSyncs, "The number of services that are allowed to sync concurrently. Larger number = more responsive service management, but more CPU (and network) load")
|
||||
fs.Int32Var(&s.ConcurrentRCSyncs, "concurrent_rc_syncs", s.ConcurrentRCSyncs, "The number of replication controllers that are allowed to sync concurrently. Larger number = more responsive replica management, but more CPU (and network) load")
|
||||
fs.Int32Var(&s.ConcurrentRSSyncs, "concurrent-replicaset-syncs", s.ConcurrentRSSyncs, "The number of replica sets that are allowed to sync concurrently. Larger number = more responsive replica management, but more CPU (and network) load")
|
||||
fs.Int32Var(&s.ConcurrentResourceQuotaSyncs, "concurrent-resource-quota-syncs", s.ConcurrentResourceQuotaSyncs, "The number of resource quotas that are allowed to sync concurrently. Larger number = more responsive quota management, but more CPU (and network) load")
|
||||
fs.Int32Var(&s.ConcurrentDeploymentSyncs, "concurrent-deployment-syncs", s.ConcurrentDeploymentSyncs, "The number of deployment objects that are allowed to sync concurrently. Larger number = more responsive deployments, but more CPU (and network) load")
|
||||
fs.Int32Var(&s.ConcurrentNamespaceSyncs, "concurrent-namespace-syncs", s.ConcurrentNamespaceSyncs, "The number of namespace objects that are allowed to sync concurrently. Larger number = more responsive namespace termination, but more CPU (and network) load")
|
||||
fs.Int32Var(&s.ConcurrentSATokenSyncs, "concurrent-serviceaccount-token-syncs", s.ConcurrentSATokenSyncs, "The number of service account token objects that are allowed to sync concurrently. Larger number = more responsive token generation, but more CPU (and network) load")
|
||||
fs.DurationVar(&s.ServiceSyncPeriod.Duration, "service-sync-period", s.ServiceSyncPeriod.Duration, "The period for syncing services with their external load balancers")
|
||||
fs.DurationVar(&s.NodeSyncPeriod.Duration, "node-sync-period", 0, ""+
|
||||
"This flag is deprecated and will be removed in future releases. See node-monitor-period for Node health checking or "+
|
||||
"route-reconciliation-period for cloud provider's route configuration settings.")
|
||||
fs.MarkDeprecated("node-sync-period", "This flag is currently no-op and will be deleted.")
|
||||
fs.DurationVar(&s.RouteReconciliationPeriod.Duration, "route-reconciliation-period", s.RouteReconciliationPeriod.Duration, "The period for reconciling routes created for Nodes by cloud provider.")
|
||||
fs.DurationVar(&s.ResourceQuotaSyncPeriod.Duration, "resource-quota-sync-period", s.ResourceQuotaSyncPeriod.Duration, "The period for syncing quota usage status in the system")
|
||||
fs.DurationVar(&s.NamespaceSyncPeriod.Duration, "namespace-sync-period", s.NamespaceSyncPeriod.Duration, "The period for syncing namespace life-cycle updates")
|
||||
fs.DurationVar(&s.PVClaimBinderSyncPeriod.Duration, "pvclaimbinder-sync-period", s.PVClaimBinderSyncPeriod.Duration, "The period for syncing persistent volumes and persistent volume claims")
|
||||
fs.DurationVar(&s.MinResyncPeriod.Duration, "min-resync-period", s.MinResyncPeriod.Duration, "The resync period in reflectors will be random between MinResyncPeriod and 2*MinResyncPeriod")
|
||||
fs.StringVar(&s.VolumeConfiguration.PersistentVolumeRecyclerConfiguration.PodTemplateFilePathNFS, "pv-recycler-pod-template-filepath-nfs", s.VolumeConfiguration.PersistentVolumeRecyclerConfiguration.PodTemplateFilePathNFS, "The file path to a pod definition used as a template for NFS persistent volume recycling")
|
||||
fs.Int32Var(&s.VolumeConfiguration.PersistentVolumeRecyclerConfiguration.MinimumTimeoutNFS, "pv-recycler-minimum-timeout-nfs", s.VolumeConfiguration.PersistentVolumeRecyclerConfiguration.MinimumTimeoutNFS, "The minimum ActiveDeadlineSeconds to use for an NFS Recycler pod")
|
||||
fs.Int32Var(&s.VolumeConfiguration.PersistentVolumeRecyclerConfiguration.IncrementTimeoutNFS, "pv-recycler-increment-timeout-nfs", s.VolumeConfiguration.PersistentVolumeRecyclerConfiguration.IncrementTimeoutNFS, "the increment of time added per Gi to ActiveDeadlineSeconds for an NFS scrubber pod")
|
||||
fs.StringVar(&s.VolumeConfiguration.PersistentVolumeRecyclerConfiguration.PodTemplateFilePathHostPath, "pv-recycler-pod-template-filepath-hostpath", s.VolumeConfiguration.PersistentVolumeRecyclerConfiguration.PodTemplateFilePathHostPath, "The file path to a pod definition used as a template for HostPath persistent volume recycling. This is for development and testing only and will not work in a multi-node cluster.")
|
||||
fs.Int32Var(&s.VolumeConfiguration.PersistentVolumeRecyclerConfiguration.MinimumTimeoutHostPath, "pv-recycler-minimum-timeout-hostpath", s.VolumeConfiguration.PersistentVolumeRecyclerConfiguration.MinimumTimeoutHostPath, "The minimum ActiveDeadlineSeconds to use for a HostPath Recycler pod. This is for development and testing only and will not work in a multi-node cluster.")
|
||||
fs.Int32Var(&s.VolumeConfiguration.PersistentVolumeRecyclerConfiguration.IncrementTimeoutHostPath, "pv-recycler-timeout-increment-hostpath", s.VolumeConfiguration.PersistentVolumeRecyclerConfiguration.IncrementTimeoutHostPath, "the increment of time added per Gi to ActiveDeadlineSeconds for a HostPath scrubber pod. This is for development and testing only and will not work in a multi-node cluster.")
|
||||
fs.BoolVar(&s.VolumeConfiguration.EnableHostPathProvisioning, "enable-hostpath-provisioner", s.VolumeConfiguration.EnableHostPathProvisioning, "Enable HostPath PV provisioning when running without a cloud provider. This allows testing and development of provisioning features. HostPath provisioning is not supported in any way, won't work in a multi-node cluster, and should not be used for anything other than testing or development.")
|
||||
fs.BoolVar(&s.VolumeConfiguration.EnableDynamicProvisioning, "enable-dynamic-provisioning", s.VolumeConfiguration.EnableDynamicProvisioning, "Enable dynamic provisioning for environments that support it.")
|
||||
fs.StringVar(&s.VolumeConfiguration.FlexVolumePluginDir, "flex-volume-plugin-dir", s.VolumeConfiguration.FlexVolumePluginDir, "Full path of the directory in which the flex volume plugin should search for additional third party volume plugins.")
|
||||
fs.Int32Var(&s.TerminatedPodGCThreshold, "terminated-pod-gc-threshold", s.TerminatedPodGCThreshold, "Number of terminated pods that can exist before the terminated pod garbage collector starts deleting terminated pods. If <= 0, the terminated pod garbage collector is disabled.")
|
||||
fs.DurationVar(&s.HorizontalPodAutoscalerSyncPeriod.Duration, "horizontal-pod-autoscaler-sync-period", s.HorizontalPodAutoscalerSyncPeriod.Duration, "The period for syncing the number of pods in horizontal pod autoscaler.")
|
||||
fs.DurationVar(&s.HorizontalPodAutoscalerUpscaleForbiddenWindow.Duration, "horizontal-pod-autoscaler-upscale-delay", s.HorizontalPodAutoscalerUpscaleForbiddenWindow.Duration, "The period since last upscale, before another upscale can be performed in horizontal pod autoscaler.")
|
||||
fs.DurationVar(&s.HorizontalPodAutoscalerDownscaleForbiddenWindow.Duration, "horizontal-pod-autoscaler-downscale-delay", s.HorizontalPodAutoscalerDownscaleForbiddenWindow.Duration, "The period since last downscale, before another downscale can be performed in horizontal pod autoscaler.")
|
||||
fs.Float64Var(&s.HorizontalPodAutoscalerTolerance, "horizontal-pod-autoscaler-tolerance", s.HorizontalPodAutoscalerTolerance, "The minimum change (from 1.0) in the desired-to-actual metrics ratio for the horizontal pod autoscaler to consider scaling.")
|
||||
fs.DurationVar(&s.DeploymentControllerSyncPeriod.Duration, "deployment-controller-sync-period", s.DeploymentControllerSyncPeriod.Duration, "Period for syncing the deployments.")
|
||||
fs.DurationVar(&s.PodEvictionTimeout.Duration, "pod-eviction-timeout", s.PodEvictionTimeout.Duration, "The grace period for deleting pods on failed nodes.")
|
||||
fs.Float32Var(&s.DeletingPodsQps, "deleting-pods-qps", 0.1, "Number of nodes per second on which pods are deleted in case of node failure.")
|
||||
fs.MarkDeprecated("deleting-pods-qps", "This flag is currently no-op and will be deleted.")
|
||||
fs.Int32Var(&s.DeletingPodsBurst, "deleting-pods-burst", 0, "Number of nodes on which pods are bursty deleted in case of node failure. For more details look into RateLimiter.")
|
||||
fs.MarkDeprecated("deleting-pods-burst", "This flag is currently no-op and will be deleted.")
|
||||
fs.Int32Var(&s.RegisterRetryCount, "register-retry-count", s.RegisterRetryCount, ""+
|
||||
"The number of retries for initial node registration. Retry interval equals node-sync-period.")
|
||||
fs.MarkDeprecated("register-retry-count", "This flag is currently no-op and will be deleted.")
|
||||
fs.DurationVar(&s.NodeMonitorGracePeriod.Duration, "node-monitor-grace-period", s.NodeMonitorGracePeriod.Duration,
|
||||
"Amount of time which we allow running Node to be unresponsive before marking it unhealthy. "+
|
||||
"Must be N times more than kubelet's nodeStatusUpdateFrequency, "+
|
||||
"where N means number of retries allowed for kubelet to post node status.")
|
||||
fs.DurationVar(&s.NodeStartupGracePeriod.Duration, "node-startup-grace-period", s.NodeStartupGracePeriod.Duration,
|
||||
"Amount of time which we allow starting Node to be unresponsive before marking it unhealthy.")
|
||||
fs.DurationVar(&s.NodeMonitorPeriod.Duration, "node-monitor-period", s.NodeMonitorPeriod.Duration,
|
||||
"The period for syncing NodeStatus in NodeController.")
|
||||
fs.StringVar(&s.ServiceAccountKeyFile, "service-account-private-key-file", s.ServiceAccountKeyFile, "Filename containing a PEM-encoded private RSA or ECDSA key used to sign service account tokens.")
|
||||
fs.StringVar(&s.ClusterSigningCertFile, "cluster-signing-cert-file", s.ClusterSigningCertFile, "Filename containing a PEM-encoded X509 CA certificate used to issue cluster-scoped certificates")
|
||||
fs.StringVar(&s.ClusterSigningKeyFile, "cluster-signing-key-file", s.ClusterSigningKeyFile, "Filename containing a PEM-encoded RSA or ECDSA private key used to sign cluster-scoped certificates")
|
||||
fs.DurationVar(&s.ClusterSigningDuration.Duration, "experimental-cluster-signing-duration", s.ClusterSigningDuration.Duration, "The length of duration signed certificates will be given.")
|
||||
var dummy string
|
||||
fs.MarkDeprecated("insecure-experimental-approve-all-kubelet-csrs-for-group", "This flag does nothing.")
|
||||
fs.StringVar(&dummy, "insecure-experimental-approve-all-kubelet-csrs-for-group", "", "This flag does nothing.")
|
||||
fs.BoolVar(&s.EnableProfiling, "profiling", true, "Enable profiling via web interface host:port/debug/pprof/")
|
||||
fs.BoolVar(&s.EnableContentionProfiling, "contention-profiling", false, "Enable lock contention profiling, if profiling is enabled")
|
||||
fs.StringVar(&s.ClusterName, "cluster-name", s.ClusterName, "The instance prefix for the cluster")
|
||||
fs.StringVar(&s.ClusterCIDR, "cluster-cidr", s.ClusterCIDR, "CIDR Range for Pods in cluster. Requires --allocate-node-cidrs to be true")
|
||||
fs.StringVar(&s.ServiceCIDR, "service-cluster-ip-range", s.ServiceCIDR, "CIDR Range for Services in cluster. Requires --allocate-node-cidrs to be true")
|
||||
fs.Int32Var(&s.NodeCIDRMaskSize, "node-cidr-mask-size", s.NodeCIDRMaskSize, "Mask size for node cidr in cluster.")
|
||||
fs.BoolVar(&s.AllocateNodeCIDRs, "allocate-node-cidrs", false,
|
||||
"Should CIDRs for Pods be allocated and set on the cloud provider.")
|
||||
fs.StringVar(&s.CIDRAllocatorType, "cidr-allocator-type", "RangeAllocator",
|
||||
"Type of CIDR allocator to use")
|
||||
fs.BoolVar(&s.ConfigureCloudRoutes, "configure-cloud-routes", true, "Should CIDRs allocated by allocate-node-cidrs be configured on the cloud provider.")
|
||||
fs.StringVar(&s.Master, "master", s.Master, "The address of the Kubernetes API server (overrides any value in kubeconfig)")
|
||||
fs.StringVar(&s.Kubeconfig, "kubeconfig", s.Kubeconfig, "Path to kubeconfig file with authorization and master location information.")
|
||||
fs.StringVar(&s.RootCAFile, "root-ca-file", s.RootCAFile, "If set, this root certificate authority will be included in service account's token secret. This must be a valid PEM-encoded CA bundle.")
|
||||
fs.StringVar(&s.ContentType, "kube-api-content-type", s.ContentType, "Content type of requests sent to apiserver.")
|
||||
fs.Float32Var(&s.KubeAPIQPS, "kube-api-qps", s.KubeAPIQPS, "QPS to use while talking with kubernetes apiserver")
|
||||
fs.Int32Var(&s.KubeAPIBurst, "kube-api-burst", s.KubeAPIBurst, "Burst to use while talking with kubernetes apiserver")
|
||||
fs.DurationVar(&s.ControllerStartInterval.Duration, "controller-start-interval", s.ControllerStartInterval.Duration, "Interval between starting controller managers.")
|
||||
fs.BoolVar(&s.EnableGarbageCollector, "enable-garbage-collector", s.EnableGarbageCollector, "Enables the generic garbage collector. MUST be synced with the corresponding flag of the kube-apiserver.")
|
||||
fs.Int32Var(&s.ConcurrentGCSyncs, "concurrent-gc-syncs", s.ConcurrentGCSyncs, "The number of garbage collector workers that are allowed to sync concurrently.")
|
||||
fs.Float32Var(&s.NodeEvictionRate, "node-eviction-rate", 0.1, "Number of nodes per second on which pods are deleted in case of node failure when a zone is healthy (see --unhealthy-zone-threshold for definition of healthy/unhealthy). Zone refers to entire cluster in non-multizone clusters.")
|
||||
fs.Float32Var(&s.SecondaryNodeEvictionRate, "secondary-node-eviction-rate", 0.01, "Number of nodes per second on which pods are deleted in case of node failure when a zone is unhealthy (see --unhealthy-zone-threshold for definition of healthy/unhealthy). Zone refers to entire cluster in non-multizone clusters. This value is implicitly overridden to 0 if the cluster size is smaller than --large-cluster-size-threshold.")
|
||||
fs.Int32Var(&s.LargeClusterSizeThreshold, "large-cluster-size-threshold", 50, "Number of nodes from which NodeController treats the cluster as large for the eviction logic purposes. --secondary-node-eviction-rate is implicitly overridden to 0 for clusters this size or smaller.")
|
||||
fs.Float32Var(&s.UnhealthyZoneThreshold, "unhealthy-zone-threshold", 0.55, "Fraction of Nodes in a zone which needs to be not Ready (minimum 3) for zone to be treated as unhealthy. ")
|
||||
fs.BoolVar(&s.DisableAttachDetachReconcilerSync, "disable-attach-detach-reconcile-sync", false, "Disable volume attach detach reconciler sync. Disabling this may cause volumes to be mismatched with pods. Use wisely.")
|
||||
fs.DurationVar(&s.ReconcilerSyncLoopPeriod.Duration, "attach-detach-reconcile-sync-period", s.ReconcilerSyncLoopPeriod.Duration, "The reconciler sync wait time between volume attach detach. This duration must be larger than one second, and increasing this value from the default may allow for volumes to be mismatched with pods.")
|
||||
fs.BoolVar(&s.EnableTaintManager, "enable-taint-manager", s.EnableTaintManager, "WARNING: Beta feature. If set to true enables NoExecute Taints and will evict all not-tolerating Pod running on Nodes tainted with this kind of Taints.")
|
||||
fs.BoolVar(&s.HorizontalPodAutoscalerUseRESTClients, "horizontal-pod-autoscaler-use-rest-clients", s.HorizontalPodAutoscalerUseRESTClients, "WARNING: alpha feature. If set to true, causes the horizontal pod autoscaler controller to use REST clients through the kube-aggregator, instead of using the legacy metrics client through the API server proxy. This is required for custom metrics support in the horizontal pod autoscaler.")
|
||||
|
||||
leaderelectionconfig.BindFlags(&s.LeaderElection, fs)
|
||||
|
||||
utilfeature.DefaultFeatureGate.AddFlag(fs)
|
||||
}
|
||||
|
||||
// Validate is used to validate the options and config before launching the controller manager
|
||||
func (s *CMServer) Validate(allControllers []string, disabledByDefaultControllers []string) error {
|
||||
var errs []error
|
||||
|
||||
allControllersSet := sets.NewString(allControllers...)
|
||||
for _, controller := range s.Controllers {
|
||||
if controller == "*" {
|
||||
continue
|
||||
}
|
||||
if strings.HasPrefix(controller, "-") {
|
||||
controller = controller[1:]
|
||||
}
|
||||
|
||||
if !allControllersSet.Has(controller) {
|
||||
errs = append(errs, fmt.Errorf("%q is not in the list of known controllers", controller))
|
||||
}
|
||||
}
|
||||
|
||||
return utilerrors.NewAggregate(errs)
|
||||
}
|
237
vendor/k8s.io/kubernetes/cmd/kube-controller-manager/app/options/options_test.go
generated
vendored
Normal file
237
vendor/k8s.io/kubernetes/cmd/kube-controller-manager/app/options/options_test.go
generated
vendored
Normal file
@ -0,0 +1,237 @@
|
||||
/*
|
||||
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 options
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"sort"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/diff"
|
||||
"k8s.io/kubernetes/pkg/apis/componentconfig"
|
||||
)
|
||||
|
||||
func TestAddFlags(t *testing.T) {
|
||||
f := pflag.NewFlagSet("addflagstest", pflag.ContinueOnError)
|
||||
s := NewCMServer()
|
||||
s.AddFlags(f, []string{""}, []string{""})
|
||||
|
||||
args := []string{
|
||||
"--address=192.168.4.10",
|
||||
"--allocate-node-cidrs=true",
|
||||
"--attach-detach-reconcile-sync-period=30s",
|
||||
"--cidr-allocator-type=CloudAllocator",
|
||||
"--cloud-config=/cloud-config",
|
||||
"--cloud-provider=gce",
|
||||
"--cluster-cidr=1.2.3.4/24",
|
||||
"--cluster-name=k8s",
|
||||
"--cluster-signing-cert-file=/cluster-signing-cert",
|
||||
"--cluster-signing-key-file=/cluster-signing-key",
|
||||
"--concurrent-deployment-syncs=10",
|
||||
"--concurrent-endpoint-syncs=10",
|
||||
"--concurrent-gc-syncs=30",
|
||||
"--concurrent-namespace-syncs=20",
|
||||
"--concurrent-replicaset-syncs=10",
|
||||
"--concurrent-resource-quota-syncs=10",
|
||||
"--concurrent-service-syncs=2",
|
||||
"--concurrent-serviceaccount-token-syncs=10",
|
||||
"--concurrent_rc_syncs=10",
|
||||
"--configure-cloud-routes=false",
|
||||
"--contention-profiling=true",
|
||||
"--controller-start-interval=2m",
|
||||
"--controllers=foo,bar",
|
||||
"--deployment-controller-sync-period=45s",
|
||||
"--disable-attach-detach-reconcile-sync=true",
|
||||
"--enable-dynamic-provisioning=false",
|
||||
"--enable-garbage-collector=false",
|
||||
"--enable-hostpath-provisioner=true",
|
||||
"--enable-taint-manager=false",
|
||||
"--experimental-cluster-signing-duration=10h",
|
||||
"--flex-volume-plugin-dir=/flex-volume-plugin",
|
||||
"--horizontal-pod-autoscaler-downscale-delay=2m",
|
||||
"--horizontal-pod-autoscaler-sync-period=45s",
|
||||
"--horizontal-pod-autoscaler-upscale-delay=1m",
|
||||
"--kube-api-burst=100",
|
||||
"--kube-api-content-type=application/json",
|
||||
"--kube-api-qps=50.0",
|
||||
"--kubeconfig=/kubeconfig",
|
||||
"--large-cluster-size-threshold=100",
|
||||
"--leader-elect=false",
|
||||
"--leader-elect-lease-duration=30s",
|
||||
"--leader-elect-renew-deadline=15s",
|
||||
"--leader-elect-resource-lock=configmap",
|
||||
"--leader-elect-retry-period=5s",
|
||||
"--master=192.168.4.20",
|
||||
"--min-resync-period=8h",
|
||||
"--namespace-sync-period=10m",
|
||||
"--node-cidr-mask-size=48",
|
||||
"--node-eviction-rate=0.2",
|
||||
"--node-monitor-grace-period=30s",
|
||||
"--node-monitor-period=10s",
|
||||
"--node-startup-grace-period=30s",
|
||||
"--pod-eviction-timeout=2m",
|
||||
"--port=10000",
|
||||
"--profiling=false",
|
||||
"--pv-recycler-increment-timeout-nfs=45",
|
||||
"--pv-recycler-minimum-timeout-hostpath=45",
|
||||
"--pv-recycler-minimum-timeout-nfs=200",
|
||||
"--pv-recycler-timeout-increment-hostpath=45",
|
||||
"--pvclaimbinder-sync-period=30s",
|
||||
"--resource-quota-sync-period=10m",
|
||||
"--route-reconciliation-period=30s",
|
||||
"--secondary-node-eviction-rate=0.05",
|
||||
"--service-account-private-key-file=/service-account-private-key",
|
||||
"--service-sync-period=2m",
|
||||
"--terminated-pod-gc-threshold=12000",
|
||||
"--unhealthy-zone-threshold=0.6",
|
||||
"--use-service-account-credentials=true",
|
||||
}
|
||||
f.Parse(args)
|
||||
// Sort GCIgnoredResources because it's built from a map, which means the
|
||||
// insertion order is random.
|
||||
sort.Sort(sortedGCIgnoredResources(s.GCIgnoredResources))
|
||||
|
||||
expected := &CMServer{
|
||||
KubeControllerManagerConfiguration: componentconfig.KubeControllerManagerConfiguration{
|
||||
Port: 10000,
|
||||
Address: "192.168.4.10",
|
||||
AllocateNodeCIDRs: true,
|
||||
CloudConfigFile: "/cloud-config",
|
||||
CloudProvider: "gce",
|
||||
ClusterCIDR: "1.2.3.4/24",
|
||||
ClusterName: "k8s",
|
||||
ConcurrentDeploymentSyncs: 10,
|
||||
ConcurrentEndpointSyncs: 10,
|
||||
ConcurrentGCSyncs: 30,
|
||||
ConcurrentNamespaceSyncs: 20,
|
||||
ConcurrentRSSyncs: 10,
|
||||
ConcurrentResourceQuotaSyncs: 10,
|
||||
ConcurrentServiceSyncs: 2,
|
||||
ConcurrentSATokenSyncs: 10,
|
||||
ConcurrentRCSyncs: 10,
|
||||
ConfigureCloudRoutes: false,
|
||||
EnableContentionProfiling: true,
|
||||
ControllerStartInterval: metav1.Duration{Duration: 2 * time.Minute},
|
||||
ConcurrentDaemonSetSyncs: 2,
|
||||
ConcurrentJobSyncs: 5,
|
||||
DeletingPodsQps: 0.1,
|
||||
EnableProfiling: false,
|
||||
CIDRAllocatorType: "CloudAllocator",
|
||||
NodeCIDRMaskSize: 48,
|
||||
ServiceSyncPeriod: metav1.Duration{Duration: 2 * time.Minute},
|
||||
ResourceQuotaSyncPeriod: metav1.Duration{Duration: 10 * time.Minute},
|
||||
NamespaceSyncPeriod: metav1.Duration{Duration: 10 * time.Minute},
|
||||
PVClaimBinderSyncPeriod: metav1.Duration{Duration: 30 * time.Second},
|
||||
HorizontalPodAutoscalerSyncPeriod: metav1.Duration{Duration: 45 * time.Second},
|
||||
DeploymentControllerSyncPeriod: metav1.Duration{Duration: 45 * time.Second},
|
||||
MinResyncPeriod: metav1.Duration{Duration: 8 * time.Hour},
|
||||
RegisterRetryCount: 10,
|
||||
RouteReconciliationPeriod: metav1.Duration{Duration: 30 * time.Second},
|
||||
PodEvictionTimeout: metav1.Duration{Duration: 2 * time.Minute},
|
||||
NodeMonitorGracePeriod: metav1.Duration{Duration: 30 * time.Second},
|
||||
NodeStartupGracePeriod: metav1.Duration{Duration: 30 * time.Second},
|
||||
NodeMonitorPeriod: metav1.Duration{Duration: 10 * time.Second},
|
||||
HorizontalPodAutoscalerUpscaleForbiddenWindow: metav1.Duration{Duration: 1 * time.Minute},
|
||||
HorizontalPodAutoscalerDownscaleForbiddenWindow: metav1.Duration{Duration: 2 * time.Minute},
|
||||
HorizontalPodAutoscalerTolerance: 0.1,
|
||||
TerminatedPodGCThreshold: 12000,
|
||||
VolumeConfiguration: componentconfig.VolumeConfiguration{
|
||||
EnableDynamicProvisioning: false,
|
||||
EnableHostPathProvisioning: true,
|
||||
FlexVolumePluginDir: "/flex-volume-plugin",
|
||||
PersistentVolumeRecyclerConfiguration: componentconfig.PersistentVolumeRecyclerConfiguration{
|
||||
MaximumRetry: 3,
|
||||
MinimumTimeoutNFS: 200,
|
||||
IncrementTimeoutNFS: 45,
|
||||
MinimumTimeoutHostPath: 45,
|
||||
IncrementTimeoutHostPath: 45,
|
||||
},
|
||||
},
|
||||
ContentType: "application/json",
|
||||
KubeAPIQPS: 50.0,
|
||||
KubeAPIBurst: 100,
|
||||
LeaderElection: componentconfig.LeaderElectionConfiguration{
|
||||
ResourceLock: "configmap",
|
||||
LeaderElect: false,
|
||||
LeaseDuration: metav1.Duration{Duration: 30 * time.Second},
|
||||
RenewDeadline: metav1.Duration{Duration: 15 * time.Second},
|
||||
RetryPeriod: metav1.Duration{Duration: 5 * time.Second},
|
||||
},
|
||||
ClusterSigningCertFile: "/cluster-signing-cert",
|
||||
ClusterSigningKeyFile: "/cluster-signing-key",
|
||||
ServiceAccountKeyFile: "/service-account-private-key",
|
||||
ClusterSigningDuration: metav1.Duration{Duration: 10 * time.Hour},
|
||||
EnableGarbageCollector: false,
|
||||
GCIgnoredResources: []componentconfig.GroupResource{
|
||||
{Group: "extensions", Resource: "replicationcontrollers"},
|
||||
{Group: "", Resource: "bindings"},
|
||||
{Group: "", Resource: "componentstatuses"},
|
||||
{Group: "", Resource: "events"},
|
||||
{Group: "authentication.k8s.io", Resource: "tokenreviews"},
|
||||
{Group: "authorization.k8s.io", Resource: "subjectaccessreviews"},
|
||||
{Group: "authorization.k8s.io", Resource: "selfsubjectaccessreviews"},
|
||||
{Group: "authorization.k8s.io", Resource: "localsubjectaccessreviews"},
|
||||
{Group: "authorization.k8s.io", Resource: "selfsubjectrulesreviews"},
|
||||
{Group: "apiregistration.k8s.io", Resource: "apiservices"},
|
||||
{Group: "apiextensions.k8s.io", Resource: "customresourcedefinitions"},
|
||||
},
|
||||
NodeEvictionRate: 0.2,
|
||||
SecondaryNodeEvictionRate: 0.05,
|
||||
LargeClusterSizeThreshold: 100,
|
||||
UnhealthyZoneThreshold: 0.6,
|
||||
DisableAttachDetachReconcilerSync: true,
|
||||
ReconcilerSyncLoopPeriod: metav1.Duration{Duration: 30 * time.Second},
|
||||
Controllers: []string{"foo", "bar"},
|
||||
EnableTaintManager: false,
|
||||
HorizontalPodAutoscalerUseRESTClients: true,
|
||||
UseServiceAccountCredentials: true,
|
||||
},
|
||||
Kubeconfig: "/kubeconfig",
|
||||
Master: "192.168.4.20",
|
||||
}
|
||||
|
||||
// Sort GCIgnoredResources because it's built from a map, which means the
|
||||
// insertion order is random.
|
||||
sort.Sort(sortedGCIgnoredResources(expected.GCIgnoredResources))
|
||||
|
||||
if !reflect.DeepEqual(expected, s) {
|
||||
t.Errorf("Got different run options than expected.\nDifference detected on:\n%s", diff.ObjectReflectDiff(expected, s))
|
||||
}
|
||||
}
|
||||
|
||||
type sortedGCIgnoredResources []componentconfig.GroupResource
|
||||
|
||||
func (r sortedGCIgnoredResources) Len() int {
|
||||
return len(r)
|
||||
}
|
||||
|
||||
func (r sortedGCIgnoredResources) Less(i, j int) bool {
|
||||
if r[i].Group < r[j].Group {
|
||||
return true
|
||||
} else if r[i].Group > r[j].Group {
|
||||
return false
|
||||
}
|
||||
return r[i].Resource < r[j].Resource
|
||||
}
|
||||
|
||||
func (r sortedGCIgnoredResources) Swap(i, j int) {
|
||||
r[i], r[j] = r[j], r[i]
|
||||
}
|
187
vendor/k8s.io/kubernetes/cmd/kube-controller-manager/app/plugins.go
generated
vendored
Normal file
187
vendor/k8s.io/kubernetes/cmd/kube-controller-manager/app/plugins.go
generated
vendored
Normal file
@ -0,0 +1,187 @@
|
||||
/*
|
||||
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 app
|
||||
|
||||
import (
|
||||
// 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.
|
||||
|
||||
"fmt"
|
||||
|
||||
// Cloud providers
|
||||
"k8s.io/kubernetes/pkg/apis/componentconfig"
|
||||
_ "k8s.io/kubernetes/pkg/cloudprovider/providers"
|
||||
|
||||
// Volume plugins
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/kubernetes/pkg/cloudprovider"
|
||||
"k8s.io/kubernetes/pkg/volume"
|
||||
"k8s.io/kubernetes/pkg/volume/aws_ebs"
|
||||
"k8s.io/kubernetes/pkg/volume/azure_dd"
|
||||
"k8s.io/kubernetes/pkg/volume/azure_file"
|
||||
"k8s.io/kubernetes/pkg/volume/cinder"
|
||||
"k8s.io/kubernetes/pkg/volume/csi"
|
||||
"k8s.io/kubernetes/pkg/volume/fc"
|
||||
"k8s.io/kubernetes/pkg/volume/flexvolume"
|
||||
"k8s.io/kubernetes/pkg/volume/flocker"
|
||||
"k8s.io/kubernetes/pkg/volume/gce_pd"
|
||||
"k8s.io/kubernetes/pkg/volume/glusterfs"
|
||||
"k8s.io/kubernetes/pkg/volume/host_path"
|
||||
"k8s.io/kubernetes/pkg/volume/iscsi"
|
||||
"k8s.io/kubernetes/pkg/volume/local"
|
||||
"k8s.io/kubernetes/pkg/volume/nfs"
|
||||
"k8s.io/kubernetes/pkg/volume/photon_pd"
|
||||
"k8s.io/kubernetes/pkg/volume/portworx"
|
||||
"k8s.io/kubernetes/pkg/volume/quobyte"
|
||||
"k8s.io/kubernetes/pkg/volume/rbd"
|
||||
"k8s.io/kubernetes/pkg/volume/scaleio"
|
||||
"k8s.io/kubernetes/pkg/volume/storageos"
|
||||
volumeutil "k8s.io/kubernetes/pkg/volume/util"
|
||||
"k8s.io/kubernetes/pkg/volume/vsphere_volume"
|
||||
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
)
|
||||
|
||||
// ProbeAttachableVolumePlugins collects all volume plugins for the attach/
|
||||
// detach controller.
|
||||
// The list of plugins is manually compiled. This code and the plugin
|
||||
// initialization code for kubelet really, really need a through refactor.
|
||||
func ProbeAttachableVolumePlugins() []volume.VolumePlugin {
|
||||
allPlugins := []volume.VolumePlugin{}
|
||||
|
||||
allPlugins = append(allPlugins, aws_ebs.ProbeVolumePlugins()...)
|
||||
allPlugins = append(allPlugins, gce_pd.ProbeVolumePlugins()...)
|
||||
allPlugins = append(allPlugins, cinder.ProbeVolumePlugins()...)
|
||||
allPlugins = append(allPlugins, portworx.ProbeVolumePlugins()...)
|
||||
allPlugins = append(allPlugins, vsphere_volume.ProbeVolumePlugins()...)
|
||||
allPlugins = append(allPlugins, azure_dd.ProbeVolumePlugins()...)
|
||||
allPlugins = append(allPlugins, photon_pd.ProbeVolumePlugins()...)
|
||||
allPlugins = append(allPlugins, scaleio.ProbeVolumePlugins()...)
|
||||
allPlugins = append(allPlugins, storageos.ProbeVolumePlugins()...)
|
||||
allPlugins = append(allPlugins, fc.ProbeVolumePlugins()...)
|
||||
allPlugins = append(allPlugins, iscsi.ProbeVolumePlugins()...)
|
||||
allPlugins = append(allPlugins, rbd.ProbeVolumePlugins()...)
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.CSIPersistentVolume) {
|
||||
allPlugins = append(allPlugins, csi.ProbeVolumePlugins()...)
|
||||
}
|
||||
return allPlugins
|
||||
}
|
||||
|
||||
// GetDynamicPluginProber gets the probers of dynamically discoverable plugins
|
||||
// for the attach/detach controller.
|
||||
// Currently only Flexvolume plugins are dynamically discoverable.
|
||||
func GetDynamicPluginProber(config componentconfig.VolumeConfiguration) volume.DynamicPluginProber {
|
||||
return flexvolume.GetDynamicPluginProber(config.FlexVolumePluginDir)
|
||||
}
|
||||
|
||||
// ProbeExpandableVolumePlugins returns volume plugins which are expandable
|
||||
func ProbeExpandableVolumePlugins(config componentconfig.VolumeConfiguration) []volume.VolumePlugin {
|
||||
allPlugins := []volume.VolumePlugin{}
|
||||
|
||||
allPlugins = append(allPlugins, aws_ebs.ProbeVolumePlugins()...)
|
||||
allPlugins = append(allPlugins, gce_pd.ProbeVolumePlugins()...)
|
||||
allPlugins = append(allPlugins, cinder.ProbeVolumePlugins()...)
|
||||
allPlugins = append(allPlugins, portworx.ProbeVolumePlugins()...)
|
||||
allPlugins = append(allPlugins, vsphere_volume.ProbeVolumePlugins()...)
|
||||
allPlugins = append(allPlugins, glusterfs.ProbeVolumePlugins()...)
|
||||
allPlugins = append(allPlugins, rbd.ProbeVolumePlugins()...)
|
||||
allPlugins = append(allPlugins, azure_dd.ProbeVolumePlugins()...)
|
||||
allPlugins = append(allPlugins, photon_pd.ProbeVolumePlugins()...)
|
||||
allPlugins = append(allPlugins, scaleio.ProbeVolumePlugins()...)
|
||||
allPlugins = append(allPlugins, storageos.ProbeVolumePlugins()...)
|
||||
allPlugins = append(allPlugins, fc.ProbeVolumePlugins()...)
|
||||
if !utilfeature.DefaultFeatureGate.Enabled(features.CSIPersistentVolume) {
|
||||
allPlugins = append(allPlugins, csi.ProbeVolumePlugins()...)
|
||||
}
|
||||
return allPlugins
|
||||
}
|
||||
|
||||
// ProbeControllerVolumePlugins collects all persistent volume plugins into an
|
||||
// easy to use list. Only volume plugins that implement any of
|
||||
// provisioner/recycler/deleter interface should be returned.
|
||||
func ProbeControllerVolumePlugins(cloud cloudprovider.Interface, config componentconfig.VolumeConfiguration) []volume.VolumePlugin {
|
||||
allPlugins := []volume.VolumePlugin{}
|
||||
|
||||
// The list of plugins to probe is decided by this binary, not
|
||||
// by dynamic linking or other "magic". Plugins will be analyzed and
|
||||
// initialized later.
|
||||
|
||||
// Each plugin can make use of VolumeConfig. The single arg to this func contains *all* enumerated
|
||||
// options meant to configure volume plugins. From that single config, create an instance of volume.VolumeConfig
|
||||
// for a specific plugin and pass that instance to the plugin's ProbeVolumePlugins(config) func.
|
||||
|
||||
// HostPath recycling is for testing and development purposes only!
|
||||
hostPathConfig := volume.VolumeConfig{
|
||||
RecyclerMinimumTimeout: int(config.PersistentVolumeRecyclerConfiguration.MinimumTimeoutHostPath),
|
||||
RecyclerTimeoutIncrement: int(config.PersistentVolumeRecyclerConfiguration.IncrementTimeoutHostPath),
|
||||
RecyclerPodTemplate: volume.NewPersistentVolumeRecyclerPodTemplate(),
|
||||
ProvisioningEnabled: config.EnableHostPathProvisioning,
|
||||
}
|
||||
if err := AttemptToLoadRecycler(config.PersistentVolumeRecyclerConfiguration.PodTemplateFilePathHostPath, &hostPathConfig); err != nil {
|
||||
glog.Fatalf("Could not create hostpath recycler pod from file %s: %+v", config.PersistentVolumeRecyclerConfiguration.PodTemplateFilePathHostPath, err)
|
||||
}
|
||||
allPlugins = append(allPlugins, host_path.ProbeVolumePlugins(hostPathConfig)...)
|
||||
|
||||
nfsConfig := volume.VolumeConfig{
|
||||
RecyclerMinimumTimeout: int(config.PersistentVolumeRecyclerConfiguration.MinimumTimeoutNFS),
|
||||
RecyclerTimeoutIncrement: int(config.PersistentVolumeRecyclerConfiguration.IncrementTimeoutNFS),
|
||||
RecyclerPodTemplate: volume.NewPersistentVolumeRecyclerPodTemplate(),
|
||||
}
|
||||
if err := AttemptToLoadRecycler(config.PersistentVolumeRecyclerConfiguration.PodTemplateFilePathNFS, &nfsConfig); err != nil {
|
||||
glog.Fatalf("Could not create NFS recycler pod from file %s: %+v", config.PersistentVolumeRecyclerConfiguration.PodTemplateFilePathNFS, err)
|
||||
}
|
||||
allPlugins = append(allPlugins, nfs.ProbeVolumePlugins(nfsConfig)...)
|
||||
allPlugins = append(allPlugins, glusterfs.ProbeVolumePlugins()...)
|
||||
// add rbd provisioner
|
||||
allPlugins = append(allPlugins, rbd.ProbeVolumePlugins()...)
|
||||
allPlugins = append(allPlugins, quobyte.ProbeVolumePlugins()...)
|
||||
allPlugins = append(allPlugins, azure_file.ProbeVolumePlugins()...)
|
||||
|
||||
allPlugins = append(allPlugins, flocker.ProbeVolumePlugins()...)
|
||||
allPlugins = append(allPlugins, portworx.ProbeVolumePlugins()...)
|
||||
allPlugins = append(allPlugins, scaleio.ProbeVolumePlugins()...)
|
||||
allPlugins = append(allPlugins, local.ProbeVolumePlugins()...)
|
||||
allPlugins = append(allPlugins, storageos.ProbeVolumePlugins()...)
|
||||
|
||||
allPlugins = append(allPlugins, aws_ebs.ProbeVolumePlugins()...)
|
||||
allPlugins = append(allPlugins, gce_pd.ProbeVolumePlugins()...)
|
||||
allPlugins = append(allPlugins, cinder.ProbeVolumePlugins()...)
|
||||
allPlugins = append(allPlugins, vsphere_volume.ProbeVolumePlugins()...)
|
||||
allPlugins = append(allPlugins, azure_dd.ProbeVolumePlugins()...)
|
||||
allPlugins = append(allPlugins, photon_pd.ProbeVolumePlugins()...)
|
||||
|
||||
return allPlugins
|
||||
}
|
||||
|
||||
// AttemptToLoadRecycler tries decoding a pod from a filepath for use as a recycler for a volume.
|
||||
// If successful, this method will set the recycler on the config.
|
||||
// If unsuccessful, an error is returned. Function is exported for reuse downstream.
|
||||
func AttemptToLoadRecycler(path string, config *volume.VolumeConfig) error {
|
||||
if path != "" {
|
||||
recyclerPod, err := volumeutil.LoadPodFromFile(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = volume.ValidateRecyclerPodTemplate(recyclerPod); err != nil {
|
||||
return fmt.Errorf("Pod specification (%v): %v", path, err)
|
||||
}
|
||||
config.RecyclerPodTemplate = recyclerPod
|
||||
}
|
||||
return nil
|
||||
}
|
51
vendor/k8s.io/kubernetes/cmd/kube-controller-manager/app/policy.go
generated
vendored
Normal file
51
vendor/k8s.io/kubernetes/cmd/kube-controller-manager/app/policy.go
generated
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package app implements a server that runs a set of active
|
||||
// components. This includes replication controllers, service endpoints and
|
||||
// nodes.
|
||||
//
|
||||
package app
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/kubernetes/pkg/controller/disruption"
|
||||
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
func startDisruptionController(ctx ControllerContext) (bool, error) {
|
||||
var group = "policy"
|
||||
var version = "v1beta1"
|
||||
var resource = "poddisruptionbudgets"
|
||||
|
||||
if !ctx.AvailableResources[schema.GroupVersionResource{Group: group, Version: version, Resource: resource}] {
|
||||
glog.Infof(
|
||||
"Refusing to start disruption because resource %q in group %q is not available.",
|
||||
resource, group+"/"+version)
|
||||
return false, nil
|
||||
}
|
||||
go disruption.NewDisruptionController(
|
||||
ctx.InformerFactory.Core().V1().Pods(),
|
||||
ctx.InformerFactory.Policy().V1beta1().PodDisruptionBudgets(),
|
||||
ctx.InformerFactory.Core().V1().ReplicationControllers(),
|
||||
ctx.InformerFactory.Extensions().V1beta1().ReplicaSets(),
|
||||
ctx.InformerFactory.Extensions().V1beta1().Deployments(),
|
||||
ctx.InformerFactory.Apps().V1beta1().StatefulSets(),
|
||||
ctx.ClientBuilder.ClientOrDie("disruption-controller"),
|
||||
).Run(ctx.Stop)
|
||||
return true, nil
|
||||
}
|
33
vendor/k8s.io/kubernetes/cmd/kube-controller-manager/app/rbac.go
generated
vendored
Normal file
33
vendor/k8s.io/kubernetes/cmd/kube-controller-manager/app/rbac.go
generated
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
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
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/kubernetes/pkg/controller/clusterroleaggregation"
|
||||
)
|
||||
|
||||
func startClusterRoleAggregrationController(ctx ControllerContext) (bool, error) {
|
||||
if !ctx.AvailableResources[schema.GroupVersionResource{Group: "rbac.authorization.k8s.io", Version: "v1", Resource: "clusterroles"}] {
|
||||
return false, nil
|
||||
}
|
||||
go clusterroleaggregation.NewClusterRoleAggregation(
|
||||
ctx.InformerFactory.Rbac().V1().ClusterRoles(),
|
||||
ctx.ClientBuilder.ClientOrDie("clusterrole-aggregation-controller").RbacV1(),
|
||||
).Run(5, ctx.Stop)
|
||||
return true, nil
|
||||
}
|
54
vendor/k8s.io/kubernetes/cmd/kube-controller-manager/controller-manager.go
generated
vendored
Normal file
54
vendor/k8s.io/kubernetes/cmd/kube-controller-manager/controller-manager.go
generated
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
// The controller manager is responsible for monitoring replication
|
||||
// controllers, and creating corresponding pods to achieve the desired
|
||||
// state. It uses the API to listen for new controllers and to create/delete
|
||||
// pods.
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"k8s.io/apiserver/pkg/util/flag"
|
||||
"k8s.io/apiserver/pkg/util/logs"
|
||||
"k8s.io/kubernetes/cmd/kube-controller-manager/app"
|
||||
"k8s.io/kubernetes/cmd/kube-controller-manager/app/options"
|
||||
_ "k8s.io/kubernetes/pkg/client/metrics/prometheus" // for client metric registration
|
||||
_ "k8s.io/kubernetes/pkg/util/reflector/prometheus" // for reflector metric registration
|
||||
_ "k8s.io/kubernetes/pkg/util/workqueue/prometheus" // for workqueue metric registration
|
||||
_ "k8s.io/kubernetes/pkg/version/prometheus" // for version metric registration
|
||||
"k8s.io/kubernetes/pkg/version/verflag"
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
func main() {
|
||||
s := options.NewCMServer()
|
||||
s.AddFlags(pflag.CommandLine, app.KnownControllers(), app.ControllersDisabledByDefault.List())
|
||||
|
||||
flag.InitFlags()
|
||||
logs.InitLogs()
|
||||
defer logs.FlushLogs()
|
||||
|
||||
verflag.PrintAndExitIfRequested()
|
||||
|
||||
if err := app.Run(s); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "%v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
51
vendor/k8s.io/kubernetes/cmd/kube-proxy/BUILD
generated
vendored
Normal file
51
vendor/k8s.io/kubernetes/cmd/kube-proxy/BUILD
generated
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
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-proxy",
|
||||
gc_linkopts = [
|
||||
"-linkmode",
|
||||
"external",
|
||||
"-extldflags",
|
||||
"-static",
|
||||
],
|
||||
importpath = "k8s.io/kubernetes/cmd/kube-proxy",
|
||||
library = ":go_default_library",
|
||||
x_defs = version_x_defs(),
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["proxy.go"],
|
||||
importpath = "k8s.io/kubernetes/cmd/kube-proxy",
|
||||
deps = [
|
||||
"//cmd/kube-proxy/app:go_default_library",
|
||||
"//pkg/client/metrics/prometheus:go_default_library",
|
||||
"//pkg/version/prometheus:go_default_library",
|
||||
"//vendor/github.com/spf13/pflag: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-proxy/app:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
)
|
115
vendor/k8s.io/kubernetes/cmd/kube-proxy/app/BUILD
generated
vendored
Normal file
115
vendor/k8s.io/kubernetes/cmd/kube-proxy/app/BUILD
generated
vendored
Normal file
@ -0,0 +1,115 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"conntrack.go",
|
||||
"server.go",
|
||||
"server_others.go",
|
||||
] + select({
|
||||
"@io_bazel_rules_go//go/platform:windows_amd64": [
|
||||
"server_windows.go",
|
||||
],
|
||||
"//conditions:default": [],
|
||||
}),
|
||||
importpath = "k8s.io/kubernetes/cmd/kube-proxy/app",
|
||||
deps = [
|
||||
"//pkg/apis/componentconfig:go_default_library",
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/client/clientset_generated/internalclientset:go_default_library",
|
||||
"//pkg/client/informers/informers_generated/internalversion:go_default_library",
|
||||
"//pkg/features:go_default_library",
|
||||
"//pkg/kubectl/cmd/util:go_default_library",
|
||||
"//pkg/kubelet/qos:go_default_library",
|
||||
"//pkg/master/ports:go_default_library",
|
||||
"//pkg/proxy:go_default_library",
|
||||
"//pkg/proxy/apis/kubeproxyconfig:go_default_library",
|
||||
"//pkg/proxy/apis/kubeproxyconfig/scheme:go_default_library",
|
||||
"//pkg/proxy/apis/kubeproxyconfig/v1alpha1:go_default_library",
|
||||
"//pkg/proxy/apis/kubeproxyconfig/validation:go_default_library",
|
||||
"//pkg/proxy/config:go_default_library",
|
||||
"//pkg/proxy/healthcheck:go_default_library",
|
||||
"//pkg/proxy/iptables:go_default_library",
|
||||
"//pkg/proxy/ipvs:go_default_library",
|
||||
"//pkg/proxy/metrics:go_default_library",
|
||||
"//pkg/proxy/userspace:go_default_library",
|
||||
"//pkg/util/configz:go_default_library",
|
||||
"//pkg/util/dbus:go_default_library",
|
||||
"//pkg/util/ipset:go_default_library",
|
||||
"//pkg/util/iptables:go_default_library",
|
||||
"//pkg/util/ipvs:go_default_library",
|
||||
"//pkg/util/mount:go_default_library",
|
||||
"//pkg/util/node:go_default_library",
|
||||
"//pkg/util/oom:go_default_library",
|
||||
"//pkg/util/pointer:go_default_library",
|
||||
"//pkg/util/resourcecontainer:go_default_library",
|
||||
"//pkg/util/sysctl:go_default_library",
|
||||
"//pkg/version:go_default_library",
|
||||
"//pkg/version/verflag:go_default_library",
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/github.com/prometheus/client_golang/prometheus:go_default_library",
|
||||
"//vendor/github.com/spf13/cobra:go_default_library",
|
||||
"//vendor/github.com/spf13/pflag:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer/json:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/net:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/server/healthz:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
|
||||
"//vendor/k8s.io/client-go/kubernetes/typed/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/client-go/rest:go_default_library",
|
||||
"//vendor/k8s.io/client-go/tools/clientcmd:go_default_library",
|
||||
"//vendor/k8s.io/client-go/tools/clientcmd/api:go_default_library",
|
||||
"//vendor/k8s.io/client-go/tools/record:go_default_library",
|
||||
"//vendor/k8s.io/utils/exec:go_default_library",
|
||||
] + select({
|
||||
"@io_bazel_rules_go//go/platform:windows_amd64": [
|
||||
"//pkg/proxy/winkernel:go_default_library",
|
||||
"//pkg/proxy/winuserspace:go_default_library",
|
||||
"//pkg/util/netsh:go_default_library",
|
||||
],
|
||||
"//conditions:default": [],
|
||||
}),
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["server_test.go"],
|
||||
importpath = "k8s.io/kubernetes/cmd/kube-proxy/app",
|
||||
library = ":go_default_library",
|
||||
deps = [
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/proxy/apis/kubeproxyconfig:go_default_library",
|
||||
"//pkg/util/configz:go_default_library",
|
||||
"//pkg/util/iptables:go_default_library",
|
||||
"//pkg/util/pointer:go_default_library",
|
||||
"//vendor/github.com/stretchr/testify/assert:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/diff:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
142
vendor/k8s.io/kubernetes/cmd/kube-proxy/app/conntrack.go
generated
vendored
Normal file
142
vendor/k8s.io/kubernetes/cmd/kube-proxy/app/conntrack.go
generated
vendored
Normal file
@ -0,0 +1,142 @@
|
||||
/*
|
||||
Copyright 2015 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
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io/ioutil"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/golang/glog"
|
||||
|
||||
"k8s.io/kubernetes/pkg/util/mount"
|
||||
"k8s.io/kubernetes/pkg/util/sysctl"
|
||||
)
|
||||
|
||||
// Conntracker is an interface to the global sysctl. Descriptions of the various
|
||||
// sysctl fields can be found here:
|
||||
//
|
||||
// https://www.kernel.org/doc/Documentation/networking/nf_conntrack-sysctl.txt
|
||||
type Conntracker interface {
|
||||
// SetMax adjusts nf_conntrack_max.
|
||||
SetMax(max int) error
|
||||
// SetTCPEstablishedTimeout adjusts nf_conntrack_tcp_timeout_established.
|
||||
SetTCPEstablishedTimeout(seconds int) error
|
||||
// SetTCPCloseWaitTimeout nf_conntrack_tcp_timeout_close_wait.
|
||||
SetTCPCloseWaitTimeout(seconds int) error
|
||||
}
|
||||
|
||||
type realConntracker struct{}
|
||||
|
||||
var readOnlySysFSError = errors.New("readOnlySysFS")
|
||||
|
||||
func (rct realConntracker) SetMax(max int) error {
|
||||
if err := rct.setIntSysCtl("nf_conntrack_max", max); err != nil {
|
||||
return err
|
||||
}
|
||||
glog.Infof("Setting nf_conntrack_max to %d", max)
|
||||
|
||||
// Linux does not support writing to /sys/module/nf_conntrack/parameters/hashsize
|
||||
// when the writer process is not in the initial network namespace
|
||||
// (https://github.com/torvalds/linux/blob/v4.10/net/netfilter/nf_conntrack_core.c#L1795-L1796).
|
||||
// Usually that's fine. But in some configurations such as with github.com/kinvolk/kubeadm-nspawn,
|
||||
// kube-proxy is in another netns.
|
||||
// Therefore, check if writing in hashsize is necessary and skip the writing if not.
|
||||
hashsize, err := readIntStringFile("/sys/module/nf_conntrack/parameters/hashsize")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if hashsize >= (max / 4) {
|
||||
return nil
|
||||
}
|
||||
|
||||
// sysfs is expected to be mounted as 'rw'. However, it may be
|
||||
// unexpectedly mounted as 'ro' by docker because of a known docker
|
||||
// issue (https://github.com/docker/docker/issues/24000). Setting
|
||||
// conntrack will fail when sysfs is readonly. When that happens, we
|
||||
// don't set conntrack hashsize and return a special error
|
||||
// readOnlySysFSError here. The caller should deal with
|
||||
// readOnlySysFSError differently.
|
||||
writable, err := isSysFSWritable()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !writable {
|
||||
return readOnlySysFSError
|
||||
}
|
||||
// TODO: generify this and sysctl to a new sysfs.WriteInt()
|
||||
glog.Infof("Setting conntrack hashsize to %d", max/4)
|
||||
return writeIntStringFile("/sys/module/nf_conntrack/parameters/hashsize", max/4)
|
||||
}
|
||||
|
||||
func (rct realConntracker) SetTCPEstablishedTimeout(seconds int) error {
|
||||
return rct.setIntSysCtl("nf_conntrack_tcp_timeout_established", seconds)
|
||||
}
|
||||
|
||||
func (rct realConntracker) SetTCPCloseWaitTimeout(seconds int) error {
|
||||
return rct.setIntSysCtl("nf_conntrack_tcp_timeout_close_wait", seconds)
|
||||
}
|
||||
|
||||
func (realConntracker) setIntSysCtl(name string, value int) error {
|
||||
entry := "net/netfilter/" + name
|
||||
|
||||
glog.Infof("Set sysctl '%v' to %v", entry, value)
|
||||
if err := sysctl.New().SetSysctl(entry, value); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// isSysFSWritable checks /proc/mounts to see whether sysfs is 'rw' or not.
|
||||
func isSysFSWritable() (bool, error) {
|
||||
const permWritable = "rw"
|
||||
const sysfsDevice = "sysfs"
|
||||
m := mount.New("" /* default mount path */)
|
||||
mountPoints, err := m.List()
|
||||
if err != nil {
|
||||
glog.Errorf("failed to list mount points: %v", err)
|
||||
return false, err
|
||||
}
|
||||
|
||||
for _, mountPoint := range mountPoints {
|
||||
if mountPoint.Type != sysfsDevice {
|
||||
continue
|
||||
}
|
||||
// Check whether sysfs is 'rw'
|
||||
if len(mountPoint.Opts) > 0 && mountPoint.Opts[0] == permWritable {
|
||||
return true, nil
|
||||
}
|
||||
glog.Errorf("sysfs is not writable: %+v (mount options are %v)",
|
||||
mountPoint, mountPoint.Opts)
|
||||
return false, readOnlySysFSError
|
||||
}
|
||||
|
||||
return false, errors.New("No sysfs mounted")
|
||||
}
|
||||
|
||||
func readIntStringFile(filename string) (int, error) {
|
||||
b, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
return strconv.Atoi(strings.TrimSpace(string(b)))
|
||||
}
|
||||
|
||||
func writeIntStringFile(filename string, value int) error {
|
||||
return ioutil.WriteFile(filename, []byte(strconv.Itoa(value)), 0640)
|
||||
}
|
595
vendor/k8s.io/kubernetes/cmd/kube-proxy/app/server.go
generated
vendored
Normal file
595
vendor/k8s.io/kubernetes/cmd/kube-proxy/app/server.go
generated
vendored
Normal file
@ -0,0 +1,595 @@
|
||||
/*
|
||||
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 app does all of the work necessary to configure and run a
|
||||
// Kubernetes app process.
|
||||
package app
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/pprof"
|
||||
"os"
|
||||
goruntime "runtime"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer/json"
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/apiserver/pkg/server/healthz"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
clientgoclientset "k8s.io/client-go/kubernetes"
|
||||
v1core "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
||||
"k8s.io/client-go/tools/record"
|
||||
"k8s.io/kubernetes/pkg/apis/componentconfig"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
||||
informers "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion"
|
||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||
"k8s.io/kubernetes/pkg/kubelet/qos"
|
||||
"k8s.io/kubernetes/pkg/master/ports"
|
||||
"k8s.io/kubernetes/pkg/proxy"
|
||||
"k8s.io/kubernetes/pkg/proxy/apis/kubeproxyconfig"
|
||||
"k8s.io/kubernetes/pkg/proxy/apis/kubeproxyconfig/scheme"
|
||||
"k8s.io/kubernetes/pkg/proxy/apis/kubeproxyconfig/v1alpha1"
|
||||
"k8s.io/kubernetes/pkg/proxy/apis/kubeproxyconfig/validation"
|
||||
"k8s.io/kubernetes/pkg/proxy/config"
|
||||
"k8s.io/kubernetes/pkg/proxy/healthcheck"
|
||||
"k8s.io/kubernetes/pkg/proxy/iptables"
|
||||
"k8s.io/kubernetes/pkg/proxy/ipvs"
|
||||
"k8s.io/kubernetes/pkg/proxy/userspace"
|
||||
"k8s.io/kubernetes/pkg/util/configz"
|
||||
utilipset "k8s.io/kubernetes/pkg/util/ipset"
|
||||
utiliptables "k8s.io/kubernetes/pkg/util/iptables"
|
||||
utilipvs "k8s.io/kubernetes/pkg/util/ipvs"
|
||||
utilnode "k8s.io/kubernetes/pkg/util/node"
|
||||
"k8s.io/kubernetes/pkg/util/oom"
|
||||
utilpointer "k8s.io/kubernetes/pkg/util/pointer"
|
||||
"k8s.io/kubernetes/pkg/util/resourcecontainer"
|
||||
"k8s.io/kubernetes/pkg/version"
|
||||
"k8s.io/kubernetes/pkg/version/verflag"
|
||||
"k8s.io/utils/exec"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
const (
|
||||
proxyModeUserspace = "userspace"
|
||||
proxyModeIPTables = "iptables"
|
||||
proxyModeIPVS = "ipvs"
|
||||
proxyModeKernelspace = "kernelspace"
|
||||
)
|
||||
|
||||
// Options contains everything necessary to create and run a proxy server.
|
||||
type Options struct {
|
||||
// ConfigFile is the location of the proxy server's configuration file.
|
||||
ConfigFile string
|
||||
// WriteConfigTo is the path where the default configuration will be written.
|
||||
WriteConfigTo string
|
||||
// CleanupAndExit, when true, makes the proxy server clean up iptables rules, then exit.
|
||||
CleanupAndExit bool
|
||||
// CleanupIPVS, when true, makes the proxy server clean up ipvs rules before running.
|
||||
CleanupIPVS bool
|
||||
// config is the proxy server's configuration object.
|
||||
config *kubeproxyconfig.KubeProxyConfiguration
|
||||
|
||||
// The fields below here are placeholders for flags that can't be directly mapped into
|
||||
// kubeproxyconfig.KubeProxyConfiguration.
|
||||
//
|
||||
// TODO remove these fields once the deprecated flags are removed.
|
||||
|
||||
// master is used to override the kubeconfig's URL to the apiserver.
|
||||
master string
|
||||
// healthzPort is the port to be used by the healthz server.
|
||||
healthzPort int32
|
||||
|
||||
scheme *runtime.Scheme
|
||||
codecs serializer.CodecFactory
|
||||
}
|
||||
|
||||
// AddFlags adds flags to fs and binds them to options.
|
||||
func AddFlags(options *Options, fs *pflag.FlagSet) {
|
||||
fs.StringVar(&options.ConfigFile, "config", options.ConfigFile, "The path to the configuration file.")
|
||||
fs.StringVar(&options.WriteConfigTo, "write-config-to", options.WriteConfigTo, "If set, write the default configuration values to this file and exit.")
|
||||
fs.BoolVar(&options.CleanupAndExit, "cleanup-iptables", options.CleanupAndExit, "If true cleanup iptables and ipvs rules and exit.")
|
||||
fs.MarkDeprecated("cleanup-iptables", "This flag is replaced by --cleanup.")
|
||||
fs.BoolVar(&options.CleanupAndExit, "cleanup", options.CleanupAndExit, "If true cleanup iptables and ipvs rules and exit.")
|
||||
fs.BoolVar(&options.CleanupIPVS, "cleanup-ipvs", options.CleanupIPVS, "If true make kube-proxy cleanup ipvs rules before running. Default is true")
|
||||
|
||||
// All flags below here are deprecated and will eventually be removed.
|
||||
|
||||
fs.Var(componentconfig.IPVar{Val: &options.config.BindAddress}, "bind-address", "The IP address for the proxy server to serve on (set to `0.0.0.0` for all IPv4 interfaces and `::` for all IPv6 interfaces)")
|
||||
fs.StringVar(&options.master, "master", options.master, "The address of the Kubernetes API server (overrides any value in kubeconfig)")
|
||||
fs.Int32Var(&options.healthzPort, "healthz-port", options.healthzPort, "The port to bind the health check server. Use 0 to disable.")
|
||||
fs.Var(componentconfig.IPVar{Val: &options.config.HealthzBindAddress}, "healthz-bind-address", "The IP address and port for the health check server to serve on (set to `0.0.0.0` for all IPv4 interfaces and `::` for all IPv6 interfaces)")
|
||||
fs.Var(componentconfig.IPVar{Val: &options.config.MetricsBindAddress}, "metrics-bind-address", "The IP address and port for the metrics server to serve on (set to `0.0.0.0` for all IPv4 interfaces and `::` for all IPv6 interfaces)")
|
||||
fs.Int32Var(options.config.OOMScoreAdj, "oom-score-adj", utilpointer.Int32PtrDerefOr(options.config.OOMScoreAdj, int32(qos.KubeProxyOOMScoreAdj)), "The oom-score-adj value for kube-proxy process. Values must be within the range [-1000, 1000]")
|
||||
fs.StringVar(&options.config.ResourceContainer, "resource-container", options.config.ResourceContainer, "Absolute name of the resource-only container to create and run the Kube-proxy in (Default: /kube-proxy).")
|
||||
fs.MarkDeprecated("resource-container", "This feature will be removed in a later release.")
|
||||
fs.StringVar(&options.config.ClientConnection.KubeConfigFile, "kubeconfig", options.config.ClientConnection.KubeConfigFile, "Path to kubeconfig file with authorization information (the master location is set by the master flag).")
|
||||
fs.Var(componentconfig.PortRangeVar{Val: &options.config.PortRange}, "proxy-port-range", "Range of host ports (beginPort-endPort, inclusive) that may be consumed in order to proxy service traffic. If unspecified (0-0) then ports will be randomly chosen.")
|
||||
fs.StringVar(&options.config.HostnameOverride, "hostname-override", options.config.HostnameOverride, "If non-empty, will use this string as identification instead of the actual hostname.")
|
||||
fs.Var(&options.config.Mode, "proxy-mode", "Which proxy mode to use: 'userspace' (older) or 'iptables' (faster) or 'ipvs'(experimental)'. If blank, use the best-available proxy (currently iptables). If the iptables proxy is selected, regardless of how, but the system's kernel or iptables versions are insufficient, this always falls back to the userspace proxy.")
|
||||
fs.Int32Var(options.config.IPTables.MasqueradeBit, "iptables-masquerade-bit", utilpointer.Int32PtrDerefOr(options.config.IPTables.MasqueradeBit, 14), "If using the pure iptables proxy, the bit of the fwmark space to mark packets requiring SNAT with. Must be within the range [0, 31].")
|
||||
fs.DurationVar(&options.config.IPTables.SyncPeriod.Duration, "iptables-sync-period", options.config.IPTables.SyncPeriod.Duration, "The maximum interval of how often iptables rules are refreshed (e.g. '5s', '1m', '2h22m'). Must be greater than 0.")
|
||||
fs.DurationVar(&options.config.IPTables.MinSyncPeriod.Duration, "iptables-min-sync-period", options.config.IPTables.MinSyncPeriod.Duration, "The minimum interval of how often the iptables rules can be refreshed as endpoints and services change (e.g. '5s', '1m', '2h22m').")
|
||||
fs.DurationVar(&options.config.IPVS.SyncPeriod.Duration, "ipvs-sync-period", options.config.IPVS.SyncPeriod.Duration, "The maximum interval of how often ipvs rules are refreshed (e.g. '5s', '1m', '2h22m'). Must be greater than 0.")
|
||||
fs.DurationVar(&options.config.IPVS.MinSyncPeriod.Duration, "ipvs-min-sync-period", options.config.IPVS.MinSyncPeriod.Duration, "The minimum interval of how often the ipvs rules can be refreshed as endpoints and services change (e.g. '5s', '1m', '2h22m').")
|
||||
fs.DurationVar(&options.config.ConfigSyncPeriod.Duration, "config-sync-period", options.config.ConfigSyncPeriod.Duration, "How often configuration from the apiserver is refreshed. Must be greater than 0.")
|
||||
fs.BoolVar(&options.config.IPTables.MasqueradeAll, "masquerade-all", options.config.IPTables.MasqueradeAll, "If using the pure iptables proxy, SNAT all traffic sent via Service cluster IPs (this not commonly needed)")
|
||||
fs.StringVar(&options.config.ClusterCIDR, "cluster-cidr", options.config.ClusterCIDR, "The CIDR range of pods in the cluster. When configured, traffic sent to a Service cluster IP from outside this range will be masqueraded and traffic sent from pods to an external LoadBalancer IP will be directed to the respective cluster IP instead")
|
||||
fs.StringVar(&options.config.ClientConnection.ContentType, "kube-api-content-type", options.config.ClientConnection.ContentType, "Content type of requests sent to apiserver.")
|
||||
fs.Float32Var(&options.config.ClientConnection.QPS, "kube-api-qps", options.config.ClientConnection.QPS, "QPS to use while talking with kubernetes apiserver")
|
||||
fs.Int32Var(&options.config.ClientConnection.Burst, "kube-api-burst", options.config.ClientConnection.Burst, "Burst to use while talking with kubernetes apiserver")
|
||||
fs.DurationVar(&options.config.UDPIdleTimeout.Duration, "udp-timeout", options.config.UDPIdleTimeout.Duration, "How long an idle UDP connection will be kept open (e.g. '250ms', '2s'). Must be greater than 0. Only applicable for proxy-mode=userspace")
|
||||
if options.config.Conntrack.Max == nil {
|
||||
options.config.Conntrack.Max = utilpointer.Int32Ptr(0)
|
||||
}
|
||||
fs.Int32Var(options.config.Conntrack.Max, "conntrack-max", *options.config.Conntrack.Max,
|
||||
"Maximum number of NAT connections to track (0 to leave as-is). This overrides conntrack-max-per-core and conntrack-min.")
|
||||
fs.MarkDeprecated("conntrack-max", "This feature will be removed in a later release.")
|
||||
fs.Int32Var(options.config.Conntrack.MaxPerCore, "conntrack-max-per-core", *options.config.Conntrack.MaxPerCore,
|
||||
"Maximum number of NAT connections to track per CPU core (0 to leave the limit as-is and ignore conntrack-min).")
|
||||
fs.Int32Var(options.config.Conntrack.Min, "conntrack-min", *options.config.Conntrack.Min,
|
||||
"Minimum number of conntrack entries to allocate, regardless of conntrack-max-per-core (set conntrack-max-per-core=0 to leave the limit as-is).")
|
||||
fs.DurationVar(&options.config.Conntrack.TCPEstablishedTimeout.Duration, "conntrack-tcp-timeout-established", options.config.Conntrack.TCPEstablishedTimeout.Duration, "Idle timeout for established TCP connections (0 to leave as-is)")
|
||||
fs.DurationVar(
|
||||
&options.config.Conntrack.TCPCloseWaitTimeout.Duration, "conntrack-tcp-timeout-close-wait",
|
||||
options.config.Conntrack.TCPCloseWaitTimeout.Duration,
|
||||
"NAT timeout for TCP connections in the CLOSE_WAIT state")
|
||||
fs.BoolVar(&options.config.EnableProfiling, "profiling", options.config.EnableProfiling, "If true enables profiling via web interface on /debug/pprof handler.")
|
||||
fs.StringVar(&options.config.IPVS.Scheduler, "ipvs-scheduler", options.config.IPVS.Scheduler, "The ipvs scheduler type when proxy mode is ipvs")
|
||||
utilfeature.DefaultFeatureGate.AddFlag(fs)
|
||||
}
|
||||
|
||||
func NewOptions() *Options {
|
||||
return &Options{
|
||||
config: new(kubeproxyconfig.KubeProxyConfiguration),
|
||||
healthzPort: ports.ProxyHealthzPort,
|
||||
scheme: scheme.Scheme,
|
||||
codecs: scheme.Codecs,
|
||||
CleanupIPVS: true,
|
||||
}
|
||||
}
|
||||
|
||||
// Complete completes all the required options.
|
||||
func (o *Options) Complete() error {
|
||||
if len(o.ConfigFile) == 0 && len(o.WriteConfigTo) == 0 {
|
||||
glog.Warning("WARNING: all flags other than --config, --write-config-to, and --cleanup are deprecated. Please begin using a config file ASAP.")
|
||||
o.applyDeprecatedHealthzPortToConfig()
|
||||
}
|
||||
|
||||
// Load the config file here in Complete, so that Validate validates the fully-resolved config.
|
||||
if len(o.ConfigFile) > 0 {
|
||||
if c, err := o.loadConfigFromFile(o.ConfigFile); err != nil {
|
||||
return err
|
||||
} else {
|
||||
o.config = c
|
||||
// Make sure we apply the feature gate settings in the config file.
|
||||
utilfeature.DefaultFeatureGate.Set(o.config.FeatureGates)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Validate validates all the required options.
|
||||
func (o *Options) Validate(args []string) error {
|
||||
if len(args) != 0 {
|
||||
return errors.New("no arguments are supported")
|
||||
}
|
||||
|
||||
if errs := validation.Validate(o.config); len(errs) != 0 {
|
||||
return errs.ToAggregate()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *Options) Run() error {
|
||||
if len(o.WriteConfigTo) > 0 {
|
||||
return o.writeConfigFile()
|
||||
}
|
||||
|
||||
proxyServer, err := NewProxyServer(o)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return proxyServer.Run()
|
||||
}
|
||||
|
||||
func (o *Options) writeConfigFile() error {
|
||||
var encoder runtime.Encoder
|
||||
mediaTypes := o.codecs.SupportedMediaTypes()
|
||||
for _, info := range mediaTypes {
|
||||
if info.MediaType == "application/yaml" {
|
||||
encoder = info.Serializer
|
||||
break
|
||||
}
|
||||
}
|
||||
if encoder == nil {
|
||||
return errors.New("unable to locate yaml encoder")
|
||||
}
|
||||
encoder = json.NewYAMLSerializer(json.DefaultMetaFactory, o.scheme, o.scheme)
|
||||
encoder = o.codecs.EncoderForVersion(encoder, v1alpha1.SchemeGroupVersion)
|
||||
|
||||
configFile, err := os.Create(o.WriteConfigTo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer configFile.Close()
|
||||
|
||||
if err := encoder.Encode(o.config, configFile); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
glog.Infof("Wrote configuration to: %s\n", o.WriteConfigTo)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// applyDeprecatedHealthzPortToConfig sets o.config.HealthzBindAddress from
|
||||
// flags passed on the command line based on the following rules:
|
||||
//
|
||||
// 1. If --healthz-port is 0, disable the healthz server.
|
||||
// 2. Otherwise, use the value of --healthz-port for the port portion of
|
||||
// o.config.HealthzBindAddress
|
||||
func (o *Options) applyDeprecatedHealthzPortToConfig() {
|
||||
if o.healthzPort == 0 {
|
||||
o.config.HealthzBindAddress = ""
|
||||
return
|
||||
}
|
||||
|
||||
index := strings.Index(o.config.HealthzBindAddress, ":")
|
||||
if index != -1 {
|
||||
o.config.HealthzBindAddress = o.config.HealthzBindAddress[0:index]
|
||||
}
|
||||
|
||||
o.config.HealthzBindAddress = fmt.Sprintf("%s:%d", o.config.HealthzBindAddress, o.healthzPort)
|
||||
}
|
||||
|
||||
// loadConfigFromFile loads the contents of file and decodes it as a
|
||||
// KubeProxyConfiguration object.
|
||||
func (o *Options) loadConfigFromFile(file string) (*kubeproxyconfig.KubeProxyConfiguration, error) {
|
||||
data, err := ioutil.ReadFile(file)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return o.loadConfig(data)
|
||||
}
|
||||
|
||||
// loadConfig decodes data as a KubeProxyConfiguration object.
|
||||
func (o *Options) loadConfig(data []byte) (*kubeproxyconfig.KubeProxyConfiguration, error) {
|
||||
configObj, gvk, err := o.codecs.UniversalDecoder().Decode(data, nil, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config, ok := configObj.(*kubeproxyconfig.KubeProxyConfiguration)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("got unexpected config type: %v", gvk)
|
||||
}
|
||||
return config, nil
|
||||
}
|
||||
|
||||
func (o *Options) ApplyDefaults(in *kubeproxyconfig.KubeProxyConfiguration) (*kubeproxyconfig.KubeProxyConfiguration, error) {
|
||||
external, err := o.scheme.ConvertToVersion(in, v1alpha1.SchemeGroupVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
o.scheme.Default(external)
|
||||
|
||||
internal, err := o.scheme.ConvertToVersion(external, kubeproxyconfig.SchemeGroupVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
out := internal.(*kubeproxyconfig.KubeProxyConfiguration)
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// NewProxyCommand creates a *cobra.Command object with default parameters
|
||||
func NewProxyCommand() *cobra.Command {
|
||||
opts := NewOptions()
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "kube-proxy",
|
||||
Long: `The Kubernetes network proxy runs on each node. This
|
||||
reflects services as defined in the Kubernetes API on each node and can do simple
|
||||
TCP and UDP stream forwarding or round robin TCP and UDP forwarding across a set of backends.
|
||||
Service cluster IPs and ports are currently found through Docker-links-compatible
|
||||
environment variables specifying ports opened by the service proxy. There is an optional
|
||||
addon that provides cluster DNS for these cluster IPs. The user must create a service
|
||||
with the apiserver API to configure the proxy.`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
verflag.PrintAndExitIfRequested()
|
||||
cmdutil.CheckErr(opts.Complete())
|
||||
cmdutil.CheckErr(opts.Validate(args))
|
||||
cmdutil.CheckErr(opts.Run())
|
||||
},
|
||||
}
|
||||
|
||||
var err error
|
||||
opts.config, err = opts.ApplyDefaults(opts.config)
|
||||
if err != nil {
|
||||
glog.Fatalf("unable to create flag defaults: %v", err)
|
||||
}
|
||||
|
||||
flags := cmd.Flags()
|
||||
AddFlags(opts, flags)
|
||||
|
||||
cmd.MarkFlagFilename("config", "yaml", "yml", "json")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
// ProxyServer represents all the parameters required to start the Kubernetes proxy server. All
|
||||
// fields are required.
|
||||
type ProxyServer struct {
|
||||
Client clientset.Interface
|
||||
EventClient v1core.EventsGetter
|
||||
IptInterface utiliptables.Interface
|
||||
IpvsInterface utilipvs.Interface
|
||||
IpsetInterface utilipset.Interface
|
||||
execer exec.Interface
|
||||
Proxier proxy.ProxyProvider
|
||||
Broadcaster record.EventBroadcaster
|
||||
Recorder record.EventRecorder
|
||||
ConntrackConfiguration kubeproxyconfig.KubeProxyConntrackConfiguration
|
||||
Conntracker Conntracker // if nil, ignored
|
||||
ProxyMode string
|
||||
NodeRef *v1.ObjectReference
|
||||
CleanupAndExit bool
|
||||
CleanupIPVS bool
|
||||
MetricsBindAddress string
|
||||
EnableProfiling bool
|
||||
OOMScoreAdj *int32
|
||||
ResourceContainer string
|
||||
ConfigSyncPeriod time.Duration
|
||||
ServiceEventHandler config.ServiceHandler
|
||||
EndpointsEventHandler config.EndpointsHandler
|
||||
HealthzServer *healthcheck.HealthzServer
|
||||
}
|
||||
|
||||
// createClients creates a kube client and an event client from the given config and masterOverride.
|
||||
// TODO remove masterOverride when CLI flags are removed.
|
||||
func createClients(config kubeproxyconfig.ClientConnectionConfiguration, masterOverride string) (clientset.Interface, v1core.EventsGetter, error) {
|
||||
var kubeConfig *rest.Config
|
||||
var err error
|
||||
|
||||
if len(config.KubeConfigFile) == 0 && len(masterOverride) == 0 {
|
||||
glog.Info("Neither kubeconfig file nor master URL was specified. Falling back to in-cluster config.")
|
||||
kubeConfig, err = rest.InClusterConfig()
|
||||
} else {
|
||||
// This creates a client, first loading any specified kubeconfig
|
||||
// file, and then overriding the Master flag, if non-empty.
|
||||
kubeConfig, err = clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
|
||||
&clientcmd.ClientConfigLoadingRules{ExplicitPath: config.KubeConfigFile},
|
||||
&clientcmd.ConfigOverrides{ClusterInfo: clientcmdapi.Cluster{Server: masterOverride}}).ClientConfig()
|
||||
}
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
kubeConfig.AcceptContentTypes = config.AcceptContentTypes
|
||||
kubeConfig.ContentType = config.ContentType
|
||||
kubeConfig.QPS = config.QPS
|
||||
//TODO make config struct use int instead of int32?
|
||||
kubeConfig.Burst = int(config.Burst)
|
||||
|
||||
client, err := clientset.NewForConfig(kubeConfig)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
eventClient, err := clientgoclientset.NewForConfig(kubeConfig)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return client, eventClient.CoreV1(), nil
|
||||
}
|
||||
|
||||
// Run runs the specified ProxyServer. This should never exit (unless CleanupAndExit is set).
|
||||
func (s *ProxyServer) Run() error {
|
||||
// To help debugging, immediately log version
|
||||
glog.Infof("Version: %+v", version.Get())
|
||||
// remove iptables rules and exit
|
||||
if s.CleanupAndExit {
|
||||
encounteredError := userspace.CleanupLeftovers(s.IptInterface)
|
||||
encounteredError = iptables.CleanupLeftovers(s.IptInterface) || encounteredError
|
||||
encounteredError = ipvs.CleanupLeftovers(s.IpvsInterface, s.IptInterface, s.IpsetInterface, s.CleanupIPVS) || encounteredError
|
||||
if encounteredError {
|
||||
return errors.New("encountered an error while tearing down rules.")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// TODO(vmarmol): Use container config for this.
|
||||
var oomAdjuster *oom.OOMAdjuster
|
||||
if s.OOMScoreAdj != nil {
|
||||
oomAdjuster = oom.NewOOMAdjuster()
|
||||
if err := oomAdjuster.ApplyOOMScoreAdj(0, int(*s.OOMScoreAdj)); err != nil {
|
||||
glog.V(2).Info(err)
|
||||
}
|
||||
}
|
||||
|
||||
if len(s.ResourceContainer) != 0 {
|
||||
// Run in its own container.
|
||||
if err := resourcecontainer.RunInResourceContainer(s.ResourceContainer); err != nil {
|
||||
glog.Warningf("Failed to start in resource-only container %q: %v", s.ResourceContainer, err)
|
||||
} else {
|
||||
glog.V(2).Infof("Running in resource-only container %q", s.ResourceContainer)
|
||||
}
|
||||
}
|
||||
|
||||
if s.Broadcaster != nil && s.EventClient != nil {
|
||||
s.Broadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: s.EventClient.Events("")})
|
||||
}
|
||||
|
||||
// Start up a healthz server if requested
|
||||
if s.HealthzServer != nil {
|
||||
s.HealthzServer.Run()
|
||||
}
|
||||
|
||||
// Start up a metrics server if requested
|
||||
if len(s.MetricsBindAddress) > 0 {
|
||||
mux := http.NewServeMux()
|
||||
healthz.InstallHandler(mux)
|
||||
mux.HandleFunc("/proxyMode", func(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Fprintf(w, "%s", s.ProxyMode)
|
||||
})
|
||||
mux.Handle("/metrics", prometheus.Handler())
|
||||
if s.EnableProfiling {
|
||||
mux.HandleFunc("/debug/pprof/", pprof.Index)
|
||||
mux.HandleFunc("/debug/pprof/profile", pprof.Profile)
|
||||
mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
|
||||
mux.HandleFunc("/debug/pprof/trace", pprof.Trace)
|
||||
}
|
||||
configz.InstallHandler(mux)
|
||||
go wait.Until(func() {
|
||||
err := http.ListenAndServe(s.MetricsBindAddress, mux)
|
||||
if err != nil {
|
||||
utilruntime.HandleError(fmt.Errorf("starting metrics server failed: %v", err))
|
||||
}
|
||||
}, 5*time.Second, wait.NeverStop)
|
||||
}
|
||||
|
||||
// Tune conntrack, if requested
|
||||
// Conntracker is always nil for windows
|
||||
if s.Conntracker != nil {
|
||||
max, err := getConntrackMax(s.ConntrackConfiguration)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if max > 0 {
|
||||
err := s.Conntracker.SetMax(max)
|
||||
if err != nil {
|
||||
if err != readOnlySysFSError {
|
||||
return err
|
||||
}
|
||||
// readOnlySysFSError is caused by a known docker issue (https://github.com/docker/docker/issues/24000),
|
||||
// the only remediation we know is to restart the docker daemon.
|
||||
// Here we'll send an node event with specific reason and message, the
|
||||
// administrator should decide whether and how to handle this issue,
|
||||
// whether to drain the node and restart docker.
|
||||
// TODO(random-liu): Remove this when the docker bug is fixed.
|
||||
const message = "DOCKER RESTART NEEDED (docker issue #24000): /sys is read-only: " +
|
||||
"cannot modify conntrack limits, problems may arise later."
|
||||
s.Recorder.Eventf(s.NodeRef, api.EventTypeWarning, err.Error(), message)
|
||||
}
|
||||
}
|
||||
|
||||
if s.ConntrackConfiguration.TCPEstablishedTimeout != nil && s.ConntrackConfiguration.TCPEstablishedTimeout.Duration > 0 {
|
||||
timeout := int(s.ConntrackConfiguration.TCPEstablishedTimeout.Duration / time.Second)
|
||||
if err := s.Conntracker.SetTCPEstablishedTimeout(timeout); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if s.ConntrackConfiguration.TCPCloseWaitTimeout != nil && s.ConntrackConfiguration.TCPCloseWaitTimeout.Duration > 0 {
|
||||
timeout := int(s.ConntrackConfiguration.TCPCloseWaitTimeout.Duration / time.Second)
|
||||
if err := s.Conntracker.SetTCPCloseWaitTimeout(timeout); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
informerFactory := informers.NewSharedInformerFactory(s.Client, s.ConfigSyncPeriod)
|
||||
|
||||
// Create configs (i.e. Watches for Services and Endpoints)
|
||||
// Note: RegisterHandler() calls need to happen before creation of Sources because sources
|
||||
// only notify on changes, and the initial update (on process start) may be lost if no handlers
|
||||
// are registered yet.
|
||||
serviceConfig := config.NewServiceConfig(informerFactory.Core().InternalVersion().Services(), s.ConfigSyncPeriod)
|
||||
serviceConfig.RegisterEventHandler(s.ServiceEventHandler)
|
||||
go serviceConfig.Run(wait.NeverStop)
|
||||
|
||||
endpointsConfig := config.NewEndpointsConfig(informerFactory.Core().InternalVersion().Endpoints(), s.ConfigSyncPeriod)
|
||||
endpointsConfig.RegisterEventHandler(s.EndpointsEventHandler)
|
||||
go endpointsConfig.Run(wait.NeverStop)
|
||||
|
||||
// This has to start after the calls to NewServiceConfig and NewEndpointsConfig because those
|
||||
// functions must configure their shared informer event handlers first.
|
||||
go informerFactory.Start(wait.NeverStop)
|
||||
|
||||
// Birth Cry after the birth is successful
|
||||
s.birthCry()
|
||||
|
||||
// Just loop forever for now...
|
||||
s.Proxier.SyncLoop()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *ProxyServer) birthCry() {
|
||||
s.Recorder.Eventf(s.NodeRef, api.EventTypeNormal, "Starting", "Starting kube-proxy.")
|
||||
}
|
||||
|
||||
func getConntrackMax(config kubeproxyconfig.KubeProxyConntrackConfiguration) (int, error) {
|
||||
if config.Max != nil && *config.Max > 0 {
|
||||
if config.MaxPerCore != nil && *config.MaxPerCore > 0 {
|
||||
return -1, fmt.Errorf("invalid config: Conntrack Max and Conntrack MaxPerCore are mutually exclusive")
|
||||
}
|
||||
glog.V(3).Infof("getConntrackMax: using absolute conntrack-max (deprecated)")
|
||||
return int(*config.Max), nil
|
||||
}
|
||||
if config.MaxPerCore != nil && *config.MaxPerCore > 0 {
|
||||
floor := 0
|
||||
if config.Min != nil {
|
||||
floor = int(*config.Min)
|
||||
}
|
||||
scaled := int(*config.MaxPerCore) * goruntime.NumCPU()
|
||||
if scaled > floor {
|
||||
glog.V(3).Infof("getConntrackMax: using scaled conntrack-max-per-core")
|
||||
return scaled, nil
|
||||
}
|
||||
glog.V(3).Infof("getConntrackMax: using conntrack-min")
|
||||
return floor, nil
|
||||
}
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func getNodeIP(client clientset.Interface, hostname string) net.IP {
|
||||
var nodeIP net.IP
|
||||
node, err := client.Core().Nodes().Get(hostname, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
glog.Warningf("Failed to retrieve node info: %v", err)
|
||||
return nil
|
||||
}
|
||||
nodeIP, err = utilnode.InternalGetNodeHostIP(node)
|
||||
if err != nil {
|
||||
glog.Warningf("Failed to retrieve node IP: %v", err)
|
||||
return nil
|
||||
}
|
||||
return nodeIP
|
||||
}
|
323
vendor/k8s.io/kubernetes/cmd/kube-proxy/app/server_others.go
generated
vendored
Normal file
323
vendor/k8s.io/kubernetes/cmd/kube-proxy/app/server_others.go
generated
vendored
Normal file
@ -0,0 +1,323 @@
|
||||
// +build !windows
|
||||
|
||||
/*
|
||||
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 app does all of the work necessary to configure and run a
|
||||
// Kubernetes app process.
|
||||
package app
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
utilnet "k8s.io/apimachinery/pkg/util/net"
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
"k8s.io/client-go/tools/record"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
"k8s.io/kubernetes/pkg/proxy"
|
||||
proxyconfigapi "k8s.io/kubernetes/pkg/proxy/apis/kubeproxyconfig"
|
||||
proxyconfig "k8s.io/kubernetes/pkg/proxy/config"
|
||||
"k8s.io/kubernetes/pkg/proxy/healthcheck"
|
||||
"k8s.io/kubernetes/pkg/proxy/iptables"
|
||||
"k8s.io/kubernetes/pkg/proxy/ipvs"
|
||||
"k8s.io/kubernetes/pkg/proxy/metrics"
|
||||
"k8s.io/kubernetes/pkg/proxy/userspace"
|
||||
"k8s.io/kubernetes/pkg/util/configz"
|
||||
utildbus "k8s.io/kubernetes/pkg/util/dbus"
|
||||
utilipset "k8s.io/kubernetes/pkg/util/ipset"
|
||||
utiliptables "k8s.io/kubernetes/pkg/util/iptables"
|
||||
utilipvs "k8s.io/kubernetes/pkg/util/ipvs"
|
||||
utilnode "k8s.io/kubernetes/pkg/util/node"
|
||||
utilsysctl "k8s.io/kubernetes/pkg/util/sysctl"
|
||||
"k8s.io/utils/exec"
|
||||
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
// NewProxyServer returns a new ProxyServer.
|
||||
func NewProxyServer(o *Options) (*ProxyServer, error) {
|
||||
return newProxyServer(o.config, o.CleanupAndExit, o.CleanupIPVS, o.scheme, o.master)
|
||||
}
|
||||
|
||||
func newProxyServer(
|
||||
config *proxyconfigapi.KubeProxyConfiguration,
|
||||
cleanupAndExit bool,
|
||||
cleanupIPVS bool,
|
||||
scheme *runtime.Scheme,
|
||||
master string) (*ProxyServer, error) {
|
||||
|
||||
if config == nil {
|
||||
return nil, errors.New("config is required")
|
||||
}
|
||||
|
||||
if c, err := configz.New(proxyconfigapi.GroupName); err == nil {
|
||||
c.Set(config)
|
||||
} else {
|
||||
return nil, fmt.Errorf("unable to register configz: %s", err)
|
||||
}
|
||||
|
||||
protocol := utiliptables.ProtocolIpv4
|
||||
if net.ParseIP(config.BindAddress).To4() == nil {
|
||||
glog.V(0).Infof("IPv6 bind address (%s), assume IPv6 operation", config.BindAddress)
|
||||
protocol = utiliptables.ProtocolIpv6
|
||||
}
|
||||
|
||||
var iptInterface utiliptables.Interface
|
||||
var ipvsInterface utilipvs.Interface
|
||||
var ipsetInterface utilipset.Interface
|
||||
var dbus utildbus.Interface
|
||||
|
||||
// Create a iptables utils.
|
||||
execer := exec.New()
|
||||
|
||||
dbus = utildbus.New()
|
||||
iptInterface = utiliptables.New(execer, dbus, protocol)
|
||||
ipvsInterface = utilipvs.New(execer)
|
||||
ipsetInterface = utilipset.New(execer)
|
||||
|
||||
// We omit creation of pretty much everything if we run in cleanup mode
|
||||
if cleanupAndExit {
|
||||
return &ProxyServer{
|
||||
execer: execer,
|
||||
IptInterface: iptInterface,
|
||||
IpvsInterface: ipvsInterface,
|
||||
IpsetInterface: ipsetInterface,
|
||||
CleanupAndExit: cleanupAndExit,
|
||||
}, nil
|
||||
}
|
||||
|
||||
client, eventClient, err := createClients(config.ClientConnection, master)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Create event recorder
|
||||
hostname := utilnode.GetHostname(config.HostnameOverride)
|
||||
eventBroadcaster := record.NewBroadcaster()
|
||||
recorder := eventBroadcaster.NewRecorder(scheme, v1.EventSource{Component: "kube-proxy", Host: hostname})
|
||||
|
||||
nodeRef := &v1.ObjectReference{
|
||||
Kind: "Node",
|
||||
Name: hostname,
|
||||
UID: types.UID(hostname),
|
||||
Namespace: "",
|
||||
}
|
||||
|
||||
var healthzServer *healthcheck.HealthzServer
|
||||
var healthzUpdater healthcheck.HealthzUpdater
|
||||
if len(config.HealthzBindAddress) > 0 {
|
||||
healthzServer = healthcheck.NewDefaultHealthzServer(config.HealthzBindAddress, 2*config.IPTables.SyncPeriod.Duration, recorder, nodeRef)
|
||||
healthzUpdater = healthzServer
|
||||
}
|
||||
|
||||
var proxier proxy.ProxyProvider
|
||||
var serviceEventHandler proxyconfig.ServiceHandler
|
||||
var endpointsEventHandler proxyconfig.EndpointsHandler
|
||||
|
||||
proxyMode := getProxyMode(string(config.Mode), iptInterface, ipsetInterface, iptables.LinuxKernelCompatTester{})
|
||||
if proxyMode == proxyModeIPTables {
|
||||
glog.V(0).Info("Using iptables Proxier.")
|
||||
nodeIP := net.ParseIP(config.BindAddress)
|
||||
if nodeIP.Equal(net.IPv4zero) || nodeIP.Equal(net.IPv6zero) {
|
||||
nodeIP = getNodeIP(client, hostname)
|
||||
}
|
||||
if config.IPTables.MasqueradeBit == nil {
|
||||
// MasqueradeBit must be specified or defaulted.
|
||||
return nil, fmt.Errorf("unable to read IPTables MasqueradeBit from config")
|
||||
}
|
||||
|
||||
// TODO this has side effects that should only happen when Run() is invoked.
|
||||
proxierIPTables, err := iptables.NewProxier(
|
||||
iptInterface,
|
||||
utilsysctl.New(),
|
||||
execer,
|
||||
config.IPTables.SyncPeriod.Duration,
|
||||
config.IPTables.MinSyncPeriod.Duration,
|
||||
config.IPTables.MasqueradeAll,
|
||||
int(*config.IPTables.MasqueradeBit),
|
||||
config.ClusterCIDR,
|
||||
hostname,
|
||||
nodeIP,
|
||||
recorder,
|
||||
healthzUpdater,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to create proxier: %v", err)
|
||||
}
|
||||
metrics.RegisterMetrics()
|
||||
proxier = proxierIPTables
|
||||
serviceEventHandler = proxierIPTables
|
||||
endpointsEventHandler = proxierIPTables
|
||||
// No turning back. Remove artifacts that might still exist from the userspace Proxier.
|
||||
glog.V(0).Info("Tearing down inactive rules.")
|
||||
// TODO this has side effects that should only happen when Run() is invoked.
|
||||
userspace.CleanupLeftovers(iptInterface)
|
||||
// IPVS Proxier will generate some iptables rules, need to clean them before switching to other proxy mode.
|
||||
// Besides, ipvs proxier will create some ipvs rules as well. Because there is no way to tell if a given
|
||||
// ipvs rule is created by IPVS proxier or not. Users should explicitly specify `--clean-ipvs=true` to flush
|
||||
// all ipvs rules when kube-proxy start up. Users do this operation should be with caution.
|
||||
ipvs.CleanupLeftovers(ipvsInterface, iptInterface, ipsetInterface, cleanupIPVS)
|
||||
} else if proxyMode == proxyModeIPVS {
|
||||
glog.V(0).Info("Using ipvs Proxier.")
|
||||
proxierIPVS, err := ipvs.NewProxier(
|
||||
iptInterface,
|
||||
ipvsInterface,
|
||||
ipsetInterface,
|
||||
utilsysctl.New(),
|
||||
execer,
|
||||
config.IPVS.SyncPeriod.Duration,
|
||||
config.IPVS.MinSyncPeriod.Duration,
|
||||
config.IPTables.MasqueradeAll,
|
||||
int(*config.IPTables.MasqueradeBit),
|
||||
config.ClusterCIDR,
|
||||
hostname,
|
||||
getNodeIP(client, hostname),
|
||||
recorder,
|
||||
healthzServer,
|
||||
config.IPVS.Scheduler,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to create proxier: %v", err)
|
||||
}
|
||||
metrics.RegisterMetrics()
|
||||
proxier = proxierIPVS
|
||||
serviceEventHandler = proxierIPVS
|
||||
endpointsEventHandler = proxierIPVS
|
||||
glog.V(0).Info("Tearing down inactive rules.")
|
||||
// TODO this has side effects that should only happen when Run() is invoked.
|
||||
userspace.CleanupLeftovers(iptInterface)
|
||||
iptables.CleanupLeftovers(iptInterface)
|
||||
} else {
|
||||
glog.V(0).Info("Using userspace Proxier.")
|
||||
// This is a proxy.LoadBalancer which NewProxier needs but has methods we don't need for
|
||||
// our config.EndpointsConfigHandler.
|
||||
loadBalancer := userspace.NewLoadBalancerRR()
|
||||
// set EndpointsConfigHandler to our loadBalancer
|
||||
endpointsEventHandler = loadBalancer
|
||||
|
||||
// TODO this has side effects that should only happen when Run() is invoked.
|
||||
proxierUserspace, err := userspace.NewProxier(
|
||||
loadBalancer,
|
||||
net.ParseIP(config.BindAddress),
|
||||
iptInterface,
|
||||
execer,
|
||||
*utilnet.ParsePortRangeOrDie(config.PortRange),
|
||||
config.IPTables.SyncPeriod.Duration,
|
||||
config.IPTables.MinSyncPeriod.Duration,
|
||||
config.UDPIdleTimeout.Duration,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to create proxier: %v", err)
|
||||
}
|
||||
serviceEventHandler = proxierUserspace
|
||||
proxier = proxierUserspace
|
||||
|
||||
// Remove artifacts from the iptables and ipvs Proxier, if not on Windows.
|
||||
glog.V(0).Info("Tearing down inactive rules.")
|
||||
// TODO this has side effects that should only happen when Run() is invoked.
|
||||
iptables.CleanupLeftovers(iptInterface)
|
||||
// IPVS Proxier will generate some iptables rules, need to clean them before switching to other proxy mode.
|
||||
// Besides, ipvs proxier will create some ipvs rules as well. Because there is no way to tell if a given
|
||||
// ipvs rule is created by IPVS proxier or not. Users should explicitly specify `--clean-ipvs=true` to flush
|
||||
// all ipvs rules when kube-proxy start up. Users do this operation should be with caution.
|
||||
ipvs.CleanupLeftovers(ipvsInterface, iptInterface, ipsetInterface, cleanupIPVS)
|
||||
}
|
||||
|
||||
iptInterface.AddReloadFunc(proxier.Sync)
|
||||
|
||||
return &ProxyServer{
|
||||
Client: client,
|
||||
EventClient: eventClient,
|
||||
IptInterface: iptInterface,
|
||||
IpvsInterface: ipvsInterface,
|
||||
IpsetInterface: ipsetInterface,
|
||||
execer: execer,
|
||||
Proxier: proxier,
|
||||
Broadcaster: eventBroadcaster,
|
||||
Recorder: recorder,
|
||||
ConntrackConfiguration: config.Conntrack,
|
||||
Conntracker: &realConntracker{},
|
||||
ProxyMode: proxyMode,
|
||||
NodeRef: nodeRef,
|
||||
MetricsBindAddress: config.MetricsBindAddress,
|
||||
EnableProfiling: config.EnableProfiling,
|
||||
OOMScoreAdj: config.OOMScoreAdj,
|
||||
ResourceContainer: config.ResourceContainer,
|
||||
ConfigSyncPeriod: config.ConfigSyncPeriod.Duration,
|
||||
ServiceEventHandler: serviceEventHandler,
|
||||
EndpointsEventHandler: endpointsEventHandler,
|
||||
HealthzServer: healthzServer,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func getProxyMode(proxyMode string, iptver iptables.IPTablesVersioner, ipsetver ipvs.IPSetVersioner, kcompat iptables.KernelCompatTester) string {
|
||||
if proxyMode == proxyModeUserspace {
|
||||
return proxyModeUserspace
|
||||
}
|
||||
|
||||
if len(proxyMode) > 0 && proxyMode == proxyModeIPTables {
|
||||
return tryIPTablesProxy(iptver, kcompat)
|
||||
}
|
||||
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.SupportIPVSProxyMode) {
|
||||
if proxyMode == proxyModeIPVS {
|
||||
return tryIPVSProxy(iptver, ipsetver, kcompat)
|
||||
} else {
|
||||
glog.Warningf("Can't use ipvs proxier, trying iptables proxier")
|
||||
return tryIPTablesProxy(iptver, kcompat)
|
||||
}
|
||||
}
|
||||
glog.Warningf("Flag proxy-mode=%q unknown, assuming iptables proxy", proxyMode)
|
||||
return tryIPTablesProxy(iptver, kcompat)
|
||||
}
|
||||
|
||||
func tryIPVSProxy(iptver iptables.IPTablesVersioner, ipsetver ipvs.IPSetVersioner, kcompat iptables.KernelCompatTester) string {
|
||||
// guaranteed false on error, error only necessary for debugging
|
||||
// IPVS Proxier relies on ipset
|
||||
useIPVSProxy, err := ipvs.CanUseIPVSProxier(ipsetver)
|
||||
if err != nil {
|
||||
// Try to fallback to iptables before falling back to userspace
|
||||
utilruntime.HandleError(fmt.Errorf("can't determine whether to use ipvs proxy, error: %v", err))
|
||||
}
|
||||
if useIPVSProxy {
|
||||
return proxyModeIPVS
|
||||
}
|
||||
|
||||
// Try to fallback to iptables before falling back to userspace
|
||||
glog.V(1).Infof("Can't use ipvs proxier, trying iptables proxier")
|
||||
return tryIPTablesProxy(iptver, kcompat)
|
||||
}
|
||||
|
||||
func tryIPTablesProxy(iptver iptables.IPTablesVersioner, kcompat iptables.KernelCompatTester) string {
|
||||
// guaranteed false on error, error only necessary for debugging
|
||||
useIPTablesProxy, err := iptables.CanUseIPTablesProxier(iptver, kcompat)
|
||||
if err != nil {
|
||||
utilruntime.HandleError(fmt.Errorf("can't determine whether to use iptables proxy, using userspace proxier: %v", err))
|
||||
return proxyModeUserspace
|
||||
}
|
||||
if useIPTablesProxy {
|
||||
return proxyModeIPTables
|
||||
}
|
||||
// Fallback.
|
||||
glog.V(1).Infof("Can't use iptables proxy, using userspace proxier")
|
||||
return proxyModeUserspace
|
||||
}
|
431
vendor/k8s.io/kubernetes/cmd/kube-proxy/app/server_test.go
generated
vendored
Normal file
431
vendor/k8s.io/kubernetes/cmd/kube-proxy/app/server_test.go
generated
vendored
Normal file
@ -0,0 +1,431 @@
|
||||
/*
|
||||
Copyright 2015 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
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/diff"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
"k8s.io/kubernetes/pkg/proxy/apis/kubeproxyconfig"
|
||||
"k8s.io/kubernetes/pkg/util/configz"
|
||||
"k8s.io/kubernetes/pkg/util/iptables"
|
||||
utilpointer "k8s.io/kubernetes/pkg/util/pointer"
|
||||
)
|
||||
|
||||
type fakeNodeInterface struct {
|
||||
node api.Node
|
||||
}
|
||||
|
||||
func (fake *fakeNodeInterface) Get(hostname string, options metav1.GetOptions) (*api.Node, error) {
|
||||
return &fake.node, nil
|
||||
}
|
||||
|
||||
type fakeIPTablesVersioner struct {
|
||||
version string // what to return
|
||||
err error // what to return
|
||||
}
|
||||
|
||||
func (fake *fakeIPTablesVersioner) GetVersion() (string, error) {
|
||||
return fake.version, fake.err
|
||||
}
|
||||
|
||||
type fakeIPSetVersioner struct {
|
||||
version string // what to return
|
||||
err error // what to return
|
||||
}
|
||||
|
||||
func (fake *fakeIPSetVersioner) GetVersion() (string, error) {
|
||||
return fake.version, fake.err
|
||||
}
|
||||
|
||||
type fakeKernelCompatTester struct {
|
||||
ok bool
|
||||
}
|
||||
|
||||
func (fake *fakeKernelCompatTester) IsCompatible() error {
|
||||
if !fake.ok {
|
||||
return fmt.Errorf("error")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Test_getProxyMode(t *testing.T) {
|
||||
if runtime.GOOS != "linux" {
|
||||
t.Skip("skipping on non-Linux")
|
||||
}
|
||||
var cases = []struct {
|
||||
flag string
|
||||
annotationKey string
|
||||
annotationVal string
|
||||
iptablesVersion string
|
||||
ipsetVersion string
|
||||
kernelCompat bool
|
||||
iptablesError error
|
||||
ipsetError error
|
||||
expected string
|
||||
}{
|
||||
{ // flag says userspace
|
||||
flag: "userspace",
|
||||
expected: proxyModeUserspace,
|
||||
},
|
||||
{ // flag says iptables, error detecting version
|
||||
flag: "iptables",
|
||||
iptablesError: fmt.Errorf("oops!"),
|
||||
expected: proxyModeUserspace,
|
||||
},
|
||||
{ // flag says iptables, version too low
|
||||
flag: "iptables",
|
||||
iptablesVersion: "0.0.0",
|
||||
expected: proxyModeUserspace,
|
||||
},
|
||||
{ // flag says iptables, version ok, kernel not compatible
|
||||
flag: "iptables",
|
||||
iptablesVersion: iptables.MinCheckVersion,
|
||||
kernelCompat: false,
|
||||
expected: proxyModeUserspace,
|
||||
},
|
||||
{ // flag says iptables, version ok, kernel is compatible
|
||||
flag: "iptables",
|
||||
iptablesVersion: iptables.MinCheckVersion,
|
||||
kernelCompat: true,
|
||||
expected: proxyModeIPTables,
|
||||
},
|
||||
{ // detect, error
|
||||
flag: "",
|
||||
iptablesError: fmt.Errorf("oops!"),
|
||||
expected: proxyModeUserspace,
|
||||
},
|
||||
{ // detect, version too low
|
||||
flag: "",
|
||||
iptablesVersion: "0.0.0",
|
||||
expected: proxyModeUserspace,
|
||||
},
|
||||
{ // detect, version ok, kernel not compatible
|
||||
flag: "",
|
||||
iptablesVersion: iptables.MinCheckVersion,
|
||||
kernelCompat: false,
|
||||
expected: proxyModeUserspace,
|
||||
},
|
||||
{ // detect, version ok, kernel is compatible
|
||||
flag: "",
|
||||
iptablesVersion: iptables.MinCheckVersion,
|
||||
kernelCompat: true,
|
||||
expected: proxyModeIPTables,
|
||||
},
|
||||
}
|
||||
for i, c := range cases {
|
||||
versioner := &fakeIPTablesVersioner{c.iptablesVersion, c.iptablesError}
|
||||
kcompater := &fakeKernelCompatTester{c.kernelCompat}
|
||||
ipsetver := &fakeIPSetVersioner{c.ipsetVersion, c.ipsetError}
|
||||
r := getProxyMode(c.flag, versioner, ipsetver, kcompater)
|
||||
if r != c.expected {
|
||||
t.Errorf("Case[%d] Expected %q, got %q", i, c.expected, r)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This test verifies that NewProxyServer does not crash when CleanupAndExit is true.
|
||||
func TestProxyServerWithCleanupAndExit(t *testing.T) {
|
||||
// Each bind address below is a separate test case
|
||||
bindAddresses := []string{
|
||||
"0.0.0.0",
|
||||
"::",
|
||||
}
|
||||
for _, addr := range bindAddresses {
|
||||
options := NewOptions()
|
||||
|
||||
options.config = &kubeproxyconfig.KubeProxyConfiguration{
|
||||
BindAddress: addr,
|
||||
}
|
||||
options.CleanupAndExit = true
|
||||
|
||||
proxyserver, err := NewProxyServer(options)
|
||||
|
||||
assert.Nil(t, err, "unexpected error in NewProxyServer, addr: %s", addr)
|
||||
assert.NotNil(t, proxyserver, "nil proxy server obj, addr: %s", addr)
|
||||
assert.NotNil(t, proxyserver.IptInterface, "nil iptables intf, addr: %s", addr)
|
||||
assert.True(t, proxyserver.CleanupAndExit, "false CleanupAndExit, addr: %s", addr)
|
||||
|
||||
// Clean up config for next test case
|
||||
configz.Delete(kubeproxyconfig.GroupName)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetConntrackMax(t *testing.T) {
|
||||
ncores := runtime.NumCPU()
|
||||
testCases := []struct {
|
||||
min int32
|
||||
max int32
|
||||
maxPerCore int32
|
||||
expected int
|
||||
err string
|
||||
}{
|
||||
{
|
||||
expected: 0,
|
||||
},
|
||||
{
|
||||
max: 12345,
|
||||
expected: 12345,
|
||||
},
|
||||
{
|
||||
max: 12345,
|
||||
maxPerCore: 67890,
|
||||
expected: -1,
|
||||
err: "mutually exclusive",
|
||||
},
|
||||
{
|
||||
maxPerCore: 67890, // use this if Max is 0
|
||||
min: 1, // avoid 0 default
|
||||
expected: 67890 * ncores,
|
||||
},
|
||||
{
|
||||
maxPerCore: 1, // ensure that Min is considered
|
||||
min: 123456,
|
||||
expected: 123456,
|
||||
},
|
||||
{
|
||||
maxPerCore: 0, // leave system setting
|
||||
min: 123456,
|
||||
expected: 0,
|
||||
},
|
||||
}
|
||||
|
||||
for i, tc := range testCases {
|
||||
cfg := kubeproxyconfig.KubeProxyConntrackConfiguration{
|
||||
Min: utilpointer.Int32Ptr(tc.min),
|
||||
Max: utilpointer.Int32Ptr(tc.max),
|
||||
MaxPerCore: utilpointer.Int32Ptr(tc.maxPerCore),
|
||||
}
|
||||
x, e := getConntrackMax(cfg)
|
||||
if e != nil {
|
||||
if tc.err == "" {
|
||||
t.Errorf("[%d] unexpected error: %v", i, e)
|
||||
} else if !strings.Contains(e.Error(), tc.err) {
|
||||
t.Errorf("[%d] expected an error containing %q: %v", i, tc.err, e)
|
||||
}
|
||||
} else if x != tc.expected {
|
||||
t.Errorf("[%d] expected %d, got %d", i, tc.expected, x)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestLoadConfig tests proper operation of loadConfig()
|
||||
func TestLoadConfig(t *testing.T) {
|
||||
|
||||
yamlTemplate := `apiVersion: kubeproxy.config.k8s.io/v1alpha1
|
||||
bindAddress: %s
|
||||
clientConnection:
|
||||
acceptContentTypes: "abc"
|
||||
burst: 100
|
||||
contentType: content-type
|
||||
kubeconfig: "/path/to/kubeconfig"
|
||||
qps: 7
|
||||
clusterCIDR: "%s"
|
||||
configSyncPeriod: 15s
|
||||
conntrack:
|
||||
max: 4
|
||||
maxPerCore: 2
|
||||
min: 1
|
||||
tcpCloseWaitTimeout: 10s
|
||||
tcpEstablishedTimeout: 20s
|
||||
featureGates: "all"
|
||||
healthzBindAddress: "%s"
|
||||
hostnameOverride: "foo"
|
||||
iptables:
|
||||
masqueradeAll: true
|
||||
masqueradeBit: 17
|
||||
minSyncPeriod: 10s
|
||||
syncPeriod: 60s
|
||||
ipvs:
|
||||
minSyncPeriod: 10s
|
||||
syncPeriod: 60s
|
||||
kind: KubeProxyConfiguration
|
||||
metricsBindAddress: "%s"
|
||||
mode: "%s"
|
||||
oomScoreAdj: 17
|
||||
portRange: "2-7"
|
||||
resourceContainer: /foo
|
||||
udpTimeoutMilliseconds: 123ms
|
||||
`
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
mode string
|
||||
bindAddress string
|
||||
clusterCIDR string
|
||||
healthzBindAddress string
|
||||
metricsBindAddress string
|
||||
}{
|
||||
{
|
||||
name: "iptables mode, IPv4 all-zeros bind address",
|
||||
mode: "iptables",
|
||||
bindAddress: "0.0.0.0",
|
||||
clusterCIDR: "1.2.3.0/24",
|
||||
healthzBindAddress: "1.2.3.4:12345",
|
||||
metricsBindAddress: "2.3.4.5:23456",
|
||||
},
|
||||
{
|
||||
name: "iptables mode, non-zeros IPv4 config",
|
||||
mode: "iptables",
|
||||
bindAddress: "9.8.7.6",
|
||||
clusterCIDR: "1.2.3.0/24",
|
||||
healthzBindAddress: "1.2.3.4:12345",
|
||||
metricsBindAddress: "2.3.4.5:23456",
|
||||
},
|
||||
{
|
||||
// Test for 'bindAddress: "::"' (IPv6 all-zeros) in kube-proxy
|
||||
// config file. The user will need to put quotes around '::' since
|
||||
// 'bindAddress: ::' is invalid yaml syntax.
|
||||
name: "iptables mode, IPv6 \"::\" bind address",
|
||||
mode: "iptables",
|
||||
bindAddress: "\"::\"",
|
||||
clusterCIDR: "fd00:1::0/64",
|
||||
healthzBindAddress: "[fd00:1::5]:12345",
|
||||
metricsBindAddress: "[fd00:2::5]:23456",
|
||||
},
|
||||
{
|
||||
// Test for 'bindAddress: "[::]"' (IPv6 all-zeros in brackets)
|
||||
// in kube-proxy config file. The user will need to use
|
||||
// surrounding quotes here since 'bindAddress: [::]' is invalid
|
||||
// yaml syntax.
|
||||
name: "iptables mode, IPv6 \"[::]\" bind address",
|
||||
mode: "iptables",
|
||||
bindAddress: "\"[::]\"",
|
||||
clusterCIDR: "fd00:1::0/64",
|
||||
healthzBindAddress: "[fd00:1::5]:12345",
|
||||
metricsBindAddress: "[fd00:2::5]:23456",
|
||||
},
|
||||
{
|
||||
// Test for 'bindAddress: ::0' (another form of IPv6 all-zeros).
|
||||
// No surrounding quotes are required around '::0'.
|
||||
name: "iptables mode, IPv6 ::0 bind address",
|
||||
mode: "iptables",
|
||||
bindAddress: "::0",
|
||||
clusterCIDR: "fd00:1::0/64",
|
||||
healthzBindAddress: "[fd00:1::5]:12345",
|
||||
metricsBindAddress: "[fd00:2::5]:23456",
|
||||
},
|
||||
{
|
||||
name: "ipvs mode, IPv6 config",
|
||||
mode: "ipvs",
|
||||
bindAddress: "2001:db8::1",
|
||||
clusterCIDR: "fd00:1::0/64",
|
||||
healthzBindAddress: "[fd00:1::5]:12345",
|
||||
metricsBindAddress: "[fd00:2::5]:23456",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
expBindAddr := tc.bindAddress
|
||||
if tc.bindAddress[0] == '"' {
|
||||
// Surrounding double quotes will get stripped by the yaml parser.
|
||||
expBindAddr = expBindAddr[1 : len(tc.bindAddress)-1]
|
||||
}
|
||||
expected := &kubeproxyconfig.KubeProxyConfiguration{
|
||||
BindAddress: expBindAddr,
|
||||
ClientConnection: kubeproxyconfig.ClientConnectionConfiguration{
|
||||
AcceptContentTypes: "abc",
|
||||
Burst: 100,
|
||||
ContentType: "content-type",
|
||||
KubeConfigFile: "/path/to/kubeconfig",
|
||||
QPS: 7,
|
||||
},
|
||||
ClusterCIDR: tc.clusterCIDR,
|
||||
ConfigSyncPeriod: metav1.Duration{Duration: 15 * time.Second},
|
||||
Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
|
||||
Max: utilpointer.Int32Ptr(4),
|
||||
MaxPerCore: utilpointer.Int32Ptr(2),
|
||||
Min: utilpointer.Int32Ptr(1),
|
||||
TCPCloseWaitTimeout: &metav1.Duration{Duration: 10 * time.Second},
|
||||
TCPEstablishedTimeout: &metav1.Duration{Duration: 20 * time.Second},
|
||||
},
|
||||
FeatureGates: "all",
|
||||
HealthzBindAddress: tc.healthzBindAddress,
|
||||
HostnameOverride: "foo",
|
||||
IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{
|
||||
MasqueradeAll: true,
|
||||
MasqueradeBit: utilpointer.Int32Ptr(17),
|
||||
MinSyncPeriod: metav1.Duration{Duration: 10 * time.Second},
|
||||
SyncPeriod: metav1.Duration{Duration: 60 * time.Second},
|
||||
},
|
||||
IPVS: kubeproxyconfig.KubeProxyIPVSConfiguration{
|
||||
MinSyncPeriod: metav1.Duration{Duration: 10 * time.Second},
|
||||
SyncPeriod: metav1.Duration{Duration: 60 * time.Second},
|
||||
},
|
||||
MetricsBindAddress: tc.metricsBindAddress,
|
||||
Mode: kubeproxyconfig.ProxyMode(tc.mode),
|
||||
OOMScoreAdj: utilpointer.Int32Ptr(17),
|
||||
PortRange: "2-7",
|
||||
ResourceContainer: "/foo",
|
||||
UDPIdleTimeout: metav1.Duration{Duration: 123 * time.Millisecond},
|
||||
}
|
||||
|
||||
options := NewOptions()
|
||||
|
||||
yaml := fmt.Sprintf(
|
||||
yamlTemplate, tc.bindAddress, tc.clusterCIDR,
|
||||
tc.healthzBindAddress, tc.metricsBindAddress, tc.mode)
|
||||
config, err := options.loadConfig([]byte(yaml))
|
||||
assert.NoError(t, err, "unexpected error for %s: %v", tc.name, err)
|
||||
if !reflect.DeepEqual(expected, config) {
|
||||
t.Fatalf("unexpected config for %s, diff = %s", tc.name, diff.ObjectDiff(config, expected))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestLoadConfigFailures tests failure modes for loadConfig()
|
||||
func TestLoadConfigFailures(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
config string
|
||||
expErr string
|
||||
}{
|
||||
{
|
||||
name: "Decode error test",
|
||||
config: "Twas bryllyg, and ye slythy toves",
|
||||
expErr: "could not find expected ':'",
|
||||
},
|
||||
{
|
||||
name: "Bad config type test",
|
||||
config: "kind: KubeSchedulerConfiguration",
|
||||
expErr: "no kind",
|
||||
},
|
||||
{
|
||||
name: "Missing quotes around :: bindAddress",
|
||||
config: "bindAddress: ::",
|
||||
expErr: "mapping values are not allowed in this context",
|
||||
},
|
||||
}
|
||||
version := "apiVersion: kubeproxy.config.k8s.io/v1alpha1"
|
||||
for _, tc := range testCases {
|
||||
options := NewOptions()
|
||||
config := fmt.Sprintf("%s\n%s", version, tc.config)
|
||||
_, err := options.loadConfig([]byte(config))
|
||||
if assert.Error(t, err, tc.name) {
|
||||
assert.Contains(t, err.Error(), tc.expErr, tc.name)
|
||||
}
|
||||
}
|
||||
}
|
191
vendor/k8s.io/kubernetes/cmd/kube-proxy/app/server_windows.go
generated
vendored
Normal file
191
vendor/k8s.io/kubernetes/cmd/kube-proxy/app/server_windows.go
generated
vendored
Normal file
@ -0,0 +1,191 @@
|
||||
// +build windows
|
||||
|
||||
/*
|
||||
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 app does all of the work necessary to configure and run a
|
||||
// Kubernetes app process.
|
||||
package app
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
_ "net/http/pprof"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
utilnet "k8s.io/apimachinery/pkg/util/net"
|
||||
"k8s.io/client-go/tools/record"
|
||||
"k8s.io/kubernetes/pkg/proxy"
|
||||
proxyconfigapi "k8s.io/kubernetes/pkg/proxy/apis/kubeproxyconfig"
|
||||
proxyconfig "k8s.io/kubernetes/pkg/proxy/config"
|
||||
"k8s.io/kubernetes/pkg/proxy/healthcheck"
|
||||
"k8s.io/kubernetes/pkg/proxy/winkernel"
|
||||
"k8s.io/kubernetes/pkg/proxy/winuserspace"
|
||||
"k8s.io/kubernetes/pkg/util/configz"
|
||||
utilnetsh "k8s.io/kubernetes/pkg/util/netsh"
|
||||
utilnode "k8s.io/kubernetes/pkg/util/node"
|
||||
"k8s.io/utils/exec"
|
||||
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
// NewProxyServer returns a new ProxyServer.
|
||||
func NewProxyServer(o *Options) (*ProxyServer, error) {
|
||||
return newProxyServer(o.config, o.CleanupAndExit, o.scheme, o.master)
|
||||
}
|
||||
|
||||
func newProxyServer(config *proxyconfigapi.KubeProxyConfiguration, cleanupAndExit bool, scheme *runtime.Scheme, master string) (*ProxyServer, error) {
|
||||
if config == nil {
|
||||
return nil, errors.New("config is required")
|
||||
}
|
||||
|
||||
if c, err := configz.New(proxyconfigapi.GroupName); err == nil {
|
||||
c.Set(config)
|
||||
} else {
|
||||
return nil, fmt.Errorf("unable to register configz: %s", err)
|
||||
}
|
||||
|
||||
// We omit creation of pretty much everything if we run in cleanup mode
|
||||
if cleanupAndExit {
|
||||
return &ProxyServer{CleanupAndExit: cleanupAndExit}, nil
|
||||
}
|
||||
|
||||
client, eventClient, err := createClients(config.ClientConnection, master)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Create event recorder
|
||||
hostname := utilnode.GetHostname(config.HostnameOverride)
|
||||
eventBroadcaster := record.NewBroadcaster()
|
||||
recorder := eventBroadcaster.NewRecorder(scheme, v1.EventSource{Component: "kube-proxy", Host: hostname})
|
||||
|
||||
nodeRef := &v1.ObjectReference{
|
||||
Kind: "Node",
|
||||
Name: hostname,
|
||||
UID: types.UID(hostname),
|
||||
Namespace: "",
|
||||
}
|
||||
|
||||
var healthzServer *healthcheck.HealthzServer
|
||||
var healthzUpdater healthcheck.HealthzUpdater
|
||||
if len(config.HealthzBindAddress) > 0 {
|
||||
healthzServer = healthcheck.NewDefaultHealthzServer(config.HealthzBindAddress, 2*config.IPTables.SyncPeriod.Duration, recorder, nodeRef)
|
||||
healthzUpdater = healthzServer
|
||||
}
|
||||
|
||||
var proxier proxy.ProxyProvider
|
||||
var serviceEventHandler proxyconfig.ServiceHandler
|
||||
var endpointsEventHandler proxyconfig.EndpointsHandler
|
||||
|
||||
proxyMode := getProxyMode(string(config.Mode), winkernel.WindowsKernelCompatTester{})
|
||||
if proxyMode == proxyModeKernelspace {
|
||||
glog.V(0).Info("Using Kernelspace Proxier.")
|
||||
proxierKernelspace, err := winkernel.NewProxier(
|
||||
config.IPTables.SyncPeriod.Duration,
|
||||
config.IPTables.MinSyncPeriod.Duration,
|
||||
config.IPTables.MasqueradeAll,
|
||||
int(*config.IPTables.MasqueradeBit),
|
||||
config.ClusterCIDR,
|
||||
hostname,
|
||||
getNodeIP(client, hostname),
|
||||
recorder,
|
||||
healthzUpdater,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to create proxier: %v", err)
|
||||
}
|
||||
proxier = proxierKernelspace
|
||||
endpointsEventHandler = proxierKernelspace
|
||||
serviceEventHandler = proxierKernelspace
|
||||
} else {
|
||||
glog.V(0).Info("Using userspace Proxier.")
|
||||
execer := exec.New()
|
||||
var netshInterface utilnetsh.Interface
|
||||
netshInterface = utilnetsh.New(execer)
|
||||
|
||||
// This is a proxy.LoadBalancer which NewProxier needs but has methods we don't need for
|
||||
// our config.EndpointsConfigHandler.
|
||||
loadBalancer := winuserspace.NewLoadBalancerRR()
|
||||
|
||||
// set EndpointsConfigHandler to our loadBalancer
|
||||
endpointsEventHandler = loadBalancer
|
||||
proxierUserspace, err := winuserspace.NewProxier(
|
||||
loadBalancer,
|
||||
net.ParseIP(config.BindAddress),
|
||||
netshInterface,
|
||||
*utilnet.ParsePortRangeOrDie(config.PortRange),
|
||||
// TODO @pires replace below with default values, if applicable
|
||||
config.IPTables.SyncPeriod.Duration,
|
||||
config.UDPIdleTimeout.Duration,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to create proxier: %v", err)
|
||||
}
|
||||
proxier = proxierUserspace
|
||||
serviceEventHandler = proxierUserspace
|
||||
glog.V(0).Info("Tearing down pure-winkernel proxy rules.")
|
||||
winkernel.CleanupLeftovers()
|
||||
}
|
||||
|
||||
return &ProxyServer{
|
||||
Client: client,
|
||||
EventClient: eventClient,
|
||||
Proxier: proxier,
|
||||
Broadcaster: eventBroadcaster,
|
||||
Recorder: recorder,
|
||||
ProxyMode: proxyMode,
|
||||
NodeRef: nodeRef,
|
||||
MetricsBindAddress: config.MetricsBindAddress,
|
||||
EnableProfiling: config.EnableProfiling,
|
||||
OOMScoreAdj: config.OOMScoreAdj,
|
||||
ResourceContainer: config.ResourceContainer,
|
||||
ConfigSyncPeriod: config.ConfigSyncPeriod.Duration,
|
||||
ServiceEventHandler: serviceEventHandler,
|
||||
EndpointsEventHandler: endpointsEventHandler,
|
||||
HealthzServer: healthzServer,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func getProxyMode(proxyMode string, kcompat winkernel.KernelCompatTester) string {
|
||||
if proxyMode == proxyModeUserspace {
|
||||
return proxyModeUserspace
|
||||
} else if proxyMode == proxyModeKernelspace {
|
||||
return tryWinKernelSpaceProxy(kcompat)
|
||||
}
|
||||
return proxyModeUserspace
|
||||
}
|
||||
|
||||
func tryWinKernelSpaceProxy(kcompat winkernel.KernelCompatTester) string {
|
||||
// Check for Windows Kernel Version if we can support Kernel Space proxy
|
||||
// Check for Windows Version
|
||||
|
||||
// guaranteed false on error, error only necessary for debugging
|
||||
useWinKerelProxy, err := winkernel.CanUseWinKernelProxier(kcompat)
|
||||
if err != nil {
|
||||
glog.Errorf("Can't determine whether to use windows kernel proxy, using userspace proxier: %v", err)
|
||||
return proxyModeUserspace
|
||||
}
|
||||
if useWinKerelProxy {
|
||||
return proxyModeKernelspace
|
||||
}
|
||||
// Fallback.
|
||||
glog.V(1).Infof("Can't use winkernel proxy, using userspace proxier")
|
||||
return proxyModeUserspace
|
||||
}
|
49
vendor/k8s.io/kubernetes/cmd/kube-proxy/proxy.go
generated
vendored
Normal file
49
vendor/k8s.io/kubernetes/cmd/kube-proxy/proxy.go
generated
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
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 main
|
||||
|
||||
import (
|
||||
goflag "flag"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
|
||||
utilflag "k8s.io/apiserver/pkg/util/flag"
|
||||
"k8s.io/apiserver/pkg/util/logs"
|
||||
"k8s.io/kubernetes/cmd/kube-proxy/app"
|
||||
_ "k8s.io/kubernetes/pkg/client/metrics/prometheus" // for client metric registration
|
||||
_ "k8s.io/kubernetes/pkg/version/prometheus" // for version metric registration
|
||||
)
|
||||
|
||||
func main() {
|
||||
command := app.NewProxyCommand()
|
||||
|
||||
// TODO: once we switch everything over to Cobra commands, we can go back to calling
|
||||
// utilflag.InitFlags() (by removing its pflag.Parse() call). For now, we have to set the
|
||||
// normalize func and add the go flag set by hand.
|
||||
pflag.CommandLine.SetNormalizeFunc(utilflag.WordSepNormalizeFunc)
|
||||
pflag.CommandLine.AddGoFlagSet(goflag.CommandLine)
|
||||
// utilflag.InitFlags()
|
||||
logs.InitLogs()
|
||||
defer logs.FlushLogs()
|
||||
|
||||
if err := command.Execute(); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
45
vendor/k8s.io/kubernetes/cmd/kubeadm/BUILD
generated
vendored
Normal file
45
vendor/k8s.io/kubernetes/cmd/kubeadm/BUILD
generated
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
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 = "kubeadm",
|
||||
gc_linkopts = [
|
||||
"-linkmode",
|
||||
"external",
|
||||
"-extldflags",
|
||||
"-static",
|
||||
],
|
||||
importpath = "k8s.io/kubernetes/cmd/kubeadm",
|
||||
library = ":go_default_library",
|
||||
x_defs = version_x_defs(),
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["kubeadm.go"],
|
||||
importpath = "k8s.io/kubernetes/cmd/kubeadm",
|
||||
deps = ["//cmd/kubeadm/app:go_default_library"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//cmd/kubeadm/app:all-srcs",
|
||||
"//cmd/kubeadm/test:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
)
|
17
vendor/k8s.io/kubernetes/cmd/kubeadm/OWNERS
generated
vendored
Normal file
17
vendor/k8s.io/kubernetes/cmd/kubeadm/OWNERS
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
approvers:
|
||||
- jbeda
|
||||
- luxas
|
||||
- mikedanese
|
||||
- krousey
|
||||
- timothysc
|
||||
reviewers:
|
||||
- mikedanese
|
||||
- luxas
|
||||
- dmmcquay
|
||||
- krousey
|
||||
- timothysc
|
||||
- fabriziopandini
|
||||
- jamiehannaford
|
||||
- kad
|
||||
- xiangpengzhao
|
||||
- mattmoyer
|
54
vendor/k8s.io/kubernetes/cmd/kubeadm/app/BUILD
generated
vendored
Normal file
54
vendor/k8s.io/kubernetes/cmd/kubeadm/app/BUILD
generated
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["kubeadm.go"],
|
||||
importpath = "k8s.io/kubernetes/cmd/kubeadm/app",
|
||||
deps = [
|
||||
"//cmd/kubeadm/app/apis/kubeadm/install:go_default_library",
|
||||
"//cmd/kubeadm/app/cmd:go_default_library",
|
||||
"//vendor/github.com/spf13/pflag:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//cmd/kubeadm/app/apis/kubeadm:all-srcs",
|
||||
"//cmd/kubeadm/app/cmd:all-srcs",
|
||||
"//cmd/kubeadm/app/constants:all-srcs",
|
||||
"//cmd/kubeadm/app/discovery:all-srcs",
|
||||
"//cmd/kubeadm/app/features:all-srcs",
|
||||
"//cmd/kubeadm/app/images:all-srcs",
|
||||
"//cmd/kubeadm/app/phases/addons/dns:all-srcs",
|
||||
"//cmd/kubeadm/app/phases/addons/proxy:all-srcs",
|
||||
"//cmd/kubeadm/app/phases/bootstraptoken/clusterinfo:all-srcs",
|
||||
"//cmd/kubeadm/app/phases/bootstraptoken/node:all-srcs",
|
||||
"//cmd/kubeadm/app/phases/certs:all-srcs",
|
||||
"//cmd/kubeadm/app/phases/controlplane:all-srcs",
|
||||
"//cmd/kubeadm/app/phases/etcd:all-srcs",
|
||||
"//cmd/kubeadm/app/phases/kubeconfig:all-srcs",
|
||||
"//cmd/kubeadm/app/phases/kubelet:all-srcs",
|
||||
"//cmd/kubeadm/app/phases/markmaster:all-srcs",
|
||||
"//cmd/kubeadm/app/phases/selfhosting:all-srcs",
|
||||
"//cmd/kubeadm/app/phases/token:all-srcs",
|
||||
"//cmd/kubeadm/app/phases/upgrade:all-srcs",
|
||||
"//cmd/kubeadm/app/phases/uploadconfig:all-srcs",
|
||||
"//cmd/kubeadm/app/preflight:all-srcs",
|
||||
"//cmd/kubeadm/app/util:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
)
|
44
vendor/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/BUILD
generated
vendored
Normal file
44
vendor/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/BUILD
generated
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"doc.go",
|
||||
"register.go",
|
||||
"types.go",
|
||||
"well_known_labels.go",
|
||||
"zz_generated.deepcopy.go",
|
||||
],
|
||||
importpath = "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm",
|
||||
deps = [
|
||||
"//pkg/kubelet/apis/kubeletconfig/v1alpha1:go_default_library",
|
||||
"//pkg/proxy/apis/kubeproxyconfig/v1alpha1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//cmd/kubeadm/app/apis/kubeadm/fuzzer:all-srcs",
|
||||
"//cmd/kubeadm/app/apis/kubeadm/install:all-srcs",
|
||||
"//cmd/kubeadm/app/apis/kubeadm/v1alpha1:all-srcs",
|
||||
"//cmd/kubeadm/app/apis/kubeadm/validation:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
)
|
23
vendor/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/doc.go
generated
vendored
Normal file
23
vendor/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/doc.go
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package kubeadm is the package that contains the libraries that drive the kubeadm binary.
|
||||
// kubeadm is responsible for handling a Kubernetes cluster's lifecycle.
|
||||
|
||||
// +k8s:deepcopy-gen=package
|
||||
// +groupName=kubeadm.k8s.io
|
||||
|
||||
package kubeadm // import "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
34
vendor/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/fuzzer/BUILD
generated
vendored
Normal file
34
vendor/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/fuzzer/BUILD
generated
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["fuzzer.go"],
|
||||
importpath = "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/fuzzer",
|
||||
deps = [
|
||||
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
||||
"//pkg/kubelet/apis/kubeletconfig/v1alpha1:go_default_library",
|
||||
"//pkg/proxy/apis/kubeproxyconfig/v1alpha1:go_default_library",
|
||||
"//pkg/util/pointer:go_default_library",
|
||||
"//vendor/github.com/google/gofuzz:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user