{ depot, lib, config, ... }: let inherit (lib) mkOption nameValuePair mapToAttrs types mkEnableOption mapAttrs' filterAttrs mkMerge mapAttrsToList concatStringsSep mkBefore; minutes = m: m * 60; serversType = types.attrsOf (types.submodule ({ name, ... }: { options = { enable = mkOption { type = types.bool; default = true; }; resourceName = mkOption { type = types.str; default = "server_${name}"; internal = true; }; extraPolicies = mkOption { type = with types; listOf str; default = []; }; apps = mkOption { type = with types; listOf str; default = []; }; appPolicies = mkOption { # Server-specific app policies. type = with types; attrsOf lines; default = {}; }; userPolicies = mkOption { # Server-specific user policies. type = with types; attrsOf lines; default = {}; }; hostnames = mkOption { type = with types; listOf str; default = [ "${name}" "${name}.as205479.net" "${name}.blade.as205479.net" "${name}.int.as205479.net" "${name}.otter-acoustic.ts.net" ]; }; policy = mkOption { type = types.lines; default = '' path "ssh-host/sign/${name}" { capabilities = ["update"] allowed_parameters = { "cert_type" = ["host"] "public_key" = [] "valid_principals" = [] } } ''; }; }; config.apps = mkBefore [ "deployer" ]; })); cfg = config.my.enabledServers; in { options = { my.servers = mkOption { type = serversType; }; my.enabledServers = mkOption { internal = true; readOnly = true; default = filterAttrs (n: v: v.enable) config.my.servers; type = serversType; }; }; config.my.servers = mapToAttrs (name: nameValuePair name {}) (builtins.attrNames depot.ops.nixos.systemConfigs); config.resource = mkMerge (mapAttrsToList (serverName: serverCfg: mkMerge ([{ vault_policy.${serverCfg.resourceName} = { name = "server/${serverName}"; inherit (serverCfg) policy; }; vault_approle_auth_backend_role.${serverCfg.resourceName} = { backend = "\${vault_auth_backend.approle.path}"; role_name = serverName; role_id = serverName; secret_id_num_uses = 0; token_ttl = minutes 20; token_max_ttl = minutes 30; token_policies = ["default" "server" "server-user" "\${vault_policy.${serverCfg.resourceName}.name}"] ++ serverCfg.extraPolicies ++ (map (name: "\${vault_policy.app_${name}.name}") serverCfg.apps) ++ (map (name: "\${vault_policy.server_${serverCfg.resourceName}_app_${name}.name}") (builtins.attrNames serverCfg.appPolicies)) ++ (map (name: "\${vault_policy.server_${serverCfg.resourceName}_user_${name}.name}") (builtins.attrNames serverCfg.userPolicies)); }; vault_identity_entity.${serverCfg.resourceName} = { name = serverName; metadata.server = serverName; }; vault_identity_entity_alias.${serverCfg.resourceName} = { name = serverName; mount_accessor = "\${vault_auth_backend.approle.accessor}"; canonical_id = "\${vault_identity_entity.${serverCfg.resourceName}.id}"; }; vault_ssh_secret_backend_role.${serverCfg.resourceName} = { name = serverName; backend = "\${vault_mount.ssh-host.path}"; key_type = "ca"; allow_host_certificates = true; allow_bare_domains = true; allowed_domains = concatStringsSep "," serverCfg.hostnames; ttl = 7 * 24 * 60 * 60; max_ttl = 7 * 24 * 60 * 60; }; }] ++ mapAttrsToList (appName: policy: { vault_policy.${"server_${serverCfg.resourceName}_app_${appName}"} = { name = "server/${serverName}/app/${appName}"; inherit policy; }; }) serverCfg.appPolicies ++ mapAttrsToList (userName: policy: { vault_policy.${"server_${serverCfg.resourceName}_user_${userName}"} = { name = "server/${serverName}/user/${userName}"; inherit policy; }; }) serverCfg.userPolicies)) cfg); }