diff --git a/pkg/client/cmd/clientcmd.go b/pkg/client/cmd/clientcmd.go index 2c3621a25a45..d7c81b018196 100644 --- a/pkg/client/cmd/clientcmd.go +++ b/pkg/client/cmd/clientcmd.go @@ -1,24 +1,229 @@ -package clientconfig +package cmd import ( - "k8s.io/kubernetes/pkg/api" + "fmt" + "io/ioutil" + "os" + "strings" + + "github.com/golang/glog" + "github.com/spf13/cobra" + "github.com/spf13/pflag" + + restclient "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" + kclientcmd "k8s.io/client-go/tools/clientcmd" + kclientcmdapi "k8s.io/client-go/tools/clientcmd/api" + + kclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" + + "github.com/openshift/origin/pkg/client/config" + "github.com/openshift/origin/pkg/cmd/flagtypes" + "github.com/openshift/origin/pkg/cmd/util" ) -func EnvVars(host string, caData []byte, insecure bool, bearerTokenFile string) []api.EnvVar { - envvars := []api.EnvVar{ - {Name: "KUBERNETES_MASTER", Value: host}, - {Name: "OPENSHIFT_MASTER", Value: host}, +const ConfigSyntax = " --master=" + +// Config contains all the necessary bits for client configuration +type Config struct { + // MasterAddr is the address the master can be reached on (host, host:port, or URL). + MasterAddr flagtypes.Addr + // KubernetesAddr is the address of the Kubernetes server (host, host:port, or URL). + // If omitted defaults to the master. + KubernetesAddr flagtypes.Addr + // CommonConfig is the shared base config for both the OpenShift config and Kubernetes config + CommonConfig restclient.Config + // Namespace is the namespace to act in + Namespace string + + // If set, allow kubeconfig file loading + FromFile bool + // If true, no environment is loaded (for testing, primarily) + SkipEnv bool + clientConfig clientcmd.ClientConfig +} + +// NewConfig returns a new configuration +func NewConfig() *Config { + return &Config{ + MasterAddr: flagtypes.Addr{Value: "localhost:8080", DefaultScheme: "http", DefaultPort: 8080, AllowPrefix: true}.Default(), + KubernetesAddr: flagtypes.Addr{Value: "localhost:8080", DefaultScheme: "http", DefaultPort: 8080}.Default(), + CommonConfig: restclient.Config{}, + } +} + +// Bind binds configuration values to the passed flagset +func (cfg *Config) Bind(flags *pflag.FlagSet) { + flags.Var(&cfg.MasterAddr, "master", "The address the master can be reached on (host, host:port, or URL).") + flags.Var(&cfg.KubernetesAddr, "kubernetes", "The address of the Kubernetes server (host, host:port, or URL). If omitted defaults to the master.") + + if cfg.FromFile { + cfg.clientConfig = DefaultClientConfig(flags) + } else { + BindClientConfigSecurityFlags(&cfg.CommonConfig, flags) + } +} + +// BindToFile is used when this config will not be bound to flags, but should load the config file +// from disk if available. +func (cfg *Config) BindToFile() *Config { + cfg.clientConfig = DefaultClientConfig(pflag.NewFlagSet("empty", pflag.ContinueOnError)) + return cfg +} + +// OpenShiftConfig returns the OpenShift configuration +func (cfg *Config) OpenShiftConfig() *restclient.Config { + err := cfg.bindEnv() + if err != nil { + glog.Error(err) + } + + osConfig := cfg.CommonConfig + if len(osConfig.Host) == 0 || cfg.MasterAddr.Provided { + osConfig.Host = cfg.MasterAddr.String() + } + + return &osConfig +} + +// Clients returns an OpenShift and a Kubernetes client from a given configuration +func (cfg *Config) Clients() (kclientset.Interface, error) { + cfg.bindEnv() + + kubeClientset, err := kclientset.NewForConfig(cfg.KubeConfig()) + if err != nil { + return nil, fmt.Errorf("Unable to configure Kubernetes client: %v", err) + } + + return kubeClientset, nil +} + +// BindClientConfigSecurityFlags adds flags for the supplied client config +func BindClientConfigSecurityFlags(config *restclient.Config, flags *pflag.FlagSet) { + flags.BoolVar(&config.Insecure, "insecure-skip-tls-verify", config.Insecure, "If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure.") + flags.StringVar(&config.CertFile, "client-certificate", config.CertFile, "Path to a client certificate file for TLS.") + flags.StringVar(&config.KeyFile, "client-key", config.KeyFile, "Path to a client key file for TLS.") + flags.StringVar(&config.CAFile, "certificate-authority", config.CAFile, "Path to a cert. file for the certificate authority") + flags.StringVar(&config.BearerToken, "token", config.BearerToken, "If present, the bearer token for this request.") +} + +// KubeConfig returns the Kubernetes configuration +func (cfg *Config) KubeConfig() *restclient.Config { + err := cfg.bindEnv() + if err != nil { + glog.Error(err) + } + + kaddr := cfg.KubernetesAddr + if !kaddr.Provided { + kaddr = cfg.MasterAddr + } + + kConfig := cfg.CommonConfig + kConfig.Host = kaddr.URL.String() + + return &kConfig +} + +func (cfg *Config) bindEnv() error { + // bypass loading from env + if cfg.SkipEnv { + return nil + } + var err error + + // callers may not use the config file if they have specified a master directly, for backwards + // compatibility with components that used to use env, switch to service account token, and have + // config defined in env. + _, masterSet := util.GetEnv("OPENSHIFT_MASTER") + specifiedMaster := masterSet || cfg.MasterAddr.Provided + + if cfg.clientConfig != nil && !specifiedMaster { + clientConfig, err := cfg.clientConfig.ClientConfig() + if err != nil { + return err + } + cfg.CommonConfig = *clientConfig + cfg.Namespace, _, err = cfg.clientConfig.Namespace() + if err != nil { + return err + } + + if !cfg.MasterAddr.Provided { + cfg.MasterAddr.Set(cfg.CommonConfig.Host) + } + if !cfg.KubernetesAddr.Provided { + cfg.KubernetesAddr.Set(cfg.CommonConfig.Host) + } + return nil + } + + // Legacy path - preserve env vars set on pods that previously were honored. + if value, ok := util.GetEnv("KUBERNETES_MASTER"); ok && !cfg.KubernetesAddr.Provided { + cfg.KubernetesAddr.Set(value) + } + if value, ok := util.GetEnv("OPENSHIFT_MASTER"); ok && !cfg.MasterAddr.Provided { + cfg.MasterAddr.Set(value) + } + if value, ok := util.GetEnv("BEARER_TOKEN"); ok && len(cfg.CommonConfig.BearerToken) == 0 { + cfg.CommonConfig.BearerToken = value + } + if value, ok := util.GetEnv("BEARER_TOKEN_FILE"); ok && len(cfg.CommonConfig.BearerToken) == 0 { + if tokenData, tokenErr := ioutil.ReadFile(value); tokenErr == nil { + cfg.CommonConfig.BearerToken = strings.TrimSpace(string(tokenData)) + if len(cfg.CommonConfig.BearerToken) == 0 { + err = fmt.Errorf("BEARER_TOKEN_FILE %q was empty", value) + } + } else { + err = fmt.Errorf("Error reading BEARER_TOKEN_FILE %q: %v", value, tokenErr) + } + } + + if value, ok := util.GetEnv("OPENSHIFT_CA_FILE"); ok && len(cfg.CommonConfig.CAFile) == 0 { + cfg.CommonConfig.CAFile = value + } else if value, ok := util.GetEnv("OPENSHIFT_CA_DATA"); ok && len(cfg.CommonConfig.CAData) == 0 { + cfg.CommonConfig.CAData = []byte(value) + } + + if value, ok := util.GetEnv("OPENSHIFT_CERT_FILE"); ok && len(cfg.CommonConfig.CertFile) == 0 { + cfg.CommonConfig.CertFile = value + } else if value, ok := util.GetEnv("OPENSHIFT_CERT_DATA"); ok && len(cfg.CommonConfig.CertData) == 0 { + cfg.CommonConfig.CertData = []byte(value) } - if len(bearerTokenFile) > 0 { - envvars = append(envvars, api.EnvVar{Name: "BEARER_TOKEN_FILE", Value: bearerTokenFile}) + if value, ok := util.GetEnv("OPENSHIFT_KEY_FILE"); ok && len(cfg.CommonConfig.KeyFile) == 0 { + cfg.CommonConfig.KeyFile = value + } else if value, ok := util.GetEnv("OPENSHIFT_KEY_DATA"); ok && len(cfg.CommonConfig.KeyData) == 0 { + cfg.CommonConfig.KeyData = []byte(value) } - if len(caData) > 0 { - envvars = append(envvars, api.EnvVar{Name: "OPENSHIFT_CA_DATA", Value: string(caData)}) - } else if insecure { - envvars = append(envvars, api.EnvVar{Name: "OPENSHIFT_INSECURE", Value: "true"}) + if value, ok := util.GetEnv("OPENSHIFT_INSECURE"); ok && len(value) != 0 { + cfg.CommonConfig.Insecure = value == "true" } - return envvars + return err +} + +func DefaultClientConfig(flags *pflag.FlagSet) kclientcmd.ClientConfig { + loadingRules := config.NewOpenShiftClientConfigLoadingRules() + flags.StringVar(&loadingRules.ExplicitPath, config.OpenShiftConfigFlagName, "", "Path to the config file to use for CLI requests.") + cobra.MarkFlagFilename(flags, config.OpenShiftConfigFlagName) + + // set our explicit defaults + defaultOverrides := &kclientcmd.ConfigOverrides{ClusterDefaults: kclientcmdapi.Cluster{Server: os.Getenv("KUBERNETES_MASTER")}} + loadingRules.DefaultClientConfig = kclientcmd.NewDefaultClientConfig(kclientcmdapi.Config{}, defaultOverrides) + + overrides := &kclientcmd.ConfigOverrides{ClusterDefaults: defaultOverrides.ClusterDefaults} + overrideFlags := kclientcmd.RecommendedConfigOverrideFlags("") + overrideFlags.ContextOverrideFlags.Namespace.ShortName = "n" + overrideFlags.AuthOverrideFlags.Username.LongName = "" + overrideFlags.AuthOverrideFlags.Password.LongName = "" + kclientcmd.BindOverrideFlags(overrides, flags, overrideFlags) + cobra.MarkFlagFilename(flags, overrideFlags.AuthOverrideFlags.ClientCertificate.LongName) + cobra.MarkFlagFilename(flags, overrideFlags.AuthOverrideFlags.ClientKey.LongName) + cobra.MarkFlagFilename(flags, overrideFlags.ClusterOverrideFlags.CertificateAuthority.LongName) + + clientConfig := kclientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, overrides) + + return clientConfig } diff --git a/pkg/client/config/loader.go b/pkg/client/config/loader.go new file mode 100644 index 000000000000..22779773fb66 --- /dev/null +++ b/pkg/client/config/loader.go @@ -0,0 +1,55 @@ +package config + +import ( + "os" + "path" + "path/filepath" + "runtime" + + "k8s.io/client-go/tools/clientcmd" + "k8s.io/client-go/util/homedir" +) + +const ( + OpenShiftConfigPathEnvVar = "KUBECONFIG" + OpenShiftConfigFlagName = "config" + OpenShiftConfigHomeDir = ".kube" + OpenShiftConfigHomeFileName = "config" + OpenShiftConfigHomeDirFileName = OpenShiftConfigHomeDir + "/" + OpenShiftConfigHomeFileName +) + +var RecommendedHomeFile = path.Join(homedir.HomeDir(), OpenShiftConfigHomeDirFileName) + +// currentMigrationRules returns a map that holds the history of recommended home directories used in previous versions. +// Any future changes to RecommendedHomeFile and related are expected to add a migration rule here, in order to make +// sure existing config files are migrated to their new locations properly. +func CurrentMigrationRules() map[string]string { + oldRecommendedHomeFile := path.Join(homedir.HomeDir(), ".kube/.config") + oldRecommendedWindowsHomeFile := path.Join(os.Getenv("HOME"), OpenShiftConfigHomeDirFileName) + + migrationRules := map[string]string{} + migrationRules[RecommendedHomeFile] = oldRecommendedHomeFile + if runtime.GOOS == "windows" { + migrationRules[RecommendedHomeFile] = oldRecommendedWindowsHomeFile + } + return migrationRules +} + +// NewOpenShiftClientConfigLoadingRules returns file priority loading rules for OpenShift. +// 1. --config value +// 2. if KUBECONFIG env var has a value, use it. Otherwise, ~/.kube/config file +func NewOpenShiftClientConfigLoadingRules() *clientcmd.ClientConfigLoadingRules { + chain := []string{} + + envVarFile := os.Getenv(OpenShiftConfigPathEnvVar) + if len(envVarFile) != 0 { + chain = append(chain, filepath.SplitList(envVarFile)...) + } else { + chain = append(chain, RecommendedHomeFile) + } + + return &clientcmd.ClientConfigLoadingRules{ + Precedence: chain, + MigrationRules: CurrentMigrationRules(), + } +} diff --git a/pkg/cmd/infra/router/f5.go b/pkg/cmd/infra/router/f5.go index 8a2b28a2a041..c9515cde5481 100644 --- a/pkg/cmd/infra/router/f5.go +++ b/pkg/cmd/infra/router/f5.go @@ -12,6 +12,7 @@ import ( "k8s.io/kubernetes/pkg/kubectl/cmd/templates" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" + clientcmd "github.com/openshift/origin/pkg/client/cmd" "github.com/openshift/origin/pkg/cmd/util" cmdversion "github.com/openshift/origin/pkg/cmd/version" "github.com/openshift/origin/pkg/oc/cli/util/clientcmd" diff --git a/pkg/cmd/infra/router/template.go b/pkg/cmd/infra/router/template.go index 5fa4cbd65290..43707d3984ad 100644 --- a/pkg/cmd/infra/router/template.go +++ b/pkg/cmd/infra/router/template.go @@ -27,6 +27,7 @@ import ( "k8s.io/kubernetes/pkg/kubectl/cmd/templates" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" + clientcmd "github.com/openshift/origin/pkg/client/cmd" "github.com/openshift/origin/pkg/cmd/server/crypto" "github.com/openshift/origin/pkg/cmd/util" cmdversion "github.com/openshift/origin/pkg/cmd/version" diff --git a/pkg/oc/admin/diagnostics/config.go b/pkg/oc/admin/diagnostics/config.go index de8020c955e4..94f890695477 100644 --- a/pkg/oc/admin/diagnostics/config.go +++ b/pkg/oc/admin/diagnostics/config.go @@ -5,9 +5,9 @@ import ( clientcmdapi "k8s.io/client-go/tools/clientcmd/api" + "github.com/openshift/origin/pkg/client/config" clientdiagnostics "github.com/openshift/origin/pkg/oc/admin/diagnostics/diagnostics/client" "github.com/openshift/origin/pkg/oc/admin/diagnostics/diagnostics/types" - "github.com/openshift/origin/pkg/oc/cli/config" ) // determine if we even have a client config diff --git a/pkg/oc/admin/diagnostics/diagnostics.go b/pkg/oc/admin/diagnostics/diagnostics.go index 96b030c3444f..815cd7ec1889 100644 --- a/pkg/oc/admin/diagnostics/diagnostics.go +++ b/pkg/oc/admin/diagnostics/diagnostics.go @@ -18,13 +18,13 @@ import ( "k8s.io/kubernetes/pkg/kubectl/cmd/templates" kcmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" + "github.com/openshift/origin/pkg/client/config" "github.com/openshift/origin/pkg/cmd/flagtypes" "github.com/openshift/origin/pkg/cmd/util/variable" "github.com/openshift/origin/pkg/oc/admin/diagnostics/diagnostics/log" netutil "github.com/openshift/origin/pkg/oc/admin/diagnostics/diagnostics/networkpod/util" "github.com/openshift/origin/pkg/oc/admin/diagnostics/diagnostics/types" "github.com/openshift/origin/pkg/oc/admin/diagnostics/options" - "github.com/openshift/origin/pkg/oc/cli/config" osclientcmd "github.com/openshift/origin/pkg/oc/cli/util/clientcmd" ) diff --git a/pkg/oc/admin/diagnostics/diagnostics/client/config_loading.go b/pkg/oc/admin/diagnostics/diagnostics/client/config_loading.go index 72a4185ae1f2..3ca1dcef5b13 100644 --- a/pkg/oc/admin/diagnostics/diagnostics/client/config_loading.go +++ b/pkg/oc/admin/diagnostics/diagnostics/client/config_loading.go @@ -8,9 +8,9 @@ import ( flag "github.com/spf13/pflag" "k8s.io/client-go/tools/clientcmd" + "github.com/openshift/origin/pkg/client/config" "github.com/openshift/origin/pkg/oc/admin/diagnostics/diagnostics/types" "github.com/openshift/origin/pkg/oc/admin/diagnostics/diagnostics/util" - "github.com/openshift/origin/pkg/oc/cli/config" ) // ConfigLoading is a little special in that it is run separately as a precondition diff --git a/pkg/oc/admin/diagnostics/diagnostics/network/setup.go b/pkg/oc/admin/diagnostics/diagnostics/network/setup.go index 6a48806b9ade..a99df4fa6273 100644 --- a/pkg/oc/admin/diagnostics/diagnostics/network/setup.go +++ b/pkg/oc/admin/diagnostics/diagnostics/network/setup.go @@ -16,11 +16,11 @@ import ( kclientcmd "k8s.io/client-go/tools/clientcmd" kapi "k8s.io/kubernetes/pkg/api" + "github.com/openshift/origin/pkg/client/config" "github.com/openshift/origin/pkg/network" networkapi "github.com/openshift/origin/pkg/network/apis/network" "github.com/openshift/origin/pkg/oc/admin/diagnostics/diagnostics/networkpod/util" diagutil "github.com/openshift/origin/pkg/oc/admin/diagnostics/diagnostics/util" - "github.com/openshift/origin/pkg/oc/cli/config" ) func (d *NetworkDiagnostic) TestSetup() error { diff --git a/pkg/oc/admin/diagnostics/diagnostics/pod/auth.go b/pkg/oc/admin/diagnostics/diagnostics/pod/auth.go index a5056281b054..baee222af4ff 100644 --- a/pkg/oc/admin/diagnostics/diagnostics/pod/auth.go +++ b/pkg/oc/admin/diagnostics/diagnostics/pod/auth.go @@ -15,6 +15,7 @@ import ( knet "k8s.io/apimachinery/pkg/util/net" restclient "k8s.io/client-go/rest" + clientcmd "github.com/openshift/origin/pkg/client/cmd" "github.com/openshift/origin/pkg/cmd/flagtypes" "github.com/openshift/origin/pkg/oc/admin/diagnostics/diagnostics/types" "github.com/openshift/origin/pkg/oc/cli/util/clientcmd" diff --git a/pkg/oc/bootstrap/docker/openshift/helper.go b/pkg/oc/bootstrap/docker/openshift/helper.go index a37077f7eab9..d109302f442c 100644 --- a/pkg/oc/bootstrap/docker/openshift/helper.go +++ b/pkg/oc/bootstrap/docker/openshift/helper.go @@ -20,6 +20,7 @@ import ( kapi "k8s.io/kubernetes/pkg/api" defaultsapi "github.com/openshift/origin/pkg/build/controller/build/defaults/api" + clientconfig "github.com/openshift/origin/pkg/client/config" "github.com/openshift/origin/pkg/cmd/server/admin" configapi "github.com/openshift/origin/pkg/cmd/server/api" _ "github.com/openshift/origin/pkg/cmd/server/api/install" @@ -31,7 +32,6 @@ import ( dockerexec "github.com/openshift/origin/pkg/oc/bootstrap/docker/exec" "github.com/openshift/origin/pkg/oc/bootstrap/docker/host" "github.com/openshift/origin/pkg/oc/bootstrap/docker/run" - cliconfig "github.com/openshift/origin/pkg/oc/cli/config" kclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" ) @@ -74,7 +74,7 @@ var ( DefaultPorts = append(BasePorts, DefaultDNSPort) PortsWithAlternateDNS = append(BasePorts, AlternateDNSPort) AllPorts = append(append(RouterPorts, DefaultPorts...), AlternateDNSPort) - SocatPidFile = filepath.Join(homedir.HomeDir(), cliconfig.OpenShiftConfigHomeDir, "socat-8443.pid") + SocatPidFile = filepath.Join(homedir.HomeDir(), clientconfig.OpenShiftConfigHomeDir, "socat-8443.pid") defaultCertHosts = []string{ "127.0.0.1", "172.30.0.1", diff --git a/pkg/oc/cli/cmd/wrappers.go b/pkg/oc/cli/cmd/wrappers.go index a03792f38398..0ca631d1dd3f 100644 --- a/pkg/oc/cli/cmd/wrappers.go +++ b/pkg/oc/cli/cmd/wrappers.go @@ -18,9 +18,9 @@ import ( "k8s.io/kubernetes/pkg/kubectl/cmd/templates" kcmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" + cmdconfig "github.com/openshift/origin/pkg/client/config" cmdutil "github.com/openshift/origin/pkg/cmd/util" "github.com/openshift/origin/pkg/oc/cli/cmd/create" - cmdconfig "github.com/openshift/origin/pkg/oc/cli/config" "github.com/openshift/origin/pkg/oc/cli/describe" "github.com/openshift/origin/pkg/oc/cli/util/clientcmd" ) diff --git a/pkg/oc/cli/config/loader.go b/pkg/oc/cli/config/loader.go index 0632ac213854..dded33da05a4 100644 --- a/pkg/oc/cli/config/loader.go +++ b/pkg/oc/cli/config/loader.go @@ -2,72 +2,46 @@ package config import ( "os" - "path" "path/filepath" - "runtime" "github.com/spf13/cobra" "k8s.io/client-go/tools/clientcmd" kclientcmd "k8s.io/client-go/tools/clientcmd" - "k8s.io/client-go/util/homedir" kcmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" -) -const ( - OpenShiftConfigPathEnvVar = "KUBECONFIG" - OpenShiftConfigFlagName = "config" - OpenShiftConfigHomeDir = ".kube" - OpenShiftConfigHomeFileName = "config" - OpenShiftConfigHomeDirFileName = OpenShiftConfigHomeDir + "/" + OpenShiftConfigHomeFileName + "github.com/openshift/origin/pkg/client/config" ) -var RecommendedHomeFile = path.Join(homedir.HomeDir(), OpenShiftConfigHomeDirFileName) - -// currentMigrationRules returns a map that holds the history of recommended home directories used in previous versions. -// Any future changes to RecommendedHomeFile and related are expected to add a migration rule here, in order to make -// sure existing config files are migrated to their new locations properly. -func currentMigrationRules() map[string]string { - oldRecommendedHomeFile := path.Join(homedir.HomeDir(), ".kube/.config") - oldRecommendedWindowsHomeFile := path.Join(os.Getenv("HOME"), OpenShiftConfigHomeDirFileName) - - migrationRules := map[string]string{} - migrationRules[RecommendedHomeFile] = oldRecommendedHomeFile - if runtime.GOOS == "windows" { - migrationRules[RecommendedHomeFile] = oldRecommendedWindowsHomeFile - } - return migrationRules -} - // NewOpenShiftClientConfigLoadingRules returns file priority loading rules for OpenShift. // 1. --config value // 2. if KUBECONFIG env var has a value, use it. Otherwise, ~/.kube/config file func NewOpenShiftClientConfigLoadingRules() *clientcmd.ClientConfigLoadingRules { chain := []string{} - envVarFile := os.Getenv(OpenShiftConfigPathEnvVar) + envVarFile := os.Getenv(config.OpenShiftConfigPathEnvVar) if len(envVarFile) != 0 { chain = append(chain, filepath.SplitList(envVarFile)...) } else { - chain = append(chain, RecommendedHomeFile) + chain = append(chain, config.RecommendedHomeFile) } return &clientcmd.ClientConfigLoadingRules{ Precedence: chain, - MigrationRules: currentMigrationRules(), + MigrationRules: config.CurrentMigrationRules(), } } func NewPathOptions(cmd *cobra.Command) *kclientcmd.PathOptions { - return NewPathOptionsWithConfig(kcmdutil.GetFlagString(cmd, OpenShiftConfigFlagName)) + return NewPathOptionsWithConfig(kcmdutil.GetFlagString(cmd, config.OpenShiftConfigFlagName)) } func NewPathOptionsWithConfig(configPath string) *kclientcmd.PathOptions { return &kclientcmd.PathOptions{ - GlobalFile: RecommendedHomeFile, + GlobalFile: config.RecommendedHomeFile, - EnvVar: OpenShiftConfigPathEnvVar, - ExplicitFileFlag: OpenShiftConfigFlagName, + EnvVar: config.OpenShiftConfigPathEnvVar, + ExplicitFileFlag: config.OpenShiftConfigFlagName, LoadingRules: &kclientcmd.ClientConfigLoadingRules{ ExplicitPath: configPath, diff --git a/pkg/oc/cli/util/clientcmd/factory_client_access.go b/pkg/oc/cli/util/clientcmd/factory_client_access.go index edf530053f94..56adbb549210 100644 --- a/pkg/oc/cli/util/clientcmd/factory_client_access.go +++ b/pkg/oc/cli/util/clientcmd/factory_client_access.go @@ -36,8 +36,8 @@ import ( deployapi "github.com/openshift/origin/pkg/apps/apis/apps" deploycmd "github.com/openshift/origin/pkg/apps/cmd" + osclientcmd "github.com/openshift/origin/pkg/client/cmd" imageclient "github.com/openshift/origin/pkg/image/generated/internalclientset" - "github.com/openshift/origin/pkg/oc/cli/config" "github.com/openshift/origin/pkg/oc/cli/describe" routegen "github.com/openshift/origin/pkg/route/generator" ) @@ -63,7 +63,7 @@ func NewClientAccessFactory(optionalClientConfig kclientcmd.ClientConfig) Client clientConfig := optionalClientConfig if optionalClientConfig == nil { // TODO: there should be two client configs, one for OpenShift, and one for Kubernetes - clientConfig = DefaultClientConfig(flags) + clientConfig = osclientcmd.DefaultClientConfig(flags) clientConfig = defaultingClientConfig{clientConfig} } factory := &ring0Factory{ @@ -115,30 +115,6 @@ func (f *discoveryFactory) DiscoveryClient() (discovery.CachedDiscoveryInterface return kcmdutil.NewCachedDiscoveryClient(newLegacyDiscoveryClient(kubeClient.Discovery().RESTClient()), cacheDir, time.Duration(10*time.Minute)), nil } -func DefaultClientConfig(flags *pflag.FlagSet) kclientcmd.ClientConfig { - loadingRules := config.NewOpenShiftClientConfigLoadingRules() - flags.StringVar(&loadingRules.ExplicitPath, config.OpenShiftConfigFlagName, "", "Path to the config file to use for CLI requests.") - cobra.MarkFlagFilename(flags, config.OpenShiftConfigFlagName) - - // set our explicit defaults - defaultOverrides := &kclientcmd.ConfigOverrides{ClusterDefaults: kclientcmdapi.Cluster{Server: os.Getenv("KUBERNETES_MASTER")}} - loadingRules.DefaultClientConfig = kclientcmd.NewDefaultClientConfig(kclientcmdapi.Config{}, defaultOverrides) - - overrides := &kclientcmd.ConfigOverrides{ClusterDefaults: defaultOverrides.ClusterDefaults} - overrideFlags := kclientcmd.RecommendedConfigOverrideFlags("") - overrideFlags.ContextOverrideFlags.Namespace.ShortName = "n" - overrideFlags.AuthOverrideFlags.Username.LongName = "" - overrideFlags.AuthOverrideFlags.Password.LongName = "" - kclientcmd.BindOverrideFlags(overrides, flags, overrideFlags) - cobra.MarkFlagFilename(flags, overrideFlags.AuthOverrideFlags.ClientCertificate.LongName) - cobra.MarkFlagFilename(flags, overrideFlags.AuthOverrideFlags.ClientKey.LongName) - cobra.MarkFlagFilename(flags, overrideFlags.ClusterOverrideFlags.CertificateAuthority.LongName) - - clientConfig := kclientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, overrides) - - return clientConfig -} - func (f *ring0Factory) OpenShiftClientConfig() kclientcmd.ClientConfig { return f.clientConfig } diff --git a/test/integration/login_test.go b/test/integration/login_test.go index e8d39036e422..4320f0ad64b2 100644 --- a/test/integration/login_test.go +++ b/test/integration/login_test.go @@ -10,11 +10,11 @@ import ( "k8s.io/client-go/tools/clientcmd" authorizationclient "github.com/openshift/origin/pkg/authorization/generated/internalclientset" + "github.com/openshift/origin/pkg/client/config" "github.com/openshift/origin/pkg/cmd/server/bootstrappolicy" newproject "github.com/openshift/origin/pkg/oc/admin/project" "github.com/openshift/origin/pkg/oc/cli/cmd" "github.com/openshift/origin/pkg/oc/cli/cmd/login" - "github.com/openshift/origin/pkg/oc/cli/config" projectclient "github.com/openshift/origin/pkg/project/generated/internalclientset" userclient "github.com/openshift/origin/pkg/user/generated/internalclientset/typed/user/internalversion" testutil "github.com/openshift/origin/test/util"