# `checks.module-eval-ci-metrics` — see ./lib.nix for the shared rationale # (why this suite exists, naming convention, "evaluates not executes"). The CI # run poller's unit and timer, its default, its CA trust, its collector route # and its IdP registration; its store grants are in ./bao-grants.nix beside # every other principal's, and its dashboard in ./grafana.nix. # # Every fixture is a shared one, so this cluster evaluates no host of its own. { pkgs, lib, self, nixosSystem, shared, }: let inherit (import ./lib.nix { inherit pkgs lib self nixosSystem ; }) runGroup ; bare = shared.bareWithController; # Every swarm service on one host: the store mints the poller's leaf, so the # poller defaults on, beside authelia, the publisher and the collector. allLocal = shared.allLocal; svc = allLocal.systemd.services.swarm-ci-metrics; env = svc.environment; clientId = allLocal.services.hyperhive.swarm.ci-metrics.clientId; otel = allLocal.services.hyperhive.swarm.otel; cases = [ { # The control is the same unit and timer on the all-local host: a # misspelled attribute path would make the absence arm pass alone. name = "the CI run poller's unit and timer exist only where its host enables it"; ok = !(bare.systemd.services ? swarm-ci-metrics) && !(bare.systemd.timers ? swarm-ci-metrics) && allLocal.services.hyperhive.deploy.ci-metrics.enable && svc.serviceConfig.Type == "oneshot" && !(svc.serviceConfig.RemainAfterExit or false) && allLocal.systemd.timers.swarm-ci-metrics.timerConfig.OnUnitInactiveSec == "5min" && lib.elem "timers.target" allLocal.systemd.timers.swarm-ci-metrics.wantedBy; } { # The leaf is handed in as a credential, never an argument; the forge # token and the client secret are read from the store per pass. name = "the poller loads only its store leaf, keeps its cursor in its state directory and carries no secret in its unit"; ok = lib.elem "bao-client-key.pem:/var/lib/swarm-bao-pki/ci-metrics-key.pem" svc.serviceConfig.LoadCredential && lib.elem "bao-client.pem:/var/lib/swarm-bao-pki/ci-metrics.pem" svc.serviceConfig.LoadCredential && env.BAO_CLIENT_KEY == "/run/credentials/swarm-ci-metrics.service/bao-client-key.pem" && svc.serviceConfig.DynamicUser && svc.serviceConfig.StateDirectory == "swarm-ci-metrics" && !(lib.any (n: lib.hasSuffix "TOKEN" n || lib.hasSuffix "SECRET" n) (lib.attrNames env)); } { # The endpoint the poller pushes to is the route the collector admits # its client on, and that route feeds the swarm tier's metrics pipeline. name = "the poller pushes to its own collector route, which admits its client into the metrics pipeline"; ok = let h = shared.baoWithCollector; s = h.containers.swarm-otel.config.services.opentelemetry-collector.settings; in env.SWARM_CI_METRICS_OTLP_ENDPOINT == "https://${otel.domain}/swarm-ci-metrics" && env.SWARM_CI_METRICS_OIDC_CLIENT_ID == clientId && otel.serviceProducers.swarm-ci-metrics.clientId == clientId && s.receivers."otlp/swarm-ci-metrics".protocols.http.auth.authenticator == "oidc/swarm-ci-metrics" && s.extensions."oidc/swarm-ci-metrics".audience == clientId && lib.elem "otlp/swarm-ci-metrics" s.service.pipelines."metrics/${otel.producerName}".receivers && h.services.nginx.virtualHosts.${otel.domain}.locations ? "/swarm-ci-metrics/"; } { # The forge, authelia and the collector chain to the swarm's own CA; # without the bundle every pass fails `UnknownIssuer`. hive-c0re's # bundle on the bare host is the control that the absence arm looks up # a unit name the module would write. name = "the poller trusts the swarm's CA through its own bundle, which exists only where the poller does"; ok = allLocal.services.hyperhive.gateway.useSelfSigned && (env.SSL_CERT_FILE or null) == "/run/swarm-ci-metrics-ca/trust-bundle.pem" && lib.elem "swarm-ci-metrics-ca-bundle.service" svc.requires && lib.elem "hive-tls-ca.service" ( allLocal.systemd.services.swarm-ci-metrics-ca-bundle.requires or [ ] ) && bare.systemd.services ? hive-c0re-ca-bundle && !(bare.systemd.services ? swarm-ci-metrics-ca-bundle); } { name = "the poller's client is registered as a machine, and the publisher carries its secret"; ok = let c = lib.findFirst ( c: c.id == clientId ) null allLocal.services.hyperhive.swarm.authelia.oidc.clients; in c != null && c.kind == "machine" && c.audience == [ clientId ] && lib.hasInfix "secret/swarm/services/${clientId}/oidc/client" ( allLocal.containers.swarm-authelia.config.systemd.services.swarm-secret-publish.script ); } ]; in runGroup "ci-metrics" cases