# The swarm's message queue as every hive sees it: where it is reached and # what it is registered as, identical on every host. What the host running it # decides, and the container itself, are in ./swarm-nats.nix. { lib, config, ... }: let swarmDomain = config.services.hyperhive.swarm.domain; # Total on a null swarm domain, for the reason ./swarm-bao.nix gives. domainBase = if swarmDomain == null then "invalid" else swarmDomain; in { options.services.hyperhive.swarm.nats = { # `enable` moved to `services.hyperhive.deploy.nats.enable` — see # ./deploy.nix. What the queue IS to every hive: its domain, ports # and client id. # ⚠️ Deliberately NO `package` option for the NATS server, anywhere — # not here and not under `deploy.nats` either, where every other # service's build now lives. `services.nats` upstream does not expose # one; it resolves `pkgs.nats-server` itself, so an option would be # ignored or need an overlay to mean anything, and an option that does # not control what it names is worse than its absence. Pin the build # with `nixpkgs.overlays` if you need to. (`deploy.nats.authPackage` # is a different thing: the callout responder, which IS ours.) domain = lib.mkOption { type = lib.types.str; default = "nats.${domainBase}"; defaultText = lib.literalExpression ''"nats.''${services.hyperhive.swarm.domain}"''; description = '' Name every client reaches the queue on, as `tls://:`, and the only name its certificate carries. A **sibling** of the swarm's other service names, for the reason {option}`services.hyperhive.swarm.bao.domain` gives. The host running the queue answers it through `gateway.localNames`. Every other hive resolves it through the operator's upstream DNS, which is where a multi-host swarm needs a record for it. Not in {option}`services.hyperhive.swarm.serviceDomains`: that list is the names a gateway vhost fronts, and nginx fronts nothing here. ''; }; port = lib.mkOption { type = lib.types.port; default = 4222; description = '' TCP port the queue listens on. 4222 is upstream's default and sits outside hyperhive's claimed ranges (dashboard 7000, forge 3000, matrix 8008, every agent in 8100..8999 via FNV-1a hash). Opened on the bridge interface, for agent containers, and on `wg-hive` when this host is on the mesh, for other hives. Never host-wide. TLS only: a client that does not speak it is refused. Unlike {option}`monitorPort` and {option}`metricsPort`, the address is not what bounds who may use this port: the queue's `auth_callout` refuses every client it cannot identify. ''; }; monitorPort = lib.mkOption { type = lib.types.port; default = 8222; description = '' Port NATS serves its **monitoring** endpoint on, bound to loopback. Not a metrics endpoint: the server has no Prometheus format of its own. This serves `/varz`, `/connz`, `/routez` as JSON, and the exporter below is what translates it — which is why enabling the exporter without this produces a process that starts cleanly and scrapes nothing. ⚠️ Loopback, and the exporter is the only intended reader. The endpoint is unauthenticated and `/connz` names every connected client, so the address it binds is the whole access control. Do not widen it, and do not put it behind a gateway vhost expecting that to add one. ''; }; metricsPort = lib.mkOption { type = lib.types.port; default = 7777; description = '' Port the Prometheus exporter serves NATS's metrics on, bound to loopback for the swarm collector to scrape. ⚠️ This and {option}`monitorPort` are two more claims on a port space every swarm container shares — they run in this container but `privateNetwork = false`, so a collision with any other hyperhive service is a runtime coin toss over which process gets the port, with nothing in any log saying so. Both defaults are upstream's own (`nats-server` 8222, `prometheus-nats-exporter` 7777) and neither is claimed elsewhere in this repo, checked when they were added. ''; }; clientId = lib.mkOption { type = lib.types.str; default = "swarm-nats"; description = '' OAuth2 client id the queue's authentication path identifies itself with. Must match the `id` of the corresponding entry in `services.hyperhive.swarm.authelia.oidc.clients` — which this module contributes for you when both run on this host. ''; }; }; }