-
Notifications
You must be signed in to change notification settings - Fork 291
/
flags.go
137 lines (121 loc) · 2.98 KB
/
flags.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
package feature
import (
"fmt"
)
// The status of a feature flag
// It starts as Active (we're using this flag to evaluate the feature)
// Then when we no longer need it, we make it a noop. Leave it for an upgrade cycle.
// Then move it to Obsolete, which will cause a warning. Leave it for an upgrade cycle.
// Then remove the flag altogether.
type Status int
const (
Active Status = iota
Noop
Obsolete
// After Obsolete is Error, but it's not a value we can set
)
const MultipleContainersPerPod = "multiple_containers_per_pod"
const Events = "events"
const Snapshots = "snapshots"
const UpdateHistory = "update_history"
const Facets = "facets"
const Labels = "labels"
const LiveUpdateV2 = "live_update_v2"
const DisableResources = "disable_resources"
const BulkDisableResources = "bulk_disable_resources"
// The Value a flag can have. Status should never be changed.
type Value struct {
Enabled bool
Status Status
}
// Defaults is the initial values for a FeatureSet.
// Don't modify after initializing.
type Defaults map[string]Value
// MainDefaults is the defaults we use in Main
var MainDefaults = Defaults{
MultipleContainersPerPod: Value{
Enabled: true,
Status: Obsolete,
},
Events: Value{
Enabled: true,
Status: Obsolete,
},
Snapshots: Value{
Enabled: true,
// Snapshots FF is used by disable_snapshots() which hides the button
// in the web UI
Status: Active,
},
UpdateHistory: Value{
Enabled: false,
Status: Obsolete,
},
Facets: Value{
Enabled: true,
Status: Obsolete,
},
Labels: Value{
Enabled: true,
Status: Obsolete,
},
LiveUpdateV2: Value{
Enabled: true,
Status: Active,
},
DisableResources: Value{
Enabled: true,
Status: Active,
},
BulkDisableResources: Value{
Enabled: false,
Status: Obsolete,
},
}
// FeatureSet is a mutable set of Features.
type FeatureSet map[string]Value
// Create a FeatureSet from defaults.
func FromDefaults(d Defaults) FeatureSet {
r := make(FeatureSet)
for k, v := range d {
r[k] = v
}
return r
}
// ObsoleteError is an error that a feature flag is obsolete
type ObsoleteError string
func (s ObsoleteError) Error() string {
return string(s)
}
// Set sets enabled for a feature if it's active. Returns an error if flag is unknown or obsolete.
func (s FeatureSet) Set(name string, enabled bool) error {
v, ok := s[name]
if !ok {
return fmt.Errorf("Unknown feature flag: %s", name)
}
switch v.Status {
case Obsolete:
return ObsoleteError(fmt.Sprintf("Obsolete feature flag: %s", name))
case Noop:
return nil
}
v.Enabled = enabled
s[name] = v
return nil
}
// Get gets whether a feature is enabled.
func (s FeatureSet) Get(name string) bool {
v, ok := s[name]
if !ok {
panic("get of unknown feature flag (code should use feature.Foo instead of \"foo\" to get a flag)")
}
return v.Enabled
}
// ToEnabled returns a copy of the enabled values of the FeatureSet
func (s FeatureSet) ToEnabled() map[string]bool {
r := make(map[string]bool)
for k, v := range s {
r[k] = v.Enabled
}
return r
}