Skip to content

Notification Rule Processing Engine - #766

Open
malinosqui wants to merge 15 commits into
notification-rule-baselinefrom
notification-rule-enhancements
Open

malinosqui wants to merge 15 commits into
notification-rule-baselinefrom
notification-rule-enhancements

Conversation

@malinosqui

@malinosqui malinosqui commented Jun 1, 2026

Copy link
Copy Markdown

This pull request refactors the Alerting Rule List view to eliminate dependencies on the Ruler API for Grafana-managed rules. By relying exclusively on the Prometheus API, it simplifies data loading and improves performance when rendering the rule list.

Key Changes:

  • API Optimization: Removed Ruler API calls (useGetGrafanaRulerGroupQuery) and related prefetching logic from the rule list view. The list now populates directly from Prometheus rule data (GrafanaPromRuleDTO).
  • Component Refactoring:
    • Introduced a new GrafanaRuleListItem component to render rule items directly from Prometheus rules, replacing the previous GrafanaRuleLoader.
    • Removed the complex matchRules logic in GrafanaGroupLoader that previously synchronized Ruler rules with Prometheus rules.
    • Updated AlertRuleMenu and RuleActionsButtons.V2 to support rendering action buttons and dropdown menus using either Ruler or Prometheus rule data.
  • RBAC & Permissions:
    • Introduced new ability hooks (useGrafanaPromRuleAbilities, useIsGrafanaPromRuleEditable) to evaluate user permissions (edit, delete, duplicate, silence, etc.) using Prometheus rule data and folder UIDs, bypassing the need for Ruler rules.
    • Updated existing components to check permissions using these new hooks when accessed from the list view.
  • Data Model Updates: Added the provenance field to GrafanaPromRuleDTOBase and introduced an isProvisionedPromRule utility to allow the UI to identify provisioned rules directly from the Prometheus API response.

konrad147 and others added 15 commits July 7, 2025 09:13
* wip

* Add working actions for GMA rules based on Prom-only API

* Remove Ruler-loader related code for Grafana rules

Co-authored-by: Sonia Augilar <sonia.aguilar@grafana.com>

* Remove outdated tests

* add some comments

* remove commented code

* remove showLocation property

* Add missing mocks in tests

* Add showLocation to GrafanaRuleListItem, improve useAbilities, address PR feedback

* Enhance GrafanaGroupLoader tests: Add permission checks and More button functionality

- Introduced user permission grants for alerting actions in tests.
- Added tests for rendering the More button with action menu options.
- Verified that each rule has its own action buttons and handles permissions correctly.
- Ensured the edit button is not rendered when user lacks edit permissions.
- Confirmed the correct menu actions are displayed when the More button is clicked.

* Update translations

---------

Co-authored-by: Sonia Aguilar <soniaaguilarpeiron@gmail.com>
Co-authored-by: Sonia Augilar <sonia.aguilar@grafana.com>
@malinosqui

malinosqui commented Jun 1, 2026

Copy link
Copy Markdown
Author

Code Review Completed! 🔥

The code review was successfully completed based on your current configurations.

Kody Guide: Usage and Configuration
Interacting with Kody
  • Request a Review: Ask Kody to review your PR manually by adding a comment with the @kody start-review command at the root of your PR.

  • Validate Business Logic: Ask Kody to validate your code against business rules by adding a comment with the @kody -v business-logic command.

  • Provide Feedback: Help Kody learn and improve by reacting to its comments with a 👍 for helpful suggestions or a 👎 if improvements are needed.

Current Kody Configuration
Review Options

The following review options are enabled or disabled:

Options Enabled
Bug
Performance
Security
Business Logic

Access your configuration settings here.

Comment on lines +242 to 250
const isProvisioned = rule ? isProvisionedRule(rule) : false;
// TODO: Add support for federated rules
// const isFederated = isFederatedRuleGroup();
const isFederated = false;
const isGrafanaManagedAlertRule = rulerRuleType.grafana.rule(rule);
const isPluginProvided = isPluginProvidedRule(rule);

// if a rule is either provisioned, federated or provided by a plugin rule, we don't allow it to be removed or edited
const immutableRule = isProvisioned || isFederated || isPluginProvided;

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kody code-review Bug high

Immutability bypass occurs in useAllRulerRuleAbilities because hardcoding isFederated to false surfaces mutation actions for Mimir and Loki federated rules. Restore the isFederatedRuleGroup() evaluation to ensure these rules remain strictly immutable.

const isProvisioned = rule ? isProvisionedRule(rule) : false;
const isFederated = isFederatedRuleGroup(groupIdentifier); // or pass down group/fetch it
const isGrafanaManagedAlertRule = rulerRuleType.grafana.rule(rule);
const isPluginProvided = isPluginProvidedRule(rule);

// if a rule is either provisioned, federated or provided by a plugin rule, we don't allow it to be removed or edited
const immutableRule = isProvisioned || isFederated || isPluginProvided;
Prompt for LLM

File public/app/features/alerting/unified/hooks/useAbilities.ts:

Line 242 to 250:

WHAT: The `isFederated` check was removed and hardcoded to `false` in `useAllRulerRuleAbilities`, dropping immutability guarantees for federated rules. WHY: Mimir/Loki federated rules rely on this check to disable mutation actions; hardcoding it to false surfaces Edit/Delete buttons in the UI for rules that must remain strictly immutable. HOW: Restore the federated evaluation (e.g. `isFederatedRuleGroup()`) by passing the group or fetching the group context, rather than hardcoding it to false.

Suggested Code:

    const isProvisioned = rule ? isProvisionedRule(rule) : false;
    const isFederated = isFederatedRuleGroup(groupIdentifier); // or pass down group/fetch it
    const isGrafanaManagedAlertRule = rulerRuleType.grafana.rule(rule);
    const isPluginProvided = isPluginProvidedRule(rule);

    // if a rule is either provisioned, federated or provided by a plugin rule, we don't allow it to be removed or edited
    const immutableRule = isProvisioned || isFederated || isPluginProvided;

Talk to Kody by mentioning @kody

Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction.

@@ -93,3 +114,38 @@ export function RuleActionsButtons({ compact, rule, promRule, groupIdentifier }:
</Stack>

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kody code-review Bug high

Silence drawer rendering failure occurs because rulerRuleType.grafana.alertingRule(rule) evaluates to false when rule is undefined following the removal of Ruler API calls. Expand the rendering condition to include prometheusRuleType.grafana.alertingRule(promRule) and update SilenceGrafanaRuleDrawer to support the promRule context.

{(rulerRuleType.grafana.alertingRule(rule) || prometheusRuleType.grafana.alertingRule(promRule)) && showSilenceDrawer && (
  <SilenceGrafanaRuleDrawer rulerRule={rule} promRule={promRule} onClose={() => setShowSilenceDrawer(false)} />
)}
Prompt for LLM

File public/app/features/alerting/unified/rule-list/components/RuleActionsButtons.V2.tsx:

Line 114:

WHAT: The Silence drawer silently fails to open when clicking 'Silence' in the list view because it strictly requires the `rule` (RulerRuleDTO) object which is no longer passed. WHY: The PR removed Ruler API calls in the list view, meaning `rule` is undefined; the condition `rulerRuleType.grafana.alertingRule(rule)` evaluates to false, so the drawer is never mounted even though the state opens it. HOW: Expand the rendering condition to also check `promRule` (e.g., `prometheusRuleType.grafana.alertingRule(promRule)`) and update the drawer to support `promRule` or fetch the Ruler rule internally.

Suggested Code:

      {(rulerRuleType.grafana.alertingRule(rule) || prometheusRuleType.grafana.alertingRule(promRule)) && showSilenceDrawer && (
        <SilenceGrafanaRuleDrawer rulerRule={rule} promRule={promRule} onClose={() => setShowSilenceDrawer(false)} />
      )}

Talk to Kody by mentioning @kody

Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants