hive-tls: a gateway host without the services-issuer pair evaluates and goes red at runtime
Drop the eval assertion b78190e1 added. It refused every self-signed gateway host that does not run the store, which is the default hive shape, and contradicts docs/swarm/secrets.md's supported no-store deployment. The approved #4921 plan has such a host evaluate and fail at runtime; `requireServicesIssuer` already exits 1 naming both options, on the root-fetch branch and before issuing. The module-eval case that pinned `hiveWithController { }` as refused now pins it, and a hive-less gateway with no pair, as evaluating with the unit's refusal in the script. The fixture pairs the assertion forced into forge-placement, nats-tls and swarm-otel-identity are reverted. Refs #4921
This commit is contained in:
parent
5761398d60
commit
6a9c819136
7 changed files with 37 additions and 52 deletions
|
|
@ -333,30 +333,6 @@ in
|
|||
};
|
||||
|
||||
config = lib.mkIf active {
|
||||
assertions = [
|
||||
{
|
||||
assertion = haveServicesIssuer;
|
||||
message = ''
|
||||
services.hyperhive.gateway serves the self-signed leaf on this host,
|
||||
which needs the swarm-services issuer's store identity: set both
|
||||
|
||||
services.hyperhive.deploy.bao.servicesIssuerClientCertFile
|
||||
services.hyperhive.deploy.bao.servicesIssuerClientKeyFile
|
||||
|
||||
swarm-services-cert.service presents it to ask the swarm secret
|
||||
store for the swarm-services leaf and to fetch the store's pki root.
|
||||
|
||||
Both default to the pair glue-bao-tls.nix mints when
|
||||
services.hyperhive.deploy.bao.enable is true (the host that runs
|
||||
the store). Otherwise copy services-issuer.pem and
|
||||
services-issuer-key.pem from the store host's /var/lib/swarm-bao-pki/
|
||||
and name them in those two options, or give the gateway a
|
||||
certificate of its own (services.hyperhive.gateway.tls.certDir or
|
||||
services.hyperhive.gateway.tls.acme.enable).
|
||||
'';
|
||||
}
|
||||
];
|
||||
|
||||
# The state dir and the trust bundle. Never waits on the store: the
|
||||
# store's container is ordered after this unit, which writes the
|
||||
# bundle it bind-mounts, so the leaf is `hive-tls-resign`'s.
|
||||
|
|
|
|||
|
|
@ -1967,8 +1967,9 @@ in
|
|||
`pki/issue/swarm-services` and nothing else, and it is the same on
|
||||
every gateway host, whether or not a hive runs there.
|
||||
|
||||
Required on every host whose gateway serves the self-signed leaf;
|
||||
unset fails evaluation.
|
||||
Required on every host whose gateway serves the self-signed leaf.
|
||||
Unset, the host evaluates and `swarm-services-cert` fails, naming
|
||||
both options.
|
||||
|
||||
./glue-bao-tls.nix points it at the leaf it mints on the store's host.
|
||||
On a gateway host without the store, it is a file the operator copies
|
||||
|
|
|
|||
|
|
@ -73,8 +73,6 @@ let
|
|||
deploy.forgejo.ci.jobTimeout = "2h";
|
||||
deploy.bao.ciRunnerClientCertFile = "/etc/pki/bao-ci-runner.pem";
|
||||
deploy.bao.ciRunnerClientKeyFile = "/etc/pki/bao-ci-runner-key.pem";
|
||||
deploy.bao.servicesIssuerClientCertFile = "/etc/pki/bao-services-issuer.pem";
|
||||
deploy.bao.servicesIssuerClientKeyFile = "/etc/pki/bao-services-issuer-key.pem";
|
||||
};
|
||||
# The old name alone, with no store identity placed and none defaulted.
|
||||
ciUnderForgeNoIdentity = hive {
|
||||
|
|
@ -90,8 +88,6 @@ let
|
|||
swarm.forge.ci.package = pkgs.hello;
|
||||
deploy.bao.ciRunnerClientCertFile = "/etc/pki/bao-ci-runner.pem";
|
||||
deploy.bao.ciRunnerClientKeyFile = "/etc/pki/bao-ci-runner-key.pem";
|
||||
deploy.bao.servicesIssuerClientCertFile = "/etc/pki/bao-services-issuer.pem";
|
||||
deploy.bao.servicesIssuerClientKeyFile = "/etc/pki/bao-services-issuer-key.pem";
|
||||
};
|
||||
|
||||
runsForge = m: m.services.hyperhive.deploy.forgejo.enable && m.containers ? hive-forge;
|
||||
|
|
|
|||
|
|
@ -288,9 +288,11 @@ let
|
|||
&& refsHive [ noService.systemd.services.hive-tls-resign ];
|
||||
}
|
||||
{
|
||||
# The control is the same host with the pair placed, and the store's
|
||||
# host, where the glue supplies it.
|
||||
name = "a self-signed gateway with no services-issuer pair fails evaluation, naming both options";
|
||||
# A host with no store and no pair placed is a supported shape: it
|
||||
# evaluates, and its unit goes red. The control is the same host with
|
||||
# the pair placed, whose branch fetches, and the store's host, where
|
||||
# the glue supplies the pair.
|
||||
name = "a self-signed gateway with no services-issuer pair evaluates, and its unit fails naming both options";
|
||||
ok =
|
||||
let
|
||||
refused =
|
||||
|
|
@ -298,15 +300,29 @@ let
|
|||
lib.any (
|
||||
a:
|
||||
!a.assertion
|
||||
&& lib.hasInfix "services.hyperhive.deploy.bao.servicesIssuerClientCertFile" a.message
|
||||
&& lib.hasInfix "services.hyperhive.deploy.bao.servicesIssuerClientKeyFile" a.message
|
||||
&& (
|
||||
lib.hasInfix "servicesIssuerClientCertFile" a.message
|
||||
|| lib.hasInfix "servicesIssuerClientKeyFile" a.message
|
||||
)
|
||||
) m.assertions;
|
||||
redUnit =
|
||||
m:
|
||||
let
|
||||
branch = noSvcBranch m.systemd.services.swarm-services-cert.script;
|
||||
in
|
||||
lib.hasInfix "services.hyperhive.deploy.bao.servicesIssuerClientCertFile (unset)" branch
|
||||
&& lib.hasInfix "services.hyperhive.deploy.bao.servicesIssuerClientKeyFile (unset)" branch
|
||||
&& lib.hasSuffix "exit 1" (lib.removeSuffix "\n" branch)
|
||||
&& !(lib.hasInfix "/v1/pki/ca/pem" branch);
|
||||
in
|
||||
refused gatewayNoHiveNoPair
|
||||
&& refused noIdentity
|
||||
&& !(refused gatewayNoHive)
|
||||
&& !(refused noService)
|
||||
&& !(refused allLocal)
|
||||
!(refused gatewayNoHiveNoPair)
|
||||
&& !(refused noIdentity)
|
||||
&& redUnit gatewayNoHiveNoPair
|
||||
&& redUnit noIdentity
|
||||
&& !(redUnit gatewayNoHive)
|
||||
&& lib.hasInfix "/v1/pki/ca/pem" (
|
||||
noSvcBranch gatewayNoHive.systemd.services.swarm-services-cert.script
|
||||
)
|
||||
&&
|
||||
allLocal.services.hyperhive.deploy.bao.servicesIssuerClientCertFile
|
||||
== "/var/lib/swarm-bao-pki/services-issuer.pem";
|
||||
|
|
|
|||
|
|
@ -67,16 +67,14 @@ let
|
|||
# address set by hand: what every hive but one in a multi-host swarm looks
|
||||
# like. The controller is on too, since it may run away from the queue.
|
||||
#
|
||||
# The forge's secret, the controller's store identity and the gateway's
|
||||
# services-issuer pair are what a hive away from authelia and the store
|
||||
# already has to be handed, and none is an address; without them this hive
|
||||
# would fail assertions that have nothing to do with the queue.
|
||||
# The forge's secret and the controller's store identity are what a hive
|
||||
# away from authelia and the store already has to be handed, and none is an
|
||||
# address; without them this hive would fail assertions that have nothing to
|
||||
# do with the queue.
|
||||
remoteSecrets = {
|
||||
deploy.forgejo.sso.clientSecretFile = "/var/lib/forgejo-oidc/by-hand.secret";
|
||||
deploy.swarm-controller.baoClientCertFile = "/var/lib/swarm-controller/bao-client.pem";
|
||||
deploy.swarm-controller.baoClientKeyFile = "/var/lib/swarm-controller/bao-client-key.pem";
|
||||
deploy.bao.servicesIssuerClientCertFile = "/etc/pki/bao-services-issuer.pem";
|
||||
deploy.bao.servicesIssuerClientKeyFile = "/etc/pki/bao-services-issuer-key.pem";
|
||||
};
|
||||
remote = hiveWithController (
|
||||
lib.recursiveUpdate remoteSecrets { deploy.swarm-controller.enable = true; }
|
||||
|
|
|
|||
|
|
@ -27,12 +27,9 @@ let
|
|||
# hive's telemetry with nothing to push authenticated with, which is the
|
||||
# already-supported degrade `haveCollectorSecret` names above the module's
|
||||
# `let`. What this fixture is for is checking the reading unit itself does
|
||||
# not render, rather than rendering with an env var nothing filled in. Its
|
||||
# gateway has a certificate of its own: a self-signed one needs the
|
||||
# services-issuer identity.
|
||||
# not render, rather than rendering with an env var nothing filled in.
|
||||
otelNoIdentity = hive {
|
||||
deploy.swarm-otel.enable = true;
|
||||
gateway.tls.certDir = "/var/lib/acme/t.local";
|
||||
swarm.authelia.url = "https://auth.example.invalid";
|
||||
deploy.forgejo.sso.clientSecretFile = "/var/lib/forgejo-oidc/by-hand.secret";
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue