Switch to github.com/golang/dep for vendoring

Signed-off-by: Mrunal Patel <mrunalp@gmail.com>
This commit is contained in:
Mrunal Patel 2017-01-31 16:45:59 -08:00
parent d6ab91be27
commit 8e5b17cf13
15431 changed files with 3971413 additions and 8881 deletions

49
vendor/k8s.io/kubernetes/cmd/BUILD generated vendored Normal file
View file

@ -0,0 +1,49 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
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/genslateyaml:all-srcs",
"//cmd/genswaggertypedocs:all-srcs",
"//cmd/genutils:all-srcs",
"//cmd/genyaml:all-srcs",
"//cmd/hyperkube:all-srcs",
"//cmd/kube-aggregator:all-srcs",
"//cmd/kube-apiserver:all-srcs",
"//cmd/kube-controller-manager:all-srcs",
"//cmd/kube-discovery:all-srcs",
"//cmd/kube-proxy:all-srcs",
"//cmd/kubeadm:all-srcs",
"//cmd/kubectl:all-srcs",
"//cmd/kubelet:all-srcs",
"//cmd/kubemark:all-srcs",
"//cmd/libs/go2idl/client-gen:all-srcs",
"//cmd/libs/go2idl/conversion-gen:all-srcs",
"//cmd/libs/go2idl/deepcopy-gen:all-srcs",
"//cmd/libs/go2idl/defaulter-gen:all-srcs",
"//cmd/libs/go2idl/go-to-protobuf:all-srcs",
"//cmd/libs/go2idl/import-boss:all-srcs",
"//cmd/libs/go2idl/informer-gen:all-srcs",
"//cmd/libs/go2idl/lister-gen:all-srcs",
"//cmd/libs/go2idl/openapi-gen:all-srcs",
"//cmd/libs/go2idl/set-gen:all-srcs",
"//cmd/linkcheck:all-srcs",
"//cmd/mungedocs:all-srcs",
],
tags = ["automanaged"],
)

5
vendor/k8s.io/kubernetes/cmd/OWNERS generated vendored Normal file
View file

@ -0,0 +1,5 @@
assignees:
- dchen1107
- lavalamp
- mikedanese
- thockin

39
vendor/k8s.io/kubernetes/cmd/clicheck/BUILD generated vendored Normal file
View file

@ -0,0 +1,39 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_binary",
"go_library",
)
go_binary(
name = "clicheck",
library = ":go_default_library",
tags = ["automanaged"],
)
go_library(
name = "go_default_library",
srcs = ["check_cli_conventions.go"],
tags = ["automanaged"],
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"],
)

View file

