mirror of
https://github.com/oddlama/nix-config.git
synced 2025-10-11 07:10:39 +02:00
refactor: move all proxy related configuration to the nodes that define them
This commit is contained in:
parent
ead3c1696f
commit
998d6d5348
12 changed files with 122 additions and 176 deletions
6
flake.lock
generated
6
flake.lock
generated
|
@ -31,11 +31,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1686610839,
|
"lastModified": 1686617801,
|
||||||
"narHash": "sha256-rK3m7hth4Nc7Xmi83Mf4j53s1Ym9mJr312g7ct4i5Ck=",
|
"narHash": "sha256-fXNOCYjuFL4427jRW9C5xdc7KSJKhoFxXbBrxE3kibU=",
|
||||||
"owner": "oddlama",
|
"owner": "oddlama",
|
||||||
"repo": "agenix-rekey",
|
"repo": "agenix-rekey",
|
||||||
"rev": "cd77cb3bd43ece5b5fb1517d4b32338ac3cc5798",
|
"rev": "787efa41f1611403320517bbd41cd7cb7ebdf93d",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
../../../modules/interface-naming.nix
|
../../../modules/interface-naming.nix
|
||||||
../../../modules/microvms.nix
|
../../../modules/microvms.nix
|
||||||
../../../modules/promtail.nix
|
../../../modules/promtail.nix
|
||||||
|
../../../modules/proxied-domains.nix
|
||||||
../../../modules/repo.nix
|
../../../modules/repo.nix
|
||||||
../../../modules/wireguard.nix
|
../../../modules/wireguard.nix
|
||||||
];
|
];
|
||||||
|
|
|
@ -14,34 +14,6 @@
|
||||||
# TODO message = "non-deterministic uid detected for: ${name}";
|
# TODO message = "non-deterministic uid detected for: ${name}";
|
||||||
# TODO });
|
# TODO });
|
||||||
|
|
||||||
age.secrets.loki-basic-auth-hashes = {
|
|
||||||
rekeyFile = ./secrets/loki-basic-auth-hashes.age;
|
|
||||||
generator = {
|
|
||||||
# Dependencies are added by the nodes that define passwords using
|
|
||||||
# distributed-config.
|
|
||||||
script = {
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
decrypt,
|
|
||||||
deps,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
lib.flip lib.concatMapStrings deps ({
|
|
||||||
name,
|
|
||||||
host,
|
|
||||||
file,
|
|
||||||
}: ''
|
|
||||||
echo " -> Aggregating [32m"${lib.escapeShellArg host}":[m[33m"${lib.escapeShellArg name}"[m" >&2
|
|
||||||
echo -n ${lib.escapeShellArg host}" "
|
|
||||||
${decrypt} ${lib.escapeShellArg file} \
|
|
||||||
| ${pkgs.caddy}/bin/caddy hash-password --algorithm bcrypt \
|
|
||||||
|| die "Failure while aggregating caddy basic auth hashes"
|
|
||||||
'');
|
|
||||||
};
|
|
||||||
mode = "440";
|
|
||||||
group = "caddy";
|
|
||||||
};
|
|
||||||
|
|
||||||
services.caddy = {
|
services.caddy = {
|
||||||
enable = true;
|
enable = true;
|
||||||
package = pkgs.caddy.withPackages {
|
package = pkgs.caddy.withPackages {
|
||||||
|
@ -53,99 +25,5 @@
|
||||||
];
|
];
|
||||||
vendorHash = "sha256-RqSXQihtY5+ACaMo7bLdhu1A+qcraexb1W/Ia+aUF1k";
|
vendorHash = "sha256-RqSXQihtY5+ACaMo7bLdhu1A+qcraexb1W/Ia+aUF1k";
|
||||||
};
|
};
|
||||||
|
|
||||||
# globalConfig = ''
|
|
||||||
# # servers {
|
|
||||||
# # metrics
|
|
||||||
# # }
|
|
||||||
|
|
||||||
# order authenticate before respond
|
|
||||||
# order authorize before basicauth
|
|
||||||
|
|
||||||
# security {
|
|
||||||
# oauth identity provider generic {
|
|
||||||
# realm generic
|
|
||||||
# driver generic
|
|
||||||
# client_id {env.GENERIC_CLIENT_ID}
|
|
||||||
# client_secret {env.GENERIC_CLIENT_SECRET}
|
|
||||||
# scopes openid email profile
|
|
||||||
# base_auth_url https://${authDomain}/ui/oauth2
|
|
||||||
# metadata_url https://${authDomain}/oauth2/openid/{env.GENERIC_CLIENT_ID}/.well-known/openid-configuration
|
|
||||||
# }
|
|
||||||
|
|
||||||
# authentication portal myportal {
|
|
||||||
# crypto default token lifetime 3600
|
|
||||||
# crypto key sign-verify {env.JWT_SHARED_KEY}
|
|
||||||
# enable identity provider generic
|
|
||||||
# cookie domain myfiosgateway.com
|
|
||||||
# ui {
|
|
||||||
# links {
|
|
||||||
# "My Identity" "/whoami" icon "las la-user"
|
|
||||||
# }
|
|
||||||
# }
|
|
||||||
|
|
||||||
# transform user {
|
|
||||||
# match realm generic
|
|
||||||
# action add role authp/user
|
|
||||||
# ui link "File Server" https://assetq.myfiosgateway.com:8443/ icon "las la-star"
|
|
||||||
# }
|
|
||||||
|
|
||||||
# transform user {
|
|
||||||
# match realm generic
|
|
||||||
# match email greenpau@contoso.com
|
|
||||||
# action add role authp/admin
|
|
||||||
# }
|
|
||||||
# }
|
|
||||||
|
|
||||||
# authorization policy mypolicy {
|
|
||||||
# set auth url https://auth.myfiosgateway.com:8443/oauth2/generic
|
|
||||||
# crypto key verify {env.JWT_SHARED_KEY}
|
|
||||||
# allow roles authp/admin authp/user
|
|
||||||
# validate bearer header
|
|
||||||
# inject headers with claims
|
|
||||||
# }
|
|
||||||
# }
|
|
||||||
# '';
|
|
||||||
|
|
||||||
# TODO move subconfigs to the relevant hosts instead.
|
|
||||||
# -> have something like merged config nodes.<name>....
|
|
||||||
# -> needs to be in a way that doesn't trigger infinite recursion
|
|
||||||
|
|
||||||
virtualHosts.${config.proxyDomains.kanidm} = {
|
|
||||||
useACMEHost = config.lib.extra.matchingWildcardCert config.proxyDomains.kanidm;
|
|
||||||
extraConfig = ''
|
|
||||||
encode zstd gzip
|
|
||||||
reverse_proxy {
|
|
||||||
to https://${nodes.ward-kanidm.config.extra.wireguard.proxy-sentinel.ipv4}:${lib.last (lib.splitString ":" nodes.ward-kanidm.config.services.kanidm.serverSettings.bindaddress)}
|
|
||||||
transport http {
|
|
||||||
tls_insecure_skip_verify
|
|
||||||
}
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
virtualHosts.${config.proxyDomains.grafana} = {
|
|
||||||
useACMEHost = config.lib.extra.matchingWildcardCert config.proxyDomains.grafana;
|
|
||||||
extraConfig = ''
|
|
||||||
encode zstd gzip
|
|
||||||
reverse_proxy {
|
|
||||||
to http://${nodes.ward-grafana.config.extra.wireguard.proxy-sentinel.ipv4}:${toString nodes.ward-grafana.config.services.grafana.settings.server.http_port}
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
virtualHosts.${config.proxyDomains.loki} = {
|
|
||||||
useACMEHost = config.lib.extra.matchingWildcardCert config.proxyDomains.loki;
|
|
||||||
extraConfig = ''
|
|
||||||
encode zstd gzip
|
|
||||||
skip_log
|
|
||||||
basicauth {
|
|
||||||
import ${config.age.secrets.loki-basic-auth-hashes.path}
|
|
||||||
}
|
|
||||||
reverse_proxy {
|
|
||||||
to http://${nodes.ward-loki.config.extra.wireguard.proxy-sentinel.ipv4}:${toString nodes.ward-loki.config.services.loki.configuration.server.http_listen_port}
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
|
|
||||||
./fs.nix
|
./fs.nix
|
||||||
./net.nix
|
./net.nix
|
||||||
./proxied-domains.nix
|
|
||||||
|
|
||||||
./acme.nix
|
./acme.nix
|
||||||
./caddy.nix
|
./caddy.nix
|
||||||
|
|
|
@ -1,25 +0,0 @@
|
||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}: let
|
|
||||||
inherit
|
|
||||||
(lib)
|
|
||||||
mkOption
|
|
||||||
types
|
|
||||||
;
|
|
||||||
|
|
||||||
inherit (config.repo.secrets.local) personalDomain;
|
|
||||||
in {
|
|
||||||
options.proxiedDomains = mkOption {
|
|
||||||
type = types.attrsOf types.str;
|
|
||||||
default = {};
|
|
||||||
description = "Registry of relevant proxied domains";
|
|
||||||
};
|
|
||||||
|
|
||||||
config.proxiedDomains = {
|
|
||||||
grafana = "grafana.${personalDomain}";
|
|
||||||
kanidm = "auth.${personalDomain}";
|
|
||||||
loki = "loki.${personalDomain}";
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,10 +0,0 @@
|
||||||
age-encryption.org/v1
|
|
||||||
-> X25519 vqJImcuJU5nQkpNVBkRvU5gEjhiIT6GJIlKIa7Yv1T4
|
|
||||||
e30hk35HKlgSfI++1rC/CSJBjD0NInyUWv5suU2aDxU
|
|
||||||
-> piv-p256 xqSe8Q Agg6on210aOduBZKkxcooDEb5INXxTn0py0lufQz3ymG
|
|
||||||
TT2/sfJlvVIPaCNoqHVpAkYcrpQJ2K0OTclpuNCd2Gw
|
|
||||||
-> _cB-grease
|
|
||||||
|
|
||||||
--- 31UQg77E61iYmWHRniBdikMqVz7L8C6WYpWKrNvVi2k
|
|
||||||
UMËÍ@ÿâ!¢ìŠ{ÚÝ�XQzŽ!yöžÑ 6X\³è]…UÁi®‰Œ4Ìð•—¼ByX‚´‘Ùøu\Þ^’ÃB¸.ò�h›%`”‹¸ÚM¸+
|
|
||||||
qd$c¨-R;ȆÖV…#êŽ[¼{örqq¦èµÎÃV¨ql6«°î‹ÀÂEf©(RX¥2ÇiÖßKž�ï¬gÑì°ßWÐp‡ 9Óì5°D}z
|
|
|
@ -5,7 +5,10 @@
|
||||||
nodes,
|
nodes,
|
||||||
utils,
|
utils,
|
||||||
...
|
...
|
||||||
}: {
|
}: let
|
||||||
|
sentinelCfg = nodes.sentinel.config;
|
||||||
|
grafanaDomain = "grafana.${sentinelCfg.repo.secrets.local.personalDomain}";
|
||||||
|
in {
|
||||||
imports = [
|
imports = [
|
||||||
../../../../modules/proxy-via-sentinel.nix
|
../../../../modules/proxy-via-sentinel.nix
|
||||||
];
|
];
|
||||||
|
@ -27,9 +30,23 @@
|
||||||
group = "grafana";
|
group = "grafana";
|
||||||
};
|
};
|
||||||
|
|
||||||
nodes.sentinel.age.secrets.loki-basic-auth-hashes.generator.dependencies = [
|
nodes.sentinel = {
|
||||||
config.age.secrets.grafana-loki-basic-auth-password
|
age.secrets.loki-basic-auth-hashes.generator.dependencies = [
|
||||||
];
|
config.age.secrets.grafana-loki-basic-auth-password
|
||||||
|
];
|
||||||
|
|
||||||
|
proxiedDomains.grafana = grafanaDomain;
|
||||||
|
|
||||||
|
services.caddy.virtualHosts.${grafanaDomain} = {
|
||||||
|
useACMEHost = sentinelCfg.lib.extra.matchingWildcardCert grafanaDomain;
|
||||||
|
extraConfig = ''
|
||||||
|
encode zstd gzip
|
||||||
|
reverse_proxy {
|
||||||
|
to http://${config.services.grafana.settings.server.http_addr}:${toString config.services.grafana.settings.server.http_port}
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
services.grafana = {
|
services.grafana = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
@ -38,8 +55,8 @@
|
||||||
users.allow_sign_up = false;
|
users.allow_sign_up = false;
|
||||||
|
|
||||||
server = {
|
server = {
|
||||||
domain = nodes.sentinel.config.proxiedDomains.grafana;
|
domain = grafanaDomain;
|
||||||
root_url = "https://${nodes.sentinel.config.proxiedDomains.grafana}";
|
root_url = "https://${grafanaDomain}";
|
||||||
enforce_domain = true;
|
enforce_domain = true;
|
||||||
enable_gzip = true;
|
enable_gzip = true;
|
||||||
http_addr = config.extra.wireguard.proxy-sentinel.ipv4;
|
http_addr = config.extra.wireguard.proxy-sentinel.ipv4;
|
||||||
|
@ -66,9 +83,9 @@
|
||||||
client_secret = "r6Yk5PPSXFfYDPpK6TRCzXK8y1rTrfcb8F7wvNC5rZpyHTMF"; # TODO temporary test not a real secret
|
client_secret = "r6Yk5PPSXFfYDPpK6TRCzXK8y1rTrfcb8F7wvNC5rZpyHTMF"; # TODO temporary test not a real secret
|
||||||
scopes = "openid email profile";
|
scopes = "openid email profile";
|
||||||
login_attribute_path = "prefered_username";
|
login_attribute_path = "prefered_username";
|
||||||
auth_url = "https://${nodes.sentinel.config.proxiedDomains.kanidm}/ui/oauth2";
|
auth_url = "https://${sentinelCfg.proxiedDomains.kanidm}/ui/oauth2";
|
||||||
token_url = "https://${nodes.sentinel.config.proxiedDomains.kanidm}/oauth2/token";
|
token_url = "https://${sentinelCfg.proxiedDomains.kanidm}/oauth2/token";
|
||||||
api_url = "https://${nodes.sentinel.config.proxiedDomains.kanidm}/oauth2/openid/grafana/userinfo";
|
api_url = "https://${sentinelCfg.proxiedDomains.kanidm}/oauth2/openid/grafana/userinfo";
|
||||||
use_pkce = true;
|
use_pkce = true;
|
||||||
# Allow mapping oauth2 roles to server admin
|
# Allow mapping oauth2 roles to server admin
|
||||||
allow_assign_grafana_admin = true;
|
allow_assign_grafana_admin = true;
|
||||||
|
@ -89,7 +106,7 @@
|
||||||
name = "Loki";
|
name = "Loki";
|
||||||
type = "loki";
|
type = "loki";
|
||||||
access = "proxy";
|
access = "proxy";
|
||||||
url = "https://${nodes.sentinel.config.proxiedDomains.loki}";
|
url = "https://${sentinelCfg.proxiedDomains.loki}";
|
||||||
orgId = 1;
|
orgId = 1;
|
||||||
basicAuth = true;
|
basicAuth = true;
|
||||||
basicAuthUser = nodeName;
|
basicAuthUser = nodeName;
|
||||||
|
|
|
@ -5,7 +5,10 @@
|
||||||
pkgs,
|
pkgs,
|
||||||
utils,
|
utils,
|
||||||
...
|
...
|
||||||
}: {
|
}: let
|
||||||
|
sentinelCfg = nodes.sentinel.config;
|
||||||
|
kanidmDomain = "auth.${sentinelCfg.repo.secrets.local.personalDomain}";
|
||||||
|
in {
|
||||||
imports = [
|
imports = [
|
||||||
../../../../modules/proxy-via-sentinel.nix
|
../../../../modules/proxy-via-sentinel.nix
|
||||||
];
|
];
|
||||||
|
@ -26,12 +29,29 @@
|
||||||
group = "kanidm";
|
group = "kanidm";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
nodes.sentinel = {
|
||||||
|
proxiedDomains.kanidm = kanidmDomain;
|
||||||
|
|
||||||
|
services.caddy.virtualHosts.${kanidmDomain} = {
|
||||||
|
useACMEHost = sentinelCfg.lib.extra.matchingWildcardCert kanidmDomain;
|
||||||
|
extraConfig = ''
|
||||||
|
encode zstd gzip
|
||||||
|
reverse_proxy {
|
||||||
|
to https://${config.services.kanidm.serverSettings.bindaddress}
|
||||||
|
transport http {
|
||||||
|
tls_insecure_skip_verify
|
||||||
|
}
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
services.kanidm = {
|
services.kanidm = {
|
||||||
enableServer = true;
|
enableServer = true;
|
||||||
# enablePAM = true;
|
# enablePAM = true;
|
||||||
serverSettings = {
|
serverSettings = {
|
||||||
domain = nodes.sentinel.config.proxiedDomains.kanidm;
|
domain = kanidmDomain;
|
||||||
origin = "https://${nodes.sentinel.config.proxiedDomains.kanidm}";
|
origin = "https://${kanidmDomain}";
|
||||||
tls_chain = config.age.secrets."kanidm-self-signed.crt".path;
|
tls_chain = config.age.secrets."kanidm-self-signed.crt".path;
|
||||||
tls_key = config.age.secrets."kanidm-self-signed.key".path;
|
tls_key = config.age.secrets."kanidm-self-signed.key".path;
|
||||||
bindaddress = "${config.extra.wireguard.proxy-sentinel.ipv4}:8300";
|
bindaddress = "${config.extra.wireguard.proxy-sentinel.ipv4}:8300";
|
||||||
|
|
|
@ -4,7 +4,10 @@
|
||||||
nodes,
|
nodes,
|
||||||
utils,
|
utils,
|
||||||
...
|
...
|
||||||
}: {
|
}: let
|
||||||
|
sentinelCfg = nodes.sentinel.config;
|
||||||
|
lokiDomain = "loki.${sentinelCfg.repo.secrets.local.personalDomain}";
|
||||||
|
in {
|
||||||
imports = [
|
imports = [
|
||||||
../../../../modules/proxy-via-sentinel.nix
|
../../../../modules/proxy-via-sentinel.nix
|
||||||
];
|
];
|
||||||
|
@ -13,6 +16,52 @@
|
||||||
sentinel-to-local.allowedTCPPorts = [3100];
|
sentinel-to-local.allowedTCPPorts = [3100];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
nodes.sentinel = {
|
||||||
|
proxiedDomains.loki = lokiDomain;
|
||||||
|
|
||||||
|
age.secrets.loki-basic-auth-hashes = {
|
||||||
|
rekeyFile = ./secrets/loki-basic-auth-hashes.age;
|
||||||
|
generator = {
|
||||||
|
# Dependencies are added by the nodes that define passwords using
|
||||||
|
# distributed-config.
|
||||||
|
script = {
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
decrypt,
|
||||||
|
deps,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
lib.flip lib.concatMapStrings deps ({
|
||||||
|
name,
|
||||||
|
host,
|
||||||
|
file,
|
||||||
|
}: ''
|
||||||
|
echo " -> Aggregating [32m"${lib.escapeShellArg host}":[m[33m"${lib.escapeShellArg name}"[m" >&2
|
||||||
|
echo -n ${lib.escapeShellArg host}" "
|
||||||
|
${decrypt} ${lib.escapeShellArg file} \
|
||||||
|
| ${pkgs.caddy}/bin/caddy hash-password --algorithm bcrypt \
|
||||||
|
|| die "Failure while aggregating caddy basic auth hashes"
|
||||||
|
'');
|
||||||
|
};
|
||||||
|
mode = "440";
|
||||||
|
group = "caddy";
|
||||||
|
};
|
||||||
|
|
||||||
|
services.caddy.virtualHosts.${lokiDomain} = {
|
||||||
|
useACMEHost = sentinelCfg.lib.extra.matchingWildcardCert lokiDomain;
|
||||||
|
extraConfig = ''
|
||||||
|
encode zstd gzip
|
||||||
|
skip_log
|
||||||
|
basicauth {
|
||||||
|
import ${sentinelCfg.age.secrets.loki-basic-auth-hashes.path}
|
||||||
|
}
|
||||||
|
reverse_proxy {
|
||||||
|
to http://${config.services.loki.configuration.server.http_listen_address}:${toString config.services.loki.configuration.server.http_listen_port}
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
services.loki = let
|
services.loki = let
|
||||||
lokiDir = "/var/lib/loki";
|
lokiDir = "/var/lib/loki";
|
||||||
in {
|
in {
|
||||||
|
|
10
hosts/ward/microvms/loki/secrets/loki-basic-auth-hashes.age
Normal file
10
hosts/ward/microvms/loki/secrets/loki-basic-auth-hashes.age
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
age-encryption.org/v1
|
||||||
|
-> X25519 oTqcGYrzcjVyYkWQndidK7lfyMfQUFaLukLu9ru7ygc
|
||||||
|
0viOW4o/PQEhZfZFOx4UxbRBCGUXCYcvDv6r8hi6aiQ
|
||||||
|
-> piv-p256 xqSe8Q Akl/Ab1PwdLsyhJv3KzPxdALttqJdNk1wNj+pNnrFs9v
|
||||||
|
FbVps0hL4XpaPxrIBFmBi+a4YKIjTYsqBjN9JwzpkP8
|
||||||
|
-> ^/?z7Md-grease QDfMgTO
|
||||||
|
b+w4gj1Yxs6ocBCJN6AgLDad1/+EZ+HZ0zvMvGJaztxeIhNLSsiqoBn2GpwX6IcY
|
||||||
|
YWpLnO3Fw1xaU9Jqn9HJIqyYGFX1O5dBlvgu1rqgxytwiEEcDZaXOA1ZIupE
|
||||||
|
--- 0jXcY3KP8+JMsQ6+uhLE2bS1vGau/hr2b5ZD2SIUkbE
|
||||||
|
ąŠô>@2([žsÎ&ꆴd»KŽş’<w‰kÖqପZ$VĘ[Äf_Ć‘d-u´š‰ëß˝ź|^ß×ƶ–Q7�cIÇl*ćŕÚŮłźĽ€łś”ź•�™´2úńzgcUâza5>1}ĂiĆ_ ~�ÎÍžÁ™ü�«˛ŮQây�ĐÜW°P:qQ}"Óôň]+Pŕ:´Ŕqg|3köŃ&6˙őÉŘ`hG
|
|
@ -37,7 +37,7 @@ in {
|
||||||
isColmenaNode = elem nodeName (attrNames colmenaNodes);
|
isColmenaNode = elem nodeName (attrNames colmenaNodes);
|
||||||
otherNodes = filter (n: n != nodeName) (attrNames colmenaNodes);
|
otherNodes = filter (n: n != nodeName) (attrNames colmenaNodes);
|
||||||
foreignConfigs = concatMap (n: colmenaNodes.${n}.config.nodes.${nodeName} or []) otherNodes;
|
foreignConfigs = concatMap (n: colmenaNodes.${n}.config.nodes.${nodeName} or []) otherNodes;
|
||||||
toplevelAttrs = ["age" "networking" "systemd" "services"];
|
toplevelAttrs = ["age" "proxiedDomains" "networking" "systemd" "services"];
|
||||||
in
|
in
|
||||||
optionalAttrs isColmenaNode (mergeToplevelConfigs toplevelAttrs (
|
optionalAttrs isColmenaNode (mergeToplevelConfigs toplevelAttrs (
|
||||||
foreignConfigs
|
foreignConfigs
|
||||||
|
|
7
modules/proxied-domains.nix
Normal file
7
modules/proxied-domains.nix
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
{lib, ...}: {
|
||||||
|
options.proxiedDomains = lib.mkOption {
|
||||||
|
type = lib.types.attrsOf lib.types.str;
|
||||||
|
default = {};
|
||||||
|
description = "Registry of proxied domains for easy cross-node referencing.";
|
||||||
|
};
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue