forked from rhd-gitops-example/odo
/
preference.go
286 lines (237 loc) · 8.86 KB
/
preference.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
package preference
import (
"fmt"
"os"
"os/user"
"path/filepath"
"strconv"
"strings"
"github.com/golang/glog"
"github.com/pkg/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/openshift/odo/pkg/util"
)
const (
globalConfigEnvName = "GLOBALODOCONFIG"
configFileName = "preference.yaml"
preferenceKind = "Preference"
preferenceAPIVersion = "odo.openshift.io/v1alpha1"
//DefaultTimeout for openshift server connection check (in seconds)
DefaultTimeout = 1
// DefaultPushTimeout is the default timeout for pods (in seconds)
DefaultPushTimeout = 240
// UpdateNotificationSetting is the name of the setting controlling update notification
UpdateNotificationSetting = "UpdateNotification"
// UpdateNotificationSettingDescription is human-readable description for the update notification setting
UpdateNotificationSettingDescription = "Flag to control if an update notification is shown or not (Default: true)"
// NamePrefixSetting is the name of the setting controlling name prefix
NamePrefixSetting = "NamePrefix"
// NamePrefixSettingDescription is human-readable description for the name prefix setting
NamePrefixSettingDescription = "Use this value to set a default name prefix (Default: current directory name)"
// TimeoutSetting is the name of the setting controlling timeout for connection check
TimeoutSetting = "Timeout"
// PushTimeoutSetting is the name of the setting controlling PushTimeout
PushTimeoutSetting = "PushTimeout"
)
// TimeoutSettingDescription is human-readable description for the timeout setting
var TimeoutSettingDescription = fmt.Sprintf("Timeout (in seconds) for OpenShift server connection check (Default: %d)", DefaultTimeout)
// PushTimeoutSettingDescription adds a description for PushTimeout
var PushTimeoutSettingDescription = fmt.Sprintf("PushTimeout (in seconds) for waiting for a Pod to come up (Default: %d)", DefaultPushTimeout)
// This value can be provided to set a seperate directory for users 'homedir' resolution
// note for mocking purpose ONLY
var customHomeDir = os.Getenv("CUSTOM_HOMEDIR")
var (
// records information on supported parameters
supportedParameterDescriptions = map[string]string{
UpdateNotificationSetting: UpdateNotificationSettingDescription,
NamePrefixSetting: NamePrefixSettingDescription,
TimeoutSetting: TimeoutSettingDescription,
PushTimeoutSetting: PushTimeoutSettingDescription,
}
// set-like map to quickly check if a parameter is supported
lowerCaseParameters = util.GetLowerCaseParameters(GetSupportedParameters())
)
// PreferenceInfo wraps the preference and provides helpers to
// serialize it.
type PreferenceInfo struct {
Filename string `yaml:"FileName,omitempty"`
Preference `yaml:",omitempty"`
}
// OdoSettings holds all odo specific configurations
type OdoSettings struct {
// Controls if an update notification is shown or not
UpdateNotification *bool `yaml:"UpdateNotification,omitempty"`
// Holds the prefix part of generated random application name
NamePrefix *string `yaml:"NamePrefix,omitempty"`
// Timeout for OpenShift server connection check
Timeout *int `yaml:"Timeout,omitempty"`
// PushTimeout for OpenShift pod timeout check
PushTimeout *int `yaml:"PushTimeout,omitempty"`
}
// Preference stores all the preferences related to odo
type Preference struct {
metav1.TypeMeta `yaml:",inline"`
// Odo settings holds the odo specific global settings
OdoSettings OdoSettings `yaml:"OdoSettings,omitempty"`
}
func getPreferenceFile() (string, error) {
if env, ok := os.LookupEnv(globalConfigEnvName); ok {
return env, nil
}
if len(customHomeDir) != 0 {
return filepath.Join(customHomeDir, ".odo", configFileName), nil
}
currentUser, err := user.Current()
if err != nil {
return "", err
}
return filepath.Join(currentUser.HomeDir, ".odo", configFileName), nil
}
// New returns the PreferenceInfo to retain the expected behavior
func New() (*PreferenceInfo, error) {
return NewPreferenceInfo()
}
// NewPreference creates an empty Preference struct with type meta information
func NewPreference() Preference {
return Preference{
TypeMeta: metav1.TypeMeta{
Kind: preferenceKind,
APIVersion: preferenceAPIVersion,
},
}
}
// NewPreferenceInfo gets the PreferenceInfo from preference file and creates the preference file in case it's
// not present
func NewPreferenceInfo() (*PreferenceInfo, error) {
preferenceFile, err := getPreferenceFile()
glog.V(4).Infof("The path for preference file is %+v", preferenceFile)
if err != nil {
return nil, errors.Wrap(err, "unable to get odo preference file")
}
c := PreferenceInfo{
Preference: NewPreference(),
Filename: preferenceFile,
}
// if the preference file doesn't exist then we dont worry about it and return
if _, err = os.Stat(preferenceFile); os.IsNotExist(err) {
return &c, nil
}
err = util.GetFromFile(&c.Preference, c.Filename)
if err != nil {
return nil, err
}
return &c, nil
}
// SetConfiguration modifies Odo configurations in the config file
// as of now being used for nameprefix, timeout, updatenotification
// TODO: Use reflect to set parameters
func (c *PreferenceInfo) SetConfiguration(parameter string, value string) error {
if p, ok := asSupportedParameter(parameter); ok {
// processing values according to the parameter names
switch p {
case "timeout":
typedval, err := strconv.Atoi(value)
if err != nil {
return errors.Wrapf(err, "unable to set %s to %s", parameter, value)
}
if typedval < 0 {
return errors.Errorf("cannot set timeout to less than 0")
}
c.OdoSettings.Timeout = &typedval
case "pushtimeout":
typedval, err := strconv.Atoi(value)
if err != nil {
return errors.Wrapf(err, "unable to set %s to %s", parameter, value)
}
if typedval < 0 {
return errors.Errorf("cannot set timeout to less than 0")
}
c.OdoSettings.PushTimeout = &typedval
case "updatenotification":
val, err := strconv.ParseBool(strings.ToLower(value))
if err != nil {
return errors.Wrapf(err, "unable to set %s to %s", parameter, value)
}
c.OdoSettings.UpdateNotification = &val
case "nameprefix":
c.OdoSettings.NamePrefix = &value
}
} else {
return errors.Errorf("unknown parameter :'%s' is not a parameter in odo preference", parameter)
}
err := util.WriteToFile(&c.Preference, c.Filename)
if err != nil {
return errors.Wrapf(err, "unable to set %s", parameter)
}
return nil
}
// DeleteConfiguration delete Odo configurations in the global config file
// as of now being used for nameprefix, timeout, updatenotification
func (c *PreferenceInfo) DeleteConfiguration(parameter string) error {
if p, ok := asSupportedParameter(parameter); ok {
// processing values according to the parameter names
if err := util.DeleteConfiguration(&c.OdoSettings, p); err != nil {
return err
}
} else {
return errors.Errorf("unknown parameter :'%s' is not a parameter in the odo preference", parameter)
}
err := util.WriteToFile(&c.Preference, c.Filename)
if err != nil {
return errors.Wrapf(err, "unable to set %s", parameter)
}
return nil
}
// IsSet checks if the value is set in the preference
func (c *PreferenceInfo) IsSet(parameter string) bool {
return util.IsSet(c.OdoSettings, parameter)
}
// GetTimeout returns the value of Timeout from config
// and if absent then returns default
func (c *PreferenceInfo) GetTimeout() int {
// default timeout value is 1
if c.OdoSettings.Timeout == nil {
return DefaultTimeout
}
return *c.OdoSettings.Timeout
}
// GetPushTimeout gets the value set by PushTimeout
func (c *PreferenceInfo) GetPushTimeout() int {
// default timeout value is 1
if c.OdoSettings.PushTimeout == nil {
return DefaultPushTimeout
}
return *c.OdoSettings.PushTimeout
}
// GetUpdateNotification returns the value of UpdateNotification from config
// and if absent then returns default
func (c *PreferenceInfo) GetUpdateNotification() bool {
if c.OdoSettings.UpdateNotification == nil {
return true
}
return *c.OdoSettings.UpdateNotification
}
// GetNamePrefix returns the value of Prefix from config
// and if absent then returns default
func (c *PreferenceInfo) GetNamePrefix() string {
if c.OdoSettings.NamePrefix == nil {
return ""
}
return *c.OdoSettings.NamePrefix
}
// FormatSupportedParameters outputs supported parameters and their description
func FormatSupportedParameters() (result string) {
for _, v := range GetSupportedParameters() {
result = result + v + " - " + supportedParameterDescriptions[v] + "\n"
}
return "\nAvailable Parameters:\n" + result
}
// asSupportedParameter checks that the given parameter is supported and returns a lower case version of it if it is
func asSupportedParameter(param string) (string, bool) {
lower := strings.ToLower(param)
return lower, lowerCaseParameters[lower]
}
// GetSupportedParameters returns the name of the supported parameters
func GetSupportedParameters() []string {
return util.GetSortedKeys(supportedParameterDescriptions)
}