Skip to content

Commit 809312a

Browse files
authored
Add method to get all enabled feature flags for a user (#187)
In buildbot, we want to start passing feature flags down to netlify build. To do so, we need a method to get all enabled flags for a user. For this particular case, we only care about boolean ones. This adds a method to the featureflag package to do so. LanuchDarkly's Go SDK provides a way to get all flags for a user, so we wrap that in another method to select just the enabled boolean ones. For tests, it uses the file config as suggested by LaunchDarkly docs: https://docs.launchdarkly.com/sdk/concepts/flags-from-files
1 parent 5f0cbe7 commit 809312a

File tree

7 files changed

+65
-5
lines changed

7 files changed

+65
-5
lines changed

featureflag/config.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
package featureflag
22

3-
import "time"
3+
import (
4+
"time"
5+
6+
ld "gopkg.in/launchdarkly/go-server-sdk.v4"
7+
)
48

59
type Config struct {
6-
Key string
7-
RequestTimeout time.Duration `mapstructure:"request_timeout" split_words:"true" default:"5s"`
8-
Enabled bool `default:"false"`
10+
Key string
11+
RequestTimeout time.Duration `mapstructure:"request_timeout" split_words:"true" default:"5s"`
12+
Enabled bool `default:"false"`
13+
updateProcessorFactory ld.UpdateProcessorFactory
914
}

featureflag/featureflag.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ type Client interface {
1414

1515
Variation(key, defaultVal, userID string) string
1616
VariationUser(key string, defaultVal string, user ld.User) string
17+
18+
AllEnabledFlags(key string) []string
1719
}
1820

1921
type ldClient struct {
@@ -30,6 +32,11 @@ func NewClient(cfg *Config, logger logrus.FieldLogger) (Client, error) {
3032
config.Offline = true
3133
}
3234

35+
if cfg.updateProcessorFactory != nil {
36+
config.UpdateProcessorFactory = cfg.updateProcessorFactory
37+
config.SendEvents = false
38+
}
39+
3340
if logger == nil {
3441
logger = noopLogger()
3542
}
@@ -65,6 +72,23 @@ func (c *ldClient) VariationUser(key string, defaultVal string, user ld.User) st
6572
return res
6673
}
6774

75+
func (c *ldClient) AllEnabledFlags(key string) []string {
76+
res := c.AllFlagsState(ld.NewUser(key), ld.DetailsOnlyForTrackedFlags)
77+
flagMap := res.ToValuesMap()
78+
79+
var flags []string
80+
for flag, value := range flagMap {
81+
switch value.(type) {
82+
case bool:
83+
if value == true {
84+
flags = append(flags, flag)
85+
}
86+
}
87+
}
88+
89+
return flags
90+
}
91+
6892
func noopLogger() *logrus.Logger {
6993
l := logrus.New()
7094
l.SetOutput(ioutil.Discard)

featureflag/featureflag_test.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"time"
66

77
"github.com/stretchr/testify/require"
8+
"gopkg.in/launchdarkly/go-server-sdk.v4/ldfiledata"
89
)
910

1011
func TestOfflineClient(t *testing.T) {
@@ -39,3 +40,19 @@ func TestMockClient(t *testing.T) {
3940
require.Equal(t, "BAR", mock.Variation("FOO", "DFLT", "12345"))
4041
require.Equal(t, "DFLT", mock.Variation("FOOBAR", "DFLT", "12345"))
4142
}
43+
44+
func TestAllEnabledFlags(t *testing.T) {
45+
fileSource := ldfiledata.NewFileDataSourceFactory(ldfiledata.FilePaths("./fixtures/flags.yml"))
46+
cfg := Config{
47+
Key: "ABCD",
48+
RequestTimeout: time.Second,
49+
Enabled: true,
50+
updateProcessorFactory: fileSource,
51+
}
52+
client, err := NewClient(&cfg, nil)
53+
require.NoError(t, err)
54+
55+
flags := client.AllEnabledFlags("userid")
56+
57+
require.Equal(t, []string{"my-boolean-flag-key"}, flags)
58+
}

featureflag/fixtures/flags.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
flagValues:
2+
my-string-flag-key: "value-1"
3+
my-boolean-flag-key: true
4+
my-boolean-off-flag-key: false
5+
my-integer-flag-key: 3

featureflag/mock.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package featureflag
22

3-
import ld "gopkg.in/launchdarkly/go-server-sdk.v4"
3+
import (
4+
ld "gopkg.in/launchdarkly/go-server-sdk.v4"
5+
)
46

57
type MockClient struct {
68
BoolVars map[string]bool
@@ -28,3 +30,7 @@ func (c MockClient) VariationUser(key string, defaultVal string, _ ld.User) stri
2830
}
2931
return res
3032
}
33+
34+
func (c MockClient) AllEnabledFlags(string) []string {
35+
return []string{}
36+
}

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ require (
4949
golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc
5050
gopkg.in/DataDog/dd-trace-go.v1 v1.26.0
5151
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
52+
gopkg.in/ghodss/yaml.v1 v1.0.0 // indirect
5253
gopkg.in/launchdarkly/go-sdk-common.v1 v1.0.0-20200401173443-991b2f427a01 // indirect
5354
gopkg.in/launchdarkly/go-server-sdk.v4 v4.0.0-20200729232655-2a44fb361895
5455
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,8 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8
558558
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
559559
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
560560
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
561+
gopkg.in/ghodss/yaml.v1 v1.0.0 h1:JlY4R6oVz+ZSvcDhVfNQ/k/8Xo6yb2s1PBhslPZPX4c=
562+
gopkg.in/ghodss/yaml.v1 v1.0.0/go.mod h1:HDvRMPQLqycKPs9nWLuzZWxsxRzISLCRORiDpBUOMqg=
561563
gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno=
562564
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
563565
gopkg.in/launchdarkly/go-sdk-common.v1 v1.0.0-20200204015611-d48d1b4f4e70/go.mod h1:2kE5FCTDQ53bqRSOfJpE5fdiAQYiN9LESONDNyEBFjI=

0 commit comments

Comments
 (0)