swarm-bao: put a wrapped bao on the host, with this store's coordinates
Reading a role out of the store took four round-trips of environment guessing: the certificate has no IP SAN so loopback cannot verify, the DNS name resolves to the bridge from inside the container, and the CA the client needs lives on the host, which had no `bao` at all. The wrapper carries the address, the server CA and — where the PKI glue minted one — the reader's own leaf, so cert-auth login needs nothing typed. `--set-default` throughout: an operator pointing BAO_ADDR elsewhere still wins. Only the wrapper reaches PATH. `wrapProgram` renames the real binary, so there is no unwrapped `bao` to reach by accident, and the module-eval case asserting the package's absence is what keeps a later "install it too" from undoing that.
This commit is contained in:
parent
d2c501d1b2
commit
c24dd03485
2 changed files with 85 additions and 0 deletions
|
|
@ -219,6 +219,39 @@ let
|
|||
|
||||
clientCaPath = "${tlsDir}/client-ca.pem";
|
||||
|
||||
# The store's own CLI, on the host, with this deployment's coordinates already
|
||||
# in the environment. Only the wrapper goes on `PATH` — `wrapProgram` renames
|
||||
# the real binary, so there is no unwrapped `bao` to reach by accident and
|
||||
# produce a connection that names no cause.
|
||||
#
|
||||
# `--set-default`, not `--set`: an operator pointing `BAO_ADDR` at another
|
||||
# store must win. A wrapper that overrode an explicit environment would be the
|
||||
# same class of surprise it exists to remove.
|
||||
baoCli =
|
||||
let
|
||||
# The reader's identity `glue-bao-tls` already mints on this host, so
|
||||
# cert-auth login needs nothing typed either. A token stays the
|
||||
# operator's to supply — a wrapper cannot conjure one.
|
||||
wrapArgs = [
|
||||
"--set-default BAO_ADDR ${lib.escapeShellArg "https://${cfg.domain}:${toString cfg.port}"}"
|
||||
]
|
||||
++ lib.optional (
|
||||
baoDeploy.serverCaFile != null
|
||||
) "--set-default BAO_CACERT ${lib.escapeShellArg baoDeploy.serverCaFile}"
|
||||
++ lib.optionals (baoDeploy.clientCertFile != null && baoDeploy.clientKeyFile != null) [
|
||||
"--set-default BAO_CLIENT_CERT ${lib.escapeShellArg baoDeploy.clientCertFile}"
|
||||
"--set-default BAO_CLIENT_KEY ${lib.escapeShellArg baoDeploy.clientKeyFile}"
|
||||
];
|
||||
in
|
||||
pkgs.symlinkJoin {
|
||||
name = "bao-hive";
|
||||
paths = [ baoDeploy.package ];
|
||||
nativeBuildInputs = [ pkgs.makeWrapper ];
|
||||
postBuild = ''
|
||||
wrapProgram $out/bin/bao ${lib.concatStringsSep " " wrapArgs}
|
||||
'';
|
||||
};
|
||||
|
||||
extraListeners = lib.listToAttrs (
|
||||
lib.imap1 (
|
||||
i: addr:
|
||||
|
|
@ -678,6 +711,12 @@ in
|
|||
})
|
||||
|
||||
(lib.mkIf (hyperhiveCfg.enable && deployCfg.bao.enable) {
|
||||
# The wrapper alone, never `baoDeploy.package`: openbao's own module
|
||||
# installs the CLI *inside* the container, and this host had none at all,
|
||||
# so an operator either hopped into the container or re-typed the
|
||||
# addresses on every command.
|
||||
environment.systemPackages = [ baoCli ];
|
||||
|
||||
# The in-container unit plus the two host-side ones this module defines.
|
||||
# `swarm-bao-pki` and `swarm-bao-matrix-token` are declared by the glue
|
||||
# modules that create them, per the option's own rule — and a name
|
||||
|
|
|
|||
Loading…
Reference in a new issue