-
Notifications
You must be signed in to change notification settings - Fork 76
/
config_field_types.go
277 lines (232 loc) · 8.1 KB
/
config_field_types.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
package config
import (
"crypto/tls"
"fmt"
"strings"
"github.com/launchdarkly/ld-relay/v8/internal/credential"
"github.com/launchdarkly/go-sdk-common/v3/ldlog"
)
func errBadLogLevel(s string) error {
return fmt.Errorf("%q is not a valid log level", s)
}
func errBadTLSVersion(s string) error {
return fmt.Errorf("%q is not a valid TLS version", s)
}
// SDKKey is a type tag to indicate when a string is used as a server-side SDK key for a LaunchDarkly
// environment.
type SDKKey string
// MobileKey is a type tag to indicate when a string is used as a mobile key for a LaunchDarkly
// environment.
type MobileKey string
// EnvironmentID is a type tag to indicate when a string is used as a client-side environment ID for a
// LaunchDarkly environment.
type EnvironmentID string
// AutoConfigKey is a type tag to indicate when a string is used as an auto-configuration key.
type AutoConfigKey string
// FilterID represents the unique ID for a filter. It is different from the key, which is scoped to the project
// level.
type FilterID string
// FilterKey represents the key that should be used when making requests to LaunchDarkly in order to obtain
// a filtered environment.
type FilterKey string
// DefaultFilter represents the lack of a filter, meaning a full LaunchDarkly environment.
const DefaultFilter = FilterKey("")
// GetAuthorizationHeaderValue for SDKKey returns the same string, since SDK keys are passed in
// the Authorization header.
func (k SDKKey) GetAuthorizationHeaderValue() string {
return string(k)
}
func (k SDKKey) Defined() bool {
return k != ""
}
func (k SDKKey) String() string {
return string(k)
}
func (k SDKKey) Compare(cr credential.AutoConfig) (credential.SDKCredential, credential.Status) {
if cr.SDKKey == k {
return nil, credential.Unchanged
}
if cr.ExpiringSDKKey == k {
// If the AutoConfig update contains an ExpiringSDKKey that is equal to *this* key, then it means
// this key is now considered deprecated.
return cr.SDKKey, credential.Deprecated
} else {
// Otherwise if the AutoConfig update contains *some other* key, then it means this one must be considered
// expired.
return cr.SDKKey, credential.Expired
}
}
// GetAuthorizationHeaderValue for MobileKey returns the same string, since mobile keys are passed in the
// Authorization header.
func (k MobileKey) GetAuthorizationHeaderValue() string {
return string(k)
}
func (k MobileKey) Defined() bool {
return k != ""
}
func (k MobileKey) String() string {
return string(k)
}
func (k MobileKey) Compare(cr credential.AutoConfig) (credential.SDKCredential, credential.Status) {
if cr.MobileKey == k {
return nil, credential.Unchanged
}
return cr.MobileKey, credential.Expired
}
// GetAuthorizationHeaderValue for EnvironmentID returns an empty string, since environment IDs are not
// passed in a header but as part of the request URL.
func (k EnvironmentID) GetAuthorizationHeaderValue() string {
return ""
}
func (k EnvironmentID) Defined() bool {
return k != ""
}
func (k EnvironmentID) String() string {
return string(k)
}
func (k EnvironmentID) Compare(_ credential.AutoConfig) (credential.SDKCredential, credential.Status) {
// EnvironmentIDs should not change.
return nil, credential.Unchanged
}
// GetAuthorizationHeaderValue for AutoConfigKey returns the same string, since these keys are passed in
// the Authorization header. Note that unlike the other kinds of authorization keys, this one is never
// present in an incoming request; it is only used in requests from Relay to LaunchDarkly.
func (k AutoConfigKey) GetAuthorizationHeaderValue() string {
return string(k)
}
func (k AutoConfigKey) Compare(_ credential.AutoConfig) (credential.SDKCredential, credential.Status) {
// AutoConfigKeys should not change.
return nil, credential.Unchanged
}
func (k AutoConfigKey) String() string {
return string(k)
}
// UnmarshalText allows the SDKKey type to be set from environment variables.
func (k *SDKKey) UnmarshalText(data []byte) error {
*k = SDKKey(string(data))
return nil
}
// UnmarshalText allows the MobileKey type to be set from environment variables.
func (k *MobileKey) UnmarshalText(data []byte) error {
*k = MobileKey(string(data))
return nil
}
// UnmarshalText allows the EnvironmentID type to be set from environment variables.
func (k *EnvironmentID) UnmarshalText(data []byte) error {
*k = EnvironmentID(string(data))
return nil
}
// UnmarshalText allows the AutoConfigKey type to be set from environment variables.
func (k *AutoConfigKey) UnmarshalText(data []byte) error {
*k = AutoConfigKey(string(data))
return nil
}
func (k AutoConfigKey) Defined() bool {
return k != ""
}
// OptLogLevel represents an optional log level parameter. It must match one of the level names "debug",
// "info", "warn", or "error" (case-insensitive).
//
// The zero value OptLogLevel{} is valid and undefined (IsDefined() is false).
type OptLogLevel struct {
level ldlog.LogLevel
}
// NewOptLogLevel creates an OptLogLevel that wraps the given value.
func NewOptLogLevel(level ldlog.LogLevel) OptLogLevel {
return OptLogLevel{level: level}
}
// NewOptLogLevelFromString creates an OptLogLevel from a string that must either be a valid log level
// name or an empty string.
func NewOptLogLevelFromString(levelName string) (OptLogLevel, error) {
if levelName == "" {
return OptLogLevel{}, nil
}
for _, level := range []ldlog.LogLevel{ldlog.Debug, ldlog.Info, ldlog.Warn, ldlog.Error, ldlog.None} {
if strings.EqualFold(level.Name(), levelName) {
return NewOptLogLevel(level), nil
}
}
return OptLogLevel{}, errBadLogLevel(levelName)
}
// IsDefined returns true if the instance contains a value.
func (o OptLogLevel) IsDefined() bool {
return o.level != 0
}
// GetOrElse returns the wrapped value, or the alternative value if there is no value.
func (o OptLogLevel) GetOrElse(orElseValue ldlog.LogLevel) ldlog.LogLevel {
if o.level == 0 {
return orElseValue
}
return o.level
}
// UnmarshalText attempts to parse the value from a byte string, using the same logic as
// NewOptLogLevelFromString.
func (o *OptLogLevel) UnmarshalText(data []byte) error {
opt, err := NewOptLogLevelFromString(string(data))
if err == nil {
*o = opt
}
return err
}
// OptTLSVersion represents an optional TLS level parameter. When represented as a string, it must be
// "1.0", "1.1", "1.2", or "1.3". This is converted into a uint16 value as defined by crypto/tls.
type OptTLSVersion struct {
value uint16
}
// NewOptTLSVersion creates an OptTLSVersion that wraps the given value. It does not validate that the
// value is one supported by crypto/tls. A value of zero is equivalent to undefined.
func NewOptTLSVersion(value uint16) OptTLSVersion {
return OptTLSVersion{value}
}
// NewOptTLSVersionFromString creates an OptTLSVersion corresponding to the given version string, which must
// be either a valid TLS major and minor version ("1.2") or an empty string.
func NewOptTLSVersionFromString(version string) (OptTLSVersion, error) {
switch version {
case "":
return NewOptTLSVersion(0), nil
case "1.0":
return NewOptTLSVersion(tls.VersionTLS10), nil
case "1.1":
return NewOptTLSVersion(tls.VersionTLS11), nil
case "1.2":
return NewOptTLSVersion(tls.VersionTLS12), nil
case "1.3":
return NewOptTLSVersion(tls.VersionTLS13), nil
default:
return OptTLSVersion{}, errBadTLSVersion(version)
}
}
// IsDefined returns true if the instance contains a value.
func (o OptTLSVersion) IsDefined() bool {
return o.value != 0
}
// Get returns the wrapped value, or zero if there is no value.
func (o OptTLSVersion) Get() uint16 {
return o.value
}
// UnmarshalText attempts to parse the value from a byte string, using the same logic as
// NewOptTLSVersionFromString.
func (o *OptTLSVersion) UnmarshalText(data []byte) error {
opt, err := NewOptTLSVersionFromString(string(data))
if err == nil {
*o = opt
}
return err
}
// String returns a string description of the value.
func (o OptTLSVersion) String() string {
switch o.value {
case 0:
return ""
case tls.VersionTLS10:
return "1.0"
case tls.VersionTLS11:
return "1.1"
case tls.VersionTLS12:
return "1.2"
case tls.VersionTLS13:
return "1.3"
default:
return fmt.Sprintf("unknown (%d)", o.value)
}
}