Extend OpenFeature service (#106707)
This commit is contained in:
@@ -476,6 +476,9 @@ type Cfg struct {
|
||||
// Query history
|
||||
QueryHistoryEnabled bool
|
||||
|
||||
// Open feature settings
|
||||
OpenFeature OpenFeatureSettings
|
||||
|
||||
Storage StorageSettings
|
||||
|
||||
Search SearchSettings
|
||||
@@ -1319,6 +1322,11 @@ func (cfg *Cfg) parseINIFile(iniFile *ini.File) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := cfg.readOpenFeatureSettings(); err != nil {
|
||||
cfg.Logger.Error("Failed to read open feature settings", "error", err)
|
||||
return err
|
||||
}
|
||||
|
||||
cfg.readDataSourcesSettings()
|
||||
cfg.readDataSourceSecuritySettings()
|
||||
cfg.readK8sDashboardCleanupSettings()
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
package setting
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
const (
|
||||
StaticProviderType = "static"
|
||||
GOFFProviderType = "goff"
|
||||
)
|
||||
|
||||
type OpenFeatureSettings struct {
|
||||
ProviderType string
|
||||
URL *url.URL
|
||||
TargetingKey string
|
||||
ContextAttrs map[string]any
|
||||
}
|
||||
|
||||
func (cfg *Cfg) readOpenFeatureSettings() error {
|
||||
cfg.OpenFeature = OpenFeatureSettings{}
|
||||
|
||||
config := cfg.Raw.Section("feature_toggles.openfeature")
|
||||
cfg.OpenFeature.ProviderType = config.Key("provider").MustString(StaticProviderType)
|
||||
cfg.OpenFeature.TargetingKey = config.Key("targetingKey").MustString(cfg.AppURL)
|
||||
|
||||
strURL := config.Key("url").MustString("")
|
||||
|
||||
if strURL != "" && cfg.OpenFeature.ProviderType == GOFFProviderType {
|
||||
u, err := url.Parse(strURL)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid feature provider url: %w", err)
|
||||
}
|
||||
cfg.OpenFeature.URL = u
|
||||
}
|
||||
|
||||
// build the eval context attributes using [feature_toggles.openfeature.context] section
|
||||
ctxConf := cfg.Raw.Section("feature_toggles.openfeature.context")
|
||||
attrs := map[string]any{}
|
||||
for _, key := range ctxConf.KeyStrings() {
|
||||
attrs[key] = ctxConf.Key(key).String()
|
||||
}
|
||||
|
||||
// Some default attributes
|
||||
if _, ok := attrs["grafana_version"]; !ok {
|
||||
attrs["grafana_version"] = BuildVersion
|
||||
}
|
||||
|
||||
cfg.OpenFeature.ContextAttrs = attrs
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package setting
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func Test_CtxAttrs(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
conf string
|
||||
expected map[string]any
|
||||
}{
|
||||
{
|
||||
name: "empty config - only default attributes should be present",
|
||||
expected: map[string]any{
|
||||
"grafana_version": "",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "config with some attributes",
|
||||
conf: `
|
||||
[feature_toggles.openfeature.context]
|
||||
foo = bar
|
||||
baz = qux
|
||||
quux = corge`,
|
||||
expected: map[string]any{
|
||||
"foo": "bar",
|
||||
"baz": "qux",
|
||||
"quux": "corge",
|
||||
"grafana_version": "",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "config with an attribute that overrides a default one",
|
||||
conf: `
|
||||
[feature_toggles.openfeature.context]
|
||||
grafana_version = 10.0.0
|
||||
foo = bar`,
|
||||
expected: map[string]any{
|
||||
"grafana_version": "10.0.0",
|
||||
"foo": "bar",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
cfg, err := NewCfgFromBytes([]byte(tc.conf))
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, tc.expected, cfg.OpenFeature.ContextAttrs)
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user