@marble-sh/backstage-plugin-grafana-common 1.1.0 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,38 @@
1
1
  # @marble-sh/backstage-plugin-grafana-common
2
2
 
3
+ ## 1.2.1
4
+
5
+ ### Patch Changes
6
+
7
+ - c9c9f23: Documentation: a full entity-annotation reference (exact matching semantics,
8
+ how the annotations combine, visibility gating, and error behavior for
9
+ unknown instance names) in the frontend and common READMEs, and a new
10
+ "Creating the Grafana service account and token" walkthrough in the backend
11
+ README — UI steps, the Grafana Cloud `glsa_` vs `glc_` token distinction,
12
+ and a per-feature permission table (Viewer covers all read paths;
13
+ `datasources:query` caveat for panel graphs under Enterprise/Cloud data
14
+ source permissions; Editor / `fixed:dashboards:writer` for the scaffolder
15
+ module).
16
+
17
+ ## 1.2.0
18
+
19
+ ### Minor Changes
20
+
21
+ - a31b91d: Added: the dashboards tab now renders real graphs and the alerts tab a live
22
+ detail table. The backend gained read-only panel routes
23
+ (`GET …/dashboards/:uid/panels` and `GET …/panels/:panelId/data?from&to`)
24
+ that read a dashboard's model, resolve its template variables' current
25
+ values, query the panel targets through Grafana's `/api/ds/query`, and
26
+ return normalized time series — gated by the new `grafana.allowPanelQueries`
27
+ flag and cached per `grafana.panelDataCacheTtl` (default 30s). The frontend
28
+ draws `timeseries`/`graph` panels as charts and `stat`/`gauge`/`singlestat`
29
+ panels as value tiles, per-dashboard and lazily, with a time-range picker
30
+ and refresh. Alerts are enriched with rule uid (deep links), health,
31
+ active-since, active instance count, dashboard/panel links, and the
32
+ `summary` annotation. `GrafanaClient`/`GrafanaService` gained _optional_
33
+ `getPanels`/`getPanelData` members, so existing custom implementations
34
+ remain compatible.
35
+
3
36
  ## 1.1.0
4
37
 
5
38
  ### Minor Changes
package/README.md CHANGED
@@ -12,16 +12,28 @@ It provides:
12
12
 
13
13
  ## Entity annotations
14
14
 
