Skip to content

Commit 14a5503

Browse files
committed
move main client configuration to pkg/client/config
1 parent 41e9a84 commit 14a5503

File tree

14 files changed

+294
-81
lines changed

14 files changed

+294
-81
lines changed

pkg/client/cmd/clientcmd.go

+218-13
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,229 @@
1-
package clientconfig
1+
package cmd
22

33
import (
4-
"k8s.io/kubernetes/pkg/api"
4+
"fmt"
5+
"io/ioutil"
6+
"os"
7+
"strings"
8+
9+
"github.com/golang/glog"
10+
"github.com/spf13/cobra"
11+
"github.com/spf13/pflag"
12+
13+
restclient "k8s.io/client-go/rest"
14+
"k8s.io/client-go/tools/clientcmd"
15+
kclientcmd "k8s.io/client-go/tools/clientcmd"
16+
kclientcmdapi "k8s.io/client-go/tools/clientcmd/api"
17+
18+
kclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
19+
20+
"github.com/openshift/origin/pkg/client/config"
21+
"github.com/openshift/origin/pkg/cmd/flagtypes"
22+
"github.com/openshift/origin/pkg/cmd/util"
523
)
624

7-
func EnvVars(host string, caData []byte, insecure bool, bearerTokenFile string) []api.EnvVar {
8-
envvars := []api.EnvVar{
9-
{Name: "KUBERNETES_MASTER", Value: host},
10-
{Name: "OPENSHIFT_MASTER", Value: host},
25+
const ConfigSyntax = " --master=<addr>"
26+
27+
// Config contains all the necessary bits for client configuration
28+
type Config struct {
29+
// MasterAddr is the address the master can be reached on (host, host:port, or URL).
30+
MasterAddr flagtypes.Addr
31+
// KubernetesAddr is the address of the Kubernetes server (host, host:port, or URL).
32+
// If omitted defaults to the master.
33+
KubernetesAddr flagtypes.Addr
34+
// CommonConfig is the shared base config for both the OpenShift config and Kubernetes config
35+
CommonConfig restclient.Config
36+
// Namespace is the namespace to act in
37+
Namespace string
38+
39+
// If set, allow kubeconfig file loading
40+
FromFile bool
41+
// If true, no environment is loaded (for testing, primarily)
42+
SkipEnv bool
43+
clientConfig clientcmd.ClientConfig
44+
}
45+
46+
// NewConfig returns a new configuration
47+
func NewConfig() *Config {
48+
return &Config{
49+
MasterAddr: flagtypes.Addr{Value: "localhost:8080", DefaultScheme: "http", DefaultPort: 8080, AllowPrefix: true}.Default(),
50+
KubernetesAddr: flagtypes.Addr{Value: "localhost:8080", DefaultScheme: "http", DefaultPort: 8080}.Default(),
51+
CommonConfig: restclient.Config{},
52+
}
53+
}
54+
55+
// Bind binds configuration values to the passed flagset
56+
func (cfg *Config) Bind(flags *pflag.FlagSet) {
57+
flags.Var(&cfg.MasterAddr, "master", "The address the master can be reached on (host, host:port, or URL).")
58+
flags.Var(&cfg.KubernetesAddr, "kubernetes", "The address of the Kubernetes server (host, host:port, or URL). If omitted defaults to the master.")
59+
60+
if cfg.FromFile {
61+
cfg.clientConfig = DefaultClientConfig(flags)
62+
} else {
63+
BindClientConfigSecurityFlags(&cfg.CommonConfig, flags)
64+
}
65+
}
66+
67+
// BindToFile is used when this config will not be bound to flags, but should load the config file
68+
// from disk if available.
69+
func (cfg *Config) BindToFile() *Config {
70+
cfg.clientConfig = DefaultClientConfig(pflag.NewFlagSet("empty", pflag.ContinueOnError))
71+
return cfg
72+
}
73+
74+
// OpenShiftConfig returns the OpenShift configuration
75+
func (cfg *Config) OpenShiftConfig() *restclient.Config {
76+
err := cfg.bindEnv()
77+
if err != nil {
78+
glog.Error(err)
79+
}
80+
81+
osConfig := cfg.CommonConfig
82+
if len(osConfig.Host) == 0 || cfg.MasterAddr.Provided {
83+
osConfig.Host = cfg.MasterAddr.String()
84+
}
85+
86+
return &osConfig
87+
}
88+
89+
// Clients returns an OpenShift and a Kubernetes client from a given configuration
90+
func (cfg *Config) Clients() (kclientset.Interface, error) {
91+
cfg.bindEnv()
92+
93+
kubeClientset, err := kclientset.NewForConfig(cfg.KubeConfig())
94+
if err != nil {
95+
return nil, fmt.Errorf("Unable to configure Kubernetes client: %v", err)
96+
}
97+
98+
return kubeClientset, nil
99+
}
100+
101+
// BindClientConfigSecurityFlags adds flags for the supplied client config
102+
func BindClientConfigSecurityFlags(config *restclient.Config, flags *pflag.FlagSet) {
103+
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.")
104+
flags.StringVar(&config.CertFile, "client-certificate", config.CertFile, "Path to a client certificate file for TLS.")
105+
flags.StringVar(&config.KeyFile, "client-key", config.KeyFile, "Path to a client key file for TLS.")
106+
flags.StringVar(&config.CAFile, "certificate-authority", config.CAFile, "Path to a cert. file for the certificate authority")
107+
flags.StringVar(&config.BearerToken, "token", config.BearerToken, "If present, the bearer token for this request.")
108+
}
109+
110+
// KubeConfig returns the Kubernetes configuration
111+
func (cfg *Config) KubeConfig() *restclient.Config {
112+
err := cfg.bindEnv()
113+
if err != nil {
114+
glog.Error(err)
115+
}
116+
117+
kaddr := cfg.KubernetesAddr
118+
if !kaddr.Provided {
119+
kaddr = cfg.MasterAddr
120+
}
121+
122+
kConfig := cfg.CommonConfig
123+
kConfig.Host = kaddr.URL.String()
124+
125+
return &kConfig
126+
}
127+
128+
func (cfg *Config) bindEnv() error {
129+
// bypass loading from env
130+
if cfg.SkipEnv {
131+
return nil
132+
}
133+
var err error
134+
135+
// callers may not use the config file if they have specified a master directly, for backwards
136+
// compatibility with components that used to use env, switch to service account token, and have
137+
// config defined in env.
138+
_, masterSet := util.GetEnv("OPENSHIFT_MASTER")
139+
specifiedMaster := masterSet || cfg.MasterAddr.Provided
140+
141+
if cfg.clientConfig != nil && !specifiedMaster {
142+
clientConfig, err := cfg.clientConfig.ClientConfig()
143+
if err != nil {
144+
return err
145+
}
146+
cfg.CommonConfig = *clientConfig
147+
cfg.Namespace, _, err = cfg.clientConfig.Namespace()
148+
if err != nil {
149+
return err
150+
}
151+
152+
if !cfg.MasterAddr.Provided {
153+
cfg.MasterAddr.Set(cfg.CommonConfig.Host)
154+
}
155+
if !cfg.KubernetesAddr.Provided {
156+
cfg.KubernetesAddr.Set(cfg.CommonConfig.Host)
157+
}
158+
return nil
159+
}
160+
161+
// Legacy path - preserve env vars set on pods that previously were honored.
162+
if value, ok := util.GetEnv("KUBERNETES_MASTER"); ok && !cfg.KubernetesAddr.Provided {
163+
cfg.KubernetesAddr.Set(value)
164+
}
165+
if value, ok := util.GetEnv("OPENSHIFT_MASTER"); ok && !cfg.MasterAddr.Provided {
166+
cfg.MasterAddr.Set(value)
167+
}
168+
if value, ok := util.GetEnv("BEARER_TOKEN"); ok && len(cfg.CommonConfig.BearerToken) == 0 {
169+
cfg.CommonConfig.BearerToken = value
170+
}
171+
if value, ok := util.GetEnv("BEARER_TOKEN_FILE"); ok && len(cfg.CommonConfig.BearerToken) == 0 {
172+
if tokenData, tokenErr := ioutil.ReadFile(value); tokenErr == nil {
173+
cfg.CommonConfig.BearerToken = strings.TrimSpace(string(tokenData))
174+
if len(cfg.CommonConfig.BearerToken) == 0 {
175+
err = fmt.Errorf("BEARER_TOKEN_FILE %q was empty", value)
176+
}
177+
} else {
178+
err = fmt.Errorf("Error reading BEARER_TOKEN_FILE %q: %v", value, tokenErr)
179+
}
180+
}
181+
182+
if value, ok := util.GetEnv("OPENSHIFT_CA_FILE"); ok && len(cfg.CommonConfig.CAFile) == 0 {
183+
cfg.CommonConfig.CAFile = value
184+
} else if value, ok := util.GetEnv("OPENSHIFT_CA_DATA"); ok && len(cfg.CommonConfig.CAData) == 0 {
185+
cfg.CommonConfig.CAData = []byte(value)
186+
}
187+
188+
if value, ok := util.GetEnv("OPENSHIFT_CERT_FILE"); ok && len(cfg.CommonConfig.CertFile) == 0 {
189+
cfg.CommonConfig.CertFile = value
190+
} else if value, ok := util.GetEnv("OPENSHIFT_CERT_DATA"); ok && len(cfg.CommonConfig.CertData) == 0 {
191+
cfg.CommonConfig.CertData = []byte(value)
11192
}
12193

13-
if len(bearerTokenFile) > 0 {
14-
envvars = append(envvars, api.EnvVar{Name: "BEARER_TOKEN_FILE", Value: bearerTokenFile})
194+
if value, ok := util.GetEnv("OPENSHIFT_KEY_FILE"); ok && len(cfg.CommonConfig.KeyFile) == 0 {
195+
cfg.CommonConfig.KeyFile = value
196+
} else if value, ok := util.GetEnv("OPENSHIFT_KEY_DATA"); ok && len(cfg.CommonConfig.KeyData) == 0 {
197+
cfg.CommonConfig.KeyData = []byte(value)
15198
}
16199

17-
if len(caData) > 0 {
18-
envvars = append(envvars, api.EnvVar{Name: "OPENSHIFT_CA_DATA", Value: string(caData)})
19-
} else if insecure {
20-
envvars = append(envvars, api.EnvVar{Name: "OPENSHIFT_INSECURE", Value: "true"})
200+
if value, ok := util.GetEnv("OPENSHIFT_INSECURE"); ok && len(value) != 0 {
201+
cfg.CommonConfig.Insecure = value == "true"
21202
}
22203

23-
return envvars
204+
return err
205+
}
206+
207+
func DefaultClientConfig(flags *pflag.FlagSet) kclientcmd.ClientConfig {
208+
loadingRules := config.NewOpenShiftClientConfigLoadingRules()
209+
flags.StringVar(&loadingRules.ExplicitPath, config.OpenShiftConfigFlagName, "", "Path to the config file to use for CLI requests.")
210+
cobra.MarkFlagFilename(flags, config.OpenShiftConfigFlagName)
211+
212+
// set our explicit defaults
213+
defaultOverrides := &kclientcmd.ConfigOverrides{ClusterDefaults: kclientcmdapi.Cluster{Server: os.Getenv("KUBERNETES_MASTER")}}
214+
loadingRules.DefaultClientConfig = kclientcmd.NewDefaultClientConfig(kclientcmdapi.Config{}, defaultOverrides)
215+
216+
overrides := &kclientcmd.ConfigOverrides{ClusterDefaults: defaultOverrides.ClusterDefaults}
217+
overrideFlags := kclientcmd.RecommendedConfigOverrideFlags("")
218+
overrideFlags.ContextOverrideFlags.Namespace.ShortName = "n"
219+
overrideFlags.AuthOverrideFlags.Username.LongName = ""
220+
overrideFlags.AuthOverrideFlags.Password.LongName = ""
221+
kclientcmd.BindOverrideFlags(overrides, flags, overrideFlags)
222+
cobra.MarkFlagFilename(flags, overrideFlags.AuthOverrideFlags.ClientCertificate.LongName)
223+
cobra.MarkFlagFilename(flags, overrideFlags.AuthOverrideFlags.ClientKey.LongName)
224+
cobra.MarkFlagFilename(flags, overrideFlags.ClusterOverrideFlags.CertificateAuthority.LongName)
225+
226+
clientConfig := kclientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, overrides)
227+
228+
return clientConfig
24229
}

pkg/client/config/loader.go

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package config
2+
3+
import (
4+
"os"
5+
"path"
6+
"path/filepath"
7+
"runtime"
8+
9+
"k8s.io/client-go/tools/clientcmd"
10+
"k8s.io/client-go/util/homedir"
11+
)
12+
13+
const (
14+
OpenShiftConfigPathEnvVar = "KUBECONFIG"
15+
OpenShiftConfigFlagName = "config"
16+
OpenShiftConfigHomeDir = ".kube"
17+
OpenShiftConfigHomeFileName = "config"
18+
OpenShiftConfigHomeDirFileName = OpenShiftConfigHomeDir + "/" + OpenShiftConfigHomeFileName
19+
)
20+
21+
var RecommendedHomeFile = path.Join(homedir.HomeDir(), OpenShiftConfigHomeDirFileName)
22+
23+
// currentMigrationRules returns a map that holds the history of recommended home directories used in previous versions.
24+
// Any future changes to RecommendedHomeFile and related are expected to add a migration rule here, in order to make
25+
// sure existing config files are migrated to their new locations properly.
26+
func CurrentMigrationRules() map[string]string {
27+
oldRecommendedHomeFile := path.Join(homedir.HomeDir(), ".kube/.config")
28+
oldRecommendedWindowsHomeFile := path.Join(os.Getenv("HOME"), OpenShiftConfigHomeDirFileName)
29+
30+
migrationRules := map[string]string{}
31+
migrationRules[RecommendedHomeFile] = oldRecommendedHomeFile
32+
if runtime.GOOS == "windows" {
33+
migrationRules[RecommendedHomeFile] = oldRecommendedWindowsHomeFile
34+
}
35+
return migrationRules
36+
}
37+
38+
// NewOpenShiftClientConfigLoadingRules returns file priority loading rules for OpenShift.
39+
// 1. --config value
40+
// 2. if KUBECONFIG env var has a value, use it. Otherwise, ~/.kube/config file
41+
func NewOpenShiftClientConfigLoadingRules() *clientcmd.ClientConfigLoadingRules {
42+
chain := []string{}
43+
44+
envVarFile := os.Getenv(OpenShiftConfigPathEnvVar)
45+
if len(envVarFile) != 0 {
46+
chain = append(chain, filepath.SplitList(envVarFile)...)
47+
} else {
48+
chain = append(chain, RecommendedHomeFile)
49+
}
50+
51+
return &clientcmd.ClientConfigLoadingRules{
52+
Precedence: chain,
53+
MigrationRules: CurrentMigrationRules(),
54+
}
55+
}

pkg/cmd/infra/router/f5.go

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
1313
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
1414

15+
clientcmd "github.com/openshift/origin/pkg/client/cmd"
1516
"github.com/openshift/origin/pkg/cmd/util"
1617
cmdversion "github.com/openshift/origin/pkg/cmd/version"
1718
"github.com/openshift/origin/pkg/oc/cli/util/clientcmd"

pkg/cmd/infra/router/template.go

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
2828
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
2929

30+
clientcmd "github.com/openshift/origin/pkg/client/cmd"
3031
"github.com/openshift/origin/pkg/cmd/server/crypto"
3132
"github.com/openshift/origin/pkg/cmd/util"
3233
cmdversion "github.com/openshift/origin/pkg/cmd/version"

pkg/oc/admin/diagnostics/config.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ import (
55

66
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
77

8+
"github.com/openshift/origin/pkg/client/config"
89
clientdiagnostics "github.com/openshift/origin/pkg/oc/admin/diagnostics/diagnostics/client"
910
"github.com/openshift/origin/pkg/oc/admin/diagnostics/diagnostics/types"
10-
"github.com/openshift/origin/pkg/oc/cli/config"
1111
)
1212

1313
// determine if we even have a client config

pkg/oc/admin/diagnostics/diagnostics.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,13 @@ import (
1818
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
1919
kcmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
2020

21+
"github.com/openshift/origin/pkg/client/config"
2122
"github.com/openshift/origin/pkg/cmd/flagtypes"
2223
"github.com/openshift/origin/pkg/cmd/util/variable"
2324
"github.com/openshift/origin/pkg/oc/admin/diagnostics/diagnostics/log"
2425
netutil "github.com/openshift/origin/pkg/oc/admin/diagnostics/diagnostics/networkpod/util"
2526
"github.com/openshift/origin/pkg/oc/admin/diagnostics/diagnostics/types"
2627
"github.com/openshift/origin/pkg/oc/admin/diagnostics/options"
27-
"github.com/openshift/origin/pkg/oc/cli/config"
2828
osclientcmd "github.com/openshift/origin/pkg/oc/cli/util/clientcmd"
2929
)
3030

pkg/oc/admin/diagnostics/diagnostics/client/config_loading.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ import (
88
flag "github.com/spf13/pflag"
99
"k8s.io/client-go/tools/clientcmd"
1010

11+
"github.com/openshift/origin/pkg/client/config"
1112
"github.com/openshift/origin/pkg/oc/admin/diagnostics/diagnostics/types"
1213
"github.com/openshift/origin/pkg/oc/admin/diagnostics/diagnostics/util"
13-
"github.com/openshift/origin/pkg/oc/cli/config"
1414
)
1515

1616
// ConfigLoading is a little special in that it is run separately as a precondition

pkg/oc/admin/diagnostics/diagnostics/network/setup.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ import (
1616
kclientcmd "k8s.io/client-go/tools/clientcmd"
1717
kapi "k8s.io/kubernetes/pkg/api"
1818

19+
"github.com/openshift/origin/pkg/client/config"
1920
"github.com/openshift/origin/pkg/network"
2021
networkapi "github.com/openshift/origin/pkg/network/apis/network"
2122
"github.com/openshift/origin/pkg/oc/admin/diagnostics/diagnostics/networkpod/util"
2223
diagutil "github.com/openshift/origin/pkg/oc/admin/diagnostics/diagnostics/util"
23-
"github.com/openshift/origin/pkg/oc/cli/config"
2424
)
2525

2626
func (d *NetworkDiagnostic) TestSetup() error {

pkg/oc/admin/diagnostics/diagnostics/pod/auth.go

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
knet "k8s.io/apimachinery/pkg/util/net"
1616
restclient "k8s.io/client-go/rest"
1717

18+
clientcmd "github.com/openshift/origin/pkg/client/cmd"
1819
"github.com/openshift/origin/pkg/cmd/flagtypes"
1920
"github.com/openshift/origin/pkg/oc/admin/diagnostics/diagnostics/types"
2021
"github.com/openshift/origin/pkg/oc/cli/util/clientcmd"

pkg/oc/bootstrap/docker/openshift/helper.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
kapi "k8s.io/kubernetes/pkg/api"
2121

2222
defaultsapi "github.com/openshift/origin/pkg/build/controller/build/defaults/api"
23+
clientconfig "github.com/openshift/origin/pkg/client/config"
2324
"github.com/openshift/origin/pkg/cmd/server/admin"
2425
configapi "github.com/openshift/origin/pkg/cmd/server/api"
2526
_ "github.com/openshift/origin/pkg/cmd/server/api/install"
@@ -31,7 +32,6 @@ import (
3132
dockerexec "github.com/openshift/origin/pkg/oc/bootstrap/docker/exec"
3233
"github.com/openshift/origin/pkg/oc/bootstrap/docker/host"
3334
"github.com/openshift/origin/pkg/oc/bootstrap/docker/run"
34-
cliconfig "github.com/openshift/origin/pkg/oc/cli/config"
3535
kclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
3636
)
3737

@@ -74,7 +74,7 @@ var (
7474
DefaultPorts = append(BasePorts, DefaultDNSPort)
7575
PortsWithAlternateDNS = append(BasePorts, AlternateDNSPort)
7676
AllPorts = append(append(RouterPorts, DefaultPorts...), AlternateDNSPort)
77-
SocatPidFile = filepath.Join(homedir.HomeDir(), cliconfig.OpenShiftConfigHomeDir, "socat-8443.pid")
77+
SocatPidFile = filepath.Join(homedir.HomeDir(), clientconfig.OpenShiftConfigHomeDir, "socat-8443.pid")
7878
defaultCertHosts = []string{
7979
"127.0.0.1",
8080
"172.30.0.1",

0 commit comments

Comments
 (0)