@ -0,0 +1,48 @@
/*
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() {
errors := []error{}
kubectl := cmd.NewKubectlCommand(cmdutil.NewFactory(nil), os.Stdin, ioutil.Discard, ioutil.Discard)
result := cmdsanity.CheckCmdTree(kubectl, cmdsanity.AllCmdChecks, []string{})
errors = append(errors, result...)
if len(errors) > 0 {
for i, err := range errors {
fmt.Fprintf(os.Stderr, "%d. %s\n\n", i+1, err)
}
os.Exit(1)
}
fmt.Fprintln(os.Stdout, "Congrats, CLI looks good!")
}

View file

@ -0,0 +1,51 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_binary",
"go_library",
)
go_binary(
name = "cloud-controller-manager",
library = ":go_default_library",
tags = ["automanaged"],
)
go_library(
name = "go_default_library",
srcs = ["controller-manager.go"],
tags = ["automanaged"],
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:go_default_library",
"//pkg/cloudprovider/providers:go_default_library",
"//pkg/util/flag:go_default_library",
"//pkg/util/logs:go_default_library",
"//pkg/version/prometheus:go_default_library",
"//pkg/version/verflag:go_default_library",
"//vendor:github.com/golang/glog",
"//vendor:github.com/spf13/pflag",
"//vendor:k8s.io/apiserver/pkg/healthz",
],
)
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"],
)

View file

@ -0,0 +1,54 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["controllermanager.go"],
tags = ["automanaged"],
deps = [
"//cmd/cloud-controller-manager/app/options:go_default_library",
"//pkg/api/v1:go_default_library",
"//pkg/client/clientset_generated/clientset:go_default_library",
"//pkg/client/clientset_generated/clientset/typed/core/v1:go_default_library",
"//pkg/client/leaderelection:go_default_library",
"//pkg/client/leaderelection/resourcelock:go_default_library",
"//pkg/client/record:go_default_library",
"//pkg/client/restclient:go_default_library",
"//pkg/client/unversioned/clientcmd:go_default_library",
"//pkg/cloudprovider:go_default_library",
"//pkg/controller:go_default_library",
"//pkg/controller/cloud:go_default_library",
"//pkg/controller/informers: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",
"//vendor:github.com/prometheus/client_golang/prometheus",
"//vendor:github.com/spf13/cobra",
"//vendor:github.com/spf13/pflag",
"//vendor:k8s.io/apimachinery/pkg/util/wait",
"//vendor:k8s.io/apiserver/pkg/healthz",
],
)
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"],
)

View file

@ -0,0 +1,251 @@
/*
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"
"strconv"
"time"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/apiserver/pkg/healthz"
"k8s.io/kubernetes/cmd/cloud-controller-manager/app/options"
"k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
v1core "k8s.io/kubernetes/pkg/client/clientset_generated/clientset/typed/core/v1"
"k8s.io/kubernetes/pkg/client/leaderelection"
"k8s.io/kubernetes/pkg/client/leaderelection/resourcelock"
"k8s.io/kubernetes/pkg/client/record"
"k8s.io/kubernetes/pkg/client/restclient"
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
"k8s.io/kubernetes/pkg/cloudprovider"
"k8s.io/kubernetes/pkg/controller"
nodecontroller "k8s.io/kubernetes/pkg/controller/cloud"
"k8s.io/kubernetes/pkg/controller/informers"
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 (
// Jitter 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, cloud cloudprovider.Interface) error {
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 := clientset.NewForConfigOrDie(restclient.AddUserAgent(kubeconfig, "leader-election"))
// Start the external controller manager server
go func() {
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)
}
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())
}()
eventBroadcaster := record.NewBroadcaster()
eventBroadcaster.StartLogging(glog.Infof)
eventBroadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: kubeClient.Core().Events("")})
recorder := eventBroadcaster.NewRecorder(v1.EventSource{Component: "cloud-controller-manager"})
run := func(stop <-chan struct{}) {
rootClientBuilder := controller.SimpleControllerClientBuilder{
ClientConfig: kubeconfig,
}
var clientBuilder controller.ControllerClientBuilder
if len(s.ServiceAccountKeyFile) > 0 && s.UseServiceAccountCredentials {
clientBuilder = controller.SAControllerClientBuilder{
ClientConfig: restclient.AnonymousClientConfig(kubeconfig),
CoreClient: kubeClient.Core(),
Namespace: "kube-system",
}
} else {
clientBuilder = rootClientBuilder
}
err := StartControllers(s, kubeconfig, rootClientBuilder, 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 := resourcelock.EndpointsLock{
EndpointsMeta: v1.ObjectMeta{
Namespace: "kube-system",
Name: "cloud-controller-manager",
},
Client: leaderElectionClient,
LockConfig: resourcelock.ResourceLockConfig{
Identity: id + "-external-cloud-controller",
EventRecorder: recorder,
},
}
// 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, rootClientBuilder, 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 rootClientBuilder.ClientOrDie(serviceAccountName)
}
sharedInformers := informers.NewSharedInformerFactory(client("shared-informers"), nil, resyncPeriod(s)())
_, clusterCIDR, err := net.ParseCIDR(s.ClusterCIDR)
if err != nil {
glog.Warningf("Unsuccessful parsing of cluster CIDR %v: %v", s.ClusterCIDR, err)
}
// Start the CloudNodeController
nodeController, err := nodecontroller.NewCloudNodeController(
sharedInformers.Nodes(),
client("cloud-node-controller"), cloud,
s.NodeMonitorPeriod.Duration)
if err != nil {
glog.Fatalf("Failed to initialize nodecontroller: %v", err)
}
nodeController.Run()
time.Sleep(wait.Jitter(s.ControllerStartInterval.Duration, ControllerStartJitter))
// Start the service controller
serviceController, err := servicecontroller.New(cloud, client("service-controller"), s.ClusterName)
if err != nil {
glog.Errorf("Failed to start service controller: %v", err)
} else {
serviceController.Run(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 {
routeController := routecontroller.New(routes, client("route-controller"), s.ClusterName, clusterCIDR)
routeController.Run(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.
var versionStrings []string
err = wait.PollImmediate(time.Second, 10*time.Second, func() (bool, error) {
if versionStrings, 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 {}
}

View file

@ -0,0 +1,35 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["options.go"],
tags = ["automanaged"],
deps = [
"//pkg/apis/componentconfig:go_default_library",
"//pkg/client/leaderelection:go_default_library",
"//pkg/master/ports:go_default_library",
"//pkg/util/config:go_default_library",
"//vendor:github.com/spf13/pflag",
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
)

View file

@ -0,0 +1,86 @@
/*
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"
"k8s.io/kubernetes/pkg/apis/componentconfig"
"k8s.io/kubernetes/pkg/client/leaderelection"
"k8s.io/kubernetes/pkg/master/ports"
"k8s.io/kubernetes/pkg/util/config"
"github.com/spf13/pflag"
)
// CloudControllerMangerServer is the main context object for the controller manager.
type CloudControllerManagerServer struct {
componentconfig.KubeControllerManagerConfiguration
Master string
Kubeconfig string
}
// NewCloudControllerManagerServer creates a new ExternalCMServer with a default config.
func NewCloudControllerManagerServer() *CloudControllerManagerServer {
s := CloudControllerManagerServer{
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: leaderelection.DefaultLeaderElectionConfiguration(),
ControllerStartInterval: metav1.Duration{Duration: 0 * time.Second},
},
}
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. Empty 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.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.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.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.StringVar(&s.ClusterCIDR, "cluster-cidr", s.ClusterCIDR, "CIDR Range for Pods 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.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.")
leaderelection.BindFlags(&s.LeaderElection, fs)
config.DefaultFeatureGate.AddFlag(fs)
}

View file

@ -0,0 +1,64 @@
/*
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/healthz"
"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
"k8s.io/kubernetes/pkg/cloudprovider"
_ "k8s.io/kubernetes/pkg/cloudprovider/providers"
"k8s.io/kubernetes/pkg/util/flag"
"k8s.io/kubernetes/pkg/util/logs"
_ "k8s.io/kubernetes/pkg/version/prometheus" // for version metric registration
"k8s.io/kubernetes/pkg/version/verflag"
"github.com/golang/glog"
"github.com/spf13/pflag"
)
func init() {
healthz.DefaultHealthz()
}
func main() {
s := options.NewCloudControllerManagerServer()
s.AddFlags(pflag.CommandLine)
flag.InitFlags()
logs.InitLogs()
defer logs.FlushLogs()
verflag.PrintAndExitIfRequested()
cloud, err := cloudprovider.InitCloudProvider(s.CloudProvider, s.CloudConfigFile)
if err != nil {
glog.Fatalf("Cloud provider could not be initialized: %v", err)
}
if err := app.Run(s, cloud); err != nil {
fmt.Fprintf(os.Stderr, "%v\n", err)
os.Exit(1)
}
}

40
vendor/k8s.io/kubernetes/cmd/gendocs/BUILD generated vendored Normal file
View file

@ -0,0 +1,40 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_binary",
"go_library",
)
go_binary(
name = "gendocs",
library = ":go_default_library",
tags = ["automanaged"],
)
go_library(
name = "go_default_library",
srcs = ["gen_kubectl_docs.go"],
tags = ["automanaged"],
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",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
)

View 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)
}

43
vendor/k8s.io/kubernetes/cmd/genkubedocs/BUILD generated vendored Normal file
View file

@ -0,0 +1,43 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_binary",
"go_library",
)
go_binary(
name = "genkubedocs",
library = ":go_default_library",
tags = ["automanaged"],
)
go_library(
name = "go_default_library",
srcs = ["gen_kube_docs.go"],
tags = ["automanaged"],
deps = [
"//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/kubelet/app:go_default_library",
"//plugin/cmd/kube-scheduler/app:go_default_library",
"//vendor:github.com/spf13/cobra/doc",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
)

View file

@ -0,0 +1,75 @@
/*
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"
"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"
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 "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)
default:
fmt.Fprintf(os.Stderr, "Module %s is not supported", module)
os.Exit(1)
}
}

47
vendor/k8s.io/kubernetes/cmd/genman/BUILD generated vendored Normal file
View file

@ -0,0 +1,47 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_binary",
"go_library",
)
go_binary(
name = "genman",
library = ":go_default_library",
tags = ["automanaged"],
)
go_library(
name = "go_default_library",
srcs = ["gen_kube_man.go"],
tags = ["automanaged"],
deps = [
"//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/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",
"//vendor:github.com/spf13/cobra",
"//vendor:github.com/spf13/pflag",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
)

215
vendor/k8s.io/kubernetes/cmd/genman/gen_kube_man.go generated vendored Normal file
View file

@ -0,0 +1,215 @@
/*
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"
"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"
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 "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)
}
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)
}
}

41
vendor/k8s.io/kubernetes/cmd/genslateyaml/BUILD generated vendored Normal file
View file

@ -0,0 +1,41 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_binary",
"go_library",
)
go_binary(
name = "genslateyaml",
library = ":go_default_library",
tags = ["automanaged"],
)
go_library(
name = "go_default_library",
srcs = ["gen_slate_yaml.go"],
tags = ["automanaged"],
deps = [
"//pkg/kubectl/cmd:go_default_library",
"//pkg/kubectl/cmd/util:go_default_library",
"//vendor:github.com/spf13/cobra",
"//vendor:github.com/spf13/pflag",
"//vendor:gopkg.in/yaml.v2",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
)

View file

@ -0,0 +1,197 @@
/*
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 (
"flag"
"fmt"
"io/ioutil"
"os"
"sort"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"gopkg.in/yaml.v2"
"k8s.io/kubernetes/pkg/kubectl/cmd"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
)
// gen_slate_yaml creates a yaml representation of the kubectl help commands. This is to be consumed
// by tools to generate documentation.
var outputFile = flag.String("output", "", "Destination for kubectl yaml representation.")
func main() {
flag.Parse()
if len(*outputFile) < 1 {
fmt.Printf("Must specify --output.\n")
os.Exit(1)
}
// Initialize a kubectl command that we can use to get the help documentation
kubectl := cmd.NewKubectlCommand(cmdutil.NewFactory(nil), os.Stdin, ioutil.Discard, ioutil.Discard)
// Create the structural representation
spec := NewKubectlSpec(kubectl)
// Write the spec to a file as yaml
WriteFile(spec)
}
func WriteFile(spec KubectlSpec) {
// Marshall the yaml
final, err := yaml.Marshal(&spec)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
// Create the file
outFile, err := os.Create(*outputFile)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
defer outFile.Close()
// Write the file
_, err = outFile.Write(final)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
}
func NewKubectlSpec(c *cobra.Command) KubectlSpec {
return KubectlSpec{
TopLevelCommandGroups: []TopLevelCommands{NewTopLevelCommands(c.Commands())},
}
}
func NewTopLevelCommands(cs []*cobra.Command) TopLevelCommands {
tlc := TopLevelCommands{}
for _, c := range cs {
tlc.Commands = append(tlc.Commands, NewTopLevelCommand(c))
}
sort.Sort(tlc)
return tlc
}
func NewTopLevelCommand(c *cobra.Command) TopLevelCommand {
result := TopLevelCommand{
MainCommand: NewCommand(c, ""),
}
for _, sub := range c.Commands() {
result.SubCommands = append(result.SubCommands, NewSubCommands(sub, "")...)
}
sort.Sort(result.SubCommands)
return result
}
// Parse the Options
func NewOptions(flags *pflag.FlagSet) Options {
result := Options{}
flags.VisitAll(func(flag *pflag.Flag) {
opt := &Option{
Name: flag.Name,
Shorthand: flag.Shorthand,
DefaultValue: flag.DefValue,
Usage: flag.Usage,
}
result = append(result, opt)
})
return result
}
// Parse the Commands
func NewSubCommands(c *cobra.Command, path string) Commands {
subCommands := Commands{NewCommand(c, path+c.Name())}
for _, subCommand := range c.Commands() {
subCommands = append(subCommands, NewSubCommands(subCommand, path+c.Name()+" ")...)
}
return subCommands
}
func NewCommand(c *cobra.Command, path string) *Command {
return &Command{
Name: c.Name(),
Path: path,
Description: c.Long,
Synopsis: c.Short,
Example: c.Example,
Options: NewOptions(c.NonInheritedFlags()),
InheritedOptions: NewOptions(c.InheritedFlags()),
Usage: c.Use,
}
}
//////////////////////////
// Types
//////////////////////////
type KubectlSpec struct {
TopLevelCommandGroups []TopLevelCommands `yaml:",omitempty"`
}
type TopLevelCommands struct {
Commands []TopLevelCommand `yaml:",omitempty"`
}
type TopLevelCommand struct {
MainCommand *Command `yaml:",omitempty"`
SubCommands Commands `yaml:",omitempty"`
}
type Options []*Option
type Option struct {
Name string `yaml:",omitempty"`
Shorthand string `yaml:",omitempty"`
DefaultValue string `yaml:"default_value,omitempty"`
Usage string `yaml:",omitempty"`
}
type Commands []*Command
type Command struct {
Name string `yaml:",omitempty"`
Path string `yaml:",omitempty"`
Synopsis string `yaml:",omitempty"`
Description string `yaml:",omitempty"`
Options Options `yaml:",omitempty"`
InheritedOptions Options `yaml:"inherited_options,omitempty"`
Example string `yaml:",omitempty"`
SeeAlso []string `yaml:"see_also,omitempty"`
Usage string `yaml:",omitempty"`
}
func (a Options) Len() int { return len(a) }
func (a Options) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a Options) Less(i, j int) bool {
return a[i].Name < a[j].Name
}
func (a TopLevelCommands) Len() int { return len(a.Commands) }
func (a TopLevelCommands) Swap(i, j int) { a.Commands[i], a.Commands[j] = a.Commands[j], a.Commands[i] }
func (a TopLevelCommands) Less(i, j int) bool {
return a.Commands[i].MainCommand.Path < a.Commands[j].MainCommand.Path
}
func (a Commands) Len() int { return len(a) }
func (a Commands) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a Commands) Less(i, j int) bool {
return a[i].Path < a[j].Path
}

39
vendor/k8s.io/kubernetes/cmd/genswaggertypedocs/BUILD generated vendored Normal file
View file

@ -0,0 +1,39 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_binary",
"go_library",
)
go_binary(
name = "genswaggertypedocs",
library = ":go_default_library",
tags = ["automanaged"],
)
go_library(
name = "go_default_library",
srcs = ["swagger_type_docs.go"],
tags = ["automanaged"],
deps = [
"//vendor:github.com/golang/glog",
"//vendor:github.com/spf13/pflag",
"//vendor:k8s.io/apimachinery/pkg/runtime",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
)

View 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)
}
}
}

35
vendor/k8s.io/kubernetes/cmd/genutils/BUILD generated vendored Normal file
View file

@ -0,0 +1,35 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
"go_test",
)
go_library(
name = "go_default_library",
srcs = ["genutils.go"],
tags = ["automanaged"],
)
go_test(
name = "go_default_test",
srcs = ["genutils_test.go"],
library = ":go_default_library",
tags = ["automanaged"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
)

41
vendor/k8s.io/kubernetes/cmd/genutils/genutils.go generated vendored Normal file
View 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 genutils
import (
"fmt"
"os"
"path/filepath"
)
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\n", outDir)
}
outDir = outDir + "/"
return outDir, nil
}

42
vendor/k8s.io/kubernetes/cmd/genutils/genutils_test.go generated vendored Normal file
View 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(err)
}
}
func TestNotDir(t *testing.T) {
_, err := OutDir("./genutils_test.go")
if err == nil {
t.Fatal(err)
}
}

42
vendor/k8s.io/kubernetes/cmd/genyaml/BUILD generated vendored Normal file
View file

@ -0,0 +1,42 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_binary",
"go_library",
)
go_binary(
name = "genyaml",
library = ":go_default_library",
tags = ["automanaged"],
)
go_library(
name = "go_default_library",
srcs = ["gen_kubectl_yaml.go"],
tags = ["automanaged"],
deps = [
"//cmd/genutils:go_default_library",
"//pkg/kubectl/cmd:go_default_library",
"//pkg/kubectl/cmd/util:go_default_library",
"//vendor:github.com/spf13/cobra",
"//vendor:github.com/spf13/pflag",
"//vendor:gopkg.in/yaml.v2",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
)

View 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)
}
}

84
vendor/k8s.io/kubernetes/cmd/hyperkube/BUILD generated vendored Normal file
View file

@ -0,0 +1,84 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_binary",
"go_library",
"go_test",
)
go_binary(
name = "hyperkube",
library = ":go_default_library",
tags = ["automanaged"],
)
go_test(
name = "go_default_test",
srcs = ["hyperkube_test.go"],
library = ":go_default_library",
tags = ["automanaged"],
deps = [
"//vendor:github.com/spf13/cobra",
"//vendor:github.com/stretchr/testify/assert",
],
)
go_library(
name = "go_default_library",
srcs = [
"federation-apiserver.go",
"federation-controller-manager.go",
"hyperkube.go",
"kube-apiserver.go",
"kube-controller-manager.go",
"kube-proxy.go",
"kube-scheduler.go",
"kubectl.go",
"kubelet.go",
"main.go",
"server.go",
],
tags = ["automanaged"],
deps = [
"//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/kube-proxy/app/options:go_default_library",
"//cmd/kubelet/app:go_default_library",
"//cmd/kubelet/app/options:go_default_library",
"//federation/cmd/federation-apiserver/app:go_default_library",
"//federation/cmd/federation-apiserver/app/options:go_default_library",
"//federation/cmd/federation-controller-manager/app:go_default_library",
"//federation/cmd/federation-controller-manager/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:go_default_library",
"//pkg/util/flag:go_default_library",
"//pkg/util/logs:go_default_library",
"//pkg/version/prometheus:go_default_library",
"//pkg/version/verflag:go_default_library",
"//plugin/cmd/kube-scheduler/app:go_default_library",
"//plugin/cmd/kube-scheduler/app/options:go_default_library",
"//vendor:github.com/spf13/pflag",
"//vendor:k8s.io/apiserver/pkg/healthz",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
)

View file

@ -0,0 +1,38 @@
/*
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 (
"k8s.io/kubernetes/federation/cmd/federation-apiserver/app"
"k8s.io/kubernetes/federation/cmd/federation-apiserver/app/options"
)
// NewFederationAPIServer creates a new hyperkube Server object that includes the
// description and flags.
func NewFederationAPIServer() *Server {
s := options.NewServerRunOptions()
hks := Server{
SimpleUsage: "federation-apiserver",
Long: "The API entrypoint for the federation control plane",
Run: func(_ *Server, args []string) error {
return app.Run(s)
},
}
s.AddFlags(hks.Flags())
return &hks
}

View file

@ -0,0 +1,38 @@
/*
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 (
"k8s.io/kubernetes/federation/cmd/federation-controller-manager/app"
"k8s.io/kubernetes/federation/cmd/federation-controller-manager/app/options"
)
// NewFederationCMServer creates a new hyperkube Server object that includes the
// description and flags.
func NewFederationCMServer() *Server {
s := options.NewCMServer()
hks := Server{
SimpleUsage: "federation-controller-manager",
Long: "Controller manager for federation control plane. Manages federation service endpoints and controllers",
Run: func(_ *Server, args []string) error {
return app.Run(s)
},
}
s.AddFlags(hks.Flags())
return &hks
}

236
vendor/k8s.io/kubernetes/cmd/hyperkube/hyperkube.go generated vendored Normal file
View file

@ -0,0 +1,236 @@
/*
Copyright 2014 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package main
import (
"errors"
"flag"
"fmt"
"io"
"io/ioutil"
"os"
"path"
"k8s.io/kubernetes/pkg/util"
utilflag "k8s.io/kubernetes/pkg/util/flag"
"k8s.io/kubernetes/pkg/util/logs"
"k8s.io/kubernetes/pkg/version/verflag"
"github.com/spf13/pflag"
)
// 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
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
}
// FindServer will find a specific server named name.
func (hk *HyperKube) FindServer(name string) (*Server, error) {
for _, s := range hk.servers {
if s.Name() == 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) 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]
baseCommand := path.Base(command)
serverName := baseCommand
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]
baseCommand = baseCommand + " " + serverName
args = args[1:]
} else {
err = errors.New("no server specified")
hk.Printf("Error: %v\n\n", err)
hk.Usage()
return err
}
}
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()
err = s.Run(s, s.Flags().Args())
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) {
err := hk.Run(args)
if err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err.Error())
os.Exit(1)
}
os.Exit(0)
}
// 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.
`
util.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
}

View file

@ -0,0 +1,223 @@
/*
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"
"github.com/spf13/cobra"
"github.com/stretchr/testify/assert"
)
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) 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) error {
s.hk.Printf("%s Run\n", s.Name())
return errors.New("server returning error")
},
}
}
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) 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) *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.AddServer(testServerError("test-error"))
hk.AddServer(testCobraCommand("test-cobra-command"))
a := strings.Split(args, " ")
t.Logf("Running full with args: %q", a)
err := hk.Run(a)
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")
assert.Contains(t, x.output, "test1 Run")
assert.NoError(t, x.err)
}
func TestLinkRun(t *testing.T) {
x := runFull(t, "test1")
assert.Contains(t, x.output, "test1 Run")
assert.NoError(t, x.err)
}
func TestTopNoArgs(t *testing.T) {
x := runFull(t, "hyperkube")
assert.EqualError(t, x.err, "no server specified")
}
func TestBadServer(t *testing.T) {
x := runFull(t, "hyperkube bad-server")
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")
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")
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")
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")
assert.NoError(t, x.err)
assert.Contains(t, x.output, "A simple server named test1")
assert.Contains(t, x.output, "-h, --help help for hyperkube")
assert.NotContains(t, x.output, "test1 Run")
}
func TestServerFlagsBad(t *testing.T) {
x := runFull(t, "hyperkube test1 --bad-flag")
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 help for hyperkube")
assert.NotContains(t, x.output, "test1 Run")
}
func TestServerError(t *testing.T) {
x := runFull(t, "hyperkube test-error")
assert.Contains(t, x.output, "test-error Run")
assert.EqualError(t, x.err, "server returning error")
}
func TestCobraCommandHelp(t *testing.T) {
x := runFull(t, "hyperkube test-cobra-command --help")
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")
assert.Contains(t, x.output, fmt.Sprintf("msg: %s", defaultCobraMessage))
}
func TestCobraCommandMessage(t *testing.T) {
x := runFull(t, "hyperkube test-cobra-command --msg foobar")
assert.Contains(t, x.output, "msg: foobar")
}
func TestCobraSubCommandHelp(t *testing.T) {
x := runFull(t, "hyperkube test-cobra-command subcommand --help")
assert.NoError(t, x.err)
assert.Contains(t, x.output, cobraSubMessageDesc)
}
func TestCobraSubCommandDefaultMessage(t *testing.T) {
x := runFull(t, "hyperkube test-cobra-command subcommand")
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")
assert.Contains(t, x.output, "submsg: foobar")
}

View file

@ -0,0 +1,38 @@
/*
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{
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) error {
return app.Run(s)
},
}
s.AddFlags(hks.Flags())
return &hks
}

View file

@ -0,0 +1,38 @@
/*
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{
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) 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
View 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 (
"k8s.io/apiserver/pkg/healthz"
"k8s.io/kubernetes/cmd/kube-proxy/app"
"k8s.io/kubernetes/cmd/kube-proxy/app/options"
)
func init() {
healthz.DefaultHealthz()
}
// NewKubeProxy creates a new hyperkube Server object that includes the
// description and flags.
func NewKubeProxy() *Server {
config := options.NewProxyConfig()
hks := Server{
SimpleUsage: "proxy",
Long: `The Kubernetes proxy server is responsible for taking traffic directed at
services and forwarding it to the appropriate pods. It generally runs on
nodes next to the Kubelet and proxies traffic from local pods to remote pods.
It is also used when handling incoming external traffic.`,
}
config.AddFlags(hks.Flags())
hks.Run = func(_ *Server, _ []string) error {
s, err := app.NewProxyServerDefault(config)
if err != nil {
return err
}
return s.Run()
}
return &hks
}

View file

@ -0,0 +1,38 @@
/*
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/plugin/cmd/kube-scheduler/app"
"k8s.io/kubernetes/plugin/cmd/kube-scheduler/app/options"
)
// NewScheduler creates a new hyperkube Server object that includes the
// description and flags.
func NewScheduler() *Server {
s := options.NewSchedulerServer()
hks := Server{
SimpleUsage: "scheduler",
Long: "Implements a Kubernetes scheduler. This will assign pods to kubelets based on capacity and constraints.",
Run: func(_ *Server, _ []string) error {
return app.Run(s)
},
}
s.AddFlags(hks.Flags())
return &hks
}

42
vendor/k8s.io/kubernetes/cmd/hyperkube/kubectl.go generated vendored Normal file
View 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) error {
cmd.SetArgs(args)
return cmd.Execute()
},
flags: localFlags,
}
}

42
vendor/k8s.io/kubernetes/cmd/hyperkube/kubelet.go generated vendored Normal file
View 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 (
"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 {
s := options.NewKubeletServer()
hks := Server{
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) error {
return app.Run(s, nil)
},
}
s.AddFlags(hks.Flags())
return &hks
}

47
vendor/k8s.io/kubernetes/cmd/hyperkube/main.go generated vendored Normal file
View file

@ -0,0 +1,47 @@
/*
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 (
"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())
hk.AddServer(NewKubelet())
hk.AddServer(NewKubeProxy())
//Federation servers
hk.AddServer(NewFederationAPIServer())
hk.AddServer(NewFederationCMServer())
hk.RunToExit(os.Args)
}

75
vendor/k8s.io/kubernetes/cmd/hyperkube/server.go generated vendored Normal file
View file

@ -0,0 +1,75 @@
/*
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/kubernetes/pkg/util"
"k8s.io/kubernetes/pkg/util/flag"
"github.com/spf13/pflag"
)
type serverRunFunc func(s *Server, args []string) 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.
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 util.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
}

58
vendor/k8s.io/kubernetes/cmd/kube-aggregator/BUILD generated vendored Normal file
View file

@ -0,0 +1,58 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_binary",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["main.go"],
tags = ["automanaged"],
deps = [
"//cmd/kube-aggregator/pkg/apis/apiregistration/install:go_default_library",
"//cmd/kube-aggregator/pkg/apis/apiregistration/validation:go_default_library",
"//cmd/kube-aggregator/pkg/client/clientset_generated/internalclientset:go_default_library",
"//cmd/kube-aggregator/pkg/client/informers/apiregistration/internalversion:go_default_library",
"//cmd/kube-aggregator/pkg/client/informers/apiregistration/v1alpha1:go_default_library",
"//cmd/kube-aggregator/pkg/client/listers/apiregistration/internalversion:go_default_library",
"//cmd/kube-aggregator/pkg/client/listers/apiregistration/v1alpha1:go_default_library",
"//cmd/kube-aggregator/pkg/cmd/server:go_default_library",
"//pkg/kubectl/cmd/util:go_default_library",
"//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-aggregator/pkg/apis/apiregistration:all-srcs",
"//cmd/kube-aggregator/pkg/apiserver:all-srcs",
"//cmd/kube-aggregator/pkg/client/clientset_generated/clientset:all-srcs",
"//cmd/kube-aggregator/pkg/client/clientset_generated/internalclientset:all-srcs",
"//cmd/kube-aggregator/pkg/client/informers:all-srcs",
"//cmd/kube-aggregator/pkg/client/listers/apiregistration/internalversion:all-srcs",
"//cmd/kube-aggregator/pkg/client/listers/apiregistration/v1alpha1:all-srcs",
"//cmd/kube-aggregator/pkg/cmd/server:all-srcs",
"//cmd/kube-aggregator/pkg/legacy:all-srcs",
"//cmd/kube-aggregator/pkg/registry/apiservice:all-srcs",
],
tags = ["automanaged"],
)
go_binary(
name = "kube-aggregator",
library = ":go_default_library",
tags = ["automanaged"],
)

View file

@ -0,0 +1,11 @@
apiVersion: apiregistration.k8s.io/v1alpha1
kind: APIService
metadata:
name: v1.
spec:
version: v1
service:
namespace: default
name: kubernetes
insecureSkipTLSVerify: true
priority: 100

View file

@ -0,0 +1,12 @@
apiVersion: apiregistration.k8s.io/v1alpha1
kind: APIService
metadata:
name: v1.autoscaling
spec:
group: autoscaling
version: v1
service:
namespace: default
name: kubernetes
insecureSkipTLSVerify: true
priority: 100

View file

@ -0,0 +1,12 @@
apiVersion: apiregistration.k8s.io/v1alpha1
kind: APIService
metadata:
name: v1.batch
spec:
group: batch
version: v1
service:
namespace: default
name: kubernetes
insecureSkipTLSVerify: true
priority: 100

View file

@ -0,0 +1,12 @@
apiVersion: apiregistration.k8s.io/v1alpha1
kind: APIService
metadata:
name: v1alpha1.certificates.k8s.io
spec:
group: certificates.k8s.io
version: v1alpha1
service:
namespace: default
name: kubernetes
insecureSkipTLSVerify: true
priority: 100

View file

@ -0,0 +1,12 @@
apiVersion: apiregistration.k8s.io/v1alpha1
kind: APIService
metadata:
name: v1alpha1.rbac.authorization.k8s.io
spec:
group: rbac.authorization.k8s.io
version: v1alpha1
service:
namespace: default
name: kubernetes
insecureSkipTLSVerify: true
priority: 100

View file

@ -0,0 +1,12 @@
apiVersion: apiregistration.k8s.io/v1alpha1
kind: APIService
metadata:
name: v1beta1.apps
spec:
group: apps
version: v1beta1
service:
namespace: default
name: kubernetes
insecureSkipTLSVerify: true
priority: 100

View file

@ -0,0 +1,12 @@
apiVersion: apiregistration.k8s.io/v1alpha1
kind: APIService
metadata:
name: v1beta1.authentication.k8s.io
spec:
group: authentication.k8s.io
version: v1beta1
service:
namespace: default
name: kubernetes
insecureSkipTLSVerify: true
priority: 100

View file

@ -0,0 +1,12 @@
apiVersion: apiregistration.k8s.io/v1alpha1
kind: APIService
metadata:
name: v1beta1.authorization.k8s.io
spec:
group: authorization.k8s.io
version: v1beta1
service:
namespace: default
name: kubernetes
insecureSkipTLSVerify: true
priority: 100

View file

@ -0,0 +1,12 @@
apiVersion: apiregistration.k8s.io/v1alpha1
kind: APIService
metadata:
name: v1beta1.extensions
spec:
group: extensions
version: v1beta1
service:
namespace: default
name: kubernetes
insecureSkipTLSVerify: true
priority: 150

View file

@ -0,0 +1,12 @@
apiVersion: apiregistration.k8s.io/v1alpha1
kind: APIService
metadata:
name: v1beta1.policy
spec:
group: policy
version: v1beta1
service:
namespace: default
name: kubernetes
insecureSkipTLSVerify: true
priority: 100

View file

@ -0,0 +1,12 @@
apiVersion: apiregistration.k8s.io/v1alpha1
kind: APIService
metadata:
name: v1beta1.storage.k8s.io
spec:
group: storage.k8s.io
version: v1beta1
service:
namespace: default
name: kubernetes
insecureSkipTLSVerify: true
priority: 100

View file

@ -0,0 +1,50 @@
kind: ReplicationController
apiVersion: v1
metadata:
name: etcd
labels:
etcd: "true"
spec:
replicas: 1
selector:
etcd: "true"
template:
metadata:
labels:
etcd: "true"
spec:
containers:
- name: etcd
image: quay.io/coreos/etcd:v3.0.15
command:
- "etcd"
- "--listen-client-urls=https://0.0.0.0:4001"
- "--advertise-client-urls=https://etcd.kube-public.svc:4001"
- "--trusted-ca-file=/var/run/serving-ca/ca.crt"
- "--cert-file=/var/run/serving-cert/tls.crt"
- "--key-file=/var/run/serving-cert/tls.key"
- "--client-cert-auth=true"
- "--listen-peer-urls=https://0.0.0.0:7001"
- "--initial-advertise-peer-urls=https://etcd.kube-public.svc:7001"
- "--peer-trusted-ca-file=/var/run/serving-ca/ca.crt"
- "--peer-cert-file=/var/run/serving-cert/tls.crt"
- "--peer-key-file=/var/run/serving-cert/tls.key"
- "--peer-client-cert-auth=true"
- "--initial-cluster=default=https://etcd.kube-public.svc:7001"
ports:
- containerPort: 4001
volumeMounts:
- mountPath: /var/run/serving-cert
name: volume-serving-cert
- mountPath: /var/run/serving-ca
name: volume-etcd-ca
volumes:
- secret:
defaultMode: 420
secretName: serving-etcd
name: volume-serving-cert
- configMap:
defaultMode: 420
name: etcd-ca
name: volume-etcd-ca

View file

@ -0,0 +1,11 @@
apiVersion: v1
kind: Service
metadata:
name: etcd
spec:
ports:
- port: 4001
protocol: TCP
targetPort: 4001
selector:
etcd: "true"

View file

@ -0,0 +1,99 @@
kind: ReplicationController
apiVersion: v1
metadata:
name: kube-aggregator
labels:
kube-aggregator: "true"
spec:
replicas: 1
selector:
kube-aggregator: "true"
template:
metadata:
labels:
kube-aggregator: "true"
spec:
containers:
- name: kube-aggregator
image: kube-aggregator:latest
imagePullPolicy: Never
livenessProbe:
failureThreshold: 3
httpGet:
path: /version
port: 443
scheme: HTTPS
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
readinessProbe:
failureThreshold: 3
httpGet:
path: /version
port: 443
scheme: HTTPS
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
args:
- "--proxy-client-cert-file=/var/run/auth-proxy-client/tls.crt"
- "--proxy-client-key-file=/var/run/auth-proxy-client/tls.key"
- "--tls-cert-file=/var/run/serving-cert/tls.crt"
- "--tls-private-key-file=/var/run/serving-cert/tls.key"
- "--tls-ca-file=/var/run/serving-ca/ca.crt"
- "--client-ca-file=/var/run/client-ca/ca.crt"
- "--requestheader-username-headers=X-Remote-User"
- "--requestheader-group-headers=X-Remote-Group"
- "--requestheader-extra-headers-prefix=X-Remote-Extra-"
- "--requestheader-client-ca-file=/var/run/request-header-ca/ca.crt"
- "--etcd-servers=https://etcd.kube-public.svc:4001"
- "--etcd-certfile=/var/run/etcd-client-cert/tls.crt"
- "--etcd-keyfile=/var/run/etcd-client-cert/tls.key"
- "--etcd-cafile=/var/run/etcd-ca/ca.crt"
ports:
- containerPort: 443
volumeMounts:
- mountPath: /var/run/request-header-ca
name: volume-request-header-ca
- mountPath: /var/run/client-ca
name: volume-client-ca
- mountPath: /var/run/auth-proxy-client
name: volume-auth-proxy-client
- mountPath: /var/run/etcd-client-cert
name: volume-etcd-client-cert
- mountPath: /var/run/serving-ca
name: volume-serving-ca
- mountPath: /var/run/serving-cert
name: volume-serving-cert
- mountPath: /var/run/etcd-ca
name: volume-etcd-ca
serviceAccountName: kube-aggregator
volumes:
- configMap:
defaultMode: 420
name: request-header-ca
name: volume-request-header-ca
- configMap:
defaultMode: 420
name: client-ca
name: volume-client-ca
- name: volume-auth-proxy-client
secret:
defaultMode: 420
secretName: auth-proxy-client
- name: volume-etcd-client-cert
secret:
defaultMode: 420
secretName: discovery-etcd
- name: volume-serving-cert
secret:
defaultMode: 420
secretName: serving-discovery
- configMap:
defaultMode: 420
name: discovery-ca
name: volume-serving-ca
- configMap:
defaultMode: 420
name: etcd-ca
name: volume-etcd-ca

View file

@ -0,0 +1,4 @@
kind: ServiceAccount
apiVersion: v1
metadata:
name: kube-aggregator

View file

@ -0,0 +1,15 @@
apiVersion: v1
kind: Service
metadata:
labels:
kube-aggregator: "true"
name: kube-aggregator
spec:
ports:
- port: 443
protocol: TCP
nodePort: 31090
targetPort: 443
selector:
kube-aggregator: "true"
type: NodePort

View file

@ -0,0 +1,17 @@
# 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.
FROM fedora
ADD kube-aggregator /
ENTRYPOINT ["/kube-aggregator"]

View file

@ -0,0 +1,16 @@
{
"servers": [
{
"serverAddress": "http://127.0.0.1:8083",
"groupVersionDiscoveryPaths": [
{
"path": "/apis"
},
{
"path": "/api",
"isLegacy": true
}
]
}
]
}

View file

@ -0,0 +1,28 @@
#!/bin/bash
# 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.
KUBE_ROOT=$(dirname "${BASH_SOURCE}")/../../..
source "${KUBE_ROOT}/hack/lib/util.sh"
# Register function to be called on EXIT to remove generated binary.
function cleanup {
rm "${KUBE_ROOT}/cmd/kube-aggregator/artifacts/simple-image/kube-aggregator"
}
trap cleanup EXIT
cp -v ${KUBE_ROOT}/_output/local/bin/linux/amd64/kube-aggregator "${KUBE_ROOT}/cmd/kube-aggregator/artifacts/simple-image/kube-aggregator"
docker build -t kube-aggregator:latest ${KUBE_ROOT}/cmd/kube-aggregator/artifacts/simple-image

View file

@ -0,0 +1,69 @@
#!/bin/bash
# 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.
set -o errexit
set -o nounset
set -o pipefail
KUBE_ROOT=$(dirname "${BASH_SOURCE}")/../../..
APIFEDERATOR_ROOT=$(dirname "${BASH_SOURCE}")/..
source "${KUBE_ROOT}/hack/lib/init.sh"
# Register function to be called on EXIT to remove generated binary.
function cleanup {
rm -f "${CLIENTGEN:-}"
rm -f "${listergen:-}"
rm -f "${informergen:-}"
}
trap cleanup EXIT
echo "Building client-gen"
CLIENTGEN="${PWD}/client-gen-binary"
go build -o "${CLIENTGEN}" ./cmd/libs/go2idl/client-gen
PREFIX=k8s.io/kubernetes/cmd/kube-aggregator/pkg/apis
INPUT_BASE="--input-base ${PREFIX}"
INPUT_APIS=(
apiregistration/
apiregistration/v1alpha1
)
INPUT="--input ${INPUT_APIS[@]}"
CLIENTSET_PATH="--clientset-path k8s.io/kubernetes/cmd/kube-aggregator/pkg/client/clientset_generated"
${CLIENTGEN} ${INPUT_BASE} ${INPUT} ${CLIENTSET_PATH}
${CLIENTGEN} --clientset-name="clientset" ${INPUT_BASE} --input apiregistration/v1alpha1 ${CLIENTSET_PATH}
echo "Building lister-gen"
listergen="${PWD}/lister-gen"
go build -o "${listergen}" ./cmd/libs/go2idl/lister-gen
LISTER_INPUT="--input-dirs k8s.io/kubernetes/cmd/kube-aggregator/pkg/apis/apiregistration --input-dirs k8s.io/kubernetes/cmd/kube-aggregator/pkg/apis/apiregistration/v1alpha1"
LISTER_PATH="--output-package k8s.io/kubernetes/cmd/kube-aggregator/pkg/client/listers"
${listergen} ${LISTER_INPUT} ${LISTER_PATH}
echo "Building informer-gen"
informergen="${PWD}/informer-gen"
go build -o "${informergen}" ./cmd/libs/go2idl/informer-gen
${informergen} \
--input-dirs k8s.io/kubernetes/cmd/kube-aggregator/pkg/apis/apiregistration --input-dirs k8s.io/kubernetes/cmd/kube-aggregator/pkg/apis/apiregistration/v1alpha1 \
--versioned-clientset-package k8s.io/kubernetes/cmd/kube-aggregator/pkg/client/clientset_generated/clientset \
--internal-clientset-package k8s.io/kubernetes/cmd/kube-aggregator/pkg/client/clientset_generated/internalclientset \
--listers-package k8s.io/kubernetes/cmd/kube-aggregator/pkg/client/listers \
--output-package k8s.io/kubernetes/cmd/kube-aggregator/pkg/client/informers
"$@"

View file

@ -0,0 +1,50 @@
#!/bin/bash
# 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.
set -o errexit
set -o nounset
set -o pipefail
KUBE_ROOT=$(dirname "${BASH_SOURCE}")/../../..
APIFEDERATOR_ROOT=$(dirname "${BASH_SOURCE}")/..
source "${KUBE_ROOT}/hack/lib/init.sh"
DIFFROOT="${APIFEDERATOR_ROOT}/pkg"
TMP_DIFFROOT="${APIFEDERATOR_ROOT}/_tmp/pkg"
_tmp="${APIFEDERATOR_ROOT}/_tmp"
cleanup() {
rm -rf "${_tmp}"
}
trap "cleanup" EXIT SIGINT
cleanup
mkdir -p "${_tmp}"
cp -a -T "${DIFFROOT}" "${TMP_DIFFROOT}"
"${APIFEDERATOR_ROOT}/hack/update-codegen.sh"
echo "diffing ${DIFFROOT} against freshly generated codegen"
ret=0
diff -Naupr "${DIFFROOT}" "${TMP_DIFFROOT}" || ret=$?
cp -a -T "${TMP_DIFFROOT}" "${DIFFROOT}"
if [[ $ret -eq 0 ]]
then
echo "${DIFFROOT} up to date."
else
echo "${DIFFROOT} is out of date. Please run hack/update-codegen.sh"
exit 1
fi

51
vendor/k8s.io/kubernetes/cmd/kube-aggregator/main.go generated vendored Normal file
View 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 main
import (
"flag"
"os"
"runtime"
"k8s.io/kubernetes/cmd/kube-aggregator/pkg/cmd/server"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/util/logs"
// force compilation of packages we'll later rely upon
_ "k8s.io/kubernetes/cmd/kube-aggregator/pkg/apis/apiregistration/install"
_ "k8s.io/kubernetes/cmd/kube-aggregator/pkg/apis/apiregistration/validation"
_ "k8s.io/kubernetes/cmd/kube-aggregator/pkg/client/clientset_generated/internalclientset"
_ "k8s.io/kubernetes/cmd/kube-aggregator/pkg/client/informers/apiregistration/internalversion"
_ "k8s.io/kubernetes/cmd/kube-aggregator/pkg/client/informers/apiregistration/v1alpha1"
_ "k8s.io/kubernetes/cmd/kube-aggregator/pkg/client/listers/apiregistration/internalversion"
_ "k8s.io/kubernetes/cmd/kube-aggregator/pkg/client/listers/apiregistration/v1alpha1"
)
func main() {
logs.InitLogs()
defer logs.FlushLogs()
if len(os.Getenv("GOMAXPROCS")) == 0 {
runtime.GOMAXPROCS(runtime.NumCPU())
}
cmd := server.NewCommandStartDiscoveryServer(os.Stdout, os.Stderr)
cmd.Flags().AddGoFlagSet(flag.CommandLine)
if err := cmd.Execute(); err != nil {
cmdutil.CheckErr(err)
}
}

View file

@ -0,0 +1,45 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"doc.go",
"helpers.go",
"register.go",
"types.go",
"zz_generated.deepcopy.go",
],
tags = ["automanaged"],
deps = [
"//pkg/api:go_default_library",
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
"//vendor:k8s.io/apimachinery/pkg/conversion",
"//vendor:k8s.io/apimachinery/pkg/runtime",
"//vendor:k8s.io/apimachinery/pkg/runtime/schema",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//cmd/kube-aggregator/pkg/apis/apiregistration/install:all-srcs",
"//cmd/kube-aggregator/pkg/apis/apiregistration/v1alpha1:all-srcs",
"//cmd/kube-aggregator/pkg/apis/apiregistration/validation:all-srcs",
],
tags = ["automanaged"],
)

View file

@ -0,0 +1,21 @@
/*
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.
*/
// +k8s:deepcopy-gen=package,register
// Package api is the internal version of the API.
// +groupName=apiregistration.k8s.io
package apiregistration

View file

@ -0,0 +1,59 @@
/*
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 apiregistration
import (
"sort"
"strings"
)
func SortedByGroup(servers []*APIService) [][]*APIService {
serversByPriority := ByPriority(servers)
sort.Sort(serversByPriority)
ret := [][]*APIService{}
for _, curr := range serversByPriority {
// check to see if we already have an entry for this group
existingIndex := -1
for j, groupInReturn := range ret {
if groupInReturn[0].Spec.Group == curr.Spec.Group {
existingIndex = j
break
}
}
if existingIndex >= 0 {
ret[existingIndex] = append(ret[existingIndex], curr)
continue
}
ret = append(ret, []*APIService{curr})
}
return ret
}
type ByPriority []*APIService
func (s ByPriority) Len() int { return len(s) }
func (s ByPriority) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (s ByPriority) Less(i, j int) bool {
if s[i].Spec.Priority == s[j].Spec.Priority {
return strings.Compare(s[i].Name, s[j].Name) < 0
}
return s[i].Spec.Priority < s[j].Spec.Priority
}

View file

@ -0,0 +1,33 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["install.go"],
tags = ["automanaged"],
deps = [
"//cmd/kube-aggregator/pkg/apis/apiregistration:go_default_library",
"//cmd/kube-aggregator/pkg/apis/apiregistration/v1alpha1:go_default_library",
"//pkg/apimachinery/announced:go_default_library",
"//vendor:k8s.io/apimachinery/pkg/util/sets",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
)

View file

@ -0,0 +1,41 @@
/*
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 install
import (
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/kubernetes/cmd/kube-aggregator/pkg/apis/apiregistration"
"k8s.io/kubernetes/cmd/kube-aggregator/pkg/apis/apiregistration/v1alpha1"
"k8s.io/kubernetes/pkg/apimachinery/announced"
)
func init() {
if err := announced.NewGroupMetaFactory(
&announced.GroupMetaFactoryArgs{
GroupName: apiregistration.GroupName,
RootScopedKinds: sets.NewString("APIService"),
VersionPreferenceOrder: []string{v1alpha1.SchemeGroupVersion.Version},
ImportPrefix: "k8s.io/kubernetes/cmd/kube-aggregator/pkg/apis/apiregistration",
AddInternalObjectsToScheme: apiregistration.AddToScheme,
},
announced.VersionToSchemeFunc{
v1alpha1.SchemeGroupVersion.Version: v1alpha1.AddToScheme,
},
).Announce().RegisterAndEnable(); err != nil {
panic(err)
}
}

View file

@ -0,0 +1,58 @@
/*
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 apiregistration
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
kapi "k8s.io/kubernetes/pkg/api"
)
const GroupName = "apiregistration.k8s.io"
// SchemeGroupVersion is group version used to register these objects
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: runtime.APIVersionInternal}
// Kind takes an unqualified kind and returns back a Group qualified GroupKind
func Kind(kind string) schema.GroupKind {
return SchemeGroupVersion.WithKind(kind).GroupKind()
}
// Resource takes an unqualified resource and returns back a Group qualified GroupResource
func Resource(resource string) schema.GroupResource {
return SchemeGroupVersion.WithResource(resource).GroupResource()
}
var (
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
AddToScheme = SchemeBuilder.AddToScheme
)
// Adds the list of known types to api.Scheme.
func addKnownTypes(scheme *runtime.Scheme) error {
scheme.AddKnownTypes(SchemeGroupVersion,
&APIService{},
&APIServiceList{},
&kapi.ListOptions{},
&kapi.DeleteOptions{},
&metav1.GetOptions{},
)
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
return nil
}

View file

@ -0,0 +1,84 @@
/*
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 apiregistration
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
kapi "k8s.io/kubernetes/pkg/api"
)
// APIServiceList is a list of APIService objects.
type APIServiceList struct {
metav1.TypeMeta
metav1.ListMeta
Items []APIService
}
// ServiceReference holds a reference to Service.legacy.k8s.io
type ServiceReference struct {
// Namespace is the namespace of the service
Namespace string
// Name is the name of the service
Name string
}
// APIServiceSpec contains information for locating and communicating with a server.
// Only https is supported, though you are able to disable certificate verification.
type APIServiceSpec struct {
// Service is a reference to the service for this API server. It must communicate
// on port 443
Service ServiceReference
// Group is the API group name this server hosts
Group string
// Version is the API version this server hosts. For example, "v1"
Version string
// InsecureSkipTLSVerify disables TLS certificate verification when communicating with this server.
// This is strongly discouraged. You should use the CABundle instead.
InsecureSkipTLSVerify bool
// CABundle is a PEM encoded CA bundle which will be used to validate an API server's serving certificate.
CABundle []byte
// Priority controls the ordering of this API group in the overall discovery document that gets served.
// Client tools like `kubectl` use this ordering to derive preference, so this ordering mechanism is important.
// Values must be between 1 and 1000
// The primary sort is based on priority, ordered lowest number to highest (10 before 20).
// The secondary sort is based on the alphabetical comparison of the name of the object. (v1.bar before v1.foo)
// We'd recommend something like: *.k8s.io (except extensions) at 100, extensions at 150
// PaaSes (OpenShift, Deis) are recommended to be in the 200s
Priority int64
}
// APIServiceStatus contains derived information about an API server
type APIServiceStatus struct {
}
// +genclient=true
// +nonNamespaced=true
// APIService represents a server for a particular GroupVersion.
// Name must be "version.group".
type APIService struct {
metav1.TypeMeta
kapi.ObjectMeta
// Spec contains information for locating and communicating with a server
Spec APIServiceSpec
// Status contains derived information about an API server
Status APIServiceStatus
}

View file

@ -0,0 +1,44 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"doc.go",
"register.go",
"types.generated.go",
"types.go",
"zz_generated.conversion.go",
"zz_generated.deepcopy.go",
],
tags = ["automanaged"],
deps = [
"//cmd/kube-aggregator/pkg/apis/apiregistration:go_default_library",
"//pkg/api/v1:go_default_library",
"//vendor:github.com/ugorji/go/codec",
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
"//vendor:k8s.io/apimachinery/pkg/conversion",
"//vendor:k8s.io/apimachinery/pkg/runtime",
"//vendor:k8s.io/apimachinery/pkg/runtime/schema",
"//vendor:k8s.io/apimachinery/pkg/types",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
)

View file

@ -0,0 +1,22 @@
/*
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.
*/
// +k8s:deepcopy-gen=package,register
// +k8s:conversion-gen=k8s.io/kubernetes/cmd/kube-aggregator/pkg/apis/apiregistration
// Package v1alpha1 is the v1alpha1 version of the API.
// +groupName=apiregistration.k8s.io
package v1alpha1