15
- | Annotation | Helper | Meaning |
16
- | ------------------------------ | ------------------------ | ------------------------------------------------------------------ |
17
- | `grafana/instance` | `getGrafanaInstanceName` | Which configured Grafana instance the entity belongs to. |
18
- | `grafana/dashboard-selector` | `getDashboardSelector` | Comma-separated title substrings; any match selects the dashboard. |
19
- | `grafana/dashboard-uid` | `getDashboardUid` | A single dashboard uid (exact, case-sensitive match). |
20
- | `grafana/tag-selector` | `getTagSelector` | A comma-separated list of dashboard tags. |
21
- | `grafana/alert-label-selector` | `getAlertLabelSelector` | A `key=value,...` list of alert label matchers. |
22
-
23
- `isGrafanaAvailable(entity)` returns `true` when an entity carries any of the
24
- above annotations, and is used to gate the Grafana entity tabs and cards.
15
+ | Annotation | Helper | Meaning |
16
+ | ------------------------------ | ------------------------ | ---------------------------------------------------------------------------------------------------------------- |
17
+ | `grafana/instance` | `getGrafanaInstanceName` | The `grafana.instances[].name` the entity belongs to (exact match). Absent = query all configured instances. |
18
+ | `grafana/dashboard-selector` | `getDashboardSelector` | Comma-separated, case-insensitive title substrings; **any** match selects the dashboard. |
19
+ | `grafana/dashboard-uid` | `getDashboardUid` | A single dashboard uid (exact, case-sensitive match). Written by catalog discovery on its dashboard `Resource`s. |
20
+ | `grafana/tag-selector` | `getTagSelector` | Comma-separated dashboard tags; the dashboard must carry **all** of them. |
21
+ | `grafana/alert-label-selector` | `getAlertLabelSelector` | `key=value,...` alert label matchers; the rule's labels must contain **all** pairs. |
22
+
23
+ The dashboard annotations combine with AND — a dashboard must pass every one
24
+ the entity carries. Empty annotation values are treated as absent. The full
25
+ matching semantics are documented in the
26
+ [frontend plugin README](../grafana/README.md#entity-annotations).
27
+
28
+ Three gating helpers decide whether an entity has Grafana content to show:
29
+
30
+ - `isDashboardsAvailable(entity)` — any of `grafana/instance`,
31
+ `grafana/dashboard-selector`, `grafana/dashboard-uid`, or
32
+ `grafana/tag-selector` is present.
33
+ - `isAlertsAvailable(entity)` — `grafana/instance` or
34
+ `grafana/alert-label-selector` is present.
35
+ - `isGrafanaAvailable(entity)` — either of the above; used to gate the Grafana
36
+ entity tabs and cards.
25
37
 
26
38
  ```ts
27
39
  import {
package/dist/index.d.ts CHANGED
@@ -146,6 +146,12 @@ type GrafanaDashboard = {
146
146
  * @public
147
147
  */
148
148
  type GrafanaAlertState = 'firing' | 'pending' | 'inactive' | 'normal' | 'no_data' | 'error' | 'unknown';
149
+ /**
150
+ * The evaluation health of a Grafana alert rule.
151
+ *
152
+ * @public
153
+ */
154
+ type GrafanaAlertHealth = 'ok' | 'error' | 'nodata' | 'unknown';
149
155
  /**
150
156
  * A Grafana alert rule together with its current state.
151
157
  *
@@ -164,6 +170,90 @@ type GrafanaAlert = {
164
170
  folderTitle?: string;
165
171
  /** The name of the instance this alert was read from. */
166
172
  instanceName: string;
173
+ /** The alert rule uid, when the source API provides one. */
174
+ uid?: string;
175
+ /** The evaluation health of the rule. */
176
+ health?: GrafanaAlertHealth;
177
+ /** The rule's `summary` annotation, if any. */
178
+ summary?: string;
179
+ /** ISO-8601 timestamp of when the rule became active, when it is. */
180
+ activeAt?: string;
181
+ /** The number of currently active (pending or firing) alert instances. */
182
+ activeCount?: number;
183
+ /** The uid of the dashboard the rule is linked to, if any. */
184
+ dashboardUid?: string;
185
+ /** The id of the panel the rule is linked to, if any. */
186
+ panelId?: number;
187
+ };
188
+ /**
189
+ * How a Grafana panel is rendered by the frontend.
190
+ *
191
+ * - `timeseries`: rendered as a chart (Grafana `timeseries` and legacy `graph`
192
+ * panels).
193
+ * - `stat`: rendered as a single-value tile (Grafana `stat`, `gauge`, and
194
+ * legacy `singlestat` panels).
195
+ * - `unsupported`: not rendered; shown as a link into Grafana.
196
+ *
197
+ * @public
198
+ */
199
+ type GrafanaPanelKind = 'timeseries' | 'stat' | 'unsupported';
200
+ /**
201
+ * A single panel of a Grafana dashboard, as listed by the backend.
202
+ *
203
+ * @public
204
+ */
205
+ type GrafanaPanel = {
206
+ /** The panel id, unique within its dashboard. */
207
+ id: number;
208
+ /** The panel title. */
209
+ title: string;
210
+ /** The raw Grafana panel type (`timeseries`, `stat`, `table`, ...). */
211
+ type: string;
212
+ /** How the frontend renders this panel. */
213
+ kind: GrafanaPanelKind;
214
+ /** The panel description, if any. */
215
+ description?: string;
216
+ /** The uid of the dashboard containing the panel. */
217
+ dashboardUid: string;
218
+ /** The name of the instance the panel was read from. */
219
+ instanceName: string;
220
+ };
221
+ /**
222
+ * A single point of a time series: a timestamp and a value.
223
+ *
224
+ * @public
225
+ */
226
+ type GrafanaPanelPoint = {
227
+ /** The point's timestamp, in epoch milliseconds. */
228
+ timeMs: number;
229
+ /** The point's value; `null` marks a gap in the series. */
230
+ value: number | null;
231
+ };
232
+ /**
233
+ * A single named series of a panel's query results.
234
+ *
235
+ * @public
236
+ */
237
+ type GrafanaPanelSeries = {
238
+ /** The display name of the series. */
239
+ name: string;
240
+ /** The labels attached to the series, if any. */
241
+ labels?: Record<string, string>;
242
+ /** The data points, ordered by time. */
243
+ points: GrafanaPanelPoint[];
244
+ };
245
+ /**
246
+ * The queried data of a single panel, normalized from Grafana data frames.
247
+ *
248
+ * @public
249
+ */
250
+ type GrafanaPanelData = {
251
+ /** The id of the panel the data belongs to. */
252
+ panelId: number;
253
+ /** The normalized series, across all of the panel's queries. */
254
+ series: GrafanaPanelSeries[];
255
+ /** Human-readable notes about queries that failed or were skipped. */
256
+ warnings?: string[];
167
257
  };
168
258
  /**
169
259
  * Response body for `GET /instances`.
@@ -189,6 +279,20 @@ type ListDashboardsResponse = {
189
279
  type ListAlertsResponse = {
190
280
  items: GrafanaAlert[];
191
281
  };
282
+ /**
283
+ * Response body for the panel listing endpoint.
284
+ *
285
+ * @public
286
+ */
287
+ type ListPanelsResponse = {
288
+ items: GrafanaPanel[];
289
+ };
290
+ /**
291
+ * Response body for the panel data endpoint.
292
+ *
293
+ * @public
294
+ */
295
+ type GetPanelDataResponse = GrafanaPanelData;
192
296
 
193
297
  export { GRAFANA_ANNOTATION_ALERT_LABEL_SELECTOR, GRAFANA_ANNOTATION_DASHBOARD_SELECTOR, GRAFANA_ANNOTATION_DASHBOARD_UID, GRAFANA_ANNOTATION_INSTANCE, GRAFANA_ANNOTATION_TAG_SELECTOR, getAlertLabelSelector, getDashboardSelector, getDashboardUid, getGrafanaInstanceName, getTagSelector, isAlertsAvailable, isDashboardsAvailable, isGrafanaAvailable, parseLabelSelector, parseTagSelector };
194
- export type { GrafanaAlert, GrafanaAlertState, GrafanaDashboard, GrafanaInstanceInfo, ListAlertsResponse, ListDashboardsResponse, ListInstancesResponse };
298
+ export type { GetPanelDataResponse, GrafanaAlert, GrafanaAlertHealth, GrafanaAlertState, GrafanaDashboard, GrafanaInstanceInfo, GrafanaPanel, GrafanaPanelData, GrafanaPanelKind, GrafanaPanelPoint, GrafanaPanelSeries, ListAlertsResponse, ListDashboardsResponse, ListInstancesResponse, ListPanelsResponse };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marble-sh/backstage-plugin-grafana-common",
3
- "version": "1.1.0",
3
+ "version": "1.2.1",
4
4
  "description": "Common functionality for the Grafana Backstage plugins (types, annotations, and API contracts)",
5
5
  "main": "./dist/index.cjs.js",
6
6
  "types": "./dist/index.d.ts",