From bd79ce32578868feb30a70115267670170136250 Mon Sep 17 00:00:00 2001 From: Hassan Abdel-Rahman Date: Mon, 18 May 2026 19:30:22 -0400 Subject: [PATCH] Grafana indexing dashboard: Delete on Active Indexing + CORS fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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) --- .../dashboards/boxel-status/indexing.json | 53 ++++++++++++++++++- packages/realm-server/server.ts | 2 +- 2 files changed, 52 insertions(+), 3 deletions(-) diff --git a/packages/observability/grafanactl/resources/dashboards/boxel-status/indexing.json b/packages/observability/grafanactl/resources/dashboards/boxel-status/indexing.json index c92d2d8c91..c7a39d6c89 100644 --- a/packages/observability/grafanactl/resources/dashboards/boxel-status/indexing.json +++ b/packages/observability/grafanactl/resources/dashboards/boxel-status/indexing.json @@ -718,8 +718,57 @@ }, "properties": [ { - "id": "custom.hidden", - "value": true + "id": "actions", + "value": [ + { + "type": "fetch", + "title": "Delete reservation ${__value.raw}", + "fetch": { + "method": "POST", + "url": "${realm_server}_grafana-complete-job", + "queryParams": [ + [ + "reservation_id", + "${__value.raw}" + ] + ], + "headers": [ + [ + "Authorization", + "Bearer ${grafana_secret}" + ] + ], + "body": "" + }, + "confirmation": "Cancel running reservation ${__value.raw}? The worker will stop processing it.", + "oneClick": false + } + ] + }, + { + "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 } ] }, diff --git a/packages/realm-server/server.ts b/packages/realm-server/server.ts index 6f42e0a430..46890553bc 100644 --- a/packages/realm-server/server.ts +++ b/packages/realm-server/server.ts @@ -395,7 +395,7 @@ export class RealmServer { cors({ origin: '*', allowHeaders: - 'Authorization, Content-Type, If-Match, If-None-Match, X-Requested-With, X-Boxel-Client-Request-Id, X-Boxel-Assume-User, X-HTTP-Method-Override, X-Boxel-Disable-Module-Cache, X-Filename, X-Boxel-During-Prerender, X-Boxel-Consuming-Realm, X-Boxel-Job-Id, X-Grafana-Device-Id', + 'Authorization, Content-Type, If-Match, If-None-Match, X-Requested-With, X-Boxel-Client-Request-Id, X-Boxel-Assume-User, X-HTTP-Method-Override, X-Boxel-Disable-Module-Cache, X-Filename, X-Boxel-During-Prerender, X-Boxel-Consuming-Realm, X-Boxel-Job-Id, X-Grafana-Device-Id, X-Grafana-Action', allowMethods: 'GET,HEAD,PUT,POST,DELETE,PATCH,OPTIONS,QUERY', // Cache the preflight response for 24 h. Without this @koa/cors // omits Access-Control-Max-Age and Chrome falls back to its