2024-03-17 18:48:49 +00:00
|
|
|
{
|
|
|
|
config,
|
|
|
|
lib,
|
|
|
|
pkgs,
|
|
|
|
...
|
|
|
|
}:
|
2023-09-03 12:55:53 +00:00
|
|
|
let
|
2024-06-17 10:42:28 +00:00
|
|
|
secretsDir = config.clan.core.clanDir + "/sops/secrets";
|
|
|
|
groupsDir = config.clan.core.clanDir + "/sops/groups";
|
2023-09-03 12:55:53 +00:00
|
|
|
|
|
|
|
# My symlink is in the nixos module detected as a directory also it works in the repl. Is this because of pure evaluation?
|
2024-03-17 18:48:49 +00:00
|
|
|
containsSymlink =
|
|
|
|
path:
|
|
|
|
builtins.pathExists path
|
|
|
|
&& (builtins.readFileType path == "directory" || builtins.readFileType path == "symlink");
|
2023-09-03 12:55:53 +00:00
|
|
|
|
2024-03-17 18:48:49 +00:00
|
|
|
containsMachine =
|
|
|
|
parent: name: type:
|
2024-06-17 10:42:28 +00:00
|
|
|
type == "directory" && containsSymlink "${parent}/${name}/machines/${config.clan.core.machineName}";
|
2023-09-03 12:55:53 +00:00
|
|
|
|
2024-03-17 18:48:49 +00:00
|
|
|
containsMachineOrGroups =
|
|
|
|
name: type:
|
|
|
|
(containsMachine secretsDir name type)
|
|
|
|
|| lib.any (
|
|
|
|
group: type == "directory" && containsSymlink "${secretsDir}/${name}/groups/${group}"
|
|
|
|
) groups;
|
2023-09-03 12:55:53 +00:00
|
|
|
|
2024-03-17 18:48:49 +00:00
|
|
|
filterDir =
|
|
|
|
filter: dir:
|
|
|
|
lib.optionalAttrs (builtins.pathExists dir) (lib.filterAttrs filter (builtins.readDir dir));
|
2023-09-03 12:55:53 +00:00
|
|
|
|
|
|
|
groups = builtins.attrNames (filterDir (containsMachine groupsDir) groupsDir);
|
|
|
|
secrets = filterDir containsMachineOrGroups secretsDir;
|
|
|
|
in
|
2023-08-28 09:09:05 +00:00
|
|
|
{
|
2024-02-16 16:03:14 +00:00
|
|
|
options = {
|
2024-06-17 10:42:28 +00:00
|
|
|
clan.core.sops.defaultGroups = lib.mkOption {
|
2024-02-16 16:03:14 +00:00
|
|
|
type = lib.types.listOf lib.types.str;
|
|
|
|
default = [ ];
|
|
|
|
example = [ "admins" ];
|
|
|
|
description = "The default groups to for encryption use when no groups are specified.";
|
|
|
|
};
|
|
|
|
};
|
2024-04-09 16:04:26 +00:00
|
|
|
|
2024-06-17 10:42:28 +00:00
|
|
|
config = lib.mkIf (config.clan.core.facts.secretStore == "sops") {
|
2024-04-09 16:04:26 +00:00
|
|
|
# Before we generate a secret we cannot know the path yet, so we need to set it to an empty string
|
2024-06-17 10:42:28 +00:00
|
|
|
clan.core.facts.secretPathFunction =
|
2024-04-12 10:39:09 +00:00
|
|
|
secret:
|
2024-06-17 10:42:28 +00:00
|
|
|
config.sops.secrets.${"${config.clan.core.machineName}-${secret.config.name}"}.path
|
2024-04-12 10:39:09 +00:00
|
|
|
or "/no-such-path";
|
2024-06-17 10:42:28 +00:00
|
|
|
clan.core.facts.secretModule = "clan_cli.facts.secret_modules.sops";
|
|
|
|
clan.core.facts.secretUploadDirectory = lib.mkDefault "/var/lib/sops-nix";
|
2024-03-17 18:48:49 +00:00
|
|
|
sops.secrets = builtins.mapAttrs (name: _: {
|
2024-06-17 10:42:28 +00:00
|
|
|
sopsFile = config.clan.core.clanDir + "/sops/secrets/${name}/secret";
|
2024-03-17 18:48:49 +00:00
|
|
|
format = "binary";
|
|
|
|
}) secrets;
|
2023-09-03 07:40:31 +00:00
|
|
|
# To get proper error messages about missing secrets we need a dummy secret file that is always present
|
2024-03-17 18:48:49 +00:00
|
|
|
sops.defaultSopsFile = lib.mkIf config.sops.validateSopsFiles (
|
|
|
|
lib.mkDefault (builtins.toString (pkgs.writeText "dummy.yaml" ""))
|
|
|
|
);
|
2023-09-19 20:57:44 +00:00
|
|
|
|
2024-03-17 18:48:49 +00:00
|
|
|
sops.age.keyFile = lib.mkIf (builtins.pathExists (
|
2024-06-17 10:42:28 +00:00
|
|
|
config.clan.core.clanDir + "/sops/secrets/${config.clan.core.machineName}-age.key/secret"
|
2024-03-17 18:48:49 +00:00
|
|
|
)) (lib.mkDefault "/var/lib/sops-nix/key.txt");
|
2023-08-28 09:09:05 +00:00
|
|
|
};
|
|
|
|
}
|