Skip to content

Commit a74840f

Browse files
committed
feat(modules): Add host-info and secrets as nixosModules
1 parent 308c375 commit a74840f

File tree

3 files changed

+161
-45
lines changed

3 files changed

+161
-45
lines changed

flake.nix

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,8 @@
203203
./modules/tailscale-autoconnect
204204
./modules/grafana-agent-flow
205205
./modules/pyroscope
206+
./modules/secrets.nix
207+
./modules/host-info.nix
206208
./packages
207209
];
208210
systems = ["x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin"];

modules/host-info.nix

Lines changed: 62 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,67 @@
1-
{
2-
config,
3-
lib,
4-
...
5-
}: {
6-
options.mcl.host-info = with lib; {
7-
type = mkOption {
8-
type = types.nullOr (types.enum ["desktop" "server"]);
9-
default = null;
10-
example = ["desktop"];
11-
description = ''
12-
Whether this host is a desktop or a server.
13-
'';
14-
};
1+
{withSystem, ...}: {
2+
flake.nixosModules.mcl-host-info = {
3+
config,
4+
lib,
5+
dirs,
6+
...
7+
}: {
8+
options.mcl.host-info = with lib; {
9+
type = mkOption {
10+
type = types.nullOr (types.enum ["desktop" "server" "container"]);
11+
default = null;
12+
example = ["desktop"];
13+
description = ''
14+
Whether this host is a desktop or a server.
15+
'';
16+
};
1517

16-
isVM = mkOption {
17-
type = types.nullOr types.bool;
18-
default = null;
19-
example = ["false"];
20-
description = ''
21-
Whether this configuration is a VM variant.
22-
'';
23-
};
18+
isDebugVM = mkOption {
19+
type = types.nullOr types.bool;
20+
default = null;
21+
example = ["false"];
22+
description = ''
23+
Whether this configuration is a VM variant with extra debug
24+
functionality.
25+
'';
26+
};
27+
28+
configPath = mkOption {
29+
type = types.nullOr types.path;
30+
default = null;
31+
example = ["machines/server/solunska-server"];
32+
description = ''
33+
The configuration path for this host relative to the repo root.
34+
'';
35+
};
2436

25-
configPath = mkOption {
26-
type = types.nullOr types.string;
27-
default = null;
28-
example = ["machines/server/solunska-server"];
29-
description = ''
30-
The configuration path for this host relative to the repo root.
31-
'';
37+
sshKey = mkOption {
38+
type = types.nullOr types.str;
39+
default = null;
40+
example = "ssh-ed25519 AAAAC3Nza";
41+
description = ''
42+
The public ssh key for this host.
43+
'';
44+
};
45+
};
46+
config = {
47+
assertions = [
48+
{
49+
assertion = config.mcl.host-info.type != null;
50+
message = "mcl.host-info.type must be defined for every host";
51+
}
52+
{
53+
assertion = config.mcl.host-info.isDebugVM != null;
54+
message = "mcl.host-info.isDebugVM must be defined for every host";
55+
}
56+
{
57+
assertion = config.mcl.host-info.configPath != null;
58+
message = "mcl.host-info.configPath must be defined for every host";
59+
}
60+
{
61+
assertion = config.mcl.host-info.sshKey != null;
62+
message = "mcl.host-info.sshKey must be defined for every host";
63+
}
64+
];
3265
};
33-
};
34-
config = {
35-
assertions = [
36-
{
37-
assertion = config.mcl.host-info.type != null;
38-
message = "mcl.host-info.type must be defined for every host";
39-
}
40-
{
41-
assertion = config.mcl.host-info.isVM != null;
42-
message = "mcl.host-info.isVM must be defined for every host";
43-
}
44-
{
45-
assertion = config.mcl.host-info.configPath != null;
46-
message = "mcl.host-info.configPath must be defined for every host";
47-
}
48-
];
4966
};
5067
}

modules/secrets.nix

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
{withSystem, ...}: {
2+
flake.nixosModules.mcl-secrets = {
3+
config,
4+
options,
5+
lib,
6+
dirs,
7+
...
8+
}: let
9+
eachServiceCfg = config.mcl.secrets.services;
10+
isDebugVM = config.mcl.host-info.isDebugVM;
11+
12+
sshKey = config.mcl.host-info.sshKey;
13+
14+
ageSecretOpts =
15+
builtins.head
16+
(builtins.head
17+
options.age.secrets.type.nestedTypes.elemType.getSubModules)
18+
.imports;
19+
20+
secretDir = let
21+
machineConfigPath = config.mcl.host-info.configPath;
22+
machineSecretDir = machineConfigPath + "/secrets";
23+
vmConfig = dirs.modules + "/default-vm-config";
24+
vmSecretDir = vmConfig + "/secrets";
25+
in
26+
if isDebugVM
27+
then vmSecretDir
28+
else machineSecretDir;
29+
in {
30+
options.mcl.secrets = with lib; {
31+
services = mkOption {
32+
type = types.attrsOf (types.submodule ({config, ...}: let
33+
serviceName = config._module.args.name;
34+
in {
35+
options = {
36+
encryptedSecretDir = mkOption {
37+
type = types.path;
38+
default = secretDir;
39+
};
40+
secrets = mkOption {
41+
default = {};
42+
type = types.attrsOf (types.submoduleWith {
43+
modules = [
44+
ageSecretOpts
45+
({name, ...}: let
46+
secretName = name;
47+
in {
48+
config = {
49+
name = "${serviceName}/${secretName}";
50+
file =
51+
lib.mkDefault (config.encryptedSecretDir + "/${serviceName}/${secretName}.age");
52+
};
53+
})
54+
];
55+
});
56+
};
57+
nix-file = mkOption {
58+
default =
59+
if (pathIsRegularFile (config.encryptedSecretDir + "/${serviceName}/secrets.nix"))
60+
then config.encryptedSecretDir + "/${serviceName}/secrets.nix"
61+
else
62+
builtins.toFile "${serviceName}-secrets.nix" ''
63+
{
64+
${concatMapStringsSep "\n" (n: "\"${n}\".publicKeys = [\"${sshKey}\"]") (builtins.attrNames config.secrets)}
65+
}
66+
'';
67+
type = types.path;
68+
};
69+
};
70+
}));
71+
default = {};
72+
example = {
73+
service1.secrets.secretA = {};
74+
service1.secrets.secretB = {};
75+
service2.secrets.secretC = {};
76+
cachix-deploy.secrets.token = {
77+
path = "/etc/cachix-agent.token";
78+
};
79+
};
80+
description = mdDoc "Per-service attrset of encryptedSecretDir and secrets";
81+
};
82+
};
83+
84+
config = lib.mkIf (eachServiceCfg != {}) {
85+
age.secrets = lib.pipe eachServiceCfg [
86+
(lib.mapAttrsToList (serviceName: service:
87+
lib.mapAttrsToList (
88+
secretName: config:
89+
lib.nameValuePair "${serviceName}/${secretName}" config
90+
)
91+
service.secrets))
92+
lib.concatLists
93+
lib.listToAttrs
94+
];
95+
};
96+
};
97+
}

0 commit comments

Comments
 (0)