diff --git a/pkg/services/featuremgmt/registry.go b/pkg/services/featuremgmt/registry.go index 55802717cb5..3539004062d 100644 --- a/pkg/services/featuremgmt/registry.go +++ b/pkg/services/featuremgmt/registry.go @@ -25,6 +25,7 @@ var ( Owner: grafanaAsCodeSquad, HideFromAdminPage: true, AllowSelfServe: false, + Expression: "false", }, { Name: "live-service-web-worker", @@ -82,6 +83,7 @@ var ( Stage: FeatureStageGeneralAvailability, Owner: grafanaAsCodeSquad, AllowSelfServe: true, + Expression: "false", }, { Name: "storage", @@ -521,6 +523,7 @@ var ( Stage: FeatureStageGeneralAvailability, FrontendOnly: true, Owner: grafanaObservabilityTracesAndProfilingSquad, + Expression: "false", }, { Name: "metricsSummary", @@ -1026,6 +1029,7 @@ var ( Stage: FeatureStageGeneralAvailability, Owner: grafanaAlertingSquad, AllowSelfServe: false, + Expression: "false", }, { Name: "newFolderPicker", @@ -1259,6 +1263,7 @@ var ( Stage: FeatureStageGeneralAvailability, Owner: identityAccessTeam, HideFromDocs: true, + Expression: "false", }, { Name: "alertingDisableSendAlertsExternal", diff --git a/pkg/services/featuremgmt/toggles_gen_test.go b/pkg/services/featuremgmt/toggles_gen_test.go index 82e6d99b765..ccadd1a46b3 100644 --- a/pkg/services/featuremgmt/toggles_gen_test.go +++ b/pkg/services/featuremgmt/toggles_gen_test.go @@ -25,46 +25,8 @@ import ( ) func TestFeatureToggleFiles(t *testing.T) { - legacyNames := map[string]bool{ - "live-service-web-worker": true, - } - t.Run("check registry constraints", func(t *testing.T) { - invalidNames := make([]string, 0) - - // Check that all flags set in code are valid - for _, flag := range standardFeatureFlags { - if flag.Expression == "true" && !(flag.Stage == FeatureStageGeneralAvailability || flag.Stage == FeatureStageDeprecated) { - t.Errorf("only FeatureStageGeneralAvailability or FeatureStageDeprecated features can be enabled by default. See: %s", flag.Name) - } - if flag.RequiresDevMode && flag.Stage != FeatureStageExperimental { - t.Errorf("only alpha features can require dev mode. See: %s", flag.Name) - } - if flag.Stage == FeatureStageUnknown { - t.Errorf("standard toggles should not have an unknown state. See: %s", flag.Name) - } - if flag.Description != strings.TrimSpace(flag.Description) { - t.Errorf("flag Description should not start/end with spaces. See: %s", flag.Name) - } - if flag.Name != strings.TrimSpace(flag.Name) { - t.Errorf("flag Name should not start/end with spaces. See: %s", flag.Name) - } - if flag.AllowSelfServe && !(flag.Stage == FeatureStageGeneralAvailability || flag.Stage == FeatureStagePublicPreview || flag.Stage == FeatureStageDeprecated) { - t.Errorf("only allow self-serving GA, PublicPreview and Deprecated toggles") - } - if flag.Owner == "" { - t.Errorf("feature %s does not have an owner. please fill the FeatureFlag.Owner property", flag.Name) - } - // Check camel case names - if flag.Name != strcase.ToLowerCamel(flag.Name) && !legacyNames[flag.Name] { - invalidNames = append(invalidNames, flag.Name) - } - } - - // Make sure the names are valid - require.Empty(t, invalidNames, "%s feature names should be camel cased", invalidNames) - // acronyms can be configured as needed via `ConfigureAcronym` function from `./strcase/camel.go` - + verifyFlagsConfiguration(t) // Now that we know they are valid, update the json database t.Run("update k8s resource list", func(t *testing.T) { created := v1.NewTime(time.Now().UTC()) @@ -180,6 +142,53 @@ func TestFeatureToggleFiles(t *testing.T) { }) } +// Check if all flags are configured properly +func verifyFlagsConfiguration(t *testing.T) { + legacyNames := map[string]bool{ + "live-service-web-worker": true, + } + invalidNames := make([]string, 0) + + // Check that all flags set in code are valid + for _, flag := range standardFeatureFlags { + if flag.Expression == "true" && !(flag.Stage == FeatureStageGeneralAvailability || flag.Stage == FeatureStageDeprecated) { + t.Errorf("only FeatureStageGeneralAvailability or FeatureStageDeprecated features can be enabled by default. See: %s", flag.Name) + } + if flag.RequiresDevMode && flag.Stage != FeatureStageExperimental { + t.Errorf("only alpha features can require dev mode. See: %s", flag.Name) + } + if flag.Stage == FeatureStageUnknown { + t.Errorf("standard toggles should not have an unknown state. See: %s", flag.Name) + } + if flag.Description != strings.TrimSpace(flag.Description) { + t.Errorf("flag Description should not start/end with spaces. See: %s", flag.Name) + } + if flag.Name != strings.TrimSpace(flag.Name) { + t.Errorf("flag Name should not start/end with spaces. See: %s", flag.Name) + } + if flag.AllowSelfServe && !(flag.Stage == FeatureStageGeneralAvailability || flag.Stage == FeatureStagePublicPreview || flag.Stage == FeatureStageDeprecated) { + t.Errorf("only allow self-serving GA, PublicPreview and Deprecated toggles") + } + if flag.Owner == "" { + t.Errorf("feature %s does not have an owner. please fill the FeatureFlag.Owner property", flag.Name) + } + if flag.Stage == FeatureStageGeneralAvailability && flag.Expression == "" { + t.Errorf("GA features must be explicitly enabled or disabled, please add the `Expression` property for %s", flag.Name) + } + if !(flag.Expression == "" || flag.Expression == "true" || flag.Expression == "false") { + t.Errorf("the `Expression` property for %s is incorrect. valid values are: `true`, `false` or empty string for default", flag.Name) + } + // Check camel case names + if flag.Name != strcase.ToLowerCamel(flag.Name) && !legacyNames[flag.Name] { + invalidNames = append(invalidNames, flag.Name) + } + } + + // Make sure the names are valid + require.Empty(t, invalidNames, "%s feature names should be camel cased", invalidNames) + // acronyms can be configured as needed via `ConfigureAcronym` function from `./strcase/camel.go` +} + func verifyAndGenerateFile(t *testing.T, fpath string, gen string) { // nolint:gosec // We can ignore the gosec G304 warning since this is a test and the function is only called explicitly above