From 550e60fe487369cde6ef25fca2510d115f961cca Mon Sep 17 00:00:00 2001 From: Sonia Aguilar <33540275+soniaAguilarPeiron@users.noreply.github.com> Date: Wed, 14 May 2025 13:35:33 +0200 Subject: [PATCH] Alerting: Check permissions for showing create recording rules button (#105256) --- .../components/rule-editor/useAlertRuleSuggestions.tsx | 2 +- .../alerting/unified/components/rules/GrafanaRules.tsx | 10 +++++++--- .../alerting/unified/components/rules/NoRulesCTA.tsx | 9 +++++++-- public/app/features/alerting/unified/featureToggles.ts | 3 --- 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/public/app/features/alerting/unified/components/rule-editor/useAlertRuleSuggestions.tsx b/public/app/features/alerting/unified/components/rule-editor/useAlertRuleSuggestions.tsx index c74b1cf2045..e751e80c185 100644 --- a/public/app/features/alerting/unified/components/rule-editor/useAlertRuleSuggestions.tsx +++ b/public/app/features/alerting/unified/components/rule-editor/useAlertRuleSuggestions.tsx @@ -11,9 +11,9 @@ import { shouldUsePrometheusRulesPrimary } from '../../featureToggles'; const { usePrometheusRuleNamespacesQuery, useLazyRulerRulesQuery, useRulerRulesQuery } = alertRuleApi; const { useDiscoverDsFeaturesQuery } = featureDiscoveryApi; -const prometheusRulesPrimary = shouldUsePrometheusRulesPrimary(); const emptyRulerConfig: RulerRulesConfigDTO = {}; +const prometheusRulesPrimary = shouldUsePrometheusRulesPrimary(); export function useGetLabelsFromDataSourceName(rulesSourceName: string) { const { data: features, isLoading: isFeaturesLoading } = useDiscoverDsFeaturesQuery({ rulesSourceName }); diff --git a/public/app/features/alerting/unified/components/rules/GrafanaRules.tsx b/public/app/features/alerting/unified/components/rules/GrafanaRules.tsx index ecfe7ec9717..b366ad9e209 100644 --- a/public/app/features/alerting/unified/components/rules/GrafanaRules.tsx +++ b/public/app/features/alerting/unified/components/rules/GrafanaRules.tsx @@ -2,6 +2,7 @@ import { css } from '@emotion/css'; import { useToggle } from 'react-use'; import { GrafanaTheme2 } from '@grafana/data'; +import { config } from '@grafana/runtime'; import { Button, LinkButton, LoadingPlaceholder, Pagination, Spinner, Stack, Text, useStyles2 } from '@grafana/ui'; import { useQueryParams } from 'app/core/hooks/useQueryParams'; import { Trans, t } from 'app/core/internationalization'; @@ -9,12 +10,12 @@ import { CombinedRuleNamespace } from 'app/types/unified-alerting'; import { DEFAULT_PER_PAGE_PAGINATION } from '../../../../../core/constants'; import { LogMessages, logInfo } from '../../Analytics'; -import { useGrafanaManagedRecordingRulesSupport } from '../../featureToggles'; import { AlertingAction, useAlertingAbility } from '../../hooks/useAbilities'; import { flattenGrafanaManagedRules } from '../../hooks/useCombinedRuleNamespaces'; import { usePagination } from '../../hooks/usePagination'; import { useUnifiedAlertingSelector } from '../../hooks/useUnifiedAlertingSelector'; import { getPaginationStyles } from '../../styles/pagination'; +import { useRulesAccess } from '../../utils/accessControlHooks'; import { GRAFANA_RULES_SOURCE_NAME } from '../../utils/datasource'; import { initialAsyncRequestState } from '../../utils/redux'; import { createRelativeUrl } from '../../utils/url'; @@ -56,8 +57,11 @@ export const GrafanaRules = ({ namespaces, expandAll }: Props) => { const [showExportDrawer, toggleShowExportDrawer] = useToggle(false); const hasGrafanaAlerts = namespaces.length > 0; - - const grafanaRecordingRulesEnabled = useGrafanaManagedRecordingRulesSupport(); + const { canCreateGrafanaRules } = useRulesAccess(); + const grafanaRecordingRulesEnabled = + config.unifiedAlerting.recordingRulesEnabled && + config.featureToggles.grafanaManagedRecordingRules && + canCreateGrafanaRules; return (
diff --git a/public/app/features/alerting/unified/components/rules/NoRulesCTA.tsx b/public/app/features/alerting/unified/components/rules/NoRulesCTA.tsx index 35c1c42ffdd..2588c493f00 100644 --- a/public/app/features/alerting/unified/components/rules/NoRulesCTA.tsx +++ b/public/app/features/alerting/unified/components/rules/NoRulesCTA.tsx @@ -1,12 +1,17 @@ +import { config } from '@grafana/runtime'; import { Dropdown, EmptyState, LinkButton, Menu, MenuItem, Stack, TextLink } from '@grafana/ui'; import { Trans, t } from 'app/core/internationalization'; -import { useGrafanaManagedRecordingRulesSupport } from '../../featureToggles'; import { useRulesAccess } from '../../utils/accessControlHooks'; const RecordingRulesButtons = () => { const { canCreateGrafanaRules, canCreateCloudRules } = useRulesAccess(); - const grafanaRecordingRulesEnabled = useGrafanaManagedRecordingRulesSupport(); + + const grafanaRecordingRulesEnabled = + config.unifiedAlerting.recordingRulesEnabled && + config.featureToggles.grafanaManagedRecordingRules && + canCreateGrafanaRules; + const canCreateAll = canCreateGrafanaRules && canCreateCloudRules && grafanaRecordingRulesEnabled; // User can create Grafana and DS-managed recording rules, show a dropdown diff --git a/public/app/features/alerting/unified/featureToggles.ts b/public/app/features/alerting/unified/featureToggles.ts index f40298b36d8..d3b3d755249 100644 --- a/public/app/features/alerting/unified/featureToggles.ts +++ b/public/app/features/alerting/unified/featureToggles.ts @@ -16,9 +16,6 @@ export const shouldUseAlertingListViewV2 = () => { return config.featureToggles.alertingListViewV2; }; -export const useGrafanaManagedRecordingRulesSupport = () => - config.unifiedAlerting.recordingRulesEnabled && config.featureToggles.grafanaManagedRecordingRules; - export const shouldAllowRecoveringDeletedRules = () => (isAdmin() && config.featureToggles.alertingRuleRecoverDeleted && config.featureToggles.alertRuleRestore) ?? false;