Grafana indexing dashboard: Delete on Active Indexing + CORS fix#4876
Conversation
Two related fixes that ship together: 1. Active Indexing panel (indexing.json): replace the hidden reservation_id column with a red "Delete" action, mirroring the Pending/Queued Indexing Jobs and Running Jobs patterns. POSTs to _grafana-complete-job with reservation_id, which routes through forceCancelJobById. 2. realm-server CORS (server.ts): add X-Grafana-Action to allowHeaders. Grafana's table-cell "fetch" action auto-adds an x-grafana-action request header, which was tripping the preflight on every Delete button across both the indexing and job-queue dashboards (Waiting Jobs, Queued Indexing Jobs, Running Jobs — and the new Active Indexing button). Without this header on the allowlist, all of them fail with "ERR_FAILED" / preflight CORS rejection on cross-origin staging/prod requests from dashboard-staging. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Observability diff (vs staging)Show diffdiff --git a/tmp/remote-canon.zGJzNH/dashboards/boxel-status/indexing.json b/tmp/committed-canon.YOy3dh/dashboards/boxel-status/indexing.json
index db72bbf..25280b9 100644
--- a/tmp/remote-canon.zGJzNH/dashboards/boxel-status/indexing.json
+++ b/tmp/committed-canon.YOy3dh/dashboards/boxel-status/indexing.json
@@ -69,6 +69,10 @@
"uid": "cef5v5sl9k7i8f"
},
"description": "System-wide operator action: queue a full reindex across every realm. The button disables itself while a `full-reindex` orchestration job is already pending or running. Per-realm reindex moved to the Realms dashboard. Click POSTs with `Authorization: Bearer ${grafana_secret}` (substituted from SSM at apply time, CS-10929).",
+ "fieldConfig": {
+ "defaults": {},
+ "overrides": []
+ },
"gridPos": {
"h": 8,
"w": 24,
@@ -714,8 +718,57 @@
},
"properties": [
{
- "id": "custom.hidden",
- "value": true
+ "id": "actions",
+ "value": [
+ {
+ "confirmation": "Cancel running reservation ${__value.raw}? The worker will stop processing it.",
+ "fetch": {
+ "body": "",
+ "headers": [
+ [
+ "Authorization",
+ "Bearer ${grafana_secret}"
+ ]
+ ],
+ "method": "POST",
+ "queryParams": [
+ [
+ "reservation_id",
+ "${__value.raw}"
+ ]
+ ],
+ "url": "${realm_server}_grafana-complete-job"
+ },
+ "oneClick": false,
+ "title": "Delete reservation ${__value.raw}",
+ "type": "fetch"
+ }
+ ]
+ },
+ {
+ "id": "mappings",
+ "value": [
+ {
+ "options": {
+ "from": 0,
+ "result": {
+ "color": "red",
+ "index": 0,
+ "text": "Delete"
+ },
+ "to": 9999999999999
+ },
+ "type": "range"
+ }
+ ]
+ },
+ {
+ "id": "displayName",
+ "value": "Action"
+ },
+ {
+ "id": "custom.filterable",
+ "value": false
}
]
},
(Run: https://github.com/cardstack/boxel/actions/runs/26066533633) |
There was a problem hiding this comment.
Pull request overview
This PR improves Grafana operational workflows for indexing by (1) adding a “Delete” action for active indexing reservations in the indexing dashboard, and (2) fixing realm-server CORS preflight failures triggered by Grafana’s table “fetch” actions.
Changes:
- Allow the
X-Grafana-Actionheader in realm-server CORS configuration to unblock Grafana table-cell fetch actions cross-origin. - Update the indexing dashboard to expose
reservation_idas a red “Delete” action in the Active Indexing panel (matching existing job-queue patterns).
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
packages/realm-server/server.ts |
Adds X-Grafana-Action to CORS allowHeaders so Grafana “fetch” actions no longer fail preflight. |
packages/observability/grafanactl/resources/dashboards/boxel-status/indexing.json |
Converts the hidden reservation_id column into an Action column with a “Delete” fetch action posting to /_grafana-complete-job. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Host Test Results 1 files 1 suites 2h 57m 11s ⏱️ Results for commit bd79ce3. For more details on these errors, see this check. Realm Server Test Results 1 files 1 suites 8m 11s ⏱️ Results for commit bd79ce3. |
Summary
Two related fixes bundled in one PR:
Add Delete button to the Active Indexing panel (
indexing.json)The Active Indexing panel had
reservation_idas a hidden column. Surface it as a red "Delete" action, identical in shape to the Pending/Queued Indexing Jobs and Running Jobs patterns. The button POSTs to the existing_grafana-complete-jobendpoint withreservation_id, which routes throughforceCancelJobByIdto stop the in-flight worker.Fix CORS preflight failure on every "Delete" button in Grafana (
server.ts)Grafana's table-cell
"type": "fetch"action automatically adds anx-grafana-action: fieldActionsrequest header. The realm server's@koa/corsallowlist didn't include it, so every cross-origin click failed preflight with:Adding
X-Grafana-ActiontoallowHeadersunblocks all four affected buttons at once:job-queue.json→ Waiting Jobs → Deletejob-queue.json→ Running Jobs → Deleteindexing.json→ Queued Indexing Jobs → Deleteindexing.json→ Active Indexing → Delete (new in this PR)Other Grafana operator actions in
users.jsonuse inlinecustomCodewith plainfetch(...), which doesn't add that header, so they were unaffected.Test plan
grafanactl resources push) and confirm Active Indexing now shows a red Delete column instead of hiddenreservation_id.dashboard-staging.stack.cards→ Active Indexing → reservation is force-cancelled, no CORS error in console.Waiting Jobs(job-queue) → succeeds (no more CORS preflight failure).Queued Indexing Jobs(indexing) → succeeds.Running Jobs(job-queue) → succeeds.🤖 Generated with Claude Code