From 46e827a8a52c990ce4cbc2a1bb38428aa5fc3d2f Mon Sep 17 00:00:00 2001 From: juanvallejo Date: Tue, 17 Apr 2018 18:21:16 -0400 Subject: [PATCH] begin building a config flags struct --- pkg/kubectl/cmd/util/config_flags.go | 121 +++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 pkg/kubectl/cmd/util/config_flags.go diff --git a/pkg/kubectl/cmd/util/config_flags.go b/pkg/kubectl/cmd/util/config_flags.go new file mode 100644 index 00000000000..24c8077899d --- /dev/null +++ b/pkg/kubectl/cmd/util/config_flags.go @@ -0,0 +1,121 @@ +/* +Copyright 2018 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 util + +import ( + "net/http" + "os" + "path/filepath" + "time" + + "github.com/spf13/cobra" + + "k8s.io/client-go/discovery" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" + "k8s.io/client-go/util/homedir" + + "k8s.io/kubernetes/pkg/kubectl/util/transport" +) + +// ConfigFlags composes the set of values necessary +// for obtaining a REST client config +type ConfigFlags struct { + CacheDir *string + KubeConfig *string +} + +// ToRESTConfig returns a REST client configuration based on a provided +// path to a .kubeconfig file, loading rules, and config flag overrides. +// Expects the AddFlags method to have been called. +func (f *ConfigFlags) ToRESTConfig() (*rest.Config, error) { + loadingRules := clientcmd.NewDefaultClientConfigLoadingRules() + // use the standard defaults for this client command + // DEPRECATED: remove and replace with something more accurate + loadingRules.DefaultClientConfig = &clientcmd.DefaultClientConfig + + if f.KubeConfig != nil { + loadingRules.ExplicitPath = *f.KubeConfig + } + + overrides := &clientcmd.ConfigOverrides{ClusterDefaults: clientcmd.ClusterDefaults} + clientConfig := clientcmd.NewInteractiveDeferredLoadingClientConfig(loadingRules, overrides, os.Stdin) + + return clientConfig.ClientConfig() +} + +// ToDiscoveryClient returns a CachedDiscoveryInterface using a computed RESTConfig. +// Expects the AddFlags method to have been called. +func (f *ConfigFlags) ToDiscoveryClient() (discovery.CachedDiscoveryInterface, error) { + config, err := f.ToRESTConfig() + if err != nil { + return nil, err + } + + // The more groups you have, the more discovery requests you need to make. + // given 25 groups (our groups + a few custom resources) with one-ish version each, discovery needs to make 50 requests + // double it just so we don't end up here again for a while. This config is only used for discovery. + config.Burst = 100 + + cacheDir := "" + if f.CacheDir != nil { + cacheDir = *f.CacheDir + } + + if len(cacheDir) > 0 { + wt := config.WrapTransport + config.WrapTransport = func(rt http.RoundTripper) http.RoundTripper { + if wt != nil { + rt = wt(rt) + } + return transport.NewCacheRoundTripper(cacheDir, rt) + } + } + + discoveryClient, err := discovery.NewDiscoveryClientForConfig(config) + if err != nil { + return nil, err + } + cacheDir = computeDiscoverCacheDir(filepath.Join(homedir.HomeDir(), ".kube", "cache", "discovery"), config.Host) + return NewCachedDiscoveryClient(discoveryClient, cacheDir, time.Duration(10*time.Minute)), nil +} + +func (f *ConfigFlags) AddFlags(cmd *cobra.Command) { + flagNames := clientcmd.RecommendedConfigOverrideFlags("") + // short flagnames are disabled by default. These are here for compatibility with existing scripts + flagNames.ClusterOverrideFlags.APIServer.ShortName = "s" + + overrides := &clientcmd.ConfigOverrides{ClusterDefaults: clientcmd.ClusterDefaults} + clientcmd.BindOverrideFlags(overrides, cmd.Flags(), flagNames) + + if f.KubeConfig != nil { + cmd.Flags().StringVar(f.KubeConfig, "kubeconfig", *f.KubeConfig, "Path to the kubeconfig file to use for CLI requests.") + } + if f.CacheDir != nil { + cmd.Flags().StringVar(f.CacheDir, FlagHTTPCacheDir, *f.CacheDir, "Default HTTP cache directory") + } +} + +func NewConfigFlags() *ConfigFlags { + defaultCacheDir := filepath.Join(homedir.HomeDir(), ".kube", "http-cache") + kubeConfig := "" + + return &ConfigFlags{ + CacheDir: &defaultCacheDir, + KubeConfig: &kubeConfig, + } +}