Skip to content

Conversation

@adamantal
Copy link
Contributor

@adamantal adamantal commented Oct 22, 2025

Description

Adding support for attaching buttons to the action. It supports templating, with the same set of substitutions as the template_enricher which was recommended as an alternative.

Also updated the docs with the custom button example.

Possibly fixing #735 and #814

Testing

tested on top of 0.29.0, worked properly for me 👌
(Note: I successfully rickrolled the team during the testing)

Concrete example:

customPlaybooks:
- triggers:
  - on_image_pull_backoff: {}
  actions:
  - image_pull_backoff_reporter: {}
  - button_enricher:
      button_text: "CLICK ME: ${namespace}"
      button_url: "..."
Screenshot 2025-10-22 at 16 11 32

@CLAassistant
Copy link

CLAassistant commented Oct 22, 2025

CLA assistant check
All committers have signed the CLA.

@coderabbitai
Copy link

coderabbitai bot commented Oct 22, 2025

Walkthrough

Adds a helper _get_labels to centralize label extraction, refactors template_enricher to use it, and introduces a new templated button enrichment action button_enricher. Documentation and examples updated to show the new action.

Changes

Cohort / File(s) Summary
Docs: Event enrichment reference
docs/playbook-reference/actions/event-enrichment.rst
Inserted a new button_enricher entry in the Prometheus Enrichers section (after template_enricher).
Docs: Prometheus examples
docs/playbook-reference/prometheus-examples/link-alert-enrichment.rst
Updated lead text to mention multiple enrichment approaches and added a button_enricher example under customPlaybooks with button_text and button_url templating.
Playbook actions implementation
playbooks/robusta_playbooks/alerts_integration.py
Removed SeverityParams; added _get_labels(event) helper; refactored template_enricher to use _get_labels; added TemplatedButtonParams and public button_enricher(event, params) which templates button_text and button_url using _get_labels.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Prom as PrometheusAlert
  participant Enricher as EnricherDispatcher
  participant Labels as _get_labels
  participant Template as template_enricher
  participant Button as button_enricher
  participant Alert as EnrichedAlert

  Prom->>Enricher: incoming alert event
  Enricher->>Labels: extract labels/subject
  Labels-->>Enricher: labels dict
  Enricher->>Template: apply templates (uses labels)
  Template-->>Enricher: adds templated links
  Enricher->>Button: apply button_enricher (templates text/url using labels)
  Button-->>Enricher: adds button link
  Enricher->>Alert: attach links/buttons and emit enriched alert
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

  • Pay attention to playbooks/robusta_playbooks/alerts_integration.py:
    • correctness and coverage of _get_labels for different event types,
    • template rendering and escaping in button_enricher,
    • any removed SeverityParams references elsewhere in the file.

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Out of Scope Changes Check ⚠️ Warning While the primary changes (button_enricher implementation, TemplatedButtonParams class, documentation updates, and _get_labels helper refactoring) are clearly in scope for the linked issue #735 requirement to add custom buttons, the removal of the SeverityParams class appears to be out of scope. This removal is not mentioned in the PR description and is not directly related to the feature request of adding buttons to Slack sink, raising questions about whether this is an undocumented cleanup or an accidental inclusion.
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (3 passed)
Check name Status Explanation
Title Check ✅ Passed The title "feat(buttons): add button enricher" directly and concisely summarizes the main change in the pull request. It clearly identifies the primary feature being added (button enricher) without vague terminology or noise. The title accurately reflects the primary user-facing addition shown in the changeset, which is the new button_enricher action that enables attaching templated buttons to alerts.
Linked Issues Check ✅ Passed The PR successfully implements the requirements from linked issue #735 (Feature Request: add custom buttons to Slack sink) by introducing the button_enricher action that enables attaching buttons to alerts. The implementation supports templating with dynamic label substitution (such as ${namespace}, ${team}, etc.), which directly enables the requested use cases of adding contextual links to ArgoCD applications and cloud provider consoles. The documentation has been updated with concrete examples showing button usage.
Description Check ✅ Passed The description is directly related to the changeset and provides meaningful context about the new feature. It explains the button enricher functionality, describes the templating support, mentions documentation updates, references potentially related issues, includes testing confirmation, and provides a concrete YAML example demonstrating usage. The description clearly communicates what was added and why.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (3)
playbooks/robusta_playbooks/alerts_integration.py (2)

441-444: Consider validating the templated URL.

After template substitution, the resulting URL could be invalid (e.g., if a label contains invalid characters or is missing, resulting in "<missing>"). The existing is_valid_url helper (line 223) could validate the final URL before creating the link, similar to how default_enricher validates the generator URL (line 243).

Apply this diff to add URL validation:

 labels = _get_labels(event)
 button_text = Template(params.button_text).safe_substitute(labels)
 button_url = Template(params.button_url).safe_substitute(labels)
+if not is_valid_url(button_url):
+    logging.warning(f"Skipping templated button with invalid URL: {button_url}")
+    return
 event.add_link(Link(url=button_url, name=button_text))

452-453: Consider validating static URLs for consistency.

While static URLs come from configuration and are less likely to be invalid, adding validation using the existing is_valid_url helper would provide consistent error handling and catch configuration mistakes early.

Apply this diff to add validation:

+if not is_valid_url(params.button_url):
+    logging.warning(f"Skipping static button with invalid URL: {params.button_url}")
+    return
 event.add_link(Link(url=params.button_url, name=params.button_text))
docs/playbook-reference/prometheus-examples/link-alert-enrichment.rst (1)

32-34: Consider documenting behavior for missing labels.

The templated button example uses ${team}, but doesn't explain what happens if the team label doesn't exist on the alert. Users might benefit from knowing that missing labels will display as "<missing>" in the button text or URL (as documented in the action's docstring).

Consider adding a brief note after line 37:

.. note::
   For templated buttons, if a referenced label doesn't exist (e.g., ``${team}``), 
   it will be replaced with the text ``<missing>`` in the final button.
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 471f567 and eb896fb.

📒 Files selected for processing (3)
  • docs/playbook-reference/actions/event-enrichment.rst (1 hunks)
  • docs/playbook-reference/prometheus-examples/link-alert-enrichment.rst (2 hunks)
  • playbooks/robusta_playbooks/alerts_integration.py (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
playbooks/robusta_playbooks/alerts_integration.py (5)
src/robusta/integrations/kubernetes/autogenerated/events.py (15)
  • KubernetesResourceEvent (126-238)
  • get_subject (215-223)
  • get_subject (394-402)
  • get_subject (416-424)
  • get_subject (451-459)
  • get_subject (473-481)
  • get_subject (508-516)
  • get_subject (530-538)
  • get_subject (565-573)
  • get_subject (587-595)
  • get_subject (622-630)
  • get_subject (644-652)
  • get_subject (679-687)
  • get_subject (701-709)
  • get_subject (736-744)
src/robusta/integrations/prometheus/models.py (3)
  • PrometheusKubernetesAlert (73-249)
  • get_alert_subject (148-203)
  • get_subject (226-227)
src/robusta/core/model/events.py (4)
  • get_subject (170-171)
  • add_enrichment (116-127)
  • add_link (100-103)
  • ExecutionBaseEvent (49-175)
src/robusta/core/reporting/base.py (3)
  • add_enrichment (343-360)
  • add_link (362-365)
  • Link (99-112)
src/robusta/core/reporting/blocks.py (1)
  • MarkdownBlock (42-61)
🪛 Ruff (0.14.1)
playbooks/robusta_playbooks/alerts_integration.py

431-431: Docstring contains ambiguous (RIGHT SINGLE QUOTATION MARK). Did you mean ``` (GRAVE ACCENT)?

(RUF002)


436-436: Docstring contains ambiguous (RIGHT SINGLE QUOTATION MARK). Did you mean ``` (GRAVE ACCENT)?

(RUF002)

🔇 Additional comments (4)
playbooks/robusta_playbooks/alerts_integration.py (3)

381-392: LGTM! Good refactoring.

The helper function extracts common label-gathering logic, reducing code duplication between template_enricher and the new button enrichers. The implementation correctly handles both event types and provides sensible defaults for missing values.


411-411: LGTM! Clean refactoring.

The change correctly delegates to the new _get_labels helper, maintaining the same behavior while improving code reuse.


456-461: LGTM! Appropriate use of broader event type.

The static enricher correctly accepts ExecutionBaseEvent (a broader base type than KubernetesResourceEvent used by the templated version), which makes sense since no label extraction is needed. This allows the static button to work with more event types.

docs/playbook-reference/prometheus-examples/link-alert-enrichment.rst (1)

32-37: LGTM! Clear examples for the new button enrichers.

The examples effectively demonstrate both enricher types and their configuration. The templated example shows variable substitution with ${team}, and the static example shows a straightforward URL button.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (3)
playbooks/robusta_playbooks/alerts_integration.py (3)

381-392: Consider explicit handling for unexpected event types.

The function will silently return a dict containing only "<missing>" default values if the event is neither PrometheusKubernetesAlert nor KubernetesResourceEvent. While the type hint suggests only KubernetesResourceEvent should be passed, adding an explicit check or log warning could prevent silent failures if the function is called with an unexpected event type in the future.

Consider adding a log warning for the else case:

 def _get_labels(event: KubernetesResourceEvent) -> Dict[str, Any]:
     labels: Dict[str, Any] = defaultdict(lambda: "<missing>")
     if isinstance(event, PrometheusKubernetesAlert):
         labels.update(event.alert.labels)
         labels.update(event.alert.annotations)
         labels.update(vars(event.get_alert_subject()))
         labels["kind"] = labels["subject_type"].value
     elif isinstance(event, KubernetesResourceEvent):
         labels.update(vars(event.get_subject()))
         labels["kind"] = labels["subject_type"].value
+    else:
+        logging.warning(f"_get_labels called with unexpected event type: {type(event)}")
 
     return labels

427-444: Validate templated URL before adding the link.

After template substitution, the button_url might contain "<missing>" placeholders or result in an invalid URL. The existing is_valid_url() helper (lines 223-232) is already used by default_enricher to validate URLs before adding links. Consider applying the same validation here to prevent invalid links from being added.

Apply this diff to add URL validation:

 @action
 def templated_button_enricher(event: KubernetesResourceEvent, params: TemplatedButtonParams):
     """
     Create a button with a templated text and URL.
     You can inject the k8s subject info and additionally on Prometheus alerts, any of the alert's Prometheus labels.
 
     Common variables to use are ${name}, ${kind}, ${namespace}, and ${node}
 
     A variable like ${foo} will be replaced by the value of info/label foo.
     If it isn't present then the text "<missing>" will be used instead.
 
     Check example for adding a template link.
 
     """
     labels = _get_labels(event)
     button_text = Template(params.button_text).safe_substitute(labels)
     button_url = Template(params.button_url).safe_substitute(labels)
+    if not is_valid_url(button_url):
+        logging.warning(f"Skipping invalid templated button URL: {button_url}")
+        return
     event.add_link(Link(url=button_url, name=button_text))

456-461: Validate static URL before adding the link.

The button_url parameter should be validated to ensure it's a valid URL before adding the link. Invalid URLs could cause issues in message rendering or break Slack/other sink integrations. Consider using the existing is_valid_url() helper (lines 223-232) for consistency with default_enricher.

Apply this diff to add URL validation:

 @action
 def static_button_enricher(event: ExecutionBaseEvent, params: StaticButtonParams):
     """
     Create a button with a static text and URL.
     """
+    if not is_valid_url(params.button_url):
+        logging.warning(f"Skipping invalid button URL: {params.button_url}")
+        return
     event.add_link(Link(url=params.button_url, name=params.button_text))
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between eb896fb and 92b8ba1.

📒 Files selected for processing (1)
  • playbooks/robusta_playbooks/alerts_integration.py (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
playbooks/robusta_playbooks/alerts_integration.py (3)
src/robusta/integrations/kubernetes/autogenerated/events.py (15)
  • KubernetesResourceEvent (126-238)
  • get_subject (215-223)
  • get_subject (394-402)
  • get_subject (416-424)
  • get_subject (451-459)
  • get_subject (473-481)
  • get_subject (508-516)
  • get_subject (530-538)
  • get_subject (565-573)
  • get_subject (587-595)
  • get_subject (622-630)
  • get_subject (644-652)
  • get_subject (679-687)
  • get_subject (701-709)
  • get_subject (736-744)
src/robusta/integrations/prometheus/models.py (2)
  • get_alert_subject (148-203)
  • get_subject (226-227)
src/robusta/core/model/events.py (4)
  • get_subject (170-171)
  • add_enrichment (116-127)
  • add_link (100-103)
  • ExecutionBaseEvent (49-175)
🔇 Additional comments (1)
playbooks/robusta_playbooks/alerts_integration.py (1)

411-411: Good refactor to eliminate code duplication.

Extracting label gathering logic into _get_labels improves maintainability and eliminates duplication between template_enricher and the new templated_button_enricher.

@adamantal adamantal changed the title feat(buttons): add static and templated button enricher feat(buttons): add button enricher Oct 29, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
playbooks/robusta_playbooks/alerts_integration.py (1)

430-436: Docstring quotation mark issue (already flagged).

This is the same quotation mark issue that was already noted in the past review comments. The docstring uses RIGHT SINGLE QUOTATION MARK (') instead of GRAVE ACCENT (`) for inline code references (lines 433, 435).

🧹 Nitpick comments (1)
playbooks/robusta_playbooks/alerts_integration.py (1)

443-447: Consider validating button_text to avoid empty button labels.

If all variables in button_text are missing, the templated result will be an empty string (since default_value=""). Adding a button with no label could be confusing for users. Consider checking that button_text is non-empty before adding the link.

For example:

     labels = _get_labels(event, default_value="")
     button_text = Template(params.button_text).safe_substitute(labels)
     button_url = Template(params.button_url).safe_substitute(labels)
-    if button_url.strip() != "":
+    if button_text.strip() and button_url.strip():
         event.add_link(Link(url=button_url, name=button_text))
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 92b8ba1 and b893b12.

📒 Files selected for processing (3)
  • docs/playbook-reference/actions/event-enrichment.rst (1 hunks)
  • docs/playbook-reference/prometheus-examples/link-alert-enrichment.rst (2 hunks)
  • playbooks/robusta_playbooks/alerts_integration.py (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • docs/playbook-reference/prometheus-examples/link-alert-enrichment.rst
  • docs/playbook-reference/actions/event-enrichment.rst
🧰 Additional context used
🧬 Code graph analysis (1)
playbooks/robusta_playbooks/alerts_integration.py (3)
src/robusta/integrations/kubernetes/autogenerated/events.py (15)
  • KubernetesResourceEvent (126-238)
  • get_subject (215-223)
  • get_subject (394-402)
  • get_subject (416-424)
  • get_subject (451-459)
  • get_subject (473-481)
  • get_subject (508-516)
  • get_subject (530-538)
  • get_subject (565-573)
  • get_subject (587-595)
  • get_subject (622-630)
  • get_subject (644-652)
  • get_subject (679-687)
  • get_subject (701-709)
  • get_subject (736-744)
src/robusta/integrations/prometheus/models.py (2)
  • get_alert_subject (148-203)
  • get_subject (226-227)
src/robusta/core/reporting/base.py (1)
  • Link (99-112)
🔇 Additional comments (3)
playbooks/robusta_playbooks/alerts_integration.py (3)

381-392: LGTM! Good refactoring to centralize label extraction.

The _get_labels helper consolidates label gathering logic that was previously inline. It properly handles both PrometheusKubernetesAlert and KubernetesResourceEvent types, and the defaultdict pattern provides clean fallback behavior for missing keys.


411-411: LGTM! Clean refactoring.

Delegating to _get_labels simplifies the function while preserving the original behavior.


418-424: LGTM! Clear parameter definition.

The parameter class is straightforward and follows the established pattern in the codebase.

@adamantal
Copy link
Contributor Author

this enricher has been implemented as an external action in https://github.com/zocks-communications/robusta-button-enricher until this PR is merged to the core actions

Copy link
Contributor

@arikalon1 arikalon1 left a comment

Choose a reason for hiding this comment

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

nice work!

Thanks for the contribution @adamantal

@arikalon1 arikalon1 merged commit 7277a57 into robusta-dev:master Nov 1, 2025
4 checks passed
@adamantal adamantal deleted the feat/buttons branch November 3, 2025 09:14
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.

3 participants