From e9054079891e73d8af9d16fd14668d1dafcd1478 Mon Sep 17 00:00:00 2001 From: DavHau Date: Thu, 12 Sep 2024 16:30:21 +0200 Subject: [PATCH] vars/sops: load sops info from nix instead of filesystem --- .../clanCore/vars/secret/sops/default.nix | 30 +++----- .../vars/secret/sops/eval-tests/default.nix | 70 +++++++++++-------- .../clanCore/vars/secret/sops/funcs.nix | 42 ++++++----- pkgs/clan-cli/clan_cli/vars/_types.py | 1 - 4 files changed, 76 insertions(+), 67 deletions(-) diff --git a/nixosModules/clanCore/vars/secret/sops/default.nix b/nixosModules/clanCore/vars/secret/sops/default.nix index f72d052e7..a3489d632 100644 --- a/nixosModules/clanCore/vars/secret/sops/default.nix +++ b/nixosModules/clanCore/vars/secret/sops/default.nix @@ -6,31 +6,21 @@ }: let - inherit (lib) importJSON flip; + inherit (lib) flip; - inherit (builtins) dirOf pathExists; - - inherit (import ./funcs.nix { inherit lib; }) listVars; + inherit (import ./funcs.nix { inherit lib; }) collectFiles; inherit (config.clan.core) machineName; - metaFile = sopsFile: dirOf sopsFile + "/meta.json"; - - metaData = sopsFile: if pathExists (metaFile sopsFile) then importJSON (metaFile sopsFile) else { }; - - isSopsSecret = + secretPath = secret: - let - meta = metaData secret.sopsFile; - in - meta.store or null == "sops" && meta.deployed or true && meta.secret or true; + if secret.share then + config.clan.core.clanDir + "/vars/shared/${secret.generator}/${secret.name}/secret" + else + config.clan.core.clanDir + + "/vars/per-machine/${machineName}/${secret.generator}/${secret.name}/secret"; - varsDirMachines = config.clan.core.clanDir + "/vars/per-machine/${machineName}"; - varsDirShared = config.clan.core.clanDir + "/vars/shared"; - - vars' = (listVars varsDirMachines) ++ (listVars varsDirShared); - - vars = lib.filter isSopsSecret vars'; + vars = collectFiles config.clan.core.vars; in { config.clan.core.vars.settings = lib.mkIf (config.clan.core.vars.settings.secretStore == "sops") { @@ -50,7 +40,7 @@ in flip map vars (secret: { name = "vars/${secret.generator}/${secret.name}"; value = { - sopsFile = secret.sopsFile; + sopsFile = secretPath secret; format = "binary"; }; }) diff --git a/nixosModules/clanCore/vars/secret/sops/eval-tests/default.nix b/nixosModules/clanCore/vars/secret/sops/eval-tests/default.nix index 7d25f3ce4..f2e09c7d5 100644 --- a/nixosModules/clanCore/vars/secret/sops/eval-tests/default.nix +++ b/nixosModules/clanCore/vars/secret/sops/eval-tests/default.nix @@ -1,43 +1,53 @@ { lib ? import , - pkgs ? import { }, }: let - inherit (import ../funcs.nix { inherit lib; }) readDirNames listVars; - - noVars = pkgs.runCommand "empty-dir" { } '' - mkdir $out - ''; - - emtpyVars = pkgs.runCommand "empty-dir" { } '' - mkdir -p $out/vars - ''; - + inherit (import ../funcs.nix { inherit lib; }) collectFiles; in { - test_readDirNames = { - expr = readDirNames ./populated/vars; - expected = [ "my_machine" ]; - }; + test_collectFiles = { + expr = collectFiles { + # secret, deployed + generators.gen_1.files.secret_deployed_file.secret = true; + generators.gen_1.files.secret_deployed_file.deploy = true; + generators.gen_1.files.secret_deployed_file.share = false; - test_listSecrets = { - expr = listVars ./populated/vars/my_machine; + # secret, deployed, shared + generators.gen_1.files.secret_deployed_shared_file.secret = true; + generators.gen_1.files.secret_deployed_shared_file.deploy = true; + generators.gen_1.files.secret_deployed_shared_file.share = true; + + # secret, undeployed + generators.gen_1.files.secret_undeployed_file.secret = true; + generators.gen_1.files.secret_undeployed_file.deploy = false; + generators.gen_1.files.secret_undeployed_file.share = false; + + # public, deployed + generators.gen_1.files.public_deployed_file.secret = false; + generators.gen_1.files.public_deployed_file.deploy = true; + generators.gen_1.files.public_deployed_file.share = false; + + # secret deployed (different generator) + generators.gen_2.files.secret_deployed_file.secret = true; + generators.gen_2.files.secret_deployed_file.deploy = true; + generators.gen_2.files.secret_deployed_file.share = false; + }; expected = [ { - generator = "my_generator"; - name = "my_secret"; - sopsFile = "${./populated/vars/my_machine}/my_generator/my_secret/secret"; + generator = "gen_1"; + name = "secret_deployed_file"; + share = false; + } + { + generator = "gen_1"; + name = "secret_deployed_shared_file"; + share = true; + } + { + generator = "gen_2"; + name = "secret_deployed_file"; + share = false; } ]; }; - - test_listSecrets_no_vars = { - expr = listVars noVars; - expected = [ ]; - }; - - test_listSecrets_empty_vars = { - expr = listVars emtpyVars; - expected = [ ]; - }; } diff --git a/nixosModules/clanCore/vars/secret/sops/funcs.nix b/nixosModules/clanCore/vars/secret/sops/funcs.nix index 68153e4a8..a842bc2b8 100644 --- a/nixosModules/clanCore/vars/secret/sops/funcs.nix +++ b/nixosModules/clanCore/vars/secret/sops/funcs.nix @@ -3,23 +3,33 @@ ... }: let - inherit (builtins) readDir; - inherit (lib) concatMap flip; + inherit (lib) + filterAttrs + flatten + flip + mapAttrsToList + ; in -rec { - readDirNames = - dir: - if !(builtins.pathExists dir) then [ ] else lib.mapAttrsToList (name: _type: name) (readDir dir); +{ - listVars = - varsDir: - flip concatMap (readDirNames (varsDir)) ( - generator_name: - flip map (readDirNames (varsDir + "/${generator_name}")) (secret_name: { - generator = generator_name; - name = secret_name; - sopsFile = "${varsDir}/${generator_name}/${secret_name}/secret"; - }) - ); + collectFiles = + vars: + let + relevantFiles = generator: flip filterAttrs generator.files (_name: f: f.secret && f.deploy); + allFiles = flatten ( + flip mapAttrsToList vars.generators ( + gen_name: generator: + flip mapAttrsToList (relevantFiles generator) ( + fname: file: + lib.trace file { + name = fname; + generator = gen_name; + inherit (generator) share; + } + ) + ) + ); + in + allFiles; } diff --git a/pkgs/clan-cli/clan_cli/vars/_types.py b/pkgs/clan-cli/clan_cli/vars/_types.py index a9765d613..79683b318 100644 --- a/pkgs/clan-cli/clan_cli/vars/_types.py +++ b/pkgs/clan-cli/clan_cli/vars/_types.py @@ -144,7 +144,6 @@ class StoreBase(ABC): directory.mkdir(parents=True, exist_ok=True) new_file = self._set(generator_name, var_name, value, shared, deployed) meta = { - "deployed": deployed, "secret": self.is_secret_store, "store": self.store_name, }