Files
ethereum-rpc-docker/utils/mint-grafana-service-account-token.sh
Claude Agent 2761625c15 utils: add mint-grafana-service-account-token.sh
Mint a Viewer Grafana service-account token on a host and print it to stdout,
so each box's local Grafana (dshackle + node_exporter + cadvisor) can be wired
into the DRPC insights MCP (grafana_servers.yaml). Idempotent SA, fresh token
per call.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 08:59:46 +00:00

77 lines
3.1 KiB
Bash
Executable File

#!/bin/bash
# mint-grafana-service-account-token.sh
#
# Create a Grafana service-account API token on THIS host's local Grafana and
# print it (and only it) to stdout. Used to wire each box's local Grafana
# (Prometheus datasource: dshackle + node_exporter + cadvisor) into the DRPC
# insights MCP server's grafana_servers.yaml.
#
# Idempotent service account, fresh token on every call (token name carries a
# timestamp), so it is safe to run repeatedly. Diagnostics go to stderr; stdout
# is just the token, so callers can capture it directly:
#
# TOKEN=$(./utils/mint-grafana-service-account-token.sh)
#
# Reads ADMIN_USER / ADMIN_PASSWORD / DOMAIN from the deploy .env (or the
# environment; environment wins). Override target/role via env or args:
# GRAFANA_URL=https://grafana.host ./utils/mint-grafana-service-account-token.sh [sa_name] [role]
# Defaults: sa_name=drpc-insights-ro, role=Viewer.
#
# Requires: curl, jq. Works against Grafana >=9 (service accounts API).
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# --- load .env (environment already set wins; otherwise source nearest .env) ---
for envf in "$PWD/.env" "$SCRIPT_DIR/../.env" "$SCRIPT_DIR/../../.env"; do
if [ -f "$envf" ]; then set -a; . "$envf" 2>/dev/null || true; set +a; break; fi
done
ADMIN_USER="${ADMIN_USER:-admin}"
ADMIN_PASSWORD="${ADMIN_PASSWORD:-admin}"
SA_NAME="${1:-drpc-insights-ro}"
ROLE="${2:-Viewer}"
# --- resolve grafana base url (matches grafana_servers.yaml: grafana.<DOMAIN>) ---
if [ -n "${GRAFANA_URL:-}" ]; then
BASE="$GRAFANA_URL"
elif [ -n "${DOMAIN:-}" ]; then
BASE="https://grafana.${DOMAIN}"
else
BASE="http://localhost:3000"
fi
log() { echo "[mint] $*" >&2; }
CURL=(curl -fsS --ipv4 -m 20 -u "${ADMIN_USER}:${ADMIN_PASSWORD}" -H "Content-Type: application/json")
command -v jq >/dev/null 2>&1 || { log "ERROR: jq not found"; exit 1; }
log "grafana=$BASE sa=$SA_NAME role=$ROLE"
# --- find existing service account, else create it (idempotent) ---
sa_id="$("${CURL[@]}" "$BASE/api/serviceaccounts/search?query=${SA_NAME}" 2>/dev/null \
| jq -r --arg n "$SA_NAME" '.serviceAccounts[]? | select(.name==$n) | .id' | head -n1 || true)"
if [ -z "${sa_id:-}" ] || [ "$sa_id" = "null" ]; then
log "creating service account '${SA_NAME}'"
sa_id="$("${CURL[@]}" -X POST "$BASE/api/serviceaccounts" \
-d "{\"name\":\"${SA_NAME}\",\"role\":\"${ROLE}\",\"isDisabled\":false}" \
| jq -r '.id' || true)"
fi
if [ -z "${sa_id:-}" ] || [ "$sa_id" = "null" ]; then
log "ERROR: could not find or create service account"; exit 1
fi
log "service account id=${sa_id}"
# --- mint a fresh token (unique name => a new token every call) ---
tok_name="drpc-insights-$(hostname -s 2>/dev/null || hostname)-$(date +%s)"
token="$("${CURL[@]}" -X POST "$BASE/api/serviceaccounts/${sa_id}/tokens" \
-d "{\"name\":\"${tok_name}\",\"role\":\"${ROLE}\"}" | jq -r '.key' || true)"
if [ -z "${token:-}" ] || [ "$token" = "null" ]; then
log "ERROR: token creation failed (check ADMIN_PASSWORD / Grafana reachability at $BASE)"; exit 1
fi
log "minted token '${tok_name}'"
echo "$token"