-
Notifications
You must be signed in to change notification settings - Fork 69
/
api.go
287 lines (241 loc) · 10.5 KB
/
api.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
package api
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"
log "github.com/sirupsen/logrus"
"github.com/newrelic/newrelic-cli/internal/config"
"github.com/newrelic/newrelic-cli/internal/utils"
)
// GetActiveProfileName retrieves the profile in use for this command execution.
// To retrieve the active profile, the following criteria are evaluated in order,
// short circuiting and returning the described value if true:
// 1. a profile has been provided with the global `--profile` flag
// 2. a profile is set in the default profile config file
// 3. "default" is returned if none of the above are true
func GetActiveProfileName() string {
if config.FlagProfileName != "" {
return config.FlagProfileName
}
profileName, err := GetDefaultProfileName()
if err != nil || profileName == "" {
return config.DefaultProfileName
}
return profileName
}
// GetDefaultProfileName retrieves the profile set in the default profile config
// file. If the file does not exist, an empty string will be returned.
func GetDefaultProfileName() (string, error) {
defaultProfileFilePath := filepath.Join(config.BasePath, config.DefaultProfileFileName)
data, err := ioutil.ReadFile(defaultProfileFilePath)
if err != nil {
if os.IsNotExist(err) {
return "", nil
}
return "", err
}
return strings.Trim(string(data), "\""), nil
}
// GetProfileNames retrieves all profile names currently configured in the credentials file.
func GetProfileNames() []string {
return config.CredentialsProvider.GetScopes()
}
// SetDefaultProfile sets the given profile as the new default in the default profile
// config file. If the given profile does not exist, the set operation will return
// an error.
func SetDefaultProfile(profileName string) error {
if ok := utils.StringInSlice(profileName, GetProfileNames()); !ok {
return fmt.Errorf("profile %s does not exist", profileName)
}
defaultProfileFilePath := filepath.Join(config.BasePath, config.DefaultProfileFileName)
return ioutil.WriteFile(defaultProfileFilePath, []byte("\""+profileName+"\""), 0644)
}
// RemoveProfile removes a profile from the credentials file. If the profile being
// removed is the default, it will attempt to find another profile to set as the
// new default. If another profile cannot be found, the default profile config file
// will be deleted.
func RemoveProfile(profileName string) error {
if err := config.CredentialsProvider.RemoveScope(profileName); err != nil {
return err
}
d, err := GetDefaultProfileName()
if err != nil {
return err
}
if d == "" || d == profileName {
names := GetProfileNames()
if len(names) > 0 {
if err = SetDefaultProfile(names[0]); err != nil {
return fmt.Errorf("could not set new default profile")
}
log.Infof("setting %s as the new default profile", names[0])
} else {
if err := removeDefaultProfile(); err != nil {
return fmt.Errorf("could not delete default profile")
}
}
}
return nil
}
// RequireActiveProfileAccountID retrieves the currently configured account ID,
// returning an error if the value retrieved is the zero value.
// When returning an account ID, the following will be evaluated in order, short-circuiting
// and returning the described value if true:
// 1. An environment variable override has been set with NEW_RELIC_ACCOUNT_ID
// 2. An account ID has been provided with the `--accountId` global flag
// 3. An account ID has been set in the active profile
func RequireActiveProfileAccountID() int {
v := GetActiveProfileAccountID()
if v == 0 {
log.Fatalf("%s is required", config.AccountID)
}
return v
}
// GetActiveProfileAccountID retrieves the currently configured account ID.
// When returning an account ID, the following will be evaluated in order, short-circuiting
// and returning the described value if true:
// 1. An environment variable override has been set with NEW_RELIC_ACCOUNT_ID
// 2. An account ID has been provided with the `--accountId` global flag
// 3. An account ID has been set in the active profile
// 4. The zero value will be returned if none of the above are true
func GetActiveProfileAccountID() int {
return getActiveProfileIntWithOverride(config.AccountID, config.FlagAccountID)
}
// GetActiveProfileString retrieves the value set for the given key in the active
// profile, if any. Environment variable overrides will be preferred over values
// set in the active profile, and a default value will be returned if it has been
// configured and no value has been set for the key in the active profile.
// An attempt will be made to convert the underlying value to a string if is not
// already stored that way. Failing the above, the zero value wil be returned.
func GetActiveProfileString(key config.FieldKey) string {
return GetProfileString(GetActiveProfileName(), key)
}
// GetProfileString retrieves the value set for the given key and profile, if any.
// Environment variable overrides will be preferred over values set in the given
// profile, and a default value will be returned if it has been configured and no
// value has been set for the key in the given profile.
// An attempt will be made to convert the underlying value to a string if is not
// already stored that way. Failing the above, the zero value wil be returned.
func GetProfileString(profileName string, key config.FieldKey) string {
v, err := config.CredentialsProvider.GetStringWithScope(profileName, key)
if err != nil {
log.Debugf("could not load string value for key %s and profile %s, returning zero value: %s", key, profileName, err)
return ""
}
return v
}
// GetProfileInt retrieves the value set for the given key and profile, if any.
// Environment variable overrides will be preferred over values set in the given
// profile, and a default value will be returned if it has been configured and no
// value has been set for the key in the given profile.
// An attempt will be made to convert the underlying value to an int if is not
// already stored that way. Failing the above, the zero value wil be returned.
func GetProfileInt(profileName string, key config.FieldKey) int {
v, err := config.CredentialsProvider.GetIntWithScope(profileName, key)
if err != nil {
log.Debugf("could not load int value for key %s and profile %s, returning zero value: %s", key, profileName, err)
return 0
}
return int(v)
}
// SetProfileValue sets a value for the given key and profile.
func SetProfileValue(profileName string, key config.FieldKey, value interface{}) error {
return config.CredentialsProvider.SetWithScope(profileName, key, value)
}
// GetLogLevel retrieves the currently configured log level.
// When returning a log level, the following will be evaluated in order, short-circuiting
// and returning the described value if true:
// 1. An environment variable override has been set with NEW_RELIC_CLI_LOG_LEVEL
// 2. A log level has been provided with the `--trace` global flag
// 2. A log level has been provided with the `--debug` global flag
// 3. A log level has been set in the config file
// 4. If none of the above is true, the default log level will be returned.
func GetLogLevel() string {
var flag string
if config.FlagDebug {
flag = "debug"
}
if config.FlagTrace {
flag = "trace"
}
l, err := getConfigStringWithOverride(config.LogLevel, flag)
if err != nil {
return config.DefaultLogLevel
}
return l
}
// GetConfigString retrieves the config value set for the given key, if any.
// Environment variable overrides will be preferred over values set in the given
// profile, and a default value will be returned if it has been configured and no
// value has been set for the key in the config file.
// An attempt will be made to convert the underlying value to a string if is not
// already stored that way. Failing the above, the zero value wil be returned.
func GetConfigString(key config.FieldKey) string {
v, err := config.ConfigStore.GetString(key)
if err != nil {
log.Debugf("could not load string value for key %s, returning zero value: %s", key, err)
return ""
}
return v
}
// GetConfigTernary retrieves the config value set for the given key, if any.
// Environment variable overrides will be preferred over values set in the given
// profile, and a default value will be returned if it has been configured and no
// value has been set for the key in the config file.
// An attempt will be made to convert the underlying value to a Ternary if is not
// already stored that way. Failing the above, the zero value wil be returned.
func GetConfigTernary(key config.FieldKey) config.Ternary {
v, err := config.ConfigStore.GetTernary(key)
if err != nil {
log.Debugf("could not load Ternary value for key %s, returning zero value: %s", key, err)
return config.Ternary("")
}
return v
}
// SetConfigValue sets a config value for the given key.
func SetConfigValue(key config.FieldKey, value interface{}) error {
return config.ConfigStore.Set(key, value)
}
// DeleteConfigValue deletes a config value for the given key.
func DeleteConfigValue(key config.FieldKey) error {
return config.ConfigStore.DeleteKey(key)
}
// GetConfigFieldDefinition retrieves the field definition for the given config key.
func GetConfigFieldDefinition(key config.FieldKey) *config.FieldDefinition {
return config.ConfigStore.GetFieldDefinition(key)
}
// ForEachProfileFieldDefinition iterates the field definitions for the profile fields.
func ForEachProfileFieldDefinition(profileName string, fn func(d config.FieldDefinition)) {
config.CredentialsProvider.ForEachFieldDefinition(fn)
}
// ForEachConfigFieldDefinition iterates the field definitions for the config fields.
func ForEachConfigFieldDefinition(fn func(d config.FieldDefinition)) {
config.ConfigStore.ForEachFieldDefinition(fn)
}
// GetValidConfigFieldKeys returns all the config field keys that can be set.
func GetValidConfigFieldKeys() (fieldKeys []config.FieldKey) {
config.ConfigStore.ForEachFieldDefinition(func(fd config.FieldDefinition) {
fieldKeys = append(fieldKeys, fd.Key)
})
return fieldKeys
}
func getActiveProfileIntWithOverride(key config.FieldKey, override int) int {
return getProfileIntWithOverride(GetActiveProfileName(), key, override)
}
func getProfileIntWithOverride(profileName string, key config.FieldKey, override int) int {
o := int64(override)
v, err := config.CredentialsProvider.GetIntWithScopeAndOverride(profileName, key, &o)
if err != nil {
return 0
}
return int(v)
}
func getConfigStringWithOverride(key config.FieldKey, override string) (string, error) {
return config.ConfigStore.GetStringWithOverride(key, &override)
}
func removeDefaultProfile() error {
defaultProfileFilePath := filepath.Join(config.BasePath, config.DefaultProfileFileName)
return os.Remove(defaultProfileFilePath)
}