feat(grafana-metric-gateway): slice 1 — backend gateway transport

Route all prometheus widget queries through Grafana /api/ds/query instead of
direct Prom HTTP. PrometheusConfig: drop base_url, add grafana_url +
datasource_uid; secret grafana_api_key (required). PrometheusWidgetSource →
MetricSource with _gateway_query POST method. normalize_grafana_frames
recovered from 65bae95 + shared _dedup_label helper. Gateway-path status
check. Startup old-config validation. CHANGELOG migration note. All adapter
tests rewritten for POST /api/ds/query + Grafana frames mock. Backend: 331
pytest pass, ruff clean. Frontend: build green (unchanged in S1).
This commit is contained in:
Developer
2026-07-09 21:24:44 +00:00
parent 798196ffc7
commit df80c68f89
10 changed files with 573 additions and 250 deletions
@@ -13,9 +13,10 @@ from media_library_viewer_api.integrations.base import (
class PrometheusConfig(ServiceConfigBase):
"""Non-secret Prometheus connection config."""
"""Non-secret Prometheus-via-Grafana gateway config."""
base_url: ServiceBaseUrl
grafana_url: ServiceBaseUrl
datasource_uid: str = "prometheus"
timeout_seconds: int = 10
@@ -57,7 +58,12 @@ DEFINITION = ServiceDefinition(
description="Metrics storage and PromQL queries.",
config_model=PrometheusConfig,
secret_fields=[
SecretField(key="api_key", label="API key", helper="Optional bearer token"),
SecretField(
key="grafana_api_key",
label="Grafana API key",
required=True,
helper="Service account token or API key for the Grafana gateway",
),
],
widget_kinds=[
widget_kind(