diff --git a/lib/fudo/deploy.nix b/lib/fudo/deploy.nix index 6cf795d..978e21f 100644 --- a/lib/fudo/deploy.nix +++ b/lib/fudo/deploy.nix @@ -2,9 +2,7 @@ with lib; let - sys = callPackage ./system.nix {}; - - site-cfg = config.fudo.sites.${sys.local-site}; + site-cfg = config.fudo.sites.${config.instance.local-site}; in { config = { diff --git a/lib/fudo/distributed-builds.nix b/lib/fudo/distributed-builds.nix index 631ece8..ab21008 100644 --- a/lib/fudo/distributed-builds.nix +++ b/lib/fudo/distributed-builds.nix @@ -2,11 +2,9 @@ with lib; let - sys = import ../system.nix { inherit config lib; }; - hostname = config.instance.hostname; - site-cfg = config.fudo.sites.${sys.local-site}; + site-cfg = config.fudo.sites.${config.instance.local-site}; has-build-servers = (length (attrNames site-cfg.build-servers)) > 0; @@ -42,7 +40,8 @@ in { isSystemUser = true; openssh.authorizedKeys.keyFiles = concatLists - (mapAttrsToList (host: hostOpts: hostOpts.build-pubkeys) sys.local-hosts); + (mapAttrsToList (host: hostOpts: hostOpts.build-pubkeys) + config.instance.local-hosts); }; }; }; diff --git a/lib/fudo/hosts.nix b/lib/fudo/hosts.nix index aed02d3..6e68b90 100644 --- a/lib/fudo/hosts.nix +++ b/lib/fudo/hosts.nix @@ -180,8 +180,6 @@ let }; }; - system = import ../system.nix { inherit config lib; }; - in { options.fudo.hosts = with types; mkOption { @@ -304,7 +302,7 @@ in { programs.adb.enable = host-cfg.android-dev; users.groups.adbusers = mkIf host-cfg.android-dev { - members = system.local-admins; + members = config.instance.local-admins; }; # programs.ssh.knownHosts = let diff --git a/lib/fudo/users.nix b/lib/fudo/users.nix index a2a6c46..028e13f 100644 --- a/lib/fudo/users.nix +++ b/lib/fudo/users.nix @@ -2,146 +2,8 @@ with lib; let - systemUserOpts = { username, ... }: { - options = with types; { - username = mkOption { - type = str; - description = "The system user's login name."; - default = username; - }; - description = mkOption { - type = str; - description = "Description of this system user's purpose or role"; - }; - - ldap-hashed-password = mkOption { - type = str; - description = - "LDAP-formatted hashed password for this user. Generate with slappasswd."; - }; - }; - }; - - userOpts = { username, ... }: { - options = with types; { - username = mkOption { - type = str; - description = "The user's login name."; - default = username; - }; - - uid = mkOption { - type = int; - description = "Unique UID number for the user."; - }; - - common-name = mkOption { - type = str; - description = "The user's common or given name."; - }; - - primary-group = mkOption { - type = str; - description = "Primary group to which the user belongs."; - }; - - login-shell = mkOption { - type = nullOr shellPackage; - description = "The user's preferred shell."; - }; - - description = mkOption { - type = str; - default = "Fudo Member"; - description = "A description of this user's role."; - }; - - ldap-hashed-passwd = mkOption { - type = nullOr str; - description = - "LDAP-formatted hashed password, used for email and other services. Use slappasswd to generate the properly-formatted password."; - default = null; - }; - - login-hashed-passwd = mkOption { - type = nullOr str; - description = - "Hashed password for shell, used for shell access to hosts. Use mkpasswd to generate the properly-formatted password."; - default = null; - }; - - ssh-authorized-keys = mkOption { - type = listOf str; - description = "SSH public keys this user can use to log in."; - default = [ ]; - }; - - # home-manager-generator = mkOption { - # type = nullOr (functionTo attrs); - # description = "Home Manager configuration for the given user."; - # default = null; - # }; - - home-directory = mkOption { - type = nullOr str; - description = "Default home directory for the given user."; - default = null; - }; - - k5login = mkOption { - type = listOf str; - description = "List of Kerberos principals that map to this user."; - default = [ ]; - }; - - ssh-keys = mkOption { - type = nullOr (submodule sshKeyOpts); - description = "Path to the user's public and private key files."; - default = null; - }; - }; - }; - - sshKeyOpts = { ... }: { - options = with types; { - private-key = mkOption { - type = str; - description = "Path to the user's private key."; - }; - - public-key = mkOption { - type = str; - description = "Path to the user's public key."; - }; - }; - }; - - groupOpts = { group-name, ... }: { - options = with types; { - group-name = mkOption { - type = nullOr str; - default = group-name; - description = "Group name."; - }; - - description = mkOption { - type = str; - description = "Description of the group or it's purpose."; - }; - - members = mkOption { - type = listOf str; - default = [ ]; - description = "A list of users who are members of the current group."; - }; - - gid = mkOption { - type = int; - description = "GID number of the group."; - }; - }; - }; + user = import ../types/users.nix { inherit lib; }; list-includes = list: el: isNull (findFirst (this: this == el) null list); @@ -181,30 +43,32 @@ let host-cfg = config.fudo.hosts.${hostname}; in { - options.fudo = { - users = mkOption { - type = with types; attrsOf (submodule userOpts); - description = "Users"; - default = { }; - }; + options = with types; { + fudo = { + users = mkOption { + type = attrsOf (submodule user.userOpts); + description = "Users"; + default = { }; + }; - groups = mkOption { - type = with types; attrsOf (submodule groupOpts); - description = "Groups"; - default = { }; - }; + groups = mkOption { + type = attrsOf (submodule user.groupOpts); + description = "Groups"; + default = { }; + }; - system-users = mkOption { - type = with types; attrsOf (submodule systemUserOpts); - description = "System users (probably not what you're looking for!)"; - default = { }; + system-users = mkOption { + type = attrsOf (submodule user.systemUserOpts); + description = "System users (probably not what you're looking for!)"; + default = { }; + }; }; }; imports = [ ./users-common.nix ]; - config = let sys = import ../system.nix { inherit lib config; }; - + config = let + sys = config.instance; in { fudo.auth.ldap-server = let ldapUsers = (filterAttrs diff --git a/lib/instance.nix b/lib/instance.nix index bc56f8b..a52e7cd 100644 --- a/lib/instance.nix +++ b/lib/instance.nix @@ -1,7 +1,9 @@ { config, lib, pkgs, ... }: with lib; -{ +let + user = import ./types/users.nix { inherit lib; }; +in { options.instance = with types; { hostname = mkOption { type = str; @@ -12,5 +14,71 @@ with lib; type = int; description = "Timestamp associated with the build. Used for e.g. DNS serials."; }; + + local-domain = mkOption { + type = str; + description = "Domain name of the current local host."; + }; + + local-site = mkOption { + type = str; + description = "Site name of the current local host."; + }; + + local-admins = mkOption { + type = listOf str; + description = "List of users who should have admin access to the local host."; + }; + + local-groups = mkOption { + type = listOf str; + description = "List of groups which should be created on the local host."; + }; + + local-hosts = mkOption { + type = listOf str; + description = "List of hosts that should be considered local to the current host."; + }; + + local-users = mkOption { + type = attrsOf user.userOpts; + description = "List of users who should have access to the local host"; + }; + }; + + config = let + local-host = config.instance.hostname; + local-domain = config.fudo.hosts.${local-host}.domain; + local-site = config.fudo.hosts.${local-host}.site; + + host-user-list = config.fudo.hosts."${local-host}".local-users; + domain-user-list = config.fudo.domains."${local-domain}".local-users; + site-user-list = config.fudo.sites."${local-site}".local-users; + local-users = + getAttrs (host-user-list ++ domain-user-list ++ site-user-list) config.fudo.users; + + host-admin-list = config.fudo.hosts."${local-host}".local-admins; + domain-admin-list = config.fudo.domains."${local-domain}".local-admins; + site-admin-list = config.fudo.sites."${local-site}".local-admins; + local-admins = host-admin-list ++ domain-admin-list ++ site-admin-list; + + host-group-list = config.fudo.hosts."${local-host}".local-groups; + domain-group-list = config.fudo.domains."${local-domain}".local-groups; + site-group-list = config.fudo.sites."${local-site}".local-groups; + local-groups = + getAttrs (host-group-list ++ domain-group-list ++ site-group-list) + config.fudo.groups; + + local-hosts = + filterAttrs (host: hostOpts: hostOpts.site == local-site) config.fudo.hosts; + in { + instance = { + local-domain = local-domain; + local-site = local-site; + local-users = local-users; + local-admins = local-admins; + local-groups = local-groups; + local-hosts = local-hosts; + }; }; } diff --git a/lib/system.nix b/lib/system.nix deleted file mode 100644 index 809885d..0000000 --- a/lib/system.nix +++ /dev/null @@ -1,71 +0,0 @@ -{ config, lib, ... }: - -with lib; -let - local-host = config.instance.hostname; - local-domain = config.fudo.hosts.${local-host}.domain; - local-site = config.fudo.hosts.${local-host}.site; - - host-user-list = config.fudo.hosts."${local-host}".local-users; - domain-user-list = config.fudo.domains."${local-domain}".local-users; - site-user-list = config.fudo.sites."${local-site}".local-users; - local-users = - getAttrs (host-user-list ++ domain-user-list ++ site-user-list) config.fudo.users; - - host-admin-list = config.fudo.hosts."${local-host}".local-admins; - domain-admin-list = config.fudo.domains."${local-domain}".local-admins; - site-admin-list = config.fudo.sites."${local-site}".local-admins; - local-admins = host-admin-list ++ domain-admin-list ++ site-admin-list; - - host-group-list = config.fudo.hosts."${local-host}".local-groups; - domain-group-list = config.fudo.domains."${local-domain}".local-groups; - site-group-list = config.fudo.sites."${local-site}".local-groups; - local-groups = - getAttrs (host-group-list ++ domain-group-list ++ site-group-list) - config.fudo.groups; - - local-hosts = - filterAttrs (host: hostOpts: hostOpts.site == local-site) config.fudo.hosts; - -in { - options.instance = with types; { - local-host = mkOption { - type = str; - description = "Name of the current local host."; - }; - local-domain = mkOption { - type = str; - description = "Domain name of the current local host."; - }; - local-site = mkOption { - type = str; - description = "Site name of the current local host."; - }; - local-users = mkOption { - type = listOf str; - description = "List of users who should have access to the local host."; - }; - local-admins = mkOption { - type = listOf str; - description = "List of users who should have admin access to the local host."; - }; - local-groups = mkOption { - type = listOf str; - description = "List of groups which should be created on the local host."; - }; - local-hosts = mkOption { - type = listOf str; - description = "List of hosts that should be considered local to the current host."; - }; - }; - - config.instance = { - local-host = local-host; - local-domain = local-domain; - local-site = local-site; - local-users = local-users; - local-admins = local-admins; - local-groups = local-groups; - local-hosts = local-hosts; - }; -} diff --git a/lib/types/user.nix b/lib/types/user.nix new file mode 100644 index 0000000..5bf9733 --- /dev/null +++ b/lib/types/user.nix @@ -0,0 +1,149 @@ +{ lib, ... }: + +{ + systemUserOpts = { username, ... }: { + options = with lib.types; { + username = mkOption { + type = str; + description = "The system user's login name."; + default = username; + }; + + description = mkOption { + type = str; + description = "Description of this system user's purpose or role"; + }; + + ldap-hashed-password = mkOption { + type = str; + description = + "LDAP-formatted hashed password for this user. Generate with slappasswd."; + }; + }; + }; + + userOpts = { username, ... }: { + options = with lib.types; { + username = mkOption { + type = str; + description = "The user's login name."; + default = username; + }; + + uid = mkOption { + type = int; + description = "Unique UID number for the user."; + }; + + common-name = mkOption { + type = str; + description = "The user's common or given name."; + }; + + primary-group = mkOption { + type = str; + description = "Primary group to which the user belongs."; + }; + + login-shell = mkOption { + type = nullOr shellPackage; + description = "The user's preferred shell."; + }; + + description = mkOption { + type = str; + default = "Fudo Member"; + description = "A description of this user's role."; + }; + + ldap-hashed-passwd = mkOption { + type = nullOr str; + description = + "LDAP-formatted hashed password, used for email and other services. Use slappasswd to generate the properly-formatted password."; + default = null; + }; + + login-hashed-passwd = mkOption { + type = nullOr str; + description = + "Hashed password for shell, used for shell access to hosts. Use mkpasswd to generate the properly-formatted password."; + default = null; + }; + + ssh-authorized-keys = mkOption { + type = listOf str; + description = "SSH public keys this user can use to log in."; + default = [ ]; + }; + + # home-manager-generator = mkOption { + # type = nullOr (functionTo attrs); + # description = "Home Manager configuration for the given user."; + # default = null; + # }; + + home-directory = mkOption { + type = nullOr str; + description = "Default home directory for the given user."; + default = null; + }; + + k5login = mkOption { + type = listOf str; + description = "List of Kerberos principals that map to this user."; + default = [ ]; + }; + + ssh-keys = mkOption { + type = nullOr (listOf (submodule sshKeyOpts)); + description = "Path to the user's public and private key files."; + default = []; + }; + }; + }; + + groupOpts = { group-name, ... }: { + options = with lib.types; { + group-name = mkOption { + type = nullOr str; + default = group-name; + description = "Group name."; + }; + + description = mkOption { + type = str; + description = "Description of the group or it's purpose."; + }; + + members = mkOption { + type = listOf str; + default = [ ]; + description = "A list of users who are members of the current group."; + }; + + gid = mkOption { + type = int; + description = "GID number of the group."; + }; + }; + }; + + sshKeyOpts = { ... }: { + options = with lib.types; { + private-key = mkOption { + type = str; + description = "Path to the user's private key."; + }; + + public-key = mkOption { + type = str; + description = "Path to the user's public key."; + }; + + key-type = mkOption { + type = enum [ "rsa" "ecdsa" "ed25519" ]; + description = "Type of the user's public key."; + }; + }; + }; +}