forked from openshift/origin
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathconfig.go
147 lines (138 loc) · 5.46 KB
/
config.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
package diagnostics
import (
"errors"
"fmt"
"io/ioutil"
"os"
"k8s.io/client-go/tools/clientcmd"
kclientcmd "k8s.io/client-go/tools/clientcmd"
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
"github.com/openshift/origin/pkg/oc/cli/admin/diagnostics/diagnostics/util"
)
// use the base factory to return a raw config (not specific to a context)
func (o DiagnosticsOptions) buildRawConfig() (*clientcmdapi.Config, error) {
kubeConfig, configErr := o.Factory.ToRawKubeConfigLoader().RawConfig()
if configErr != nil {
return nil, configErr
}
if len(kubeConfig.Contexts) == 0 {
return nil, errors.New("No contexts found in config file.")
}
return &kubeConfig, nil
}
// determine if we even have a client config
func (o DiagnosticsOptions) detectClientConfig() (expected bool, detected bool) {
if o.ClientFlags == nil {
// options for client not provided, so it must not be expected.
return false, false
}
o.Logger().Notice("CED2011", "Determining if client configuration exists for client/cluster diagnostics")
confFlagName := genericclioptions.OpenShiftKubeConfigFlagName
confFlagValue := o.ClientFlags.Lookup(confFlagName).Value.String()
successfulLoad := false
var foundPath string
rules := kclientcmd.NewDefaultClientConfigLoadingRules()
paths := append([]string{confFlagValue}, rules.Precedence...)
for index, path := range paths {
errmsg := ""
switch index {
case 0:
errmsg = fmt.Sprintf("--%s specified that client config should be at %s\n", confFlagName, path)
case len(paths) - 1: // config in ~/.kube
// no error message indicated if it is not there... user didn't say it would be
default: // can be multiple paths from the env var in theory; all cases should go here
if len(os.Getenv(kclientcmd.RecommendedConfigPathEnvVar)) != 0 {
errmsg = fmt.Sprintf("Env var %s specified that client config could be at %s\n", kclientcmd.RecommendedConfigPathEnvVar, path)
}
}
if o.canOpenConfigFile(path, errmsg) {
successfulLoad = true
foundPath = path
break
}
}
if len(foundPath) > 0 {
if len(confFlagValue) > 0 && confFlagValue != foundPath {
// found config but not where --config said
o.Logger().Error("DCli1001", fmt.Sprintf(`
The client configuration file was not found where the --%s flag indicated:
%s
A config file was found at the following location:
%s
If you wish to use this file for client configuration, you can specify it
with the --%[1]s flag, or just not specify the flag.
`, confFlagName, confFlagValue, foundPath))
}
} else { // not found, check for master-generated ones to recommend
if len(confFlagValue) > 0 {
o.Logger().Error("DCli1002", fmt.Sprintf("Did not find config file where --%s=%s indicated", confFlagName, confFlagValue))
}
adminWarningF := `
No client config file was available; however, one exists at
%[2]s
which may have been generated automatically by the master.
If you want to use this config, you should copy it to the
standard location (%[3]s),
or you can set the environment variable %[1]s:
export %[1]s=%[2]s
If not, obtain a config file and place it in the standard
location for use by the client and diagnostics.
`
// look for it in auto-generated locations when not found properly
for _, path := range util.AdminKubeConfigPaths {
msg := fmt.Sprintf("Looking for a possible client config at %s\n", path)
if o.canOpenConfigFile(path, msg) {
o.Logger().Warn("DCli1003", fmt.Sprintf(adminWarningF, kclientcmd.RecommendedConfigPathEnvVar, path, kclientcmd.RecommendedHomeFile))
break
}
}
}
return true, successfulLoad
}
// ----------------------------------------------------------
// Attempt to open file at path as client config
// If there is a problem and errmsg is set, log an error
func (o DiagnosticsOptions) canOpenConfigFile(path string, errmsg string) bool {
var (
file *os.File
err error
)
if len(path) == 0 { // empty param/envvar
return false
} else if file, err = os.Open(path); err == nil {
o.Logger().Debug("DCli1004", fmt.Sprintf("Reading client config at %s", path))
} else if len(errmsg) == 0 {
o.Logger().Debug("DCli1005", fmt.Sprintf("Could not read client config at %s:\n%#v", path, err))
} else if os.IsNotExist(err) {
o.Logger().Debug("DCli1006", errmsg+"but that file does not exist.")
} else if os.IsPermission(err) {
o.Logger().Error("DCli1007", errmsg+"but lack permission to read that file.")
} else {
o.Logger().Error("DCli1008", fmt.Sprintf("%sbut there was an error opening it:\n%#v", errmsg, err))
}
if file == nil {
return false
}
// file is open for reading
defer file.Close()
if buffer, err := ioutil.ReadAll(file); err != nil {
o.Logger().Error("DCli1009", fmt.Sprintf("Unexpected error while reading client config file (%s): %v", path, err))
} else if _, err := clientcmd.Load(buffer); err != nil {
o.Logger().Error("DCli1010", fmt.Sprintf(`
Error reading YAML from client config file (%s):
%v
This file may have been truncated or mis-edited.
Please fix, remove, or obtain a new client config`, file.Name(), err))
} else {
o.Logger().Info("DCli1011", fmt.Sprintf("Successfully read a client config file at '%s'", path))
/* Note, we're not going to use this config file directly.
* Instead, we'll defer to the openshift client code to assimilate
* flags, env vars, and the potential hierarchy of config files
* into an actual configuration that the client uses.
* However, for diagnostic purposes, record the files we find.
*/
return true
}
return false
}