{ config, lib, ... }: with lib; let cfg = config.local; inherit (config.networking) domain; in { imports = [ ./mailbox.nix ]; options.local = with types; let mailOption = mkOption { default = { }; type = submodule { options.certs = mkOption { type = listOf str; default = [ ]; }; }; }; in { sysadmin = mkOption { type = str; }; users = mkOption { default = { }; type = attrsOf (submodule ({ config, ... }: { options = { uid = mkOption { type = int; }; gid = mkOption { type = int; }; gecos = mkOption { type = str; default = ""; }; sysadmin = mkOption { type = bool; default = false; }; groups = mkOption { type = listOf str; default = [ ]; }; allowLogin = mkOption { type = bool; default = true; }; hardAliases = mkOption { type = listOf str; default = [ ]; }; mail = mailOption; }; config.groups = mkBefore (optional config.sysadmin "wheel"); })); }; virtual = mkOption { default = { }; type = attrsOf (submodule ({ name, ... }: { options = { aliases = mkOption { type = attrsOf (listOf str); default = { }; }; rules = mkOption { default = [ ]; type = listOf (submodule { options = { pattern = mkOption { type = str; }; targets = mkOption { type = listOf str; }; }; }); }; users = mkOption { default = { }; type = attrsOf (submodule { options.mail = mailOption; }); }; }; config.aliases = let sysadmin = mkDefault [ "sysadmin@${name}" ]; in { abuse = sysadmin; security = sysadmin; webmaster = sysadmin; hostmaster = sysadmin; postmaster = sysadmin; sysadmin = mkDefault [ "sysadmin@${domain}" ]; }; })); }; }; config.local = mkMerge [ { users = import ./users.nix; virtual = import ./virtual.nix; sysadmin = (findSingle (user: user.value.sysadmin) (throw "no user is declared as sysadmin") (throw "more than one user is declared as sysadmin") (mapAttrsToList nameValuePair cfg.users) ).name; } { virtual.${domain}.aliases.sysadmin = [ cfg.sysadmin ]; } ]; }