From 100a11e0de6c88fddc4e0c928534ea088c6f2dea Mon Sep 17 00:00:00 2001 From: Brad Stein Date: Thu, 1 Jan 2026 17:54:01 -0300 Subject: [PATCH] monitoring: split overview org --- .../monitoring/grafana-org-bootstrap.yaml | 110 ++++++++++++++++++ services/monitoring/helmrelease.yaml | 13 ++- services/monitoring/kustomization.yaml | 1 + 3 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 services/monitoring/grafana-org-bootstrap.yaml diff --git a/services/monitoring/grafana-org-bootstrap.yaml b/services/monitoring/grafana-org-bootstrap.yaml new file mode 100644 index 0000000..0872f4a --- /dev/null +++ b/services/monitoring/grafana-org-bootstrap.yaml @@ -0,0 +1,110 @@ +# services/monitoring/grafana-org-bootstrap.yaml +apiVersion: batch/v1 +kind: Job +metadata: + name: grafana-org-bootstrap-1 + namespace: monitoring +spec: + backoffLimit: 2 + template: + spec: + restartPolicy: OnFailure + containers: + - name: bootstrap + image: python:3.11-alpine + env: + - name: GRAFANA_URL + value: http://grafana + - name: OVERVIEW_ORG_NAME + value: Overview + - name: GRAFANA_USER + valueFrom: + secretKeyRef: + name: grafana-admin + key: admin-user + - name: GRAFANA_PASSWORD + valueFrom: + secretKeyRef: + name: grafana-admin + key: admin-password + command: ["/bin/sh", "-c"] + args: + - | + set -euo pipefail + python - <<'PY' + import base64 + import json + import os + import time + import urllib.error + import urllib.request + + grafana_url = os.environ["GRAFANA_URL"].rstrip("/") + org_name = os.environ["OVERVIEW_ORG_NAME"] + user = os.environ["GRAFANA_USER"] + password = os.environ["GRAFANA_PASSWORD"] + + auth = base64.b64encode(f"{user}:{password}".encode()).decode() + base_headers = { + "Authorization": f"Basic {auth}", + "Content-Type": "application/json", + } + + def request(path, method="GET", data=None, org_id=None): + headers = dict(base_headers) + if org_id is not None: + headers["X-Grafana-Org-Id"] = str(org_id) + payload = None + if data is not None: + payload = json.dumps(data).encode() + req = urllib.request.Request( + f"{grafana_url}{path}", + data=payload, + headers=headers, + method=method, + ) + return urllib.request.urlopen(req, timeout=10) + + for _ in range(60): + try: + with request("/api/health") as resp: + if resp.status == 200: + break + except Exception: + time.sleep(2) + else: + raise SystemExit("Grafana API did not become ready in time") + + with request("/api/orgs") as resp: + orgs = json.load(resp) + org_id = next((org["id"] for org in orgs if org["name"] == org_name), None) + if org_id is None: + with request("/api/orgs", method="POST", data={"name": org_name}) as resp: + org_id = json.load(resp).get("orgId") + if org_id is None: + raise SystemExit(f"Unable to resolve org ID for {org_name}") + + datasource = { + "name": "VictoriaMetrics", + "type": "prometheus", + "access": "proxy", + "url": "http://victoria-metrics-single-server:8428", + "isDefault": True, + "uid": "atlas-vm", + "jsonData": {"timeInterval": "15s"}, + } + try: + with request("/api/datasources/uid/atlas-vm", org_id=org_id) as resp: + if resp.status != 200: + raise urllib.error.HTTPError(resp.url, resp.status, resp.reason, resp.headers, None) + except urllib.error.HTTPError as err: + if err.code != 404: + raise + with request("/api/datasources", method="POST", data=datasource, org_id=org_id): + pass + + with request("/api/admin/provisioning/datasources/reload", method="POST"): + pass + with request("/api/admin/provisioning/dashboards/reload", method="POST"): + pass + PY diff --git a/services/monitoring/helmrelease.yaml b/services/monitoring/helmrelease.yaml index a07d207..79f1305 100644 --- a/services/monitoring/helmrelease.yaml +++ b/services/monitoring/helmrelease.yaml @@ -251,6 +251,7 @@ spec: GF_AUTH_GENERIC_OAUTH_CLIENT_ID: "grafana" GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET: "" GF_AUTH_ANONYMOUS_ENABLED: "true" + GF_AUTH_ANONYMOUS_ORG_NAME: "Overview" GF_AUTH_ANONYMOUS_ORG_ROLE: "Viewer" GF_SECURITY_ALLOW_EMBEDDING: "true" GF_AUTH_GENERIC_OAUTH_ENABLED: "true" @@ -298,12 +299,22 @@ spec: jsonData: timeInterval: "15s" uid: atlas-vm + orgId: 1 + - name: VictoriaMetrics + type: prometheus + access: proxy + url: http://victoria-metrics-single-server:8428 + isDefault: true + jsonData: + timeInterval: "15s" + uid: atlas-vm + orgId: 2 dashboardProviders: dashboardproviders.yaml: apiVersion: 1 providers: - name: overview - orgId: 1 + orgId: 2 folder: Overview type: file disableDeletion: false diff --git a/services/monitoring/kustomization.yaml b/services/monitoring/kustomization.yaml index a50a1c1..ad53bb5 100644 --- a/services/monitoring/kustomization.yaml +++ b/services/monitoring/kustomization.yaml @@ -14,3 +14,4 @@ resources: - dcgm-exporter.yaml - grafana-folders.yaml - helmrelease.yaml + - grafana-org-bootstrap.yaml