View file

@ -0,0 +1,48 @@
/*
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 v1alpha1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/kubernetes/pkg/api/v1"
)
const GroupName = "apiregistration.k8s.io"
// SchemeGroupVersion is group version used to register these objects
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha1"}
var (
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
AddToScheme = SchemeBuilder.AddToScheme
)
// Adds the list of known types to api.Scheme.
func addKnownTypes(scheme *runtime.Scheme) error {
scheme.AddKnownTypes(SchemeGroupVersion,
&APIService{},
&APIServiceList{},
&v1.ListOptions{},
&v1.DeleteOptions{},
&metav1.GetOptions{},
)
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
return nil
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,84 @@
/*
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 v1alpha1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
kapi "k8s.io/kubernetes/pkg/api/v1"
)
// APIServiceList is a list of APIService objects.
type APIServiceList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
Items []APIService `json:"items" protobuf:"bytes,2,rep,name=items"`
}
// ServiceReference holds a reference to Service.legacy.k8s.io
type ServiceReference struct {
// Namespace is the namespace of the service
Namespace string `json:"namespace,omitempty" protobuf:"bytes,1,opt,name=namespace"`
// Name is the name of the service
Name string `json:"name,omitempty" protobuf:"bytes,2,opt,name=name"`
}
// APIServiceSpec contains information for locating and communicating with a server.
// Only https is supported, though you are able to disable certificate verification.
type APIServiceSpec struct {
// Service is a reference to the service for this API server. It must communicate
// on port 443
Service ServiceReference `json:"service" protobuf:"bytes,1,opt,name=service"`
// Group is the API group name this server hosts
Group string `json:"group,omitempty" protobuf:"bytes,2,opt,name=group"`
// Version is the API version this server hosts. For example, "v1"
Version string `json:"version,omitempty" protobuf:"bytes,3,opt,name=version"`
// InsecureSkipTLSVerify disables TLS certificate verification when communicating with this server.
// This is strongly discouraged. You should use the CABundle instead.
InsecureSkipTLSVerify bool `json:"insecureSkipTLSVerify,omitempty" protobuf:"varint,4,opt,name=insecureSkipTLSVerify"`
// CABundle is a PEM encoded CA bundle which will be used to validate an API server's serving certificate.
CABundle []byte `json:"caBundle" protobuf:"bytes,5,opt,name=caBundle"`
// Priority controls the ordering of this API group in the overall discovery document that gets served.
// Client tools like `kubectl` use this ordering to derive preference, so this ordering mechanism is important.
// Values must be between 1 and 1000
// The primary sort is based on priority, ordered lowest number to highest (10 before 20).
// The secondary sort is based on the alphabetical comparison of the name of the object. (v1.bar before v1.foo)
// We'd recommend something like: *.k8s.io (except extensions) at 100, extensions at 150
// PaaSes (OpenShift, Deis) are recommended to be in the 200s
Priority int64 `json:"priority" protobuf:"varint,6,opt,name=priority"`
}
// APIServiceStatus contains derived information about an API server
type APIServiceStatus struct {
}
// +genclient=true
// +nonNamespaced=true
// APIService represents a server for a particular GroupVersion.
// Name must be "version.group".
type APIService struct {
metav1.TypeMeta `json:",inline"`
kapi.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
// Spec contains information for locating and communicating with a server
Spec APIServiceSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"`
// Status contains derived information about an API server
Status APIServiceStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"`
}

View file

@ -0,0 +1,173 @@
// +build !ignore_autogenerated
/*
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.
*/
// This file was autogenerated by conversion-gen. Do not edit it manually!
package v1alpha1
import (
conversion "k8s.io/apimachinery/pkg/conversion"
runtime "k8s.io/apimachinery/pkg/runtime"
apiregistration "k8s.io/kubernetes/cmd/kube-aggregator/pkg/apis/apiregistration"
unsafe "unsafe"
)
func init() {
SchemeBuilder.Register(RegisterConversions)
}
// RegisterConversions adds conversion functions to the given scheme.
// Public to allow building arbitrary schemes.
func RegisterConversions(scheme *runtime.Scheme) error {
return scheme.AddGeneratedConversionFuncs(
Convert_v1alpha1_APIService_To_apiregistration_APIService,
Convert_apiregistration_APIService_To_v1alpha1_APIService,
Convert_v1alpha1_APIServiceList_To_apiregistration_APIServiceList,
Convert_apiregistration_APIServiceList_To_v1alpha1_APIServiceList,
Convert_v1alpha1_APIServiceSpec_To_apiregistration_APIServiceSpec,
Convert_apiregistration_APIServiceSpec_To_v1alpha1_APIServiceSpec,
Convert_v1alpha1_APIServiceStatus_To_apiregistration_APIServiceStatus,
Convert_apiregistration_APIServiceStatus_To_v1alpha1_APIServiceStatus,
Convert_v1alpha1_ServiceReference_To_apiregistration_ServiceReference,
Convert_apiregistration_ServiceReference_To_v1alpha1_ServiceReference,
)
}
func autoConvert_v1alpha1_APIService_To_apiregistration_APIService(in *APIService, out *apiregistration.APIService, s conversion.Scope) error {
// TODO: Inefficient conversion - can we improve it?
if err := s.Convert(&in.ObjectMeta, &out.ObjectMeta, 0); err != nil {
return err
}
if err := Convert_v1alpha1_APIServiceSpec_To_apiregistration_APIServiceSpec(&in.Spec, &out.Spec, s); err != nil {
return err
}
if err := Convert_v1alpha1_APIServiceStatus_To_apiregistration_APIServiceStatus(&in.Status, &out.Status, s); err != nil {
return err
}
return nil
}
func Convert_v1alpha1_APIService_To_apiregistration_APIService(in *APIService, out *apiregistration.APIService, s conversion.Scope) error {
return autoConvert_v1alpha1_APIService_To_apiregistration_APIService(in, out, s)
}
func autoConvert_apiregistration_APIService_To_v1alpha1_APIService(in *apiregistration.APIService, out *APIService, s conversion.Scope) error {
// TODO: Inefficient conversion - can we improve it?
if err := s.Convert(&in.ObjectMeta, &out.ObjectMeta, 0); err != nil {
return err
}
if err := Convert_apiregistration_APIServiceSpec_To_v1alpha1_APIServiceSpec(&in.Spec, &out.Spec, s); err != nil {
return err
}
if err := Convert_apiregistration_APIServiceStatus_To_v1alpha1_APIServiceStatus(&in.Status, &out.Status, s); err != nil {
return err
}
return nil
}
func Convert_apiregistration_APIService_To_v1alpha1_APIService(in *apiregistration.APIService, out *APIService, s conversion.Scope) error {
return autoConvert_apiregistration_APIService_To_v1alpha1_APIService(in, out, s)
}
func autoConvert_v1alpha1_APIServiceList_To_apiregistration_APIServiceList(in *APIServiceList, out *apiregistration.APIServiceList, s conversion.Scope) error {
out.ListMeta = in.ListMeta
out.Items = *(*[]apiregistration.APIService)(unsafe.Pointer(&in.Items))
return nil
}
func Convert_v1alpha1_APIServiceList_To_apiregistration_APIServiceList(in *APIServiceList, out *apiregistration.APIServiceList, s conversion.Scope) error {
return autoConvert_v1alpha1_APIServiceList_To_apiregistration_APIServiceList(in, out, s)
}
func autoConvert_apiregistration_APIServiceList_To_v1alpha1_APIServiceList(in *apiregistration.APIServiceList, out *APIServiceList, s conversion.Scope) error {
out.ListMeta = in.ListMeta
out.Items = *(*[]APIService)(unsafe.Pointer(&in.Items))
return nil
}
func Convert_apiregistration_APIServiceList_To_v1alpha1_APIServiceList(in *apiregistration.APIServiceList, out *APIServiceList, s conversion.Scope) error {
return autoConvert_apiregistration_APIServiceList_To_v1alpha1_APIServiceList(in, out, s)
}
func autoConvert_v1alpha1_APIServiceSpec_To_apiregistration_APIServiceSpec(in *APIServiceSpec, out *apiregistration.APIServiceSpec, s conversion.Scope) error {
if err := Convert_v1alpha1_ServiceReference_To_apiregistration_ServiceReference(&in.Service, &out.Service, s); err != nil {
return err
}
out.Group = in.Group
out.Version = in.Version
out.InsecureSkipTLSVerify = in.InsecureSkipTLSVerify
out.CABundle = *(*[]byte)(unsafe.Pointer(&in.CABundle))
out.Priority = in.Priority
return nil
}
func Convert_v1alpha1_APIServiceSpec_To_apiregistration_APIServiceSpec(in *APIServiceSpec, out *apiregistration.APIServiceSpec, s conversion.Scope) error {
return autoConvert_v1alpha1_APIServiceSpec_To_apiregistration_APIServiceSpec(in, out, s)
}
func autoConvert_apiregistration_APIServiceSpec_To_v1alpha1_APIServiceSpec(in *apiregistration.APIServiceSpec, out *APIServiceSpec, s conversion.Scope) error {
if err := Convert_apiregistration_ServiceReference_To_v1alpha1_ServiceReference(&in.Service, &out.Service, s); err != nil {
return err
}
out.Group = in.Group
out.Version = in.Version
out.InsecureSkipTLSVerify = in.InsecureSkipTLSVerify
out.CABundle = *(*[]byte)(unsafe.Pointer(&in.CABundle))
out.Priority = in.Priority
return nil
}
func Convert_apiregistration_APIServiceSpec_To_v1alpha1_APIServiceSpec(in *apiregistration.APIServiceSpec, out *APIServiceSpec, s conversion.Scope) error {
return autoConvert_apiregistration_APIServiceSpec_To_v1alpha1_APIServiceSpec(in, out, s)
}
func autoConvert_v1alpha1_APIServiceStatus_To_apiregistration_APIServiceStatus(in *APIServiceStatus, out *apiregistration.APIServiceStatus, s conversion.Scope) error {
return nil
}
func Convert_v1alpha1_APIServiceStatus_To_apiregistration_APIServiceStatus(in *APIServiceStatus, out *apiregistration.APIServiceStatus, s conversion.Scope) error {
return autoConvert_v1alpha1_APIServiceStatus_To_apiregistration_APIServiceStatus(in, out, s)
}
func autoConvert_apiregistration_APIServiceStatus_To_v1alpha1_APIServiceStatus(in *apiregistration.APIServiceStatus, out *APIServiceStatus, s conversion.Scope) error {
return nil
}
func Convert_apiregistration_APIServiceStatus_To_v1alpha1_APIServiceStatus(in *apiregistration.APIServiceStatus, out *APIServiceStatus, s conversion.Scope) error {
return autoConvert_apiregistration_APIServiceStatus_To_v1alpha1_APIServiceStatus(in, out, s)
}
func autoConvert_v1alpha1_ServiceReference_To_apiregistration_ServiceReference(in *ServiceReference, out *apiregistration.ServiceReference, s conversion.Scope) error {
out.Namespace = in.Namespace
out.Name = in.Name
return nil
}
func Convert_v1alpha1_ServiceReference_To_apiregistration_ServiceReference(in *ServiceReference, out *apiregistration.ServiceReference, s conversion.Scope) error {
return autoConvert_v1alpha1_ServiceReference_To_apiregistration_ServiceReference(in, out, s)
}
func autoConvert_apiregistration_ServiceReference_To_v1alpha1_ServiceReference(in *apiregistration.ServiceReference, out *ServiceReference, s conversion.Scope) error {
out.Namespace = in.Namespace
out.Name = in.Name
return nil
}
func Convert_apiregistration_ServiceReference_To_v1alpha1_ServiceReference(in *apiregistration.ServiceReference, out *ServiceReference, s conversion.Scope) error {
return autoConvert_apiregistration_ServiceReference_To_v1alpha1_ServiceReference(in, out, s)
}

View file

@ -0,0 +1,109 @@
// +build !ignore_autogenerated
/*
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.
*/
// This file was autogenerated by deepcopy-gen. Do not edit it manually!
package v1alpha1
import (
conversion "k8s.io/apimachinery/pkg/conversion"
runtime "k8s.io/apimachinery/pkg/runtime"
v1 "k8s.io/kubernetes/pkg/api/v1"
reflect "reflect"
)
func init() {
SchemeBuilder.Register(RegisterDeepCopies)
}
// RegisterDeepCopies adds deep-copy functions to the given scheme. Public
// to allow building arbitrary schemes.
func RegisterDeepCopies(scheme *runtime.Scheme) error {
return scheme.AddGeneratedDeepCopyFuncs(
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1alpha1_APIService, InType: reflect.TypeOf(&APIService{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1alpha1_APIServiceList, InType: reflect.TypeOf(&APIServiceList{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1alpha1_APIServiceSpec, InType: reflect.TypeOf(&APIServiceSpec{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1alpha1_APIServiceStatus, InType: reflect.TypeOf(&APIServiceStatus{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1alpha1_ServiceReference, InType: reflect.TypeOf(&ServiceReference{})},
)
}
func DeepCopy_v1alpha1_APIService(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*APIService)
out := out.(*APIService)
*out = *in
if err := v1.DeepCopy_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, c); err != nil {
return err
}
if err := DeepCopy_v1alpha1_APIServiceSpec(&in.Spec, &out.Spec, c); err != nil {
return err
}
return nil
}
}
func DeepCopy_v1alpha1_APIServiceList(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*APIServiceList)
out := out.(*APIServiceList)
*out = *in
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]APIService, len(*in))
for i := range *in {
if err := DeepCopy_v1alpha1_APIService(&(*in)[i], &(*out)[i], c); err != nil {
return err
}
}
}
return nil
}
}
func DeepCopy_v1alpha1_APIServiceSpec(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*APIServiceSpec)
out := out.(*APIServiceSpec)
*out = *in
if in.CABundle != nil {
in, out := &in.CABundle, &out.CABundle
*out = make([]byte, len(*in))
copy(*out, *in)
}
return nil
}
}
func DeepCopy_v1alpha1_APIServiceStatus(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*APIServiceStatus)
out := out.(*APIServiceStatus)
*out = *in
return nil
}
}
func DeepCopy_v1alpha1_ServiceReference(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*ServiceReference)
out := out.(*ServiceReference)
*out = *in
return nil
}
}

View file

@ -0,0 +1,34 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["validation.go"],
tags = ["automanaged"],
deps = [
"//cmd/kube-aggregator/pkg/apis/apiregistration:go_default_library",
"//pkg/api/validation:go_default_library",
"//pkg/api/validation/path:go_default_library",
"//vendor:k8s.io/apimachinery/pkg/util/validation",
"//vendor:k8s.io/apimachinery/pkg/util/validation/field",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
)

View file

@ -0,0 +1,85 @@
/*
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 validation
import (
"fmt"
utilvalidation "k8s.io/apimachinery/pkg/util/validation"
"k8s.io/apimachinery/pkg/util/validation/field"
"k8s.io/kubernetes/pkg/api/validation"
"k8s.io/kubernetes/pkg/api/validation/path"
discoveryapi "k8s.io/kubernetes/cmd/kube-aggregator/pkg/apis/apiregistration"
)
func ValidateAPIService(apiServer *discoveryapi.APIService) field.ErrorList {
requiredName := apiServer.Spec.Version + "." + apiServer.Spec.Group
allErrs := validation.ValidateObjectMeta(&apiServer.ObjectMeta, false,
func(name string, prefix bool) []string {
if minimalFailures := path.IsValidPathSegmentName(name); len(minimalFailures) > 0 {
return minimalFailures
}
// the name *must* be version.group
if name != requiredName {
return []string{fmt.Sprintf("must be `spec.version+\".\"+spec.group`: %q", requiredName)}
}
return []string{}
},
field.NewPath("metadata"))
// in this case we allow empty group
if len(apiServer.Spec.Group) == 0 && apiServer.Spec.Version != "v1" {
allErrs = append(allErrs, field.Required(field.NewPath("spec", "group"), "only v1 may have an empty group and it better be legacy kube"))
}
if len(apiServer.Spec.Group) > 0 {
for _, errString := range utilvalidation.IsDNS1123Subdomain(apiServer.Spec.Group) {
allErrs = append(allErrs, field.Invalid(field.NewPath("spec", "group"), apiServer.Spec.Group, errString))
}
}
for _, errString := range utilvalidation.IsDNS1035Label(apiServer.Spec.Version) {
allErrs = append(allErrs, field.Invalid(field.NewPath("spec", "version"), apiServer.Spec.Version, errString))
}
if apiServer.Spec.Priority <= 0 || apiServer.Spec.Priority > 1000 {
allErrs = append(allErrs, field.Invalid(field.NewPath("spec", "priority"), apiServer.Spec.Priority, "priority must be positive and less than 1000"))
}
if len(apiServer.Spec.Service.Namespace) == 0 {
allErrs = append(allErrs, field.Required(field.NewPath("spec", "service", "namespace"), ""))
}
if len(apiServer.Spec.Service.Name) == 0 {
allErrs = append(allErrs, field.Required(field.NewPath("spec", "service", "name"), ""))
}
if apiServer.Spec.InsecureSkipTLSVerify && len(apiServer.Spec.CABundle) > 0 {
allErrs = append(allErrs, field.Invalid(field.NewPath("spec", "insecureSkipTLSVerify"), apiServer.Spec.InsecureSkipTLSVerify, "may not be true if caBundle is present"))
}
return allErrs
}
func ValidateAPIServiceUpdate(newAPIService *discoveryapi.APIService, oldAPIService *discoveryapi.APIService) field.ErrorList {
allErrs := validation.ValidateObjectMetaUpdate(&newAPIService.ObjectMeta, &oldAPIService.ObjectMeta, field.NewPath("metadata"))
allErrs = append(allErrs, ValidateAPIService(newAPIService)...)
return allErrs
}

View file

@ -0,0 +1,109 @@
// +build !ignore_autogenerated
/*
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.
*/
// This file was autogenerated by deepcopy-gen. Do not edit it manually!
package apiregistration
import (
conversion "k8s.io/apimachinery/pkg/conversion"
runtime "k8s.io/apimachinery/pkg/runtime"
api "k8s.io/kubernetes/pkg/api"
reflect "reflect"
)
func init() {
SchemeBuilder.Register(RegisterDeepCopies)
}
// RegisterDeepCopies adds deep-copy functions to the given scheme. Public
// to allow building arbitrary schemes.
func RegisterDeepCopies(scheme *runtime.Scheme) error {
return scheme.AddGeneratedDeepCopyFuncs(
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_apiregistration_APIService, InType: reflect.TypeOf(&APIService{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_apiregistration_APIServiceList, InType: reflect.TypeOf(&APIServiceList{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_apiregistration_APIServiceSpec, InType: reflect.TypeOf(&APIServiceSpec{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_apiregistration_APIServiceStatus, InType: reflect.TypeOf(&APIServiceStatus{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_apiregistration_ServiceReference, InType: reflect.TypeOf(&ServiceReference{})},
)
}
func DeepCopy_apiregistration_APIService(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*APIService)
out := out.(*APIService)
*out = *in
if err := api.DeepCopy_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, c); err != nil {
return err
}
if err := DeepCopy_apiregistration_APIServiceSpec(&in.Spec, &out.Spec, c); err != nil {
return err
}
return nil
}
}
func DeepCopy_apiregistration_APIServiceList(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*APIServiceList)
out := out.(*APIServiceList)
*out = *in
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]APIService, len(*in))
for i := range *in {
if err := DeepCopy_apiregistration_APIService(&(*in)[i], &(*out)[i], c); err != nil {
return err
}
}
}
return nil
}
}
func DeepCopy_apiregistration_APIServiceSpec(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*APIServiceSpec)
out := out.(*APIServiceSpec)
*out = *in
if in.CABundle != nil {
in, out := &in.CABundle, &out.CABundle
*out = make([]byte, len(*in))
copy(*out, *in)
}
return nil
}
}
func DeepCopy_apiregistration_APIServiceStatus(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*APIServiceStatus)
out := out.(*APIServiceStatus)
*out = *in
return nil
}
}
func DeepCopy_apiregistration_ServiceReference(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*ServiceReference)
out := out.(*ServiceReference)
*out = *in
return nil
}
}

