move hiveName to deploy.hive-controller; only a hive host needs a name
This commit is contained in:
parent
67f0d6a9d3
commit
0c6e8fc5a2
37 changed files with 402 additions and 215 deletions
|
|
@ -568,7 +568,7 @@ let
|
|||
l = vh."h1.hives.t.local".locations;
|
||||
gated = loc: lib.hasInfix "auth_request /__hive_authelia;" loc.extraConfig;
|
||||
in
|
||||
allLocal.services.hyperhive.swarm.dashboardDomain == "h1.hives.t.local"
|
||||
allLocal.services.hyperhive.deploy.hive-controller.dashboardDomain == "h1.hives.t.local"
|
||||
&& vh."h1.hives.t.local".forceSSL
|
||||
&& lib.all (p: gated l.${p}) [
|
||||
"/"
|
||||
|
|
@ -1251,23 +1251,133 @@ let
|
|||
&& bare.networking.bridges ? hive-br0;
|
||||
}
|
||||
{
|
||||
# Refused wherever something turns the name into an identifier, and only
|
||||
# there. The store host is the control that the refusal is not the hive's
|
||||
# alone; the host running neither is the control that it is gated at all.
|
||||
name = "a missing hiveName is refused on a hive and on a store host, not elsewhere";
|
||||
# Refused where a hive runs and nowhere else. A name is an identifier
|
||||
# only for a hive; the hive host is the control that the lookup finds the
|
||||
# refusal when there is one.
|
||||
name = "a missing hiveName is refused on a hive and not on a store, homeserver or services host";
|
||||
ok =
|
||||
let
|
||||
refusedHiveName =
|
||||
refused =
|
||||
extra:
|
||||
lib.any (a: !a.assertion && lib.hasInfix "services.hyperhive.hiveName to be set" a.message)
|
||||
(hiveWithController ({ hiveName = null; } // extra)).assertions;
|
||||
lib.any (
|
||||
a:
|
||||
!a.assertion
|
||||
&& lib.hasInfix "services.hyperhive.deploy.hive-controller.hiveName" a.message
|
||||
&& lib.hasInfix "to be set" a.message
|
||||
) (hive (lib.recursiveUpdate { deploy.hive-controller.hiveName = null; } extra)).assertions;
|
||||
in
|
||||
refusedHiveName { }
|
||||
&& refusedHiveName {
|
||||
deploy.hive-controller.enable = false;
|
||||
deploy.bao.enable = true;
|
||||
}
|
||||
&& !(refusedHiveName { deploy.hive-controller.enable = false; });
|
||||
refused { deploy.hive-controller.enable = true; }
|
||||
&& !(refused { deploy.bao.enable = true; })
|
||||
&& !(refused { deploy.matrix.enable = true; })
|
||||
&& !(refused { deploy.allSwarmServices = true; });
|
||||
}
|
||||
{
|
||||
# The directory entry is asserted for a hive and only for a hive. The
|
||||
# hive host with a name the directory lacks is the control.
|
||||
name = "a hive whose name has no swarm.hives entry is refused, and a host without a hive is not asked";
|
||||
ok =
|
||||
let
|
||||
noEntry =
|
||||
extra:
|
||||
lib.any (a: !a.assertion && lib.hasInfix "swarm.hives has no entry for this hive" a.message)
|
||||
(hive (lib.recursiveUpdate { deploy.hive-controller.hiveName = "other"; } extra)).assertions;
|
||||
in
|
||||
noEntry { deploy.hive-controller.enable = true; }
|
||||
&& !(noEntry { deploy.bao.enable = true; })
|
||||
&& !(noEntry { deploy.allSwarmServices = true; });
|
||||
}
|
||||
{
|
||||
# Nothing of the hive's identity is minted for a host that runs no hive:
|
||||
# no reader leaf named after a hive, and no reader identity at all, so
|
||||
# the glue that locates the PKI falls back to the store's own directory.
|
||||
# The hive host with the same store is the control.
|
||||
name = "a store host without a hive mints no hive reader leaf and still wires the controller and publisher";
|
||||
ok =
|
||||
let
|
||||
storeNoHive = hive {
|
||||
deploy.hive-controller.hiveName = null;
|
||||
deploy.bao.enable = true;
|
||||
deploy.swarm-controller.enable = true;
|
||||
deploy.swarm-secret-publisher.enable = true;
|
||||
};
|
||||
storeWithHive = hiveWithController {
|
||||
deploy.bao.enable = true;
|
||||
deploy.swarm-controller.enable = true;
|
||||
deploy.swarm-secret-publisher.enable = true;
|
||||
};
|
||||
pki = m: m.systemd.services.swarm-bao-pki.script;
|
||||
d = m: m.services.hyperhive.deploy;
|
||||
in
|
||||
(d storeNoHive).bao.clientCertFile == null
|
||||
&& (d storeNoHive).bao.clientKeyFile == null
|
||||
&& !(lib.hasInfix "/var/lib/swarm-bao-pki/client.pem ]" (pki storeNoHive))
|
||||
&& (d storeNoHive).swarm-controller.baoClientCertFile == "/var/lib/swarm-bao-pki/controller.pem"
|
||||
&&
|
||||
(d storeNoHive).swarm-secret-publisher.baoClientCertFile
|
||||
== "/var/lib/swarm-bao-pki/secret-publisher.pem"
|
||||
&& (d storeWithHive).bao.clientCertFile == "/var/lib/swarm-bao-pki/client.pem"
|
||||
&& lib.hasInfix "/var/lib/swarm-bao-pki/client.pem ]" (pki storeWithHive)
|
||||
&& (d storeWithHive).swarm-controller.baoClientCertFile == "/var/lib/swarm-bao-pki/controller.pem";
|
||||
}
|
||||
{
|
||||
# An operator's own reader leaf names the PKI directory, exactly as it did
|
||||
# when the glue always derived it from that path.
|
||||
name = "a controller and publisher with an operator-placed reader leaf and no store follow its directory";
|
||||
ok =
|
||||
let
|
||||
m = hive {
|
||||
deploy.swarm-controller.enable = true;
|
||||
deploy.swarm-secret-publisher.enable = true;
|
||||
deploy.bao.clientCertFile = "/etc/pki/elsewhere/client.pem";
|
||||
deploy.bao.clientKeyFile = "/etc/pki/elsewhere/client-key.pem";
|
||||
};
|
||||
d = m.services.hyperhive.deploy;
|
||||
in
|
||||
!d.bao.enable
|
||||
&& d.swarm-controller.baoClientCertFile == "/etc/pki/elsewhere/controller.pem"
|
||||
&& d.swarm-secret-publisher.baoClientCertFile == "/etc/pki/elsewhere/secret-publisher.pem";
|
||||
}
|
||||
{
|
||||
# The old spelling forwards with the module system's one warning and
|
||||
# produces the same hive. The new-path host is the control that the
|
||||
# warning is not always present.
|
||||
name = "services.hyperhive.hiveName still sets the hive's name, with a rename warning";
|
||||
ok =
|
||||
let
|
||||
old = hiveWithController {
|
||||
hiveName = "legacy";
|
||||
swarm.hives.legacy = { };
|
||||
};
|
||||
warned =
|
||||
m:
|
||||
lib.any (
|
||||
w: lib.hasInfix "services.hyperhive.hiveName" w && lib.hasInfix "has been renamed" w
|
||||
) m.warnings;
|
||||
in
|
||||
old.services.hyperhive.deploy.hive-controller.hiveName == "legacy"
|
||||
&& old.systemd.services.hive-c0re.environment.HYPERHIVE_HIVE_NAME == "legacy"
|
||||
&& warned old
|
||||
&& !(warned bare);
|
||||
}
|
||||
{
|
||||
# A hive's rendered identity, pinned so moving the option changes none of
|
||||
# it: the coordinator's name and client, the dashboard name, the CN of the
|
||||
# reader leaf the store host signs, and what the hive collector presents.
|
||||
name = "a hive's name reaches hive-c0re, the reader leaf, the dashboard and the hive collector unchanged";
|
||||
ok =
|
||||
let
|
||||
e = allLocal.systemd.services.hive-c0re.environment;
|
||||
script = allLocal.systemd.services.swarm-bao-pki.script;
|
||||
lines = lib.splitString "\n" script;
|
||||
at = lib.lists.findFirstIndex (lib.hasSuffix "swarm-bao-pki client \\") null lines;
|
||||
nextLine = builtins.head (builtins.match " *(.*)" (builtins.elemAt lines (at + 1)));
|
||||
in
|
||||
e.HYPERHIVE_HIVE_NAME == "h1"
|
||||
&& e.HIVE_C0RE_OIDC_CLIENT_ID == "hive-h1"
|
||||
&& e.HYPERHIVE_DASHBOARD_DOMAIN == "h1.hives.t.local"
|
||||
&& allLocal.services.hyperhive.deploy.hive-controller.dashboardDomain == "h1.hives.t.local"
|
||||
&& at != null
|
||||
&& nextLine == ''h1 "" clientAuth'';
|
||||
}
|
||||
{
|
||||
# The control is a host that defines no such option; the removal message
|
||||
|
|
|
|||
Loading…
Reference in a new issue