depot/ops/vault/cfg/module-acme-ca.nix

92 lines
2.3 KiB
Nix

{ config, lib, pkgs, ... }:
let
inherit (lib) mapAttrs' nameValuePair mkMerge mkOption mkIf any types;
hackterpolate = s: let
parts = builtins.split "(\\\$\\{[^}]+})" s;
unescape = s: builtins.fromJSON ''"${s}"'';
strParts = lib.imap1 (i: v: if lib.mod i 2 == 0 then unescape (builtins.elemAt v 0) else v) parts;
in lib.concatStrings strParts;
cfg = config.my.acme;
accountsEndpoints = mapAttrs' (name: value: nameValuePair "acme_account_${name}" {
depends_on = [ "vault_mount.acme" ];
path = "acme/accounts/${name}";
disable_read = true;
data_json = hackterpolate (builtins.toJSON value);
}) cfg.accounts;
rolesEndpoints = mapAttrs' (name: value: nameValuePair "acme_role_${name}" {
depends_on = [ "vault_mount.acme" ];
path = "acme/roles/${name}";
disable_read = true;
data_json = hackterpolate (builtins.toJSON value);
}) cfg.roles;
mkMergeIf = things: mkIf (any (t: t != { }) things) (mkMerge things);
in {
options = {
my.acme.mountPoint = mkOption {
default = "acme";
type = types.str;
};
my.acme.accounts = mkOption {
default = {};
type = (pkgs.formats.json { }).type;
};
my.acme.roles = mkOption {
default = {};
type = types.attrsOf (types.submodule ({ name, ... }: {
options = {
account = mkOption {
type = types.str;
default = name;
};
allow_bare_domains = mkOption {
type = types.bool;
default = true;
};
allow_subdomains = mkOption {
type = types.bool;
default = true;
};
allowed_domains = mkOption {
type = with types; listOf str;
};
cache_for_ratio = mkOption {
type = types.int;
default = 20;
};
disable_cache = mkOption {
type = types.bool;
default = false;
};
};
}));
};
};
config = {
resource.vault_mount.acme = {
path = config.my.acme.mountPoint;
type = "acme";
max_lease_ttl_seconds = 90 * 86400;
default_lease_ttl_seconds = 90 * 86400;
};
resource.vault_generic_endpoint = mkMergeIf [
accountsEndpoints
rolesEndpoints
];
};
}