diff --git a/docs/sources/alerting/alerting-rules/create-recording-rules/create-grafana-managed-recording-rules.md b/docs/sources/alerting/alerting-rules/create-recording-rules/create-grafana-managed-recording-rules.md index 13b5a957ffd..2a37f3cf270 100644 --- a/docs/sources/alerting/alerting-rules/create-recording-rules/create-grafana-managed-recording-rules.md +++ b/docs/sources/alerting/alerting-rules/create-recording-rules/create-grafana-managed-recording-rules.md @@ -63,9 +63,7 @@ To configure Grafana-managed recording rules, complete the following steps. This section only applies to Grafana OSS and Grafana Enterprise. -First, enable the `grafanaManagedRecordingRules` [feature flag](ref:configure-feature-toggles). - -Then, enable the feature by setting `enabled = true` in the `[recording_rules]` section of the Grafana config .ini. Provide the URL of your Prometheus-compatible remote-write endpoint in the `url` field, along with optional credentials or headers. +Enable the feature by setting `enabled = true` in the `[recording_rules]` section of the Grafana configuration file. Provide the URL of your Prometheus-compatible remote-write endpoint in the `url` field, along with optional credentials or headers. ``` [recording_rules] diff --git a/packages/grafana-data/src/types/featureToggles.gen.ts b/packages/grafana-data/src/types/featureToggles.gen.ts index 15a3e6ba701..73cc3a18b7a 100644 --- a/packages/grafana-data/src/types/featureToggles.gen.ts +++ b/packages/grafana-data/src/types/featureToggles.gen.ts @@ -558,10 +558,6 @@ export interface FeatureToggles { */ disableNumericMetricsSortingInExpressions?: boolean; /** - * Enables Grafana-managed recording rules. - */ - grafanaManagedRecordingRules?: boolean; - /** * Enables Query Library feature in Explore */ queryLibrary?: boolean; diff --git a/pkg/services/featuremgmt/registry.go b/pkg/services/featuremgmt/registry.go index 45fc3f955e6..0a4a0efda57 100644 --- a/pkg/services/featuremgmt/registry.go +++ b/pkg/services/featuremgmt/registry.go @@ -951,15 +951,6 @@ var ( Owner: grafanaOSSBigTent, RequiresRestart: true, }, - { - Name: "grafanaManagedRecordingRules", - Description: "Enables Grafana-managed recording rules.", - Stage: FeatureStageExperimental, - Owner: grafanaAlertingSquad, - AllowSelfServe: false, - HideFromDocs: true, - HideFromAdminPage: true, - }, { Name: "queryLibrary", Description: "Enables Query Library feature in Explore", diff --git a/pkg/services/featuremgmt/toggles_gen.csv b/pkg/services/featuremgmt/toggles_gen.csv index ffbae23fc96..e692911b325 100644 --- a/pkg/services/featuremgmt/toggles_gen.csv +++ b/pkg/services/featuremgmt/toggles_gen.csv @@ -123,7 +123,6 @@ oauthRequireSubClaim,experimental,@grafana/identity-access-team,false,false,fals newDashboardWithFiltersAndGroupBy,experimental,@grafana/dashboards-squad,false,false,false cloudWatchNewLabelParsing,GA,@grafana/aws-datasources,false,false,false disableNumericMetricsSortingInExpressions,experimental,@grafana/oss-big-tent,false,true,false -grafanaManagedRecordingRules,experimental,@grafana/alerting-squad,false,false,false queryLibrary,experimental,@grafana/grafana-frontend-platform,false,false,false logsExploreTableDefaultVisualization,experimental,@grafana/observability-logs,false,false,true newDashboardSharingComponent,GA,@grafana/sharing-squad,false,false,true diff --git a/pkg/services/featuremgmt/toggles_gen.go b/pkg/services/featuremgmt/toggles_gen.go index 05a693b67e7..92efdb79dd4 100644 --- a/pkg/services/featuremgmt/toggles_gen.go +++ b/pkg/services/featuremgmt/toggles_gen.go @@ -503,10 +503,6 @@ const ( // In server-side expressions, disable the sorting of numeric-kind metrics by their metric name or labels. FlagDisableNumericMetricsSortingInExpressions = "disableNumericMetricsSortingInExpressions" - // FlagGrafanaManagedRecordingRules - // Enables Grafana-managed recording rules. - FlagGrafanaManagedRecordingRules = "grafanaManagedRecordingRules" - // FlagQueryLibrary // Enables Query Library feature in Explore FlagQueryLibrary = "queryLibrary" diff --git a/pkg/services/featuremgmt/toggles_gen.json b/pkg/services/featuremgmt/toggles_gen.json index a755f0a79aa..f3c389fd743 100644 --- a/pkg/services/featuremgmt/toggles_gen.json +++ b/pkg/services/featuremgmt/toggles_gen.json @@ -1401,7 +1401,8 @@ "metadata": { "name": "grafanaManagedRecordingRules", "resourceVersion": "1743693517832", - "creationTimestamp": "2024-04-22T17:53:16Z" + "creationTimestamp": "2024-04-22T17:53:16Z", + "deletionTimestamp": "2025-05-16T18:56:20Z" }, "spec": { "description": "Enables Grafana-managed recording rules.", diff --git a/pkg/services/ngalert/api/api_provisioning.go b/pkg/services/ngalert/api/api_provisioning.go index 62ea856e021..aebdab68292 100644 --- a/pkg/services/ngalert/api/api_provisioning.go +++ b/pkg/services/ngalert/api/api_provisioning.go @@ -344,14 +344,6 @@ func (srv *ProvisioningSrv) RoutePostAlertRule(c *contextmodel.ReqContext, ar de return ErrResp(http.StatusBadRequest, err, "") } - if upstreamModel.Type() == alerting_models.RuleTypeRecording && !srv.featureManager.IsEnabledGlobally(featuremgmt.FlagGrafanaManagedRecordingRules) { - return ErrResp( - http.StatusBadRequest, - fmt.Errorf("%w: recording rules cannot be created on this instance", alerting_models.ErrAlertRuleFailedValidation), - "", - ) - } - provenance := determineProvenance(c) createdAlertRule, err := srv.alertRules.CreateAlertRule(c.Req.Context(), c.SignedInUser, upstreamModel, alerting_models.Provenance(provenance)) if errors.Is(err, alerting_models.ErrAlertRuleFailedValidation) { @@ -377,14 +369,6 @@ func (srv *ProvisioningSrv) RoutePutAlertRule(c *contextmodel.ReqContext, ar def ErrResp(http.StatusBadRequest, err, "") } - if updated.Type() == alerting_models.RuleTypeRecording && !srv.featureManager.IsEnabledGlobally(featuremgmt.FlagGrafanaManagedRecordingRules) { - return ErrResp( - http.StatusBadRequest, - fmt.Errorf("%w: recording rules cannot be created on this instance", alerting_models.ErrAlertRuleFailedValidation), - "", - ) - } - if UID == "" { // If there is no UID, return 404 as the UID is part of the URL. return response.Empty(http.StatusNotFound) diff --git a/pkg/services/ngalert/api/api_provisioning_test.go b/pkg/services/ngalert/api/api_provisioning_test.go index 934d9c41435..57d4ee33848 100644 --- a/pkg/services/ngalert/api/api_provisioning_test.go +++ b/pkg/services/ngalert/api/api_provisioning_test.go @@ -534,95 +534,46 @@ func TestProvisioningApi(t *testing.T) { }) t.Run("recording rules", func(t *testing.T) { - t.Run("are enabled", func(t *testing.T) { - env := createTestEnv(t, testConfig) - env.features = featuremgmt.WithFeatures(featuremgmt.FlagGrafanaManagedRecordingRules) + env := createTestEnv(t, testConfig) - t.Run("POST returns 201", func(t *testing.T) { - sut := createProvisioningSrvSutFromEnv(t, &env) - rc := createTestRequestCtx() - rule := createTestRecordingRule("rule", 1) + t.Run("POST returns 201", func(t *testing.T) { + sut := createProvisioningSrvSutFromEnv(t, &env) + rc := createTestRequestCtx() + rule := createTestRecordingRule("rule", 1) - response := sut.RoutePostAlertRule(&rc, rule) + response := sut.RoutePostAlertRule(&rc, rule) - require.Equal(t, 201, response.Status()) - }) - - t.Run("PUT returns 200", func(t *testing.T) { - sut := createProvisioningSrvSutFromEnv(t, &env) - uid := util.GenerateShortUID() - rule := createTestAlertRule("rule", 3) - rule.UID = uid - - _, err := sut.folderSvc.Create(context.Background(), &folder.CreateFolderCommand{ - UID: rule.FolderUID, - Title: "Folder Title", - OrgID: rule.OrgID, - SignedInUser: &user.SignedInUser{OrgID: rule.OrgID}, - }) - require.NoError(t, err) - - insertRuleInOrg(t, sut, rule, 3) - - // make rule a recording rule - rule.Record = &definitions.Record{ - Metric: "test_metric", - From: "A", - } - - rc := createTestRequestCtx() - rc.OrgID = 3 - - response := sut.RoutePutAlertRule(&rc, rule, rule.UID) - - require.Equal(t, 200, response.Status()) - }) + require.Equal(t, 201, response.Status()) }) - t.Run("are not enabled", func(t *testing.T) { - t.Run("POST returns 400", func(t *testing.T) { - sut := createProvisioningSrvSut(t) - rc := createTestRequestCtx() - rule := createTestRecordingRule("rule", 1) + t.Run("PUT returns 200", func(t *testing.T) { + sut := createProvisioningSrvSutFromEnv(t, &env) + uid := util.GenerateShortUID() + rule := createTestAlertRule("rule", 3) + rule.UID = uid - response := sut.RoutePostAlertRule(&rc, rule) - - require.Equal(t, 400, response.Status()) - require.NotEmpty(t, response.Body()) - require.Contains(t, string(response.Body()), "recording rules cannot be created on this instance") + _, err := sut.folderSvc.Create(context.Background(), &folder.CreateFolderCommand{ + UID: rule.FolderUID, + Title: "Folder Title", + OrgID: rule.OrgID, + SignedInUser: &user.SignedInUser{OrgID: rule.OrgID}, }) + require.NoError(t, err) - t.Run("PUT returns 400", func(t *testing.T) { - sut := createProvisioningSrvSut(t) - uid := util.GenerateShortUID() - rule := createTestAlertRule("rule", 3) - rule.UID = uid + insertRuleInOrg(t, sut, rule, 3) - _, err := sut.folderSvc.Create(context.Background(), &folder.CreateFolderCommand{ - UID: rule.FolderUID, - Title: "Folder Title", - OrgID: rule.OrgID, - SignedInUser: &user.SignedInUser{OrgID: rule.OrgID}, - }) - require.NoError(t, err) + // make rule a recording rule + rule.Record = &definitions.Record{ + Metric: "test_metric", + From: "A", + } - insertRuleInOrg(t, sut, rule, 3) + rc := createTestRequestCtx() + rc.OrgID = 3 - // make rule a recording rule - rule.Record = &definitions.Record{ - Metric: "test_metric", - From: "A", - } + response := sut.RoutePutAlertRule(&rc, rule, rule.UID) - rc := createTestRequestCtx() - rc.OrgID = 3 - - response := sut.RoutePutAlertRule(&rc, rule, rule.UID) - - require.Equal(t, 400, response.Status()) - require.NotEmpty(t, response.Body()) - require.Contains(t, string(response.Body()), "recording rules cannot be created on this instance") - }) + require.Equal(t, 200, response.Status()) }) }) diff --git a/pkg/services/ngalert/api/api_ruler_test.go b/pkg/services/ngalert/api/api_ruler_test.go index 43b13ccf9a1..d2abec97e7d 100644 --- a/pkg/services/ngalert/api/api_ruler_test.go +++ b/pkg/services/ngalert/api/api_ruler_test.go @@ -974,7 +974,6 @@ func createService(store *fakes.RuleStore, _userService *usertest.FakeUserServic authz: accesscontrol.NewRuleService(acimpl.ProvideAccessControl(featuremgmt.WithFeatures())), amConfigStore: &fakeAMRefresher{}, amRefresher: &fakeAMRefresher{}, - featureManager: featuremgmt.WithFeatures(featuremgmt.FlagGrafanaManagedRecordingRules), userService: userService, conditionValidator: &recordingConditionValidator{}, } diff --git a/pkg/services/ngalert/api/api_ruler_validation_test.go b/pkg/services/ngalert/api/api_ruler_validation_test.go index 7893766f41d..f9bd07346db 100644 --- a/pkg/services/ngalert/api/api_ruler_validation_test.go +++ b/pkg/services/ngalert/api/api_ruler_validation_test.go @@ -51,11 +51,6 @@ func makeLimits(cfg *setting.UnifiedAlertingSettings) RuleLimits { return RuleLimitsFromConfig(cfg, baseToggles) } -func allowRecording(lim RuleLimits) *RuleLimits { - lim.RecordingRulesAllowed = true - return &lim -} - func validRule() apimodels.PostableExtendedRuleNode { forDuration := model.Duration(rand.Int64N(1000)) keepFiringForDuration := model.Duration(rand.Int64N(1000)) @@ -447,8 +442,7 @@ func TestValidateRuleNode_NoUID(t *testing.T) { }, }, { - name: "accepts and converts recording rule when toggle is enabled", - limits: allowRecording(limits), + name: "accepts and converts recording rule", rule: func() *apimodels.PostableExtendedRuleNode { r := validRule() r.GrafanaManagedAlert.Record = &apimodels.Record{Metric: "some_metric", From: "A"} @@ -489,8 +483,7 @@ func TestValidateRuleNode_NoUID(t *testing.T) { }, }, { - name: "recording rules ignore fields that only make sense for Alerting rules", - limits: allowRecording(limits), + name: "recording rules ignore fields that only make sense for Alerting rules", rule: func() *apimodels.PostableExtendedRuleNode { r := validRule() r.GrafanaManagedAlert.Record = &apimodels.Record{Metric: "some_metric", From: "A"} @@ -673,22 +666,7 @@ func TestValidateRuleNodeFailures_NoUID(t *testing.T) { }, }, { - name: "rejects valid recording rules if toggle is disabled", - rule: func() *apimodels.PostableExtendedRuleNode { - r := validRule() - r.GrafanaManagedAlert.Record = &apimodels.Record{Metric: "some_metric", From: "A"} - r.GrafanaManagedAlert.Condition = "" - r.GrafanaManagedAlert.NoDataState = "" - r.GrafanaManagedAlert.ExecErrState = "" - r.GrafanaManagedAlert.NotificationSettings = nil - r.For = nil - return &r - }, - expErr: "recording rules cannot be created", - }, - { - name: "rejects recording rule with invalid metric name", - limits: allowRecording(limits), + name: "rejects recording rule with invalid metric name", rule: func() *apimodels.PostableExtendedRuleNode { r := validRule() r.GrafanaManagedAlert.Record = &apimodels.Record{Metric: "", From: "A"} @@ -702,8 +680,7 @@ func TestValidateRuleNodeFailures_NoUID(t *testing.T) { expErr: "must be a valid Prometheus metric name", }, { - name: "rejects recording rule with empty from", - limits: allowRecording(limits), + name: "rejects recording rule with empty from", rule: func() *apimodels.PostableExtendedRuleNode { r := validRule() r.GrafanaManagedAlert.Record = &apimodels.Record{Metric: "my_metric", From: ""} @@ -717,8 +694,7 @@ func TestValidateRuleNodeFailures_NoUID(t *testing.T) { expErr: "cannot be empty", }, { - name: "rejects recording rule with from not matching", - limits: allowRecording(limits), + name: "rejects recording rule with from not matching", rule: func() *apimodels.PostableExtendedRuleNode { r := validRule() r.GrafanaManagedAlert.Record = &apimodels.Record{Metric: "my_metric", From: "NOTEXIST"} diff --git a/pkg/services/ngalert/api/validation/api_ruler_validation.go b/pkg/services/ngalert/api/validation/api_ruler_validation.go index 9fa98159979..01d0b430cef 100644 --- a/pkg/services/ngalert/api/validation/api_ruler_validation.go +++ b/pkg/services/ngalert/api/validation/api_ruler_validation.go @@ -23,15 +23,12 @@ type RuleLimits struct { DefaultRuleEvaluationInterval time.Duration // All intervals must be an integer multiple of this duration. BaseInterval time.Duration - // Whether recording rules are allowed. - RecordingRulesAllowed bool } func RuleLimitsFromConfig(cfg *setting.UnifiedAlertingSettings, toggles featuremgmt.FeatureToggles) RuleLimits { return RuleLimits{ DefaultRuleEvaluationInterval: cfg.DefaultRuleEvaluationInterval, BaseInterval: cfg.BaseInterval, - RecordingRulesAllowed: toggles.IsEnabledGlobally(featuremgmt.FlagGrafanaManagedRecordingRules), } } @@ -176,10 +173,6 @@ func validateAlertingRuleFields(in *apimodels.PostableExtendedRuleNode, newRule // validateRecordingRuleFields validates only the fields on a rule that are specific to Recording rules. // it will load fields that pass validation onto newRule and return the result. func validateRecordingRuleFields(in *apimodels.PostableExtendedRuleNode, newRule ngmodels.AlertRule, limits RuleLimits, canPatch bool) (ngmodels.AlertRule, error) { - if !limits.RecordingRulesAllowed { - return ngmodels.AlertRule{}, fmt.Errorf("%w: recording rules cannot be created on this instance", ngmodels.ErrAlertRuleFailedValidation) - } - err := ValidateCondition(in.GrafanaManagedAlert.Record.From, in.GrafanaManagedAlert.Data, canPatch) if err != nil { return ngmodels.AlertRule{}, fmt.Errorf("%w: %s", ngmodels.ErrAlertRuleFailedValidation, err.Error()) diff --git a/pkg/services/ngalert/ngalert.go b/pkg/services/ngalert/ngalert.go index bf764a3647b..aaad47e2d0e 100644 --- a/pkg/services/ngalert/ngalert.go +++ b/pkg/services/ngalert/ngalert.go @@ -317,10 +317,6 @@ func (ng *AlertNG) init() error { evalFactory := eval.NewEvaluatorFactory(ng.Cfg.UnifiedAlerting, ng.DataSourceCache, ng.ExpressionService) conditionValidator := eval.NewConditionValidator(ng.DataSourceCache, ng.ExpressionService, ng.pluginsStore) - if !ng.FeatureToggles.IsEnabled(initCtx, featuremgmt.FlagGrafanaManagedRecordingRules) { - // Force-disable the feature if the feature toggle is not on - sets us up for feature toggle removal. - ng.Cfg.UnifiedAlerting.RecordingRules.Enabled = false - } recordingWriter, err := createRecordingWriter(ng.FeatureToggles, ng.Cfg.UnifiedAlerting.RecordingRules, ng.httpClientProvider, ng.DataSourceService, clk, ng.Metrics.GetRemoteWriterMetrics()) if err != nil { return fmt.Errorf("failed to initialize recording writer: %w", err) diff --git a/pkg/tests/api/alerting/api_convert_prometheus_notification_settings_test.go b/pkg/tests/api/alerting/api_convert_prometheus_notification_settings_test.go index a7c2dbe7d9d..6d3fa39b6d5 100644 --- a/pkg/tests/api/alerting/api_convert_prometheus_notification_settings_test.go +++ b/pkg/tests/api/alerting/api_convert_prometheus_notification_settings_test.go @@ -30,7 +30,7 @@ func TestIntegrationConvertPrometheusNotificationSettings(t *testing.T) { EnableUnifiedAlerting: true, DisableAnonymous: true, AppModeProduction: true, - EnableFeatureToggles: []string{"grafanaManagedRecordingRulesDatasources", "grafanaManagedRecordingRules"}, + EnableFeatureToggles: []string{"grafanaManagedRecordingRulesDatasources"}, EnableRecordingRules: true, }) diff --git a/pkg/tests/api/alerting/api_convert_prometheus_test.go b/pkg/tests/api/alerting/api_convert_prometheus_test.go index 9c9cf46e10d..0fe98677227 100644 --- a/pkg/tests/api/alerting/api_convert_prometheus_test.go +++ b/pkg/tests/api/alerting/api_convert_prometheus_test.go @@ -113,7 +113,7 @@ func TestIntegrationConvertPrometheusEndpoints_RecordingRuleTargetDatasource(t * EnableUnifiedAlerting: true, DisableAnonymous: true, AppModeProduction: true, - EnableFeatureToggles: []string{"grafanaManagedRecordingRulesDatasources", "grafanaManagedRecordingRules"}, + EnableFeatureToggles: []string{"grafanaManagedRecordingRulesDatasources"}, EnableRecordingRules: true, }) @@ -186,7 +186,7 @@ func TestIntegrationConvertPrometheusEndpoints(t *testing.T) { EnableUnifiedAlerting: true, DisableAnonymous: true, AppModeProduction: true, - EnableFeatureToggles: []string{"grafanaManagedRecordingRulesDatasources", "grafanaManagedRecordingRules"}, + EnableFeatureToggles: []string{"grafanaManagedRecordingRulesDatasources"}, EnableRecordingRules: true, }) @@ -398,7 +398,7 @@ func TestIntegrationConvertPrometheusEndpoints_UpdateRule(t *testing.T) { EnableUnifiedAlerting: true, DisableAnonymous: true, AppModeProduction: true, - EnableFeatureToggles: []string{"grafanaManagedRecordingRulesDatasources", "grafanaManagedRecordingRules"}, + EnableFeatureToggles: []string{"grafanaManagedRecordingRulesDatasources"}, EnableRecordingRules: true, }) @@ -485,7 +485,7 @@ func TestIntegrationConvertPrometheusEndpoints_Conflict(t *testing.T) { EnableUnifiedAlerting: true, DisableAnonymous: true, AppModeProduction: true, - EnableFeatureToggles: []string{"grafanaManagedRecordingRulesDatasources", "grafanaManagedRecordingRules"}, + EnableFeatureToggles: []string{"grafanaManagedRecordingRulesDatasources"}, EnableRecordingRules: true, }) @@ -573,7 +573,7 @@ func TestIntegrationConvertPrometheusEndpoints_CreatePausedRules(t *testing.T) { EnableUnifiedAlerting: true, DisableAnonymous: true, AppModeProduction: true, - EnableFeatureToggles: []string{"grafanaManagedRecordingRulesDatasources", "grafanaManagedRecordingRules"}, + EnableFeatureToggles: []string{"grafanaManagedRecordingRulesDatasources"}, EnableRecordingRules: true, }) @@ -687,7 +687,7 @@ func TestIntegrationConvertPrometheusEndpoints_FolderUIDHeader(t *testing.T) { EnableUnifiedAlerting: true, DisableAnonymous: true, AppModeProduction: true, - EnableFeatureToggles: []string{"grafanaManagedRecordingRulesDatasources", "grafanaManagedRecordingRules"}, + EnableFeatureToggles: []string{"grafanaManagedRecordingRulesDatasources"}, EnableRecordingRules: true, }) @@ -789,7 +789,7 @@ func TestIntegrationConvertPrometheusEndpoints_Provenance(t *testing.T) { EnableUnifiedAlerting: true, DisableAnonymous: true, AppModeProduction: true, - EnableFeatureToggles: []string{"grafanaManagedRecordingRulesDatasources", "grafanaManagedRecordingRules"}, + EnableFeatureToggles: []string{"grafanaManagedRecordingRulesDatasources"}, EnableRecordingRules: true, }) @@ -905,7 +905,7 @@ func TestIntegrationConvertPrometheusEndpoints_Delete(t *testing.T) { EnableUnifiedAlerting: true, DisableAnonymous: true, AppModeProduction: true, - EnableFeatureToggles: []string{"grafanaManagedRecordingRulesDatasources", "grafanaManagedRecordingRules"}, + EnableFeatureToggles: []string{"grafanaManagedRecordingRulesDatasources"}, EnableRecordingRules: true, }) diff --git a/public/app/features/alerting/unified/components/rules/GrafanaRules.tsx b/public/app/features/alerting/unified/components/rules/GrafanaRules.tsx index b6ad7751cc6..37fee65af16 100644 --- a/public/app/features/alerting/unified/components/rules/GrafanaRules.tsx +++ b/public/app/features/alerting/unified/components/rules/GrafanaRules.tsx @@ -58,10 +58,7 @@ export const GrafanaRules = ({ namespaces, expandAll }: Props) => { const [showExportDrawer, toggleShowExportDrawer] = useToggle(false); const hasGrafanaAlerts = namespaces.length > 0; const { canCreateGrafanaRules } = useRulesAccess(); - const grafanaRecordingRulesEnabled = - config.unifiedAlerting.recordingRulesEnabled && - config.featureToggles.grafanaManagedRecordingRules && - canCreateGrafanaRules; + const grafanaRecordingRulesEnabled = config.unifiedAlerting.recordingRulesEnabled && canCreateGrafanaRules; const { t } = useTranslate(); return (
diff --git a/public/app/features/alerting/unified/components/rules/NoRulesCTA.tsx b/public/app/features/alerting/unified/components/rules/NoRulesCTA.tsx index 676b8e9cfff..8acad7bfb0b 100644 --- a/public/app/features/alerting/unified/components/rules/NoRulesCTA.tsx +++ b/public/app/features/alerting/unified/components/rules/NoRulesCTA.tsx @@ -7,10 +7,7 @@ import { useRulesAccess } from '../../utils/accessControlHooks'; const RecordingRulesButtons = () => { const { canCreateGrafanaRules, canCreateCloudRules } = useRulesAccess(); - const grafanaRecordingRulesEnabled = - config.unifiedAlerting.recordingRulesEnabled && - config.featureToggles.grafanaManagedRecordingRules && - canCreateGrafanaRules; + const grafanaRecordingRulesEnabled = config.unifiedAlerting.recordingRulesEnabled && canCreateGrafanaRules; const { t } = useTranslate(); const canCreateAll = canCreateGrafanaRules && canCreateCloudRules && grafanaRecordingRulesEnabled;