forked from redhat-developer/odo
/
config.go
323 lines (275 loc) · 8.49 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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
package config
import (
"fmt"
"io/ioutil"
"os"
"os/user"
"path/filepath"
"github.com/ghodss/yaml"
"github.com/pkg/errors"
)
const (
configEnvName = "ODOCONFIG"
configFileName = "odo"
)
// OdoSettings holds all odo specific configurations
type OdoSettings struct {
// Controls if an update notification is shown or not
UpdateNotification *bool `json:"updatenotification,omitempty"`
}
// ApplicationInfo holds all important information about one application
type ApplicationInfo struct {
// name of the application
Name string `json:"name"`
// is this application active? Only one application can be active at the time
Active bool `json:"active"`
// name of the openshift project this application belongs to
Project string `json:"project"`
// last active component for this application
ActiveComponent string `json:"activeComponent"`
}
type Config struct {
// odo specific configuration settings
OdoSettings OdoSettings `json:"settings"`
// remember active applications and components per project
// when project or applications is switched we can go back to last active app/component
// Currently active application
// multiple applications can be active but each one has to be in different project
// there shouldn't be more active applications in one project
ActiveApplications []ApplicationInfo `json:"activeApplications"`
}
type ConfigInfo struct {
Filename string
Config
}
func getDefaultConfigFile() string {
currentUser, err := user.Current()
if err != nil {
return ""
}
return filepath.Join(currentUser.HomeDir, ".kube", configFileName)
}
func getOdoConfigFile() (string, error) {
if env, ok := os.LookupEnv(configEnvName); ok {
return env, nil
}
if file := getDefaultConfigFile(); len(file) > 0 {
return file, nil
}
return "", errors.New("unable to get config file")
}
func New() (*ConfigInfo, error) {
configFile, err := getOdoConfigFile()
if err != nil {
return nil, errors.Wrap(err, "unable to get odo config file")
}
// Check whether directory present or not
_, err = os.Stat(filepath.Dir(configFile))
if os.IsNotExist(err) {
err = os.MkdirAll(filepath.Dir(configFile), 0755)
if err != nil {
return nil, errors.Wrap(err, "unable to create directory")
}
}
// Check whether config file is present or not
_, err = os.Stat(configFile)
if os.IsNotExist(err) {
file, err := os.Create(configFile)
if err != nil {
return nil, errors.Wrap(err, "unable to create config file")
}
defer file.Close()
}
c := ConfigInfo{}
c.Filename = configFile
c.get()
return &c, nil
}
func (c *ConfigInfo) get() error {
configData, err := ioutil.ReadFile(c.Filename)
if err != nil {
return errors.Wrapf(err, "unable to read file %v", c.Filename)
}
err = yaml.Unmarshal(configData, &c)
if err != nil {
return errors.Wrap(err, "unable to unmarshal odo config file")
}
return nil
}
func (c *ConfigInfo) writeToFile() error {
data, err := yaml.Marshal(&c.Config)
if err != nil {
return errors.Wrap(err, "unable to marshal odo config data")
}
err = ioutil.WriteFile(c.Filename, data, 0600)
if err != nil {
return errors.Wrapf(err, "unable to write config to file %v", c.Filename)
}
return nil
}
// SetConfiguration modifies Odo configurations in the config file
// as of now only being used for updatenotification
func (c *ConfigInfo) SetConfiguration(parameter string, value bool) error {
switch parameter {
case "updatenotification":
c.OdoSettings.UpdateNotification = &value
default:
return errors.Errorf("unknown parameter :'%s' is not a parameter in odo config", parameter)
}
err := c.writeToFile()
if err != nil {
return errors.Wrapf(err, "unable to set %s", parameter)
}
return nil
}
// GetupdateNotification returns the value of UpdateNotification from config
func (c *ConfigInfo) GetUpdateNotification() bool {
if c.OdoSettings.UpdateNotification == nil {
return true
}
return *c.OdoSettings.UpdateNotification
}
// SetActiveComponent sets active component for given project and application.
// application must exist
func (c *ConfigInfo) SetActiveComponent(component string, application string, project string) error {
found := false
if c.ActiveApplications != nil {
for i, app := range c.ActiveApplications {
if app.Project == project && app.Name == application {
c.ActiveApplications[i].ActiveComponent = component
found = true
break
}
}
}
if !found {
return errors.Errorf("unable to set %s component as active, application %s in %s project doesn't exists", component, application, project)
}
err := c.writeToFile()
if err != nil {
return errors.Wrapf(err, "unable to set %s as active component", component)
}
return nil
}
// Sets the active component as blank in the configuration file
func (c *ConfigInfo) UnsetActiveComponent(application string, project string) error {
found := false
if c.ActiveApplications != nil {
for i, app := range c.ActiveApplications {
if app.Project == project && app.Name == application {
c.ActiveApplications[i].ActiveComponent = ""
found = true
break
}
}
}
if !found {
return errors.Errorf("unable to find project %s / application %s in configuration file", project, application)
}
// Write the configuration to file
err := c.writeToFile()
if err != nil {
return errors.Wrapf(err, "unable to write configuration file")
}
return nil
}
// GetActiveComponent if no component is set as current returns empty string
func (c *ConfigInfo) GetActiveComponent(application string, project string) string {
if c.ActiveApplications != nil {
for _, app := range c.ActiveApplications {
if app.Project == project && app.Name == application && app.Active == true {
return app.ActiveComponent
}
}
}
return ""
}
// GetActiveApplication get currently active application for given project
// if no application is active return empty string
func (c *ConfigInfo) GetActiveApplication(project string) string {
if c.ActiveApplications != nil {
for _, app := range c.ActiveApplications {
if app.Project == project && app.Active == true {
return app.Name
}
}
}
return ""
}
// SetActiveApplication set application as active for given project
func (c *ConfigInfo) SetActiveApplication(application string, project string) error {
if c.ActiveApplications == nil {
c.ActiveApplications = []ApplicationInfo{}
}
found := false
for i, app := range c.ActiveApplications {
// if application exists set is as Active
if app.Name == application && app.Project == project {
c.ActiveApplications[i].Active = true
found = true
break
}
}
// if application doesn't exists, add it as Active
if !found {
return fmt.Errorf("unable set application %s as active in config, it doesn't exist", application)
}
// make sure that no other application is active
for i, app := range c.ActiveApplications {
if !(app.Name == application && app.Project == project) {
c.ActiveApplications[i].Active = false
}
}
err := c.writeToFile()
if err != nil {
return errors.Wrap(err, "unable to set current application")
}
return nil
}
// AddApplication add new application to the config file
// Newly create application is NOT going to be se as Active.
func (c *ConfigInfo) AddApplication(application string, project string) error {
if c.ActiveApplications == nil {
c.ActiveApplications = []ApplicationInfo{}
}
for _, app := range c.ActiveApplications {
if app.Name == application && app.Project == project {
return fmt.Errorf("unable to add %s application, it already exists in config file", application)
}
}
// if application doesn't exists add it to slice
c.ActiveApplications = append(c.ActiveApplications,
ApplicationInfo{
Name: application,
Project: project,
Active: false,
})
err := c.writeToFile()
if err != nil {
return errors.Wrapf(err, "unable to set add %s application", application)
}
return nil
}
// DeleteApplication deletes application from given project from config file
func (c *ConfigInfo) DeleteApplication(application string, project string) error {
if c.ActiveApplications == nil {
c.ActiveApplications = []ApplicationInfo{}
}
found := false
for i, app := range c.ActiveApplications {
// if application exists set is as Active
if app.Name == application && app.Project == project {
// remove current item from array
c.ActiveApplications = append(c.ActiveApplications[:i], c.ActiveApplications[i+1:]...)
found = true
}
}
if !found {
return fmt.Errorf("application %s doesn't exist", application)
}
err := c.writeToFile()
if err != nil {
return errors.Wrapf(err, "unable to delete application %s", application)
}
return nil
}