feat: distributed config

feat: vaultwarden smtp config
This commit is contained in:
Patrick Großmann 2024-01-29 17:27:42 +01:00
parent 4158ba3bbf
commit a04313de0f
Signed by: patrick
GPG key ID: 451F95EFB8BECD0F
5 changed files with 96 additions and 2 deletions

View file

@ -22,6 +22,7 @@
../meta.nix
../smb-mounts.nix
../deterministic-ids.nix
../distributed-config.nix
../optional/iwd.nix
./impermanence

View file

@ -0,0 +1,66 @@
{
config,
lib,
nodes,
...
}: let
inherit
(lib)
attrNames
concatMap
concatStringsSep
foldl'
getAttrFromPath
mkMerge
mkOption
mkOptionType
optionals
recursiveUpdate
setAttrByPath
types
;
nodeName = config.node.name;
mkForwardedOption = path:
mkOption {
type = mkOptionType {
name = "Same type that the receiving option `${concatStringsSep "." path}` normally accepts.";
merge = _loc: defs:
builtins.filter
(x: builtins.isAttrs x -> ((x._type or "") != "__distributed_config_empty"))
(map (x: x.value) defs);
};
default = {_type = "__distributed_config_empty";};
description = ''
Anything specified here will be forwarded to `${concatStringsSep "." path}`
on the given node. Forwarding happens as-is to the raw values,
so validity can only be checked on the receiving node.
'';
};
forwardedOptions = [
["age" "secrets"]
["services" "maddy" "ensureCredentials"]
];
attrsForEachOption = f: (foldl' (acc: path: recursiveUpdate acc (setAttrByPath path (f path))) {} forwardedOptions);
in {
options.nodes = mkOption {
description = "Options forwareded to the given node.";
default = {};
type = types.attrsOf (types.submodule {
options = attrsForEachOption mkForwardedOption;
});
};
config = let
mergeConfigFromOthers = let
getConfig = path: otherNode: let
cfg = nodes.${otherNode}.config.nodes.${nodeName} or null;
in
optionals (cfg != null) (getAttrFromPath path cfg);
in
path: mkMerge (concatMap (getConfig path) (attrNames nodes));
in
attrsForEachOption mergeConfigFromOthers;
}

View file

@ -1,6 +1,7 @@
{
config,
lib,
nodes,
...
}: let
vaultwardenDomain = "pw.${config.secrets.secrets.global.domains.web}";
@ -51,6 +52,29 @@ in {
];
};
};
age.secrets.maddyPasswd = {
generator.script = "alnum";
group = "vaultwarden";
};
nodes.maddy = {
age.secrets.vaultwardenPasswd = {
inherit (config.age.secrets.maddyPasswd) rekeyFile;
inherit (nodes.maddy.config.services.maddy) group;
mode = "640";
};
services.maddy.ensureCredentials = {
"vaultwarden@${config.secrets.secrets.global.domains.mail_public}".passwordFile = nodes.maddy.config.age.secrets.vaultwardenPasswd.path;
};
};
system.activationScripts.systemd_env_smtp_passwd = {
text = ''
echo "SMTP_PASSWORD=$(< ${lib.escapeShellArg config.age.secrets.maddyPasswd.path})" > /run/vaultwarden_smtp_passwd
'';
deps = ["agenix"];
};
systemd.services.vaultwarden.serviceConfig.EnvironmentFile = ["/run/vaultwarden_smtp_passwd"];
services.vaultwarden = {
enable = true;
@ -71,9 +95,12 @@ in {
invitationOrgName = "Vaultwarden";
domain = "https://${vaultwardenDomain}";
smtpEmbedImages = true;
smtpSecurity = "force_tls";
smtpHost = "smtp.${config.secrets.secrets.global.domains.mail_public}";
smtpFrom = "vaultwarden@${config.secrets.secrets.global.domains.mail_public}";
smtpPort = 465;
smtpSecurity = "force_tls";
smtpUsername = "vaultwarden@${config.secrets.secrets.global.domains.mail_public}";
smtpEmbedImages = true;
};
environmentFile = config.age.secrets.vaultwarden-env.path;
};