nix: inline the swarm sub-path aliases at their use sites
autheliaCfg/forgeCfg/vmCfg/vlCfg were local re-exports of hyperhiveCfg.swarm.<subpath> — a shape that hides the full option path from grep, the same hazard #4356 fixed for the tls alias. Removed the six let-bindings and spelled the full hyperhiveCfg.swarm.<subpath>.<field> path at every use site instead. None of the read fields (url, machine, hiveClientPrefix, agentClientSuffix, domain, port) sit on the old side of a mkRenamedOptionModule in deploy.nix, so inlining the alias's own current path is correct as-is. Refs #4363 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
815f977d7c
commit
276bf8531a
6 changed files with 21 additions and 28 deletions
|
|
@ -35,7 +35,6 @@ let
|
||||||
hyperhiveDomain = hyperhiveCfg.domain;
|
hyperhiveDomain = hyperhiveCfg.domain;
|
||||||
swarmDomain = hyperhiveCfg.swarm.domain;
|
swarmDomain = hyperhiveCfg.swarm.domain;
|
||||||
deployCfg = hyperhiveCfg.deploy;
|
deployCfg = hyperhiveCfg.deploy;
|
||||||
forgeCfg = hyperhiveCfg.swarm.forge;
|
|
||||||
|
|
||||||
# Group an account must hold to reach operator-only surfaces. Named
|
# Group an account must hold to reach operator-only surfaces. Named
|
||||||
# here because this module writes the rule that enforces it and
|
# here because this module writes the rule that enforces it and
|
||||||
|
|
@ -78,7 +77,7 @@ let
|
||||||
# this data: `authn_strategies` on the authz endpoint also accepts
|
# this data: `authn_strategies` on the authz endpoint also accepts
|
||||||
# `CookieSession`, and a cookie carries no audience at all.
|
# `CookieSession`, and a cookie carries no audience at all.
|
||||||
metricsRule = {
|
metricsRule = {
|
||||||
domain = forgeCfg.domain;
|
domain = hyperhiveCfg.swarm.forge.domain;
|
||||||
resources = [ "^/metrics$" ];
|
resources = [ "^/metrics$" ];
|
||||||
}
|
}
|
||||||
// (
|
// (
|
||||||
|
|
|
||||||
|
|
@ -20,11 +20,8 @@ let
|
||||||
networkCfg = config.services.hyperhive.network;
|
networkCfg = config.services.hyperhive.network;
|
||||||
hyperhiveCfg = config.services.hyperhive;
|
hyperhiveCfg = config.services.hyperhive;
|
||||||
gatewayCfg = hyperhiveCfg.gateway;
|
gatewayCfg = hyperhiveCfg.gateway;
|
||||||
autheliaCfg = hyperhiveCfg.swarm.authelia;
|
|
||||||
baoCfg = hyperhiveCfg.swarm.bao;
|
baoCfg = hyperhiveCfg.swarm.bao;
|
||||||
baoDeploy = deployCfg.bao;
|
baoDeploy = deployCfg.bao;
|
||||||
vmCfg = hyperhiveCfg.swarm.victoriametrics;
|
|
||||||
vlCfg = hyperhiveCfg.swarm.victorialogs;
|
|
||||||
swarmDomain = hyperhiveCfg.swarm.domain;
|
swarmDomain = hyperhiveCfg.swarm.domain;
|
||||||
|
|
||||||
caTrust = import ./lib/hive-ca-trust.nix {
|
caTrust = import ./lib/hive-ca-trust.nix {
|
||||||
|
|
@ -90,7 +87,7 @@ let
|
||||||
# is a Grafana with no login of any kind, arrived at silently. SSO is a
|
# is a Grafana with no login of any kind, arrived at silently. SSO is a
|
||||||
# requirement of running this service, so an unconfigured swarm fails to
|
# requirement of running this service, so an unconfigured swarm fails to
|
||||||
# build and says which option to set.
|
# build and says which option to set.
|
||||||
ssoConfigured = autheliaCfg.url != null;
|
ssoConfigured = hyperhiveCfg.swarm.authelia.url != null;
|
||||||
|
|
||||||
# A reader of the store is defined by holding a certificate the store
|
# A reader of the store is defined by holding a certificate the store
|
||||||
# accepts, never by standing next to it — the rule
|
# accepts, never by standing next to it — the rule
|
||||||
|
|
@ -104,7 +101,7 @@ let
|
||||||
# around by reaching into authelia's tree whenever it happens to be local.
|
# around by reaching into authelia's tree whenever it happens to be local.
|
||||||
haveClientIdentity = baoDeploy.clientCertFile != null && baoDeploy.clientKeyFile != null;
|
haveClientIdentity = baoDeploy.clientCertFile != null && baoDeploy.clientKeyFile != null;
|
||||||
|
|
||||||
autheliaUrl = toString autheliaCfg.url;
|
autheliaUrl = toString hyperhiveCfg.swarm.authelia.url;
|
||||||
|
|
||||||
# Where the plaintext lands inside the container. Under /var/lib rather
|
# Where the plaintext lands inside the container. Under /var/lib rather
|
||||||
# than /run: Grafana may start before the delivery unit on a later boot,
|
# than /run: Grafana may start before the delivery unit on a later boot,
|
||||||
|
|
@ -304,7 +301,7 @@ in
|
||||||
|
|
||||||
datasourceUrl = lib.mkOption {
|
datasourceUrl = lib.mkOption {
|
||||||
type = lib.types.str;
|
type = lib.types.str;
|
||||||
default = "http://127.0.0.1:${toString vmCfg.port}";
|
default = "http://127.0.0.1:${toString hyperhiveCfg.swarm.victoriametrics.port}";
|
||||||
defaultText = lib.literalExpression ''"http://127.0.0.1:''${toString services.hyperhive.swarm.victoriametrics.port}"'';
|
defaultText = lib.literalExpression ''"http://127.0.0.1:''${toString services.hyperhive.swarm.victoriametrics.port}"'';
|
||||||
description = ''
|
description = ''
|
||||||
Where the provisioned datasource points. Defaults to the metrics
|
Where the provisioned datasource points. Defaults to the metrics
|
||||||
|
|
@ -317,7 +314,7 @@ in
|
||||||
|
|
||||||
logsDatasourceUrl = lib.mkOption {
|
logsDatasourceUrl = lib.mkOption {
|
||||||
type = lib.types.str;
|
type = lib.types.str;
|
||||||
default = "http://127.0.0.1:${toString vlCfg.port}";
|
default = "http://127.0.0.1:${toString hyperhiveCfg.swarm.victorialogs.port}";
|
||||||
defaultText = lib.literalExpression ''"http://127.0.0.1:''${toString services.hyperhive.swarm.victorialogs.port}"'';
|
defaultText = lib.literalExpression ''"http://127.0.0.1:''${toString services.hyperhive.swarm.victorialogs.port}"'';
|
||||||
description = ''
|
description = ''
|
||||||
Where the provisioned logs datasource points. Same reasoning as
|
Where the provisioned logs datasource points. Same reasoning as
|
||||||
|
|
|
||||||
|
|
@ -30,8 +30,6 @@ let
|
||||||
# operator sees, not a coercion error from here.
|
# operator sees, not a coercion error from here.
|
||||||
domainBase = if swarmDomain == null then "invalid" else swarmDomain;
|
domainBase = if swarmDomain == null then "invalid" else swarmDomain;
|
||||||
|
|
||||||
autheliaCfg = hyperhiveCfg.swarm.authelia;
|
|
||||||
|
|
||||||
# The collector names its components `<kind>/<owner>`, where `<owner>` is a
|
# The collector names its components `<kind>/<owner>`, where `<owner>` is a
|
||||||
# hive name for the per-hive pipelines and this literal for the swarm tier's
|
# hive name for the per-hive pipelines and this literal for the swarm tier's
|
||||||
# own. The two share one namespace and are merged with `//`, so a hive named
|
# own. The two share one namespace and are merged with `//`, so a hive named
|
||||||
|
|
@ -647,8 +645,8 @@ in
|
||||||
|
|
||||||
systemd.services.swarm-otel-oidc-secret = lib.mkIf deployCfg.authelia.enable {
|
systemd.services.swarm-otel-oidc-secret = lib.mkIf deployCfg.authelia.enable {
|
||||||
description = "deliver the swarm collector's OIDC client secret from authelia";
|
description = "deliver the swarm collector's OIDC client secret from authelia";
|
||||||
after = [ "container@${autheliaCfg.machine}.service" ];
|
after = [ "container@${hyperhiveCfg.swarm.authelia.machine}.service" ];
|
||||||
requires = [ "container@${autheliaCfg.machine}.service" ];
|
requires = [ "container@${hyperhiveCfg.swarm.authelia.machine}.service" ];
|
||||||
before = [ "container@${cfg.machine}.service" ];
|
before = [ "container@${cfg.machine}.service" ];
|
||||||
wantedBy = [ "container@${cfg.machine}.service" ];
|
wantedBy = [ "container@${cfg.machine}.service" ];
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
|
|
@ -855,7 +853,7 @@ in
|
||||||
# there is no version of this collector that runs without one.
|
# there is no version of this collector that runs without one.
|
||||||
# Stated as an assertion rather than a fallback because a guessed
|
# Stated as an assertion rather than a fallback because a guessed
|
||||||
# issuer URL evaluates cleanly and refuses every hive at runtime.
|
# issuer URL evaluates cleanly and refuses every hive at runtime.
|
||||||
assertion = autheliaCfg.url != null;
|
assertion = hyperhiveCfg.swarm.authelia.url != null;
|
||||||
message = ''
|
message = ''
|
||||||
services.hyperhive.deploy.swarm-otel.enable is true but
|
services.hyperhive.deploy.swarm-otel.enable is true but
|
||||||
services.hyperhive.swarm.authelia.url is null: every hive
|
services.hyperhive.swarm.authelia.url is null: every hive
|
||||||
|
|
@ -1065,7 +1063,7 @@ in
|
||||||
# A path, never a value — nothing here may read the
|
# A path, never a value — nothing here may read the
|
||||||
# secret, or it lands in the store world-readable.
|
# secret, or it lands in the store world-readable.
|
||||||
client_secret_file = collectorSecretPath;
|
client_secret_file = collectorSecretPath;
|
||||||
token_url = "${autheliaCfg.url}/api/oidc/token";
|
token_url = "${hyperhiveCfg.swarm.authelia.url}/api/oidc/token";
|
||||||
# The scope authelia's bearer-authz check looks for.
|
# The scope authelia's bearer-authz check looks for.
|
||||||
# The client is REGISTERED for it (the collector's
|
# The client is REGISTERED for it (the collector's
|
||||||
# entry sets `bearerAuthz`), but prometheus asks for
|
# entry sets `bearerAuthz`), but prometheus asks for
|
||||||
|
|
@ -1287,13 +1285,13 @@ in
|
||||||
lib.mapAttrs' (
|
lib.mapAttrs' (
|
||||||
h: _:
|
h: _:
|
||||||
lib.nameValuePair "oidc/${h}" {
|
lib.nameValuePair "oidc/${h}" {
|
||||||
issuer_url = autheliaCfg.url;
|
issuer_url = hyperhiveCfg.swarm.authelia.url;
|
||||||
# The audience this hive's client is registered to
|
# The audience this hive's client is registered to
|
||||||
# request, and the reason one hive's token is refused by
|
# request, and the reason one hive's token is refused by
|
||||||
# another hive's receiver. Same expression authelia
|
# another hive's receiver. Same expression authelia
|
||||||
# registers it under — a second spelling here would deny
|
# registers it under — a second spelling here would deny
|
||||||
# every hive, as a 401 that blames the token.
|
# every hive, as a 401 that blames the token.
|
||||||
audience = "${autheliaCfg.hiveClientPrefix}${h}";
|
audience = "${hyperhiveCfg.swarm.authelia.hiveClientPrefix}${h}";
|
||||||
# ⛔ DO NOT ADD `issuer_ca_path` HERE. The failure it
|
# ⛔ DO NOT ADD `issuer_ca_path` HERE. The failure it
|
||||||
# causes is invisible to every check we have.
|
# causes is invisible to every check we have.
|
||||||
#
|
#
|
||||||
|
|
@ -1336,7 +1334,7 @@ in
|
||||||
# a real swarm-controller push gets a healthy-looking 401.
|
# a real swarm-controller push gets a healthy-looking 401.
|
||||||
// {
|
// {
|
||||||
"oidc/${swarmTierName}" = {
|
"oidc/${swarmTierName}" = {
|
||||||
issuer_url = autheliaCfg.url;
|
issuer_url = hyperhiveCfg.swarm.authelia.url;
|
||||||
audience = config.services.hyperhive.swarm.controller.queueClientId;
|
audience = config.services.hyperhive.swarm.controller.queueClientId;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -1351,7 +1349,7 @@ in
|
||||||
client_id = cfg.clientId;
|
client_id = cfg.clientId;
|
||||||
# A path, never a value. Same file the scrape side reads.
|
# A path, never a value. Same file the scrape side reads.
|
||||||
client_secret_file = collectorSecretPath;
|
client_secret_file = collectorSecretPath;
|
||||||
token_url = "${autheliaCfg.url}/api/oidc/token";
|
token_url = "${hyperhiveCfg.swarm.authelia.url}/api/oidc/token";
|
||||||
# Registered is not requested: a client that does not ASK
|
# Registered is not requested: a client that does not ASK
|
||||||
# for the scope gets a token carrying none, and one that
|
# for the scope gets a token carrying none, and one that
|
||||||
# does not ask for an audience gets `aud: []`.
|
# does not ask for an audience gets `aud: []`.
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,6 @@ let
|
||||||
hyperhiveCfg = config.services.hyperhive;
|
hyperhiveCfg = config.services.hyperhive;
|
||||||
deployCfg = hyperhiveCfg.deploy;
|
deployCfg = hyperhiveCfg.deploy;
|
||||||
baoDeploy = deployCfg.bao;
|
baoDeploy = deployCfg.bao;
|
||||||
autheliaCfg = hyperhiveCfg.swarm.authelia;
|
|
||||||
cfg = deployCfg.swarm-secret-publisher;
|
cfg = deployCfg.swarm-secret-publisher;
|
||||||
|
|
||||||
# A reader is defined by holding a certificate the store accepts, never by
|
# A reader is defined by holding a certificate the store accepts, never by
|
||||||
|
|
@ -54,7 +53,9 @@ let
|
||||||
# The client id agent containers present, per hive — composed exactly as
|
# The client id agent containers present, per hive — composed exactly as
|
||||||
# ./swarm-authelia.nix composes it, from the same two read-only options, so a
|
# ./swarm-authelia.nix composes it, from the same two read-only options, so a
|
||||||
# rename there cannot leave this spelling behind.
|
# rename there cannot leave this spelling behind.
|
||||||
agentClientId = hive: "${autheliaCfg.hiveClientPrefix}${hive}${autheliaCfg.agentClientSuffix}";
|
agentClientId =
|
||||||
|
hive:
|
||||||
|
"${hyperhiveCfg.swarm.authelia.hiveClientPrefix}${hive}${hyperhiveCfg.swarm.authelia.agentClientSuffix}";
|
||||||
|
|
||||||
# The swarm's own services, as opposed to its hives. One client for the whole
|
# The swarm's own services, as opposed to its hives. One client for the whole
|
||||||
# swarm rather than one per hive, so one value in the store rather than a copy
|
# swarm rather than one per hive, so one value in the store rather than a copy
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,6 @@ let
|
||||||
networkCfg = config.services.hyperhive.network;
|
networkCfg = config.services.hyperhive.network;
|
||||||
hyperhiveCfg = config.services.hyperhive;
|
hyperhiveCfg = config.services.hyperhive;
|
||||||
gatewayCfg = hyperhiveCfg.gateway;
|
gatewayCfg = hyperhiveCfg.gateway;
|
||||||
autheliaCfg = hyperhiveCfg.swarm.authelia;
|
|
||||||
swarmDomain = hyperhiveCfg.swarm.domain;
|
swarmDomain = hyperhiveCfg.swarm.domain;
|
||||||
|
|
||||||
# Total on a null swarm domain for the same reason every sibling module is:
|
# Total on a null swarm domain for the same reason every sibling module is:
|
||||||
|
|
@ -56,7 +55,7 @@ let
|
||||||
swarmAuthRequest = ''
|
swarmAuthRequest = ''
|
||||||
auth_request /__hive_authelia;
|
auth_request /__hive_authelia;
|
||||||
auth_request_set $target_url $scheme://$http_host$request_uri;
|
auth_request_set $target_url $scheme://$http_host$request_uri;
|
||||||
error_page 401 =302 https://${autheliaCfg.domain}/?rd=$target_url;
|
error_page 401 =302 https://${hyperhiveCfg.swarm.authelia.domain}/?rd=$target_url;
|
||||||
'';
|
'';
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
|
@ -241,14 +240,14 @@ in
|
||||||
# reasoning as `swarm-ui.nix`'s own copy (measured against the
|
# reasoning as `swarm-ui.nix`'s own copy (measured against the
|
||||||
# pinned authelia binary, not copied from an example).
|
# pinned authelia binary, not copied from an example).
|
||||||
"= /__hive_authelia" = {
|
"= /__hive_authelia" = {
|
||||||
proxyPass = "https://${autheliaCfg.domain}/api/authz/auth-request";
|
proxyPass = "https://${hyperhiveCfg.swarm.authelia.domain}/api/authz/auth-request";
|
||||||
# nixpkgs appends its OWN `Host $host` after extraConfig,
|
# nixpkgs appends its OWN `Host $host` after extraConfig,
|
||||||
# which would override verifiedProxyTo's — see the comment
|
# which would override verifiedProxyTo's — see the comment
|
||||||
# on verifiedProxyTo in hive-gateway/vhost-lib.nix.
|
# on verifiedProxyTo in hive-gateway/vhost-lib.nix.
|
||||||
recommendedProxySettings = false;
|
recommendedProxySettings = false;
|
||||||
extraConfig = ''
|
extraConfig = ''
|
||||||
internal;
|
internal;
|
||||||
${gatewayCfg.lib.verifiedProxyTo autheliaCfg.domain}
|
${gatewayCfg.lib.verifiedProxyTo hyperhiveCfg.swarm.authelia.domain}
|
||||||
proxy_pass_request_body off;
|
proxy_pass_request_body off;
|
||||||
proxy_set_header Content-Length "";
|
proxy_set_header Content-Length "";
|
||||||
proxy_set_header X-Original-Method $request_method;
|
proxy_set_header X-Original-Method $request_method;
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ let
|
||||||
networkCfg = config.services.hyperhive.network;
|
networkCfg = config.services.hyperhive.network;
|
||||||
hyperhiveCfg = config.services.hyperhive;
|
hyperhiveCfg = config.services.hyperhive;
|
||||||
gatewayCfg = hyperhiveCfg.gateway;
|
gatewayCfg = hyperhiveCfg.gateway;
|
||||||
autheliaCfg = hyperhiveCfg.swarm.authelia;
|
|
||||||
swarmDomain = hyperhiveCfg.swarm.domain;
|
swarmDomain = hyperhiveCfg.swarm.domain;
|
||||||
|
|
||||||
# Total on a null swarm domain for the same reason every sibling module is:
|
# Total on a null swarm domain for the same reason every sibling module is:
|
||||||
|
|
@ -160,14 +159,14 @@ in
|
||||||
# `X-Original-Method` are what authelia's auth-request implementation
|
# `X-Original-Method` are what authelia's auth-request implementation
|
||||||
# reads, and the address it compares the token's audience against.
|
# reads, and the address it compares the token's audience against.
|
||||||
"= /__metrics_push_authz" = {
|
"= /__metrics_push_authz" = {
|
||||||
proxyPass = "https://${autheliaCfg.domain}/api/authz/auth-request";
|
proxyPass = "https://${hyperhiveCfg.swarm.authelia.domain}/api/authz/auth-request";
|
||||||
# nixpkgs appends its OWN `Host $host` after extraConfig, which
|
# nixpkgs appends its OWN `Host $host` after extraConfig, which
|
||||||
# would override verifiedProxyTo's — see the comment on
|
# would override verifiedProxyTo's — see the comment on
|
||||||
# verifiedProxyTo in hive-gateway/vhost-lib.nix.
|
# verifiedProxyTo in hive-gateway/vhost-lib.nix.
|
||||||
recommendedProxySettings = false;
|
recommendedProxySettings = false;
|
||||||
extraConfig = ''
|
extraConfig = ''
|
||||||
internal;
|
internal;
|
||||||
${gatewayCfg.lib.verifiedProxyTo autheliaCfg.domain}
|
${gatewayCfg.lib.verifiedProxyTo hyperhiveCfg.swarm.authelia.domain}
|
||||||
proxy_pass_request_body off;
|
proxy_pass_request_body off;
|
||||||
proxy_set_header Content-Length "";
|
proxy_set_header Content-Length "";
|
||||||
proxy_set_header X-Original-Method $request_method;
|
proxy_set_header X-Original-Method $request_method;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue