2023-08-28 09:09:05 +00:00
|
|
|
{ config, lib, pkgs, ... }:
|
2023-09-03 12:55:53 +00:00
|
|
|
let
|
|
|
|
secretsDir = config.clanCore.clanDir + "/sops/secrets";
|
|
|
|
groupsDir = config.clanCore.clanDir + "/sops/groups";
|
|
|
|
|
2023-09-26 15:31:45 +00:00
|
|
|
|
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?
|
|
|
|
containsSymlink = path:
|
|
|
|
builtins.pathExists path && (builtins.readFileType path == "directory" || builtins.readFileType path == "symlink");
|
|
|
|
|
|
|
|
containsMachine = parent: name: type:
|
|
|
|
type == "directory" && containsSymlink "${parent}/${name}/machines/${config.clanCore.machineName}";
|
|
|
|
|
|
|
|
containsMachineOrGroups = name: type:
|
|
|
|
(containsMachine secretsDir name type) || lib.any (group: type == "directory" && containsSymlink "${secretsDir}/${name}/groups/${group}") groups;
|
|
|
|
|
|
|
|
filterDir = filter: dir:
|
|
|
|
lib.optionalAttrs (builtins.pathExists dir)
|
|
|
|
(lib.filterAttrs filter (builtins.readDir dir));
|
|
|
|
|
|
|
|
groups = builtins.attrNames (filterDir (containsMachine groupsDir) groupsDir);
|
|
|
|
secrets = filterDir containsMachineOrGroups secretsDir;
|
|
|
|
in
|
2023-08-28 09:09:05 +00:00
|
|
|
{
|
2023-09-06 14:08:36 +00:00
|
|
|
config = lib.mkIf (config.clanCore.secretStore == "sops") {
|
2023-09-26 15:31:45 +00:00
|
|
|
clanCore.secretsDirectory = "/run/secrets";
|
|
|
|
clanCore.secretsPrefix = config.clanCore.machineName + "-";
|
2023-10-06 16:34:49 +00:00
|
|
|
system.clan = lib.mkIf (config.clanCore.secrets != { }) {
|
2023-09-26 15:31:45 +00:00
|
|
|
|
2023-09-20 16:08:47 +00:00
|
|
|
generateSecrets = pkgs.writeScript "generate-secrets" ''
|
|
|
|
#!${pkgs.python3}/bin/python
|
|
|
|
import json
|
2023-10-21 15:19:06 +00:00
|
|
|
import sys
|
2023-09-20 16:08:47 +00:00
|
|
|
from clan_cli.secrets.sops_generate import generate_secrets_from_nix
|
2023-11-30 12:01:38 +00:00
|
|
|
args = json.loads(${builtins.toJSON (builtins.toJSON {
|
|
|
|
machine_name = config.clanCore.machineName;
|
|
|
|
secret_submodules = lib.mapAttrs (_name: secret: {
|
|
|
|
secrets = builtins.attrNames secret.secrets;
|
|
|
|
facts = lib.mapAttrs (_: secret: secret.path) secret.facts;
|
|
|
|
generator = secret.generator.finalScript;
|
|
|
|
}) config.clanCore.secrets;
|
|
|
|
})})
|
2023-09-20 16:08:47 +00:00
|
|
|
generate_secrets_from_nix(**args)
|
|
|
|
'';
|
|
|
|
uploadSecrets = pkgs.writeScript "upload-secrets" ''
|
|
|
|
#!${pkgs.python3}/bin/python
|
|
|
|
import json
|
2023-10-23 20:31:12 +00:00
|
|
|
import sys
|
2023-09-20 16:08:47 +00:00
|
|
|
from clan_cli.secrets.sops_generate import upload_age_key_from_nix
|
|
|
|
# the second toJSON is needed to escape the string for the python
|
2023-09-29 16:30:11 +00:00
|
|
|
args = json.loads(${builtins.toJSON (builtins.toJSON { machine_name = config.clanCore.machineName; })})
|
|
|
|
upload_age_key_from_nix(**args)
|
2023-09-20 16:08:47 +00:00
|
|
|
'';
|
|
|
|
};
|
2023-09-03 12:55:53 +00:00
|
|
|
sops.secrets = builtins.mapAttrs
|
|
|
|
(name: _: {
|
|
|
|
sopsFile = config.clanCore.clanDir + "/sops/secrets/${name}/secret";
|
|
|
|
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
|
|
|
|
sops.defaultSopsFile = lib.mkIf config.sops.validateSopsFiles (lib.mkDefault (builtins.toString (pkgs.writeText "dummy.yaml" "")));
|
2023-09-19 20:57:44 +00:00
|
|
|
|
|
|
|
sops.age.keyFile = lib.mkIf (builtins.pathExists (config.clanCore.clanDir + "/sops/secrets/${config.clanCore.machineName}-age.key/secret"))
|
|
|
|
(lib.mkDefault "/var/lib/sops-nix/key.txt");
|
2023-09-29 16:30:11 +00:00
|
|
|
clanCore.secretsUploadDirectory = lib.mkDefault "/var/lib/sops-nix";
|
2023-08-28 09:09:05 +00:00
|
|
|
};
|
|
|
|
}
|