forked from openshift/origin
/
store.go
165 lines (135 loc) · 5.12 KB
/
store.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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
package config
import (
"fmt"
"io/ioutil"
"os"
"github.com/golang/glog"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd"
clientcmdapi "github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd/api"
"github.com/openshift/origin/pkg/cmd/flagtypes"
)
const (
fromKube = "fromkube"
fromOpenShift = "fromopenshift"
)
// A ConfigStore is the representation of a config from one individual config file. Can be used
// to persist configs by being explicit about the file to save.
type ConfigStore struct {
Config *clientcmdapi.Config
Path string
providerEngine string
}
func (c *ConfigStore) FromOpenShift() bool {
return c.providerEngine == fromOpenShift
}
func (c *ConfigStore) FromKube() bool {
return c.providerEngine == fromKube
}
// Load a ConfigStore from the explicit path to a config file provided as argument
// Error if not found.
func LoadFrom(path string) (*ConfigStore, error) {
data, err := ioutil.ReadFile(path)
if err == nil {
config, err := clientcmd.Load(data)
if err != nil {
return nil, err
}
return &ConfigStore{config, path, fromOpenShift}, nil
}
return nil, fmt.Errorf("Unable to load config file from '%v': %v", path, err.Error())
}
// Load a ConfigStore using the priority conventions declared by the ClientConfigLoadingRules.
// Error if none can be found.
func LoadWithLoadingRules() (store *ConfigStore, err error) {
loadingRules := map[string][]string{
fromOpenShift: OpenShiftClientConfigFilePriority(),
fromKube: KubeClientConfigFilePriority(),
}
for source, priorities := range loadingRules {
for _, path := range priorities {
data, err := ioutil.ReadFile(path)
if err != nil && !os.IsNotExist(err) {
return nil, fmt.Errorf("Unable to load config file from %v: %v", path, err.Error())
}
if err == nil {
config, err := clientcmd.Load(data)
if err != nil {
return store, err
}
return &ConfigStore{config, path, source}, nil
}
}
}
return nil, fmt.Errorf("Unable to load a config file from any of the expected locations.")
}
// Create a new file to store configs and returns the ConfigStore that represents it.
func CreateEmpty() (*ConfigStore, error) {
configPathToCreateIfNotFound := fmt.Sprintf("%v/%v", os.Getenv("HOME"), OpenShiftConfigHomeDirFileName)
glog.V(3).Infof("A new config will be created at: %v ", configPathToCreateIfNotFound)
newConfig := clientcmdapi.NewConfig()
if err := os.MkdirAll(fmt.Sprintf("%v/%v", os.Getenv("HOME"), OpenShiftConfigHomeDir), 0755); err != nil {
return nil, fmt.Errorf("Tried to create a new config file but failed while creating directory %v: %v", OpenShiftConfigHomeDirFileName, err)
}
glog.V(5).Infof("Created directory %v", "~/"+OpenShiftConfigHomeDir)
if err := clientcmd.WriteToFile(*newConfig, configPathToCreateIfNotFound); err != nil {
return nil, fmt.Errorf("Tried to create a new config file but failed with: %v", err)
}
glog.V(5).Infof("Created file %v", configPathToCreateIfNotFound)
data, err := ioutil.ReadFile(configPathToCreateIfNotFound)
if err != nil {
return nil, err
}
config, err := clientcmd.Load(data)
if err != nil {
return nil, err
}
return &ConfigStore{config, configPathToCreateIfNotFound, fromOpenShift}, nil
}
// Save the provided config attributes to this ConfigStore.
func (c *ConfigStore) SaveToFile(credentialsName string, namespace string, clientCfg *client.Config, rawCfg clientcmdapi.Config) error {
glog.V(4).Infof("Trying to merge and update %v config to '%v'...", c.providerEngine, c.Path)
config := clientcmdapi.NewConfig()
credentials := clientcmdapi.NewAuthInfo()
credentials.Token = clientCfg.BearerToken
credentials.ClientCertificate = clientCfg.TLSClientConfig.CertFile
if len(credentials.ClientCertificate) == 0 {
credentials.ClientCertificateData = clientCfg.TLSClientConfig.CertData
}
credentials.ClientKey = clientCfg.TLSClientConfig.KeyFile
if len(credentials.ClientKey) == 0 {
credentials.ClientKeyData = clientCfg.TLSClientConfig.KeyData
}
if len(credentialsName) == 0 {
credentialsName = "osc-login"
}
config.AuthInfos[credentialsName] = *credentials
serverAddr := flagtypes.Addr{Value: clientCfg.Host}.Default()
clusterName := fmt.Sprintf("%v:%v", serverAddr.Host, serverAddr.Port)
cluster := clientcmdapi.NewCluster()
cluster.Server = clientCfg.Host
cluster.CertificateAuthority = clientCfg.CAFile
if len(cluster.CertificateAuthority) == 0 {
cluster.CertificateAuthorityData = clientCfg.CAData
}
cluster.InsecureSkipTLSVerify = clientCfg.Insecure
config.Clusters[clusterName] = *cluster
contextName := clusterName + "-" + credentialsName
context := clientcmdapi.NewContext()
context.Cluster = clusterName
context.AuthInfo = credentialsName
context.Namespace = namespace
config.Contexts[contextName] = *context
config.CurrentContext = contextName
configToModify := c.Config
configToWrite, err := MergeConfig(rawCfg, *configToModify, *config)
if err != nil {
return err
}
// TODO need to handle file not writable (probably create a copy)
err = clientcmd.WriteToFile(*configToWrite, c.Path)
if err != nil {
return err
}
return nil
}