View file

@ -0,0 +1,94 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
"go_test",
)
go_library(
name = "go_default_library",
srcs = [
"apiserver.go",
"apiservice_controller.go",
"handler_apis.go",
"handler_proxy.go",
],
tags = ["automanaged"],
deps = [
"//cmd/kube-aggregator/pkg/apis/apiregistration:go_default_library",
"//cmd/kube-aggregator/pkg/apis/apiregistration/v1alpha1:go_default_library",
"//cmd/kube-aggregator/pkg/client/clientset_generated/clientset:go_default_library",
"//cmd/kube-aggregator/pkg/client/clientset_generated/internalclientset:go_default_library",
"//cmd/kube-aggregator/pkg/client/informers:go_default_library",
"//cmd/kube-aggregator/pkg/client/informers/apiregistration/internalversion:go_default_library",
"//cmd/kube-aggregator/pkg/client/listers/apiregistration/internalversion:go_default_library",
"//cmd/kube-aggregator/pkg/registry/apiservice/etcd:go_default_library",
"//pkg/api:go_default_library",
"//pkg/auth/handlers:go_default_library",
"//pkg/client/cache:go_default_library",
"//pkg/client/clientset_generated/clientset:go_default_library",
"//pkg/client/informers/informers_generated:go_default_library",
"//pkg/client/listers/core/v1:go_default_library",
"//pkg/client/restclient:go_default_library",
"//pkg/client/transport:go_default_library",
"//pkg/controller:go_default_library",
"//pkg/genericapiserver:go_default_library",
"//pkg/genericapiserver/api/filters:go_default_library",
"//pkg/genericapiserver/api/handlers/responsewriters:go_default_library",
"//pkg/genericapiserver/api/rest:go_default_library",
"//pkg/genericapiserver/filters:go_default_library",
"//pkg/registry/generic:go_default_library",
"//pkg/registry/generic/rest:go_default_library",
"//pkg/util/httpstream/spdy:go_default_library",
"//pkg/util/workqueue:go_default_library",
"//pkg/version:go_default_library",
"//vendor:github.com/golang/glog",
"//vendor:k8s.io/apimachinery/pkg/api/errors",
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
"//vendor:k8s.io/apimachinery/pkg/labels",
"//vendor:k8s.io/apimachinery/pkg/runtime",
"//vendor:k8s.io/apimachinery/pkg/util/runtime",
"//vendor:k8s.io/apimachinery/pkg/util/wait",
"//vendor:k8s.io/apiserver/pkg/request",
],
)
go_test(
name = "go_default_test",
srcs = [
"handler_apis_test.go",
"handler_proxy_test.go",
],
library = ":go_default_library",
tags = ["automanaged"],
deps = [
"//cmd/kube-aggregator/pkg/apis/apiregistration:go_default_library",
"//cmd/kube-aggregator/pkg/client/listers/apiregistration/internalversion:go_default_library",
"//pkg/api:go_default_library",
"//pkg/api/v1:go_default_library",
"//pkg/client/cache:go_default_library",
"//pkg/client/listers/core/v1:go_default_library",
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
"//vendor:k8s.io/apimachinery/pkg/runtime",
"//vendor:k8s.io/apimachinery/pkg/util/diff",
"//vendor:k8s.io/apimachinery/pkg/util/sets",
"//vendor:k8s.io/apiserver/pkg/authentication/user",
"//vendor:k8s.io/apiserver/pkg/request",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
)

View file

@ -0,0 +1,276 @@
/*
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 apiserver
import (
"net/http"
"os"
"time"
"k8s.io/apimachinery/pkg/util/wait"
genericapirequest "k8s.io/apiserver/pkg/request"
authhandlers "k8s.io/kubernetes/pkg/auth/handlers"
kubeclientset "k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
kubeinformers "k8s.io/kubernetes/pkg/client/informers/informers_generated"
v1listers "k8s.io/kubernetes/pkg/client/listers/core/v1"
"k8s.io/kubernetes/pkg/genericapiserver"
genericapifilters "k8s.io/kubernetes/pkg/genericapiserver/api/filters"
"k8s.io/kubernetes/pkg/genericapiserver/api/rest"
genericfilters "k8s.io/kubernetes/pkg/genericapiserver/filters"
"k8s.io/kubernetes/pkg/registry/generic"
"k8s.io/kubernetes/pkg/version"
"k8s.io/kubernetes/cmd/kube-aggregator/pkg/apis/apiregistration"
"k8s.io/kubernetes/cmd/kube-aggregator/pkg/apis/apiregistration/v1alpha1"
discoveryclientset "k8s.io/kubernetes/cmd/kube-aggregator/pkg/client/clientset_generated/clientset"
"k8s.io/kubernetes/cmd/kube-aggregator/pkg/client/clientset_generated/internalclientset"
"k8s.io/kubernetes/cmd/kube-aggregator/pkg/client/informers"
listers "k8s.io/kubernetes/cmd/kube-aggregator/pkg/client/listers/apiregistration/internalversion"
apiservicestorage "k8s.io/kubernetes/cmd/kube-aggregator/pkg/registry/apiservice/etcd"
)
// legacyAPIServiceName is the fixed name of the only non-groupified API version
const legacyAPIServiceName = "v1."
type Config struct {
GenericConfig *genericapiserver.Config
CoreAPIServerClient kubeclientset.Interface
// ProxyClientCert/Key are the client cert used to identify this proxy. Backing APIServices use
// this to confirm the proxy's identity
ProxyClientCert []byte
ProxyClientKey []byte
// RESTOptionsGetter is used to construct storage for a particular resource
RESTOptionsGetter generic.RESTOptionsGetter
}
// APIDiscoveryServer contains state for a Kubernetes cluster master/api server.
type APIDiscoveryServer struct {
GenericAPIServer *genericapiserver.GenericAPIServer
contextMapper genericapirequest.RequestContextMapper
// proxyClientCert/Key are the client cert used to identify this proxy. Backing APIServices use
// this to confirm the proxy's identity
proxyClientCert []byte
proxyClientKey []byte
// proxyHandlers are the proxy handlers that are currently registered, keyed by apiservice.name
proxyHandlers map[string]*proxyHandler
// lister is used to add group handling for /apis/<group> discovery lookups based on
// controller state
lister listers.APIServiceLister
// serviceLister is used by the discovery handler to determine whether or not to try to expose the group
serviceLister v1listers.ServiceLister
// endpointsLister is used by the discovery handler to determine whether or not to try to expose the group
endpointsLister v1listers.EndpointsLister
// proxyMux intercepts requests that need to be proxied to backing API servers
proxyMux *http.ServeMux
}
type completedConfig struct {
*Config
}
// Complete fills in any fields not set that are required to have valid data. It's mutating the receiver.
func (c *Config) Complete() completedConfig {
c.GenericConfig.Complete()
version := version.Get()
c.GenericConfig.Version = &version
return completedConfig{c}
}
// SkipComplete provides a way to construct a server instance without config completion.
func (c *Config) SkipComplete() completedConfig {
return completedConfig{c}
}
// New returns a new instance of APIDiscoveryServer from the given config.
func (c completedConfig) New() (*APIDiscoveryServer, error) {
informerFactory := informers.NewSharedInformerFactory(
internalclientset.NewForConfigOrDie(c.Config.GenericConfig.LoopbackClientConfig),
discoveryclientset.NewForConfigOrDie(c.Config.GenericConfig.LoopbackClientConfig),
5*time.Minute, // this is effectively used as a refresh interval right now. Might want to do something nicer later on.
)
kubeInformers := kubeinformers.NewSharedInformerFactory(nil, c.CoreAPIServerClient, 5*time.Minute)
proxyMux := http.NewServeMux()
// most API servers don't need to do this, but we need a custom handler chain to handle the special /apis handling here
c.Config.GenericConfig.BuildHandlerChainsFunc = (&handlerChainConfig{
informers: informerFactory,
proxyMux: proxyMux,
serviceLister: kubeInformers.Core().V1().Services().Lister(),
endpointsLister: kubeInformers.Core().V1().Endpoints().Lister(),
}).handlerChain
genericServer, err := c.Config.GenericConfig.SkipComplete().New() // completion is done in Complete, no need for a second time
if err != nil {
return nil, err
}
s := &APIDiscoveryServer{
GenericAPIServer: genericServer,
contextMapper: c.GenericConfig.RequestContextMapper,
proxyClientCert: c.ProxyClientCert,
proxyClientKey: c.ProxyClientKey,
proxyHandlers: map[string]*proxyHandler{},
lister: informerFactory.Apiregistration().InternalVersion().APIServices().Lister(),
serviceLister: kubeInformers.Core().V1().Services().Lister(),
endpointsLister: kubeInformers.Core().V1().Endpoints().Lister(),
proxyMux: proxyMux,
}
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(apiregistration.GroupName)
apiGroupInfo.GroupMeta.GroupVersion = v1alpha1.SchemeGroupVersion
v1alpha1storage := map[string]rest.Storage{}
v1alpha1storage["apiservices"] = apiservicestorage.NewREST(c.RESTOptionsGetter)
apiGroupInfo.VersionedResourcesStorageMap["v1alpha1"] = v1alpha1storage
if err := s.GenericAPIServer.InstallAPIGroup(&apiGroupInfo); err != nil {
return nil, err
}
apiserviceRegistrationController := NewAPIServiceRegistrationController(informerFactory.Apiregistration().InternalVersion().APIServices(), s)
s.GenericAPIServer.AddPostStartHook("start-informers", func(context genericapiserver.PostStartHookContext) error {
informerFactory.Start(wait.NeverStop)
kubeInformers.Start(wait.NeverStop)
return nil
})
s.GenericAPIServer.AddPostStartHook("apiservice-registration-controller", func(context genericapiserver.PostStartHookContext) error {
apiserviceRegistrationController.Run(wait.NeverStop)
return nil
})
return s, nil
}
// handlerChainConfig is the config used to build the custom handler chain for this api server
type handlerChainConfig struct {
informers informers.SharedInformerFactory
proxyMux *http.ServeMux
serviceLister v1listers.ServiceLister
endpointsLister v1listers.EndpointsLister
}
// handlerChain is a method to build the handler chain for this API server. We need a custom handler chain so that we
// can have custom handling for `/apis`, since we're hosting discovery differently from anyone else and we're hosting
// the endpoints differently, since we're proxying all groups except for apiregistration.k8s.io.
func (h *handlerChainConfig) handlerChain(apiHandler http.Handler, c *genericapiserver.Config) (secure, insecure http.Handler) {
// add this as a filter so that we never collide with "already registered" failures on `/apis`
handler := WithAPIs(apiHandler, h.informers.Apiregistration().InternalVersion().APIServices(), h.serviceLister, h.endpointsLister)
handler = genericapifilters.WithAuthorization(handler, c.RequestContextMapper, c.Authorizer)
// this mux is NOT protected by authorization, but DOES have authentication information
// this is so that everyone can hit the proxy and we can properly identify the user. The backing
// API server will deal with authorization
handler = WithProxyMux(handler, h.proxyMux)
handler = genericapifilters.WithImpersonation(handler, c.RequestContextMapper, c.Authorizer)
// audit to stdout to help with debugging as we get this started
handler = genericapifilters.WithAudit(handler, c.RequestContextMapper, os.Stdout)
handler = authhandlers.WithAuthentication(handler, c.RequestContextMapper, c.Authenticator, authhandlers.Unauthorized(c.SupportsBasicAuth))
handler = genericfilters.WithCORS(handler, c.CorsAllowedOriginList, nil, nil, nil, "true")
handler = genericfilters.WithPanicRecovery(handler, c.RequestContextMapper)
handler = genericfilters.WithTimeoutForNonLongRunningRequests(handler, c.RequestContextMapper, c.LongRunningFunc)
handler = genericfilters.WithMaxInFlightLimit(handler, c.MaxRequestsInFlight, c.MaxMutatingRequestsInFlight, c.RequestContextMapper, c.LongRunningFunc)
handler = genericapifilters.WithRequestInfo(handler, genericapiserver.NewRequestInfoResolver(c), c.RequestContextMapper)
handler = genericapirequest.WithRequestContext(handler, c.RequestContextMapper)
return handler, nil
}
// AddAPIService adds an API service. It is not thread-safe, so only call it on one thread at a time please.
// It's a slow moving API, so its ok to run the controller on a single thread
func (s *APIDiscoveryServer) AddAPIService(apiService *apiregistration.APIService) {
// if the proxyHandler already exists, it needs to be updated. The discovery bits do not
// since they are wired against listers because they require multiple resources to respond
if proxyHandler, exists := s.proxyHandlers[apiService.Name]; exists {
proxyHandler.updateAPIService(apiService)
return
}
proxyPath := "/apis/" + apiService.Spec.Group + "/" + apiService.Spec.Version
// v1. is a special case for the legacy API. It proxies to a wider set of endpoints.
if apiService.Name == "v1." {
proxyPath = "/api"
}
// register the proxy handler
proxyHandler := &proxyHandler{
contextMapper: s.contextMapper,
proxyClientCert: s.proxyClientCert,
proxyClientKey: s.proxyClientKey,
transportBuildingError: nil,
proxyRoundTripper: nil,
}
proxyHandler.updateAPIService(apiService)
s.proxyHandlers[apiService.Name] = proxyHandler
s.proxyMux.Handle(proxyPath, proxyHandler)
s.proxyMux.Handle(proxyPath+"/", proxyHandler)
// if we're dealing with the legacy group, we're done here
if apiService.Name == legacyAPIServiceName {
return
}
// it's time to register the group discovery endpoint
groupPath := "/apis/" + apiService.Spec.Group
groupDiscoveryHandler := &apiGroupHandler{
groupName: apiService.Spec.Group,
lister: s.lister,
serviceLister: s.serviceLister,
endpointsLister: s.endpointsLister,
}
// discovery is protected
s.GenericAPIServer.HandlerContainer.UnlistedRoutes.Handle(groupPath, groupDiscoveryHandler)
s.GenericAPIServer.HandlerContainer.UnlistedRoutes.Handle(groupPath+"/", groupDiscoveryHandler)
}
// RemoveAPIService removes the APIService from being handled. Later on it will disable the proxy endpoint.
// Right now it does nothing because our handler has to properly 404 itself since muxes don't unregister
func (s *APIDiscoveryServer) RemoveAPIService(apiServiceName string) {
proxyHandler, exists := s.proxyHandlers[apiServiceName]
if !exists {
return
}
proxyHandler.removeAPIService()
}
func WithProxyMux(handler http.Handler, mux *http.ServeMux) http.Handler {
if mux == nil {
return handler
}
// register the handler at this stage against everything under slash. More specific paths that get registered will take precedence
// this effectively delegates by default unless something specific gets registered.
mux.Handle("/", handler)
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
mux.ServeHTTP(w, req)
})
}

View file

@ -0,0 +1,162 @@
/*
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 apiserver
import (
"fmt"
"time"
"github.com/golang/glog"
apierrors "k8s.io/apimachinery/pkg/api/errors"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/kubernetes/pkg/client/cache"
"k8s.io/kubernetes/pkg/controller"
"k8s.io/kubernetes/pkg/util/workqueue"
"k8s.io/kubernetes/cmd/kube-aggregator/pkg/apis/apiregistration"
informers "k8s.io/kubernetes/cmd/kube-aggregator/pkg/client/informers/apiregistration/internalversion"
listers "k8s.io/kubernetes/cmd/kube-aggregator/pkg/client/listers/apiregistration/internalversion"
)
type APIHandlerManager interface {
AddAPIService(apiServer *apiregistration.APIService)
RemoveAPIService(apiServerName string)
}
type APIServiceRegistrationController struct {
apiHandlerManager APIHandlerManager
apiServerLister listers.APIServiceLister
// To allow injection for testing.
syncFn func(key string) error
queue workqueue.RateLimitingInterface
}
func NewAPIServiceRegistrationController(apiServerInformer informers.APIServiceInformer, apiHandlerManager APIHandlerManager) *APIServiceRegistrationController {
c := &APIServiceRegistrationController{
apiHandlerManager: apiHandlerManager,
apiServerLister: apiServerInformer.Lister(),
queue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "APIServiceRegistrationController"),
}
apiServerInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
AddFunc: c.addAPIService,
UpdateFunc: c.updateAPIService,
DeleteFunc: c.deleteAPIService,
})
c.syncFn = c.sync
return c
}
func (c *APIServiceRegistrationController) sync(key string) error {
apiServer, err := c.apiServerLister.Get(key)
if apierrors.IsNotFound(err) {
c.apiHandlerManager.RemoveAPIService(key)
return nil
}
if err != nil {
return err
}
c.apiHandlerManager.AddAPIService(apiServer)
return nil
}
func (c *APIServiceRegistrationController) Run(stopCh <-chan struct{}) {
defer utilruntime.HandleCrash()
defer c.queue.ShutDown()
defer glog.Infof("Shutting down APIServiceRegistrationController")
glog.Infof("Starting APIServiceRegistrationController")
// only start one worker thread since its a slow moving API and the discovery server adding bits
// aren't threadsafe
go wait.Until(c.runWorker, time.Second, stopCh)
<-stopCh
}
func (c *APIServiceRegistrationController) runWorker() {
for c.processNextWorkItem() {
}
}
// processNextWorkItem deals with one key off the queue. It returns false when it's time to quit.
func (c *APIServiceRegistrationController) processNextWorkItem() bool {
key, quit := c.queue.Get()
if quit {
return false
}
defer c.queue.Done(key)
err := c.syncFn(key.(string))
if err == nil {
c.queue.Forget(key)
return true
}
utilruntime.HandleError(fmt.Errorf("%v failed with : %v", key, err))
c.queue.AddRateLimited(key)
return true
}
func (c *APIServiceRegistrationController) enqueue(obj *apiregistration.APIService) {
key, err := controller.KeyFunc(obj)
if err != nil {
glog.Errorf("Couldn't get key for object %#v: %v", obj, err)
return
}
c.queue.Add(key)
}
func (c *APIServiceRegistrationController) addAPIService(obj interface{}) {
castObj := obj.(*apiregistration.APIService)
glog.V(4).Infof("Adding %s", castObj.Name)
c.enqueue(castObj)
}
func (c *APIServiceRegistrationController) updateAPIService(obj, _ interface{}) {
castObj := obj.(*apiregistration.APIService)
glog.V(4).Infof("Updating %s", castObj.Name)
c.enqueue(castObj)
}
func (c *APIServiceRegistrationController) deleteAPIService(obj interface{}) {
castObj, ok := obj.(*apiregistration.APIService)
if !ok {
tombstone, ok := obj.(cache.DeletedFinalStateUnknown)
if !ok {
glog.Errorf("Couldn't get object from tombstone %#v", obj)
return
}
castObj, ok = tombstone.Obj.(*apiregistration.APIService)
if !ok {
glog.Errorf("Tombstone contained object that is not expected %#v", obj)
return
}
}
glog.V(4).Infof("Deleting %q", castObj.Name)
c.enqueue(castObj)
}

View file

@ -0,0 +1,223 @@
/*
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 apiserver
import (
"net/http"
"strings"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/kubernetes/pkg/api"
v1listers "k8s.io/kubernetes/pkg/client/listers/core/v1"
"k8s.io/kubernetes/pkg/genericapiserver/api/handlers/responsewriters"
apiregistrationapi "k8s.io/kubernetes/cmd/kube-aggregator/pkg/apis/apiregistration"
apiregistrationv1alpha1api "k8s.io/kubernetes/cmd/kube-aggregator/pkg/apis/apiregistration/v1alpha1"
informers "k8s.io/kubernetes/cmd/kube-aggregator/pkg/client/informers/apiregistration/internalversion"
listers "k8s.io/kubernetes/cmd/kube-aggregator/pkg/client/listers/apiregistration/internalversion"
)
// WithAPIs adds the handling for /apis and /apis/<group: -apiregistration.k8s.io>.
func WithAPIs(handler http.Handler, informer informers.APIServiceInformer, serviceLister v1listers.ServiceLister, endpointsLister v1listers.EndpointsLister) http.Handler {
apisHandler := &apisHandler{
lister: informer.Lister(),
delegate: handler,
serviceLister: serviceLister,
endpointsLister: endpointsLister,
}
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
apisHandler.ServeHTTP(w, req)
})
}
// apisHandler serves the `/apis` endpoint.
// This is registered as a filter so that it never collides with any explictly registered endpoints
type apisHandler struct {
lister listers.APIServiceLister
serviceLister v1listers.ServiceLister
endpointsLister v1listers.EndpointsLister
delegate http.Handler
}
var discoveryGroup = metav1.APIGroup{
Name: apiregistrationapi.GroupName,
Versions: []metav1.GroupVersionForDiscovery{
{
GroupVersion: apiregistrationv1alpha1api.SchemeGroupVersion.String(),
Version: apiregistrationv1alpha1api.SchemeGroupVersion.Version,
},
},
PreferredVersion: metav1.GroupVersionForDiscovery{
GroupVersion: apiregistrationv1alpha1api.SchemeGroupVersion.String(),
Version: apiregistrationv1alpha1api.SchemeGroupVersion.Version,
},
}
func (r *apisHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
// if the URL is for OUR api group, serve it normally
if strings.HasPrefix(req.URL.Path+"/", "/apis/"+apiregistrationapi.GroupName+"/") {
r.delegate.ServeHTTP(w, req)
return
}
// don't handle URLs that aren't /apis
if req.URL.Path != "/apis" && req.URL.Path != "/apis/" {
r.delegate.ServeHTTP(w, req)
return
}
discoveryGroupList := &metav1.APIGroupList{
// always add OUR api group to the list first. Since we'll never have a registered APIService for it
// and since this is the crux of the API, having this first will give our names priority. It's good to be king.
Groups: []metav1.APIGroup{discoveryGroup},
}
apiServices, err := r.lister.List(labels.Everything())
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
apiServicesByGroup := apiregistrationapi.SortedByGroup(apiServices)
for _, apiGroupServers := range apiServicesByGroup {
// skip the legacy group
if len(apiGroupServers[0].Spec.Group) == 0 {
continue
}
discoveryGroup := convertToDiscoveryAPIGroup(apiGroupServers, r.serviceLister, r.endpointsLister)
if discoveryGroup != nil {
discoveryGroupList.Groups = append(discoveryGroupList.Groups, *discoveryGroup)
}
}
json, err := runtime.Encode(api.Codecs.LegacyCodec(), discoveryGroupList)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
if _, err := w.Write(json); err != nil {
panic(err)
}
}
// convertToDiscoveryAPIGroup takes apiservices in a single group and returns a discovery compatible object.
// if none of the services are available, it will return nil.
func convertToDiscoveryAPIGroup(apiServices []*apiregistrationapi.APIService, serviceLister v1listers.ServiceLister, endpointsLister v1listers.EndpointsLister) *metav1.APIGroup {
apiServicesByGroup := apiregistrationapi.SortedByGroup(apiServices)[0]
var discoveryGroup *metav1.APIGroup
for _, apiService := range apiServicesByGroup {
// skip any API services without actual services
if _, err := serviceLister.Services(apiService.Spec.Service.Namespace).Get(apiService.Spec.Service.Name); err != nil {
continue
}
hasActiveEndpoints := false
endpoints, err := endpointsLister.Endpoints(apiService.Spec.Service.Namespace).Get(apiService.Spec.Service.Name)
// skip any API services without endpoints
if err != nil {
continue
}
for _, subset := range endpoints.Subsets {
if len(subset.Addresses) > 0 {
hasActiveEndpoints = true
break
}
}
if !hasActiveEndpoints {
continue
}
// the first APIService which is valid becomes the default
if discoveryGroup == nil {
discoveryGroup = &metav1.APIGroup{
Name: apiService.Spec.Group,
PreferredVersion: metav1.GroupVersionForDiscovery{
GroupVersion: apiService.Spec.Group + "/" + apiService.Spec.Version,
Version: apiService.Spec.Version,
},
}
}
discoveryGroup.Versions = append(discoveryGroup.Versions,
metav1.GroupVersionForDiscovery{
GroupVersion: apiService.Spec.Group + "/" + apiService.Spec.Version,
Version: apiService.Spec.Version,
},
)
}
return discoveryGroup
}
// apiGroupHandler serves the `/apis/<group>` endpoint.
type apiGroupHandler struct {
groupName string
lister listers.APIServiceLister
serviceLister v1listers.ServiceLister
endpointsLister v1listers.EndpointsLister
}
func (r *apiGroupHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
// don't handle URLs that aren't /apis/<groupName>
if req.URL.Path != "/apis/"+r.groupName && req.URL.Path != "/apis/"+r.groupName+"/" {
http.Error(w, "", http.StatusNotFound)
return
}
apiServices, err := r.lister.List(labels.Everything())
if statusErr, ok := err.(*apierrors.StatusError); ok && err != nil {
responsewriters.WriteRawJSON(int(statusErr.Status().Code), statusErr.Status(), w)
return
}
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
apiServicesForGroup := []*apiregistrationapi.APIService{}
for _, apiService := range apiServices {
if apiService.Spec.Group == r.groupName {
apiServicesForGroup = append(apiServicesForGroup, apiService)
}
}
if len(apiServicesForGroup) == 0 {
http.Error(w, "", http.StatusNotFound)
return
}
discoveryGroup := convertToDiscoveryAPIGroup(apiServicesForGroup, r.serviceLister, r.endpointsLister)
if discoveryGroup == nil {
http.Error(w, "", http.StatusNotFound)
return
}
json, err := runtime.Encode(api.Codecs.LegacyCodec(), discoveryGroup)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
if _, err := w.Write(json); err != nil {
panic(err)
}
}

View file

@ -0,0 +1,475 @@
/*
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 apiserver
import (
"io/ioutil"
"net/http"
"net/http/httptest"
"net/http/httputil"
"testing"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/diff"
"k8s.io/kubernetes/pkg/api"
corev1 "k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/client/cache"
v1listers "k8s.io/kubernetes/pkg/client/listers/core/v1"
"k8s.io/kubernetes/cmd/kube-aggregator/pkg/apis/apiregistration"
listers "k8s.io/kubernetes/cmd/kube-aggregator/pkg/client/listers/apiregistration/internalversion"
)
type delegationHTTPHandler struct {
called bool
}
func (d *delegationHTTPHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
d.called = true
w.WriteHeader(http.StatusOK)
}
func TestAPIsDelegation(t *testing.T) {
indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
delegate := &delegationHTTPHandler{}
handler := &apisHandler{
lister: listers.NewAPIServiceLister(indexer),
delegate: delegate,
}
server := httptest.NewServer(handler)
defer server.Close()
pathToDelegation := map[string]bool{
"/": true,
"/apis": false,
"/apis/": false,
"/apis/" + apiregistration.GroupName: true,
"/apis/" + apiregistration.GroupName + "/": true,
"/apis/" + apiregistration.GroupName + "/anything": true,
"/apis/" + apiregistration.GroupName + "/anything/again": true,
"/apis/something": true,
"/apis/something/nested": true,
"/apis/something/nested/deeper": true,
"/api": true,
"/api/v1": true,
"/version": true,
}
for path, expectedDelegation := range pathToDelegation {
delegate.called = false
resp, err := http.Get(server.URL + path)
if err != nil {
t.Errorf("%s: %v", path, err)
continue
}
if resp.StatusCode != http.StatusOK {
httputil.DumpResponse(resp, true)
t.Errorf("%s: %v", path, err)
continue
}
if e, a := expectedDelegation, delegate.called; e != a {
t.Errorf("%s: expected %v, got %v", path, e, a)
continue
}
}
}
func TestAPIs(t *testing.T) {
tests := []struct {
name string
apiservices []*apiregistration.APIService
expected *metav1.APIGroupList
}{
{
name: "empty",
apiservices: []*apiregistration.APIService{},
expected: &metav1.APIGroupList{
TypeMeta: metav1.TypeMeta{Kind: "APIGroupList", APIVersion: "v1"},
Groups: []metav1.APIGroup{
discoveryGroup,
},
},
},
{
name: "simple add",
apiservices: []*apiregistration.APIService{
{
ObjectMeta: api.ObjectMeta{Name: "v1.foo"},
Spec: apiregistration.APIServiceSpec{
Service: apiregistration.ServiceReference{
Namespace: "ns",
Name: "api",
},
Group: "foo",
Version: "v1",
Priority: 10,
},
},
{
ObjectMeta: api.ObjectMeta{Name: "v1.bar"},
Spec: apiregistration.APIServiceSpec{
Service: apiregistration.ServiceReference{
Namespace: "ns",
Name: "api",
},
Group: "bar",
Version: "v1",
Priority: 11,
},
},
},
expected: &metav1.APIGroupList{
TypeMeta: metav1.TypeMeta{Kind: "APIGroupList", APIVersion: "v1"},
Groups: []metav1.APIGroup{
discoveryGroup,
{
Name: "foo",
Versions: []metav1.GroupVersionForDiscovery{
{
GroupVersion: "foo/v1",
Version: "v1",
},
},
PreferredVersion: metav1.GroupVersionForDiscovery{
GroupVersion: "foo/v1",
Version: "v1",
},
},
{
Name: "bar",
Versions: []metav1.GroupVersionForDiscovery{
{
GroupVersion: "bar/v1",
Version: "v1",
},
},
PreferredVersion: metav1.GroupVersionForDiscovery{
GroupVersion: "bar/v1",
Version: "v1",
},
},
},
},
},
{
name: "sorting",
apiservices: []*apiregistration.APIService{
{
ObjectMeta: api.ObjectMeta{Name: "v1.foo"},
Spec: apiregistration.APIServiceSpec{
Service: apiregistration.ServiceReference{
Namespace: "ns",
Name: "api",
},
Group: "foo",
Version: "v1",
Priority: 20,
},
},
{
ObjectMeta: api.ObjectMeta{Name: "v2.bar"},
Spec: apiregistration.APIServiceSpec{
Service: apiregistration.ServiceReference{
Namespace: "ns",
Name: "api",
},
Group: "bar",
Version: "v2",
Priority: 11,
},
},
{
ObjectMeta: api.ObjectMeta{Name: "v2.foo"},
Spec: apiregistration.APIServiceSpec{
Service: apiregistration.ServiceReference{
Namespace: "ns",
Name: "api",
},
Group: "foo",
Version: "v2",
Priority: 1,
},
},
{
ObjectMeta: api.ObjectMeta{Name: "v1.bar"},
Spec: apiregistration.APIServiceSpec{
Service: apiregistration.ServiceReference{
Namespace: "ns",
Name: "api",
},
Group: "bar",
Version: "v1",
Priority: 11,
},
},
},
expected: &metav1.APIGroupList{
TypeMeta: metav1.TypeMeta{Kind: "APIGroupList", APIVersion: "v1"},
Groups: []metav1.APIGroup{
discoveryGroup,
{
Name: "foo",
Versions: []metav1.GroupVersionForDiscovery{
{
GroupVersion: "foo/v2",
Version: "v2",
},
{
GroupVersion: "foo/v1",
Version: "v1",
},
},
PreferredVersion: metav1.GroupVersionForDiscovery{
GroupVersion: "foo/v2",
Version: "v2",
},
},
{
Name: "bar",
Versions: []metav1.GroupVersionForDiscovery{
{
GroupVersion: "bar/v1",
Version: "v1",
},
{
GroupVersion: "bar/v2",
Version: "v2",
},
},
PreferredVersion: metav1.GroupVersionForDiscovery{
GroupVersion: "bar/v1",
Version: "v1",
},
},
},
},
},
}
for _, tc := range tests {
indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
serviceIndexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
endpointsIndexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
delegate := &delegationHTTPHandler{}
handler := &apisHandler{
serviceLister: v1listers.NewServiceLister(serviceIndexer),
endpointsLister: v1listers.NewEndpointsLister(endpointsIndexer),
lister: listers.NewAPIServiceLister(indexer),
delegate: delegate,
}
for _, o := range tc.apiservices {
indexer.Add(o)
}
serviceIndexer.Add(&corev1.Service{ObjectMeta: corev1.ObjectMeta{Namespace: "ns", Name: "api"}})
endpointsIndexer.Add(&corev1.Endpoints{
ObjectMeta: corev1.ObjectMeta{Namespace: "ns", Name: "api"},
Subsets: []corev1.EndpointSubset{
{Addresses: []corev1.EndpointAddress{{}}},
},
},
)
server := httptest.NewServer(handler)
defer server.Close()
resp, err := http.Get(server.URL + "/apis")
if err != nil {
t.Errorf("%s: %v", tc.name, err)
continue
}
bytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
t.Errorf("%s: %v", tc.name, err)
continue
}
actual := &metav1.APIGroupList{}
if err := runtime.DecodeInto(api.Codecs.UniversalDecoder(), bytes, actual); err != nil {
t.Errorf("%s: %v", tc.name, err)
continue
}
if !api.Semantic.DeepEqual(tc.expected, actual) {
t.Errorf("%s: %v", tc.name, diff.ObjectDiff(tc.expected, actual))
continue
}
}
}
func TestAPIGroupMissing(t *testing.T) {
indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
handler := &apiGroupHandler{
lister: listers.NewAPIServiceLister(indexer),
groupName: "foo",
}
server := httptest.NewServer(handler)
defer server.Close()
resp, err := http.Get(server.URL + "/apis/groupName/foo")
if err != nil {
t.Fatal(err)
}
if resp.StatusCode != http.StatusNotFound {
t.Fatalf("expected %v, got %v", resp.StatusCode, http.StatusNotFound)
}
// foo still has no api services for it (like it was deleted), it should 404
resp, err = http.Get(server.URL + "/apis/groupName/")
if err != nil {
t.Fatal(err)
}
if resp.StatusCode != http.StatusNotFound {
t.Fatalf("expected %v, got %v", resp.StatusCode, http.StatusNotFound)
}
}
func TestAPIGroup(t *testing.T) {
tests := []struct {
name string
group string
apiservices []*apiregistration.APIService
expected *metav1.APIGroup
}{
{
name: "sorting",
group: "foo",
apiservices: []*apiregistration.APIService{
{
ObjectMeta: api.ObjectMeta{Name: "v1.foo"},
Spec: apiregistration.APIServiceSpec{
Service: apiregistration.ServiceReference{
Namespace: "ns",
Name: "api",
},
Group: "foo",
Version: "v1",
Priority: 20,
},
},
{
ObjectMeta: api.ObjectMeta{Name: "v2.bar"},
Spec: apiregistration.APIServiceSpec{
Service: apiregistration.ServiceReference{
Namespace: "ns",
Name: "api",
},
Group: "bar",
Version: "v2",
Priority: 11,
},
},
{
ObjectMeta: api.ObjectMeta{Name: "v2.foo"},
Spec: apiregistration.APIServiceSpec{
Service: apiregistration.ServiceReference{
Namespace: "ns",
Name: "api",
},
Group: "foo",
Version: "v2",
Priority: 1,
},
},
{
ObjectMeta: api.ObjectMeta{Name: "v1.bar"},
Spec: apiregistration.APIServiceSpec{
Service: apiregistration.ServiceReference{
Namespace: "ns",
Name: "api",
},
Group: "bar",
Version: "v1",
Priority: 11,
},
},
},
expected: &metav1.APIGroup{
TypeMeta: metav1.TypeMeta{Kind: "APIGroup", APIVersion: "v1"},
Name: "foo",
Versions: []metav1.GroupVersionForDiscovery{
{
GroupVersion: "foo/v2",
Version: "v2",
},
{
GroupVersion: "foo/v1",
Version: "v1",
},
},
PreferredVersion: metav1.GroupVersionForDiscovery{
GroupVersion: "foo/v2",
Version: "v2",
},
},
},
}
for _, tc := range tests {
indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
serviceIndexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
endpointsIndexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
handler := &apiGroupHandler{
lister: listers.NewAPIServiceLister(indexer),
serviceLister: v1listers.NewServiceLister(serviceIndexer),
endpointsLister: v1listers.NewEndpointsLister(endpointsIndexer),
groupName: "foo",
}
for _, o := range tc.apiservices {
indexer.Add(o)
}
serviceIndexer.Add(&corev1.Service{ObjectMeta: corev1.ObjectMeta{Namespace: "ns", Name: "api"}})
endpointsIndexer.Add(&corev1.Endpoints{
ObjectMeta: corev1.ObjectMeta{Namespace: "ns", Name: "api"},
Subsets: []corev1.EndpointSubset{
{Addresses: []corev1.EndpointAddress{{}}},
},
},
)
server := httptest.NewServer(handler)
defer server.Close()
resp, err := http.Get(server.URL + "/apis/" + tc.group)
if err != nil {
t.Errorf("%s: %v", tc.name, err)
continue
}
if resp.StatusCode != http.StatusOK {
response, _ := httputil.DumpResponse(resp, true)
t.Errorf("%s: %v", tc.name, string(response))
continue
}
bytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
t.Errorf("%s: %v", tc.name, err)
continue
}
actual := &metav1.APIGroup{}
if err := runtime.DecodeInto(api.Codecs.UniversalDecoder(), bytes, actual); err != nil {
t.Errorf("%s: %v", tc.name, err)
continue
}
if !api.Semantic.DeepEqual(tc.expected, actual) {
t.Errorf("%s: %v", tc.name, diff.ObjectDiff(tc.expected, actual))
continue
}
}
}

View file

@ -0,0 +1,210 @@
/*
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 apiserver
import (
"net/http"
"net/url"
"sync"
"k8s.io/apimachinery/pkg/runtime"
genericapirequest "k8s.io/apiserver/pkg/request"
"k8s.io/kubernetes/pkg/client/restclient"
"k8s.io/kubernetes/pkg/client/transport"
"k8s.io/kubernetes/pkg/genericapiserver/api/handlers/responsewriters"
genericrest "k8s.io/kubernetes/pkg/registry/generic/rest"
"k8s.io/kubernetes/pkg/util/httpstream/spdy"
apiregistrationapi "k8s.io/kubernetes/cmd/kube-aggregator/pkg/apis/apiregistration"
)
// proxyHandler provides a http.Handler which will proxy traffic to locations
// specified by items implementing Redirector.
type proxyHandler struct {
contextMapper genericapirequest.RequestContextMapper
// proxyClientCert/Key are the client cert used to identify this proxy. Backing APIServices use
// this to confirm the proxy's identity
proxyClientCert []byte
proxyClientKey []byte
// lock protects us for updates.
lock sync.RWMutex
// restConfig holds the information for building a roundtripper
restConfig *restclient.Config
// transportBuildingError is an error produced while building the transport. If this
// is non-nil, it will be reported to clients.
transportBuildingError error
// proxyRoundTripper is the re-useable portion of the transport. It does not vary with any request.
proxyRoundTripper http.RoundTripper
// destinationHost is the hostname of the backing API server
destinationHost string
}
func (r *proxyHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
proxyRoundTripper, err := r.getRoundTripper()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
if proxyRoundTripper == nil {
http.Error(w, "", http.StatusNotFound)
return
}
ctx, ok := r.contextMapper.Get(req)
if !ok {
http.Error(w, "missing context", http.StatusInternalServerError)
return
}
user, ok := genericapirequest.UserFrom(ctx)
if !ok {
http.Error(w, "missing user", http.StatusInternalServerError)
return
}
// write a new location based on the existing request pointed at the target service
location := &url.URL{}
location.Scheme = "https"
location.Host = r.getDestinationHost()
location.Path = req.URL.Path
location.RawQuery = req.URL.Query().Encode()
// make a new request object with the updated location and the body we already have
newReq, err := http.NewRequest(req.Method, location.String(), req.Body)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
mergeHeader(newReq.Header, req.Header)
newReq.ContentLength = req.ContentLength
// Copy the TransferEncoding is for future-proofing. Currently Go only supports "chunked" and
// it can determine the TransferEncoding based on ContentLength and the Body.
newReq.TransferEncoding = req.TransferEncoding
upgrade := false
// we need to wrap the roundtripper in another roundtripper which will apply the front proxy headers
proxyRoundTripper, upgrade, err = r.maybeWrapForConnectionUpgrades(proxyRoundTripper, req)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
proxyRoundTripper = transport.NewAuthProxyRoundTripper(user.GetName(), user.GetGroups(), user.GetExtra(), proxyRoundTripper)
// if we are upgrading, then the upgrade path tries to use this request with the TLS config we provide, but it does
// NOT use the roundtripper. Its a direct call that bypasses the round tripper. This means that we have to
// attach the "correct" user headers to the request ahead of time. After the initial upgrade, we'll be back
// at the roundtripper flow, so we only have to muck with this request, but we do have to do it.
if upgrade {
transport.SetAuthProxyHeaders(newReq, user.GetName(), user.GetGroups(), user.GetExtra())
}
handler := genericrest.NewUpgradeAwareProxyHandler(location, proxyRoundTripper, true, upgrade, &responder{w: w})
handler.ServeHTTP(w, newReq)
}
// maybeWrapForConnectionUpgrades wraps the roundtripper for upgrades. The bool indicates if it was wrapped
func (r *proxyHandler) maybeWrapForConnectionUpgrades(rt http.RoundTripper, req *http.Request) (http.RoundTripper, bool, error) {
connectionHeader := req.Header.Get("Connection")
if len(connectionHeader) == 0 {
return rt, false, nil
}
cfg := r.getRESTConfig()
tlsConfig, err := restclient.TLSConfigFor(cfg)
if err != nil {
return nil, true, err
}
upgradeRoundTripper := spdy.NewRoundTripper(tlsConfig)
wrappedRT, err := restclient.HTTPWrappersForConfig(cfg, upgradeRoundTripper)
if err != nil {
return nil, true, err
}
return wrappedRT, true, nil
}
func mergeHeader(dst, src http.Header) {
for k, vv := range src {
for _, v := range vv {
dst.Add(k, v)
}
}
}
// responder implements rest.Responder for assisting a connector in writing objects or errors.
type responder struct {
w http.ResponseWriter
}
// TODO this should properly handle content type negotiation
// if the caller asked for protobuf and you write JSON bad things happen.
func (r *responder) Object(statusCode int, obj runtime.Object) {
responsewriters.WriteRawJSON(statusCode, obj, r.w)
}
func (r *responder) Error(err error) {
http.Error(r.w, err.Error(), http.StatusInternalServerError)
}
// these methods provide locked access to fields
func (r *proxyHandler) updateAPIService(apiService *apiregistrationapi.APIService) {
r.lock.Lock()
defer r.lock.Unlock()
r.transportBuildingError = nil
r.proxyRoundTripper = nil
r.destinationHost = apiService.Spec.Service.Name + "." + apiService.Spec.Service.Namespace + ".svc"
r.restConfig = &restclient.Config{
Insecure: apiService.Spec.InsecureSkipTLSVerify,
TLSClientConfig: restclient.TLSClientConfig{
CertData: r.proxyClientCert,
KeyData: r.proxyClientKey,
CAData: apiService.Spec.CABundle,
},
}
r.proxyRoundTripper, r.transportBuildingError = restclient.TransportFor(r.restConfig)
}
func (r *proxyHandler) removeAPIService() {
r.lock.Lock()
defer r.lock.Unlock()
r.transportBuildingError = nil
r.proxyRoundTripper = nil
}
func (r *proxyHandler) getRoundTripper() (http.RoundTripper, error) {
r.lock.RLock()
defer r.lock.RUnlock()
return r.proxyRoundTripper, r.transportBuildingError
}
func (r *proxyHandler) getDestinationHost() string {
r.lock.RLock()
defer r.lock.RUnlock()
return r.destinationHost
}
func (r *proxyHandler) getRESTConfig() *restclient.Config {
r.lock.RLock()
defer r.lock.RUnlock()
return r.restConfig
}

View file

@ -0,0 +1,198 @@
/*
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 apiserver
import (
"io/ioutil"
"net/http"
"net/http/httptest"
"net/http/httputil"
"reflect"
"strings"
"testing"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apiserver/pkg/authentication/user"
genericapirequest "k8s.io/apiserver/pkg/request"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/cmd/kube-aggregator/pkg/apis/apiregistration"
)
type targetHTTPHandler struct {
called bool
headers map[string][]string
path string
}
func (d *targetHTTPHandler) Reset() {
d.path = ""
d.called = false
d.headers = nil
}
func (d *targetHTTPHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
d.path = r.URL.Path
d.called = true
d.headers = r.Header
w.WriteHeader(http.StatusOK)
}
type fakeRequestContextMapper struct {
user user.Info
}
func (m *fakeRequestContextMapper) Get(req *http.Request) (genericapirequest.Context, bool) {
ctx := genericapirequest.NewContext()
if m.user != nil {
ctx = genericapirequest.WithUser(ctx, m.user)
}
resolver := &genericapirequest.RequestInfoFactory{
APIPrefixes: sets.NewString("api", "apis"),
GrouplessAPIPrefixes: sets.NewString("api"),
}
info, err := resolver.NewRequestInfo(req)
if err == nil {
ctx = genericapirequest.WithRequestInfo(ctx, info)
}
return ctx, true
}
func (*fakeRequestContextMapper) Update(req *http.Request, context genericapirequest.Context) error {
return nil
}
func TestProxyHandler(t *testing.T) {
target := &targetHTTPHandler{}
targetServer := httptest.NewTLSServer(target)
defer targetServer.Close()
handler := &proxyHandler{}
server := httptest.NewServer(handler)
defer server.Close()
tests := map[string]struct {
user user.Info
path string
apiService *apiregistration.APIService
expectedStatusCode int
expectedBody string
expectedCalled bool
expectedHeaders map[string][]string
}{
"no target": {
expectedStatusCode: http.StatusNotFound,
},
"no user": {
apiService: &apiregistration.APIService{
ObjectMeta: api.ObjectMeta{Name: "v1.foo"},
Spec: apiregistration.APIServiceSpec{
Group: "foo",
Version: "v1",
},
},
expectedStatusCode: http.StatusInternalServerError,
expectedBody: "missing user",
},
"proxy with user": {
user: &user.DefaultInfo{
Name: "username",
Groups: []string{"one", "two"},
},
path: "/request/path",
apiService: &apiregistration.APIService{
ObjectMeta: api.ObjectMeta{Name: "v1.foo"},
Spec: apiregistration.APIServiceSpec{
Group: "foo",
Version: "v1",
InsecureSkipTLSVerify: true,
},
},
expectedStatusCode: http.StatusOK,
expectedCalled: true,
expectedHeaders: map[string][]string{
"X-Forwarded-Proto": {"https"},
"X-Forwarded-Uri": {"/request/path"},
"X-Remote-User": {"username"},
"User-Agent": {"Go-http-client/1.1"},
"Accept-Encoding": {"gzip"},
"X-Remote-Group": {"one", "two"},
},
},
"fail on bad serving cert": {
user: &user.DefaultInfo{
Name: "username",
Groups: []string{"one", "two"},
},
path: "/request/path",
apiService: &apiregistration.APIService{
ObjectMeta: api.ObjectMeta{Name: "v1.foo"},
Spec: apiregistration.APIServiceSpec{
Group: "foo",
Version: "v1",
},
},
expectedStatusCode: http.StatusServiceUnavailable,
},
}
for name, tc := range tests {
target.Reset()
handler.contextMapper = &fakeRequestContextMapper{user: tc.user}
handler.removeAPIService()
if tc.apiService != nil {
handler.updateAPIService(tc.apiService)
handler.destinationHost = targetServer.Listener.Addr().String()
}
resp, err := http.Get(server.URL + tc.path)
if err != nil {
t.Errorf("%s: %v", name, err)
continue
}
if e, a := tc.expectedStatusCode, resp.StatusCode; e != a {
body, _ := httputil.DumpResponse(resp, true)
t.Logf("%s: %v", name, string(body))
t.Errorf("%s: expected %v, got %v", name, e, a)
continue
}
bytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
t.Errorf("%s: %v", name, err)
continue
}
if !strings.Contains(string(bytes), tc.expectedBody) {
t.Errorf("%s: expected %q, got %q", name, tc.expectedBody, string(bytes))
continue
}
if e, a := tc.expectedCalled, target.called; e != a {
t.Errorf("%s: expected %v, got %v", name, e, a)
continue
}
// this varies every test
delete(target.headers, "X-Forwarded-Host")
if e, a := tc.expectedHeaders, target.headers; !reflect.DeepEqual(e, a) {
t.Errorf("%s: expected %v, got %v", name, e, a)
continue
}
}
}

View file

@ -0,0 +1,42 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"clientset.go",
"doc.go",
],
tags = ["automanaged"],
deps = [
"//cmd/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1alpha1:go_default_library",
"//pkg/client/restclient:go_default_library",
"//pkg/client/typed/discovery:go_default_library",
"//pkg/util/flowcontrol:go_default_library",
"//plugin/pkg/client/auth:go_default_library",
"//vendor:github.com/golang/glog",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//cmd/kube-aggregator/pkg/client/clientset_generated/clientset/fake:all-srcs",
"//cmd/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1alpha1:all-srcs",
],
tags = ["automanaged"],
)

View file

@ -0,0 +1,105 @@
/*
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 clientset
import (
"github.com/golang/glog"
v1alpha1apiregistration "k8s.io/kubernetes/cmd/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1alpha1"
restclient "k8s.io/kubernetes/pkg/client/restclient"
discovery "k8s.io/kubernetes/pkg/client/typed/discovery"
"k8s.io/kubernetes/pkg/util/flowcontrol"
_ "k8s.io/kubernetes/plugin/pkg/client/auth"
)
type Interface interface {
Discovery() discovery.DiscoveryInterface
ApiregistrationV1alpha1() v1alpha1apiregistration.ApiregistrationV1alpha1Interface
// Deprecated: please explicitly pick a version if possible.
Apiregistration() v1alpha1apiregistration.ApiregistrationV1alpha1Interface
}
// Clientset contains the clients for groups. Each group has exactly one
// version included in a Clientset.
type Clientset struct {
*discovery.DiscoveryClient
*v1alpha1apiregistration.ApiregistrationV1alpha1Client
}
// ApiregistrationV1alpha1 retrieves the ApiregistrationV1alpha1Client
func (c *Clientset) ApiregistrationV1alpha1() v1alpha1apiregistration.ApiregistrationV1alpha1Interface {
if c == nil {
return nil
}
return c.ApiregistrationV1alpha1Client
}
// Deprecated: Apiregistration retrieves the default version of ApiregistrationClient.
// Please explicitly pick a version.
func (c *Clientset) Apiregistration() v1alpha1apiregistration.ApiregistrationV1alpha1Interface {
if c == nil {
return nil
}
return c.ApiregistrationV1alpha1Client
}
// Discovery retrieves the DiscoveryClient
func (c *Clientset) Discovery() discovery.DiscoveryInterface {
if c == nil {
return nil
}
return c.DiscoveryClient
}
// NewForConfig creates a new Clientset for the given config.
func NewForConfig(c *restclient.Config) (*Clientset, error) {
configShallowCopy := *c
if configShallowCopy.RateLimiter == nil && configShallowCopy.QPS > 0 {
configShallowCopy.RateLimiter = flowcontrol.NewTokenBucketRateLimiter(configShallowCopy.QPS, configShallowCopy.Burst)
}
var cs Clientset
var err error
cs.ApiregistrationV1alpha1Client, err = v1alpha1apiregistration.NewForConfig(&configShallowCopy)
if err != nil {
return nil, err
}
cs.DiscoveryClient, err = discovery.NewDiscoveryClientForConfig(&configShallowCopy)
if err != nil {
glog.Errorf("failed to create the DiscoveryClient: %v", err)
return nil, err
}
return &cs, nil
}
// NewForConfigOrDie creates a new Clientset for the given config and
// panics if there is an error in the config.
func NewForConfigOrDie(c *restclient.Config) *Clientset {
var cs Clientset
cs.ApiregistrationV1alpha1Client = v1alpha1apiregistration.NewForConfigOrDie(c)
cs.DiscoveryClient = discovery.NewDiscoveryClientForConfigOrDie(c)
return &cs
}
// New creates a new Clientset for the given RESTClient.
func New(c restclient.Interface) *Clientset {
var cs Clientset
cs.ApiregistrationV1alpha1Client = v1alpha1apiregistration.New(c)
cs.DiscoveryClient = discovery.NewDiscoveryClient(c)
return &cs
}

View file

@ -0,0 +1,20 @@
/*
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.
*/
// This package is generated by client-gen with arguments: --clientset-name=clientset --clientset-path=k8s.io/kubernetes/cmd/kube-aggregator/pkg/client/clientset_generated --input=[apiregistration/v1alpha1] --input-base=k8s.io/kubernetes/cmd/kube-aggregator/pkg/apis
// This package has the automatically generated clientset.
package clientset

View file

@ -0,0 +1,41 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"clientset_generated.go",
"doc.go",
],
tags = ["automanaged"],
deps = [
"//cmd/kube-aggregator/pkg/client/clientset_generated/clientset:go_default_library",
"//cmd/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1alpha1:go_default_library",
"//cmd/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1alpha1/fake:go_default_library",
"//pkg/api:go_default_library",
"//pkg/client/testing/core:go_default_library",
"//pkg/client/typed/discovery:go_default_library",
"//pkg/client/typed/discovery/fake:go_default_library",
"//vendor:k8s.io/apimachinery/pkg/runtime",
"//vendor:k8s.io/apimachinery/pkg/watch",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
)

View file

@ -0,0 +1,72 @@
/*
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 fake
import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/watch"
clientset "k8s.io/kubernetes/cmd/kube-aggregator/pkg/client/clientset_generated/clientset"
v1alpha1apiregistration "k8s.io/kubernetes/cmd/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1alpha1"
fakev1alpha1apiregistration "k8s.io/kubernetes/cmd/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1alpha1/fake"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/client/testing/core"
"k8s.io/kubernetes/pkg/client/typed/discovery"
fakediscovery "k8s.io/kubernetes/pkg/client/typed/discovery/fake"
)
// NewSimpleClientset returns a clientset that will respond with the provided objects.
// It's backed by a very simple object tracker that processes creates, updates and deletions as-is,
// without applying any validations and/or defaults. It shouldn't be considered a replacement
// for a real clientset and is mostly useful in simple unit tests.
func NewSimpleClientset(objects ...runtime.Object) *Clientset {
o := core.NewObjectTracker(api.Scheme, api.Codecs.UniversalDecoder())
for _, obj := range objects {
if err := o.Add(obj); err != nil {
panic(err)
}
}
fakePtr := core.Fake{}
fakePtr.AddReactor("*", "*", core.ObjectReaction(o, api.Registry.RESTMapper()))
fakePtr.AddWatchReactor("*", core.DefaultWatchReactor(watch.NewFake(), nil))
return &Clientset{fakePtr}
}
// Clientset implements clientset.Interface. Meant to be embedded into a
// struct to get a default implementation. This makes faking out just the method
// you want to test easier.
type Clientset struct {
core.Fake
}
func (c *Clientset) Discovery() discovery.DiscoveryInterface {
return &fakediscovery.FakeDiscovery{Fake: &c.Fake}
}
var _ clientset.Interface = &Clientset{}
// ApiregistrationV1alpha1 retrieves the ApiregistrationV1alpha1Client
func (c *Clientset) ApiregistrationV1alpha1() v1alpha1apiregistration.ApiregistrationV1alpha1Interface {
return &fakev1alpha1apiregistration.FakeApiregistrationV1alpha1{Fake: &c.Fake}
}
// Apiregistration retrieves the ApiregistrationV1alpha1Client
func (c *Clientset) Apiregistration() v1alpha1apiregistration.ApiregistrationV1alpha1Interface {
return &fakev1alpha1apiregistration.FakeApiregistrationV1alpha1{Fake: &c.Fake}
}

View file

@ -0,0 +1,20 @@
/*
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.
*/
// This package is generated by client-gen with arguments: --clientset-name=clientset --clientset-path=k8s.io/kubernetes/cmd/kube-aggregator/pkg/client/clientset_generated --input=[apiregistration/v1alpha1] --input-base=k8s.io/kubernetes/cmd/kube-aggregator/pkg/apis
// This package has the automatically generated fake clientset.
package fake

View file

@ -0,0 +1,45 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"apiregistration_client.go",
"apiservice.go",
"doc.go",
"generated_expansion.go",
],
tags = ["automanaged"],
deps = [
"//cmd/kube-aggregator/pkg/apis/apiregistration/v1alpha1:go_default_library",
"//pkg/api:go_default_library",
"//pkg/api/v1:go_default_library",
"//pkg/client/restclient:go_default_library",
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
"//vendor:k8s.io/apimachinery/pkg/runtime/schema",
"//vendor:k8s.io/apimachinery/pkg/runtime/serializer",
"//vendor:k8s.io/apimachinery/pkg/watch",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//cmd/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1alpha1/fake:all-srcs",
],
tags = ["automanaged"],
)

View file

@ -0,0 +1,97 @@
/*
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 v1alpha1
import (
fmt "fmt"
schema "k8s.io/apimachinery/pkg/runtime/schema"
serializer "k8s.io/apimachinery/pkg/runtime/serializer"
api "k8s.io/kubernetes/pkg/api"
restclient "k8s.io/kubernetes/pkg/client/restclient"
)
type ApiregistrationV1alpha1Interface interface {
RESTClient() restclient.Interface
APIServicesGetter
}
// ApiregistrationV1alpha1Client is used to interact with features provided by the apiregistration.k8s.io group.
type ApiregistrationV1alpha1Client struct {
restClient restclient.Interface
}
func (c *ApiregistrationV1alpha1Client) APIServices() APIServiceInterface {
return newAPIServices(c)
}
// NewForConfig creates a new ApiregistrationV1alpha1Client for the given config.
func NewForConfig(c *restclient.Config) (*ApiregistrationV1alpha1Client, error) {
config := *c
if err := setConfigDefaults(&config); err != nil {
return nil, err
}
client, err := restclient.RESTClientFor(&config)
if err != nil {
return nil, err
}
return &ApiregistrationV1alpha1Client{client}, nil
}
// NewForConfigOrDie creates a new ApiregistrationV1alpha1Client for the given config and
// panics if there is an error in the config.
func NewForConfigOrDie(c *restclient.Config) *ApiregistrationV1alpha1Client {
client, err := NewForConfig(c)
if err != nil {
panic(err)
}
return client
}
// New creates a new ApiregistrationV1alpha1Client for the given RESTClient.
func New(c restclient.Interface) *ApiregistrationV1alpha1Client {
return &ApiregistrationV1alpha1Client{c}
}
func setConfigDefaults(config *restclient.Config) error {
gv, err := schema.ParseGroupVersion("apiregistration.k8s.io/v1alpha1")
if err != nil {
return err
}
// if apiregistration.k8s.io/v1alpha1 is not enabled, return an error
if !api.Registry.IsEnabledVersion(gv) {
return fmt.Errorf("apiregistration.k8s.io/v1alpha1 is not enabled")
}
config.APIPath = "/apis"
if config.UserAgent == "" {
config.UserAgent = restclient.DefaultKubernetesUserAgent()
}
copyGroupVersion := gv
config.GroupVersion = &copyGroupVersion
config.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: api.Codecs}
return nil
}
// RESTClient returns a RESTClient that is used to communicate
// with API server by this client implementation.
func (c *ApiregistrationV1alpha1Client) RESTClient() restclient.Interface {
if c == nil {
return nil
}
return c.restClient
}

View file

@ -0,0 +1,161 @@
/*
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 v1alpha1
import (
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
watch "k8s.io/apimachinery/pkg/watch"
v1alpha1 "k8s.io/kubernetes/cmd/kube-aggregator/pkg/apis/apiregistration/v1alpha1"
api "k8s.io/kubernetes/pkg/api"
v1 "k8s.io/kubernetes/pkg/api/v1"
restclient "k8s.io/kubernetes/pkg/client/restclient"
)
// APIServicesGetter has a method to return a APIServiceInterface.
// A group's client should implement this interface.
type APIServicesGetter interface {
APIServices() APIServiceInterface
}
// APIServiceInterface has methods to work with APIService resources.
type APIServiceInterface interface {
Create(*v1alpha1.APIService) (*v1alpha1.APIService, error)
Update(*v1alpha1.APIService) (*v1alpha1.APIService, error)
UpdateStatus(*v1alpha1.APIService) (*v1alpha1.APIService, error)
Delete(name string, options *v1.DeleteOptions) error
DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error
Get(name string, options meta_v1.GetOptions) (*v1alpha1.APIService, error)
List(opts v1.ListOptions) (*v1alpha1.APIServiceList, error)
Watch(opts v1.ListOptions) (watch.Interface, error)
Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *v1alpha1.APIService, err error)
APIServiceExpansion
}
// aPIServices implements APIServiceInterface
type aPIServices struct {
client restclient.Interface
}
// newAPIServices returns a APIServices
func newAPIServices(c *ApiregistrationV1alpha1Client) *aPIServices {
return &aPIServices{
client: c.RESTClient(),
}
}
// Create takes the representation of a aPIService and creates it. Returns the server's representation of the aPIService, and an error, if there is any.
func (c *aPIServices) Create(aPIService *v1alpha1.APIService) (result *v1alpha1.APIService, err error) {
result = &v1alpha1.APIService{}
err = c.client.Post().
Resource("apiservices").
Body(aPIService).
Do().
Into(result)
return
}
// Update takes the representation of a aPIService and updates it. Returns the server's representation of the aPIService, and an error, if there is any.
func (c *aPIServices) Update(aPIService *v1alpha1.APIService) (result *v1alpha1.APIService, err error) {
result = &v1alpha1.APIService{}
err = c.client.Put().
Resource("apiservices").
Name(aPIService.Name).
Body(aPIService).
Do().
Into(result)
return
}
// UpdateStatus was generated because the type contains a Status member.
// Add a +genclientstatus=false comment above the type to avoid generating UpdateStatus().
func (c *aPIServices) UpdateStatus(aPIService *v1alpha1.APIService) (result *v1alpha1.APIService, err error) {
result = &v1alpha1.APIService{}
err = c.client.Put().
Resource("apiservices").
Name(aPIService.Name).
SubResource("status").
Body(aPIService).
Do().
Into(result)
return
}
// Delete takes name of the aPIService and deletes it. Returns an error if one occurs.
func (c *aPIServices) Delete(name string, options *v1.DeleteOptions) error {
return c.client.Delete().
Resource("apiservices").
Name(name).
Body(options).
Do().
Error()
}
// DeleteCollection deletes a collection of objects.
func (c *aPIServices) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
return c.client.Delete().
Resource("apiservices").
VersionedParams(&listOptions, api.ParameterCodec).
Body(options).
Do().
Error()
}
// Get takes name of the aPIService, and returns the corresponding aPIService object, and an error if there is any.
func (c *aPIServices) Get(name string, options meta_v1.GetOptions) (result *v1alpha1.APIService, err error) {
result = &v1alpha1.APIService{}
err = c.client.Get().
Resource("apiservices").
Name(name).
VersionedParams(&options, api.ParameterCodec).
Do().
Into(result)
return
}
// List takes label and field selectors, and returns the list of APIServices that match those selectors.
func (c *aPIServices) List(opts v1.ListOptions) (result *v1alpha1.APIServiceList, err error) {
result = &v1alpha1.APIServiceList{}
err = c.client.Get().
Resource("apiservices").
VersionedParams(&opts, api.ParameterCodec).
Do().
Into(result)
return
}
// Watch returns a watch.Interface that watches the requested aPIServices.
func (c *aPIServices) Watch(opts v1.ListOptions) (watch.Interface, error) {
return c.client.Get().
Prefix("watch").
Resource("apiservices").
VersionedParams(&opts, api.ParameterCodec).
Watch()
}
// Patch applies the patch and returns the patched aPIService.
func (c *aPIServices) Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *v1alpha1.APIService, err error) {
result = &v1alpha1.APIService{}
err = c.client.Patch(pt).
Resource("apiservices").
SubResource(subresources...).
Name(name).
Body(data).
Do().
Into(result)
return
}

View file

@ -0,0 +1,20 @@
/*
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.
*/
// This package is generated by client-gen with arguments: --clientset-name=clientset --clientset-path=k8s.io/kubernetes/cmd/kube-aggregator/pkg/client/clientset_generated --input=[apiregistration/v1alpha1] --input-base=k8s.io/kubernetes/cmd/kube-aggregator/pkg/apis
// This package has the automatically generated typed clients.
package v1alpha1

View file

@ -0,0 +1,43 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"doc.go",
"fake_apiregistration_client.go",
"fake_apiservice.go",
],
tags = ["automanaged"],
deps = [
"//cmd/kube-aggregator/pkg/apis/apiregistration/v1alpha1:go_default_library",
"//cmd/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1alpha1:go_default_library",
"//pkg/api:go_default_library",
"//pkg/api/v1:go_default_library",
"//pkg/client/restclient:go_default_library",
"//pkg/client/testing/core:go_default_library",
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
"//vendor:k8s.io/apimachinery/pkg/labels",
"//vendor:k8s.io/apimachinery/pkg/runtime/schema",
"//vendor:k8s.io/apimachinery/pkg/watch",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
)

View file

@ -0,0 +1,20 @@
/*
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.
*/
// This package is generated by client-gen with arguments: --clientset-name=clientset --clientset-path=k8s.io/kubernetes/cmd/kube-aggregator/pkg/client/clientset_generated --input=[apiregistration/v1alpha1] --input-base=k8s.io/kubernetes/cmd/kube-aggregator/pkg/apis
// Package fake has the automatically generated clients.
package fake

View file

@ -0,0 +1,38 @@
/*
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 fake
import (
v1alpha1 "k8s.io/kubernetes/cmd/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1alpha1"
restclient "k8s.io/kubernetes/pkg/client/restclient"
core "k8s.io/kubernetes/pkg/client/testing/core"
)
type FakeApiregistrationV1alpha1 struct {
*core.Fake
}
func (c *FakeApiregistrationV1alpha1) APIServices() v1alpha1.APIServiceInterface {
return &FakeAPIServices{c}
}
// RESTClient returns a RESTClient that is used to communicate
// with API server by this client implementation.
func (c *FakeApiregistrationV1alpha1) RESTClient() restclient.Interface {
var ret *restclient.RESTClient
return ret
}

View file

@ -0,0 +1,120 @@
/*
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 fake
import (
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
labels "k8s.io/apimachinery/pkg/labels"
schema "k8s.io/apimachinery/pkg/runtime/schema"
watch "k8s.io/apimachinery/pkg/watch"
v1alpha1 "k8s.io/kubernetes/cmd/kube-aggregator/pkg/apis/apiregistration/v1alpha1"
api "k8s.io/kubernetes/pkg/api"
v1 "k8s.io/kubernetes/pkg/api/v1"
core "k8s.io/kubernetes/pkg/client/testing/core"
)
// FakeAPIServices implements APIServiceInterface
type FakeAPIServices struct {
Fake *FakeApiregistrationV1alpha1
}
var apiservicesResource = schema.GroupVersionResource{Group: "apiregistration.k8s.io", Version: "v1alpha1", Resource: "apiservices"}
func (c *FakeAPIServices) Create(aPIService *v1alpha1.APIService) (result *v1alpha1.APIService, err error) {
obj, err := c.Fake.
Invokes(core.NewRootCreateAction(apiservicesResource, aPIService), &v1alpha1.APIService{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha1.APIService), err
}
func (c *FakeAPIServices) Update(aPIService *v1alpha1.APIService) (result *v1alpha1.APIService, err error) {
obj, err := c.Fake.
Invokes(core.NewRootUpdateAction(apiservicesResource, aPIService), &v1alpha1.APIService{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha1.APIService), err
}
func (c *FakeAPIServices) UpdateStatus(aPIService *v1alpha1.APIService) (*v1alpha1.APIService, error) {
obj, err := c.Fake.
Invokes(core.NewRootUpdateSubresourceAction(apiservicesResource, "status", aPIService), &v1alpha1.APIService{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha1.APIService), err
}
func (c *FakeAPIServices) Delete(name string, options *v1.DeleteOptions) error {
_, err := c.Fake.
Invokes(core.NewRootDeleteAction(apiservicesResource, name), &v1alpha1.APIService{})
return err
}
func (c *FakeAPIServices) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
action := core.NewRootDeleteCollectionAction(apiservicesResource, listOptions)
_, err := c.Fake.Invokes(action, &v1alpha1.APIServiceList{})
return err
}
func (c *FakeAPIServices) Get(name string, options meta_v1.GetOptions) (result *v1alpha1.APIService, err error) {
obj, err := c.Fake.
Invokes(core.NewRootGetAction(apiservicesResource, name), &v1alpha1.APIService{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha1.APIService), err
}
func (c *FakeAPIServices) List(opts v1.ListOptions) (result *v1alpha1.APIServiceList, err error) {
obj, err := c.Fake.
Invokes(core.NewRootListAction(apiservicesResource, opts), &v1alpha1.APIServiceList{})
if obj == nil {
return nil, err
}
label, _, _ := core.ExtractFromListOptions(opts)
if label == nil {
label = labels.Everything()
}
list := &v1alpha1.APIServiceList{}
for _, item := range obj.(*v1alpha1.APIServiceList).Items {
if label.Matches(labels.Set(item.Labels)) {
list.Items = append(list.Items, item)
}
}
return list, err
}
// Watch returns a watch.Interface that watches the requested aPIServices.
func (c *FakeAPIServices) Watch(opts v1.ListOptions) (watch.Interface, error) {
return c.Fake.
InvokesWatch(core.NewRootWatchAction(apiservicesResource, opts))
}
// Patch applies the patch and returns the patched aPIService.
func (c *FakeAPIServices) Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *v1alpha1.APIService, err error) {
obj, err := c.Fake.
Invokes(core.NewRootPatchSubresourceAction(apiservicesResource, name, data, subresources...), &v1alpha1.APIService{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha1.APIService), err
}

View file

@ -0,0 +1,19 @@
/*
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 v1alpha1
type APIServiceExpansion interface{}

Some files were not shown because too many files have changed in this diff Show more