diff --git a/pkg/services/featuremgmt/models.go b/pkg/services/featuremgmt/models.go index cb378155956..596cfcb2491 100644 --- a/pkg/services/featuremgmt/models.go +++ b/pkg/services/featuremgmt/models.go @@ -130,9 +130,9 @@ type FeatureFlagType int const ( Boolean FeatureFlagType = iota - String Integer Float + String Structure ) @@ -141,13 +141,13 @@ func (t FeatureFlagType) String() string { case Boolean: return "boolean" case Integer: - return "number" + return "integer" case Float: return "float" - case Structure: - return "object" case String: return "string" + case Structure: + return "structure" } return "unknown" @@ -171,14 +171,14 @@ func (t *FeatureFlagType) UnmarshalJSON(b []byte) error { switch j { case "boolean": *t = Boolean - case "number": + case "integer": *t = Integer case "float": *t = Float - case "object": - *t = Structure case "string": *t = String + case "structure": + *t = Structure } return nil } diff --git a/pkg/services/featuremgmt/static_provider.go b/pkg/services/featuremgmt/static_provider.go index 9554c2a5ba4..183cc29bf23 100644 --- a/pkg/services/featuremgmt/static_provider.go +++ b/pkg/services/featuremgmt/static_provider.go @@ -43,11 +43,17 @@ func newStaticProvider(confFlags map[string]bool, standardFlags []FeatureFlag) ( for _, flag := range standardFlags { _, exists := flags[flag.Name] + // Fail fast if a flag is declared with a mismatched type if exists && flag.Type != Boolean { return nil, fmt.Errorf("flag %s already declared as boolean", flag.Name) } - inMemFlag, err := createFlag(flag) + // config.ini take precedence over code + if exists { + continue + } + + inMemFlag, err := createTypedFlag(flag) if err != nil { return nil, err } @@ -74,7 +80,7 @@ func createInMemoryFlag(name string, enabled bool) memprovider.InMemoryFlag { } } -func createFlag(flag FeatureFlag) (memprovider.InMemoryFlag, error) { +func createTypedFlag(flag FeatureFlag) (memprovider.InMemoryFlag, error) { defaultVariant := "default" var value any @@ -82,12 +88,12 @@ func createFlag(flag FeatureFlag) (memprovider.InMemoryFlag, error) { switch flag.Type { case Boolean: value = flag.Expression == "true" - case String: - value = flag.Expression case Integer: value, err = strconv.Atoi(flag.Expression) case Float: value, err = strconv.ParseFloat(flag.Expression, 64) + case String: + value = flag.Expression case Structure: err = json.Unmarshal([]byte(flag.Expression), &value) default: diff --git a/pkg/services/featuremgmt/static_provider_test.go b/pkg/services/featuremgmt/static_provider_test.go index 01ddcd8dc2e..ec1bf1b940d 100644 --- a/pkg/services/featuremgmt/static_provider_test.go +++ b/pkg/services/featuremgmt/static_provider_test.go @@ -94,7 +94,7 @@ ABCD = true assert.Equal(t, openFeatureEnabledFlags, enabledFeatureManager) } -func Test_StaticProvider_DifferentTypeFlagsNoSilentIgnore(t *testing.T) { +func Test_StaticProvider_FailfastOnMismatchedType(t *testing.T) { staticFlags := map[string]bool{"oldBooleanFlag": true} flag := FeatureFlag{ @@ -106,7 +106,7 @@ func Test_StaticProvider_DifferentTypeFlagsNoSilentIgnore(t *testing.T) { assert.EqualError(t, err, "flag oldBooleanFlag already declared as boolean") } -func Test_StaticProvider_DifferentType(t *testing.T) { +func Test_StaticProvider_TypedFlags(t *testing.T) { tests := []struct { flags FeatureFlag defaultValue any