Creating a hive's cert-auth role means writing the authority into the role by value -- the store matches a presented certificate against the role's own copy -- and nothing gave this daemon that file. Named separately from deploy.bao.clientCaFile rather than read off it: that option is the store's, saying which readers the store trusts on the host that runs it, while a controller runs anywhere. The glue module supplies it where the two are co-located, which is the same split baoClientCertFile already makes against the hive reader's leaf. Gated on the identity as well as the CA. Without a leaf there is nothing to write a role with, so the file would reach a daemon that cannot act on it. The module-eval arm needed a fixture of its own: a deployment that self-signs both ends points clientCaFile and serverCaFile at one file, so on the existing fixture the two authorities are the same string and wiring either into the other's slot passes. controllerTwoCas is where they differ.
47 lines
2.1 KiB
Nix
47 lines
2.1 KiB
Nix
# Glue: point the swarm controller at the bao leaf minted for it.
|
|
#
|
|
# ONE PAIRING PER FILE — controller ← bao, and nothing else. Deleting this
|
|
# leaves a controller that takes operator-provided certificate paths, which is
|
|
# what every deployment that does not mint its own already does.
|
|
#
|
|
# ⚠️ The minting is NOT here. ./glue-bao-tls.nix holds the CA and signs the
|
|
# leaf, because the thing that owns a private key owns issuing from it; a
|
|
# second signer would duplicate that file's `openssl` helper to no benefit.
|
|
# What belongs here is the pairing: which paths this host's controller reads.
|
|
#
|
|
# ⚠️ Gated on the leaf existing, not on the store being enabled. A controller
|
|
# on the store's own host is one deployment; a controller three networks away
|
|
# holding a leaf issued out of band is another, and both want the same wiring.
|
|
# `deploy.bao.enable` would have made the first one the only supported shape.
|
|
#
|
|
# Everything is `mkDefault`. An operator naming their own paths wins.
|
|
{
|
|
lib,
|
|
config,
|
|
...
|
|
}:
|
|
let
|
|
hyperhiveCfg = config.services.hyperhive;
|
|
deployCfg = hyperhiveCfg.deploy;
|
|
baoDeploy = deployCfg.bao;
|
|
|
|
# Where ./glue-bao-tls.nix puts the leaves. Derived from the reader's own
|
|
# path rather than repeating that file's directory literal: an operator who
|
|
# moves the PKI moves both, and the two cannot drift apart.
|
|
haveMintedPki = baoDeploy.clientCertFile != null;
|
|
pkiDir = if haveMintedPki then builtins.dirOf baoDeploy.clientCertFile else null;
|
|
in
|
|
{
|
|
config = lib.mkIf (hyperhiveCfg.enable && deployCfg.swarm-controller.enable && haveMintedPki) {
|
|
services.hyperhive.deploy.swarm-controller = {
|
|
baoClientCertFile = lib.mkDefault "${pkiDir}/controller.pem";
|
|
baoClientKeyFile = lib.mkDefault "${pkiDir}/controller-key.pem";
|
|
}
|
|
// lib.optionalAttrs (baoDeploy.clientCaFile != null) {
|
|
# The authority the store already trusts hives by, handed to the daemon
|
|
# that has to write it into each hive's role. One file, two readers —
|
|
# a second copy would authenticate hives the store does not.
|
|
hiveClientCaFile = lib.mkDefault baoDeploy.clientCaFile;
|
|
};
|
|
};
|
|
}
|