kore / nixos / features / kore.nix108 lines · 3001B · raw
1{ config, lib, kore, ... }:
2
3let
4 cfg = config.kore;
5 hostname = config.networking.hostName;
6
7 identityOptions = { name, ... }:
8 let
9 dir = ../../keys/identities + "/${name}";
10 sshDir = dir + "/ssh";
11 gpgFile = dir + "/gpg.asc";
12
13 sshFiles = lib.optionals (builtins.pathExists sshDir)
14 (lib.filter (lib.hasSuffix ".pub") (lib.attrNames (builtins.readDir sshDir)));
15 in {
16 options = with lib; {
17 email = mkOption {
18 type = types.nullOr types.str;
19 default = null;
20 };
21 gpg = mkOption {
22 type = types.nullOr types.str;
23 default = null;
24 };
25 sshKeys = mkOption {
26 type = types.listOf types.str;
27 default = map (file: lib.fileContents (sshDir + "/${file}")) sshFiles;
28 };
29 gpgKey = mkOption {
30 type = types.nullOr types.path;
31 default = if builtins.pathExists gpgFile then gpgFile else null;
32 };
33 };
34 };
35
36 hostOptions = with lib; {
37 system = mkOption {
38 type = types.str;
39 };
40 stateVersion = mkOption {
41 type = types.str;
42 };
43 roles = mkOption {
44 type = types.listOf types.str;
45 default = [];
46 };
47 users = mkOption {
48 type = types.listOf types.str;
49 default = [];
50 };
51 ipv4 = mkOption {
52 type = types.nullOr types.str;
53 default = null;
54 };
55 };
56in {
57 options.kore = with lib; {
58 identities = mkOption {
59 type = types.attrsOf (types.submodule identityOptions);
60 default = {};
61 };
62 hosts = mkOption {
63 type = types.attrsOf (types.submodule [{ options = hostOptions; }]);
64 default = {};
65 };
66 currentHost = mkOption {
67 type = types.submodule [{ options = hostOptions; }];
68 };
69
70 impermanence.enable = mkOption {
71 type = types.bool;
72 default = true;
73 };
74 };
75
76 config = {
77 kore = {
78 identities = kore.identities or {};
79 hosts = kore.hosts;
80 currentHost = kore.hosts.${hostname};
81 };
82
83 assertions = map (user: {
84 assertion = cfg.identities ? ${user};
85 message = "kore: ${hostname} has user ${user}, but kore.json has no identity for it";
86 }) cfg.currentHost.users;
87
88 nixpkgs.hostPlatform = cfg.currentHost.system;
89 system.stateVersion = cfg.currentHost.stateVersion;
90
91 users.users = lib.listToAttrs (lib.imap0 (i: user: lib.nameValuePair user {
92 isNormalUser = true;
93 password = "tmp";
94 extraGroups = [ "wheel" ];
95
96 subUidRanges = [{ startUid = 100000 + i * 65536; count = 65536; }];
97 subGidRanges = [{ startGid = 100000 + i * 65536; count = 65536; }];
98
99 openssh.authorizedKeys.keys = cfg.identities.${user}.sshKeys or [];
100 }) cfg.currentHost.users);
101
102 # /etc/hosts so machines resolve each other by name.
103 networking.hosts = lib.mkMerge (lib.mapAttrsToList (name: host:
104 lib.optionalAttrs (host.ipv4 != null) {
105 "${host.ipv4}" = [ "${name}.${config.networking.domain}" name ];
106 }) cfg.hosts);
107 };
108}