Dashboard see history edit this page

Talks about: , , , , , and

The StageSet controller publishes a maintained Grafana dashboard as a single-layer OCI image at ghcr.io/metio/stageset-controller-dashboard. The dashboard is grafonnet source, not pre-rendered JSON, and the controller is not a Jsonnet renderer — so you render it through JaaS , which publishes the rendered JSON as a Flux ExternalArtifact the grafana-operator picks up. The two projects are intentionally tightly coupled; JaaS is the renderer.

The dashboard opens with an SLO band — reconcile availability against its objective, error budget remaining, reconcile-latency p95 against its objective, and an availability-versus-objective trend — over a band of controller internals that explain any movement: reconciles by reason, stages applied, drift corrected, deferred updates, stage readiness, watch-engagement failures, and the controller-runtime workqueue. The series are the metrics the controller exports.

This page needs JaaS running in the cluster. If you don’t run JaaS, fetch the source from the OCI image yourself, render it with jsonnet -J vendor against grafonnet, and import the resulting JSON like any hand-built dashboard.

1. Point a Flux source at the image

It’s an OCI artifact, so use an OCIRepository. The dashboard imports grafonnet, so also install the grafonnet JsonnetLibrary (the joi chart , --set libraries.grafonnet.enabled=true).

apiVersion: source.toolkit.fluxcd.io/v1
kind: OCIRepository
metadata:
  name: stageset-controller-dashboard
  namespace: monitoring
spec:
  interval: 1h
  url: oci://ghcr.io/metio/stageset-controller-dashboard
  ref:
    tag: latest        # or a dated tag like 2026.6.22 to pin

The dashboard source also lives in this repository under dashboards/; if you mirror it into Git, a GitRepository pointing there works identically.

2. Render it with a JaaS JsonnetSnippet, passing the dashboard’s TLAs

The dashboard is a function of top-level arguments — datasource (the Prometheus datasource UID, default prometheus), title (default StageSet controller), a selector label matcher folded into every query (default empty), and the SLO knobs window (default 28d), availabilityTarget (default 0.99), and latencyTarget seconds (default 30) — supplied through JaaS’s spec.tlas.

selector is how you adapt to your Prometheus: scope the dashboard to one scrape job or cluster, e.g. selector: ['job="stageset"'] or ['cluster="prod"']. The queries never touch the namespace label, so a Prometheus that relabels it to exported_namespace doesn’t affect them; selector pins anything else.

apiVersion: jaas.metio.wtf/v1
kind: JsonnetSnippet
metadata:
  name: stageset-controller-dashboard
  namespace: monitoring
spec:
  serviceAccountName: dashboards-tenant
  # The OCI image's only file is main.jsonnet, which is spec.entryFile's default,
  # so no entryFile is needed.
  sourceRef:
    kind: OCIRepository
    name: stageset-controller-dashboard
  # grafonnet, which the dashboard imports by its full jb-vendor path, is served
  # by the JOI library installed above.
  libraries:
    - kind: JsonnetLibrary
      name: grafonnet
  # The dashboard's top-level arguments. Each value is a list; a single element
  # becomes a string TLA.
  tlas:
    datasource: ["prometheus"]              # your Prometheus datasource UID
    title: ["StageSet controller — prod"]
    selector: ['job="stageset"']            # scope every query to your scrape job/cluster
    window: ["28d"]                         # SLO window
    availabilityTarget: ["0.99"]            # reconcile-availability objective (99%)
    latencyTarget: ["30"]                   # reconcile-latency p95 objective (seconds)
  interval: 10m
  output: rendered

This is zero-maintenance: the OCIRepository polls ghcr.io/metio/stageset-controller-dashboard, so when a new dashboard is published JaaS re-renders, the ExternalArtifact digest changes, and the grafana-operator pushes the new JSON to Grafana — you reference the upstream image once and get every update automatically. Pin ref.tag to a dated tag instead of latest if you’d rather adopt updates deliberately.

JaaS renders the dashboard JSON and publishes it as an ExternalArtifact named after the snippet — stageset-controller-dashboard.

3. Hand the artifact to the grafana-operator

A GrafanaDashboard that references the published ExternalArtifact reconciles it into Grafana:

apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDashboard
metadata:
  name: stageset-controller
  namespace: monitoring
spec:
  instanceSelector:
    matchLabels:
      dashboards: "grafana"
  resyncPeriod: 30s
  sourceRef:
    apiVersion: source.toolkit.fluxcd.io/v1
    kind: ExternalArtifact
    name: stageset-controller-dashboard
    namespace: monitoring

When the published image updates (or you change the TLAs), JaaS re-renders, the ExternalArtifact digest changes, and the grafana-operator pushes the new JSON to Grafana — no manual export step.