feat(grafana): add read-only alerting actions - #240
Conversation
Add list_alert_rules, get_alert_rule, list_alert_instances, and list_contact_points. All four use Grafana's stable legacy REST API (/api/v1/provisioning/*, /api/alertmanager/*), which is not versioned per release, so they are unaffected by App Platform API version discovery.
Summary by CodeRabbit
WalkthroughAdded four Grafana provider actions for listing and retrieving alert rules, listing alert instances with optional filters, and listing contact points. New schemas validate alerting payloads. Runtime handlers call the corresponding Grafana REST endpoints and return normalized results with empty fallbacks when responses are missing. Sequence Diagram(s)sequenceDiagram
participant ProviderAction
participant grafanaActionHandlers
participant GrafanaAPI
ProviderAction->>grafanaActionHandlers: Dispatch alerting action
grafanaActionHandlers->>GrafanaAPI: Request alert rules, instances, or contact points
GrafanaAPI-->>grafanaActionHandlers: Return alerting payload
grafanaActionHandlers-->>ProviderAction: Return normalized result
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✨ Finishing Touches✨ Simplify code
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. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
src/providers/grafana/runtime.ts (1)
371-380: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winRemove the redundant
compactObjectwrapper.
grafanaRequestJsonalready dropsundefinedquery values, so pass the query object directly and avoid the helper that only hides undefined fields.Proposed simplification
- const query = compactObject({ + const query = { active: optionalBoolean(input.active), silenced: optionalBoolean(input.silenced), inhibited: optionalBoolean(input.inhibited), - }); + };As per coding guidelines, “Avoid trivial pass-through helpers and conditional object spreads that only hide
undefinedJSON fields.”🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/providers/grafana/runtime.ts` around lines 371 - 380, In executeListAlertInstances, remove the compactObject wrapper and pass the object containing active, silenced, and inhibited directly as the query argument to grafanaRequestJson; rely on grafanaRequestJson to omit undefined values and preserve the existing optionalBoolean mappings.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@src/providers/grafana/runtime.ts`:
- Around line 371-380: In executeListAlertInstances, remove the compactObject
wrapper and pass the object containing active, silenced, and inhibited directly
as the query argument to grafanaRequestJson; rely on grafanaRequestJson to omit
undefined values and preserve the existing optionalBoolean mappings.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 661922ae-a902-4c61-b9d8-63b46809043a
📒 Files selected for processing (2)
src/providers/grafana/actions.tssrc/providers/grafana/runtime.ts
There was a problem hiding this comment.
Pull request overview
Adds four new read-only alerting actions to the Grafana provider, implemented against Grafana’s legacy REST endpoints (i.e. not App Platform API-versioned), by extending the action catalog and wiring corresponding runtime handlers.
Changes:
- Add new Grafana action names and JSON schemas for:
list_alert_rules,get_alert_rule,list_alert_instances,list_contact_points. - Implement runtime request handlers for the four new alerting endpoints and register them in
grafanaActionHandlers.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
src/providers/grafana/runtime.ts |
Registers and implements the four new alerting action executors using existing grafanaRequestJson plumbing. |
src/providers/grafana/actions.ts |
Extends the Grafana action-name union and defines input/output schemas for the four new alerting actions. |
Comments suppressed due to low confidence (4)
src/providers/grafana/actions.ts:375
- Other Grafana list-style actions in this provider return a
rawfield alongside the processed list. For consistency and easier debugging, consider addingrawto this action’s output schema too.
outputSchema: s.object("Grafana alert instances.", {
alertInstances: s.array("Alert instances returned by Grafana.", alertInstanceSchema),
}),
src/providers/grafana/actions.ts:384
- Other Grafana list-style actions in this provider include a
rawfield in the output. Addingrawhere would keep the Grafana action outputs consistent and preserve the unmodified payload for troubleshooting.
outputSchema: s.object("Grafana notification contact points.", {
contactPoints: s.array("Contact points returned by Grafana.", contactPointSchema),
}),
src/providers/grafana/runtime.ts:382
- Consider returning the raw payload (or at least the filtered object-array form) alongside
alertInstances, matching the pattern used by other list actions in this provider (e.g. list_data_sources) for easier troubleshooting.
"/api/alertmanager/grafana/api/v2/alerts",
{ method: "GET", query },
{ ...context, phase: "execute" },
);
return { alertInstances: objectArrayOrEmpty(payload) };
src/providers/grafana/runtime.ts:391
- For consistency with other Grafana list actions that expose
raw(e.g. list_data_sources), consider returning arawfield here too so callers can inspect the underlying Grafana payload when needed.
"/api/v1/provisioning/contact-points",
{ method: "GET" },
{ ...context, phase: "execute" },
);
return { contactPoints: objectArrayOrEmpty(payload) };
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| outputSchema: s.object("Grafana-managed alert rules.", { | ||
| alertRules: s.array("Alert rules returned by Grafana.", alertRuleSchema), | ||
| }), |
| const payload = await grafanaRequestJson( | ||
| "/api/v1/provisioning/alert-rules", | ||
| { method: "GET" }, | ||
| { ...context, phase: "execute" }, | ||
| ); | ||
| return { alertRules: objectArrayOrEmpty(payload) }; |
Adds four read-only alerting actions to the Grafana provider:
list_alert_rulesGET /api/v1/provisioning/alert-rulesget_alert_ruleGET /api/v1/provisioning/alert-rules/:uidlist_alert_instancesGET /api/alertmanager/grafana/api/v2/alerts(supportsactive/silenced/inhibitedfilters)list_contact_pointsGET /api/v1/provisioning/contact-pointsThese endpoints belong to Grafana's stable legacy REST API and are not affected by App Platform API version discovery (#221). This exact code has been running against Grafana 12.4.3 in a private deployment for two weeks.
🤖 Generated with Claude Code