Skip to content

Instantly share code, notes, and snippets.

@growler
Created July 10, 2024 21:56
Show Gist options
  • Select an option

  • Save growler/8007301c6e83870c779066632d39f6ff to your computer and use it in GitHub Desktop.

Select an option

Save growler/8007301c6e83870c779066632d39f6ff to your computer and use it in GitHub Desktop.
{lib, ...}: with lib; let
inherit (builtins) trace length isPath isAttrs mapAttrs head concatStringsSep;
base = with types; submodule {
options = {
file = mkOption {
type = path;
description = "The path to the encrypted secret file";
example = literalExpressions ''./secrets/service/password.age'';
};
name = mkOption {
type = str;
default = "";
description = "The secret name in the agenix secret store";
example = literalExpression ''"service/secret"'';
};
inline = mkOption {
type = bool;
default = false;
description = "If the secret will be inlined into configuration file";
};
enable = mkOption {
type = bool;
description = "If the secret has been defined";
visible = false;
internal = true;
};
};
};
secretType = with types; mkOptionType rec {
inherit (base)
emptyValue typeMerge nestedTypes functor;
name = "secret";
description = "age-encrypted secret";
descriptionClass = "noun";
merge = loc: defs:
if length defs != 1 then throw "Secret ${options.showOption loc} is defined twice. Other definitions: ${options.showDefs defs}"
else let v = head defs; in
if isPath v.value
then base.merge loc [ (v // { value = { enable = true; name = concatStringsSep "/" loc; file = v.value; }; }) ]
else base.merge loc [ (v // { value = { enable = true; name = concatStringsSep "/" loc; } // v.value; }) ];
check = x: (isPath x) || (base.check x);
};
mkSecret = {description ? null, ...}@args: mkOption {
inherit description;
type = secretType;
default = removeAttrs args [ "description" ] // { enable = false; };
};
in {
lib = { inherit mkSecret; };
modules.default = {options, config, lib, ...}: with lib; let
secrets = let
recurse = set: path: out: foldlAttrs (out: name: value:
if isAttrs value then
if value ? _type && value._type == "option" then
if value ? type.name && value.type.name == "secret"
then out ++ [ (path ++ [ name ]) ]
else out
else recurse value (path ++ [ name ]) out
else out
) out set; in recurse options [ ] [ ];
in {
config = {
age.secrets = builtins.listToAttrs (builtins.concatMap (path: let
secret = lib.attrByPath path {} config;
in
if secret ? enable && secret.enable
then [{ name = secret.name; value = builtins.removeAttrs secret [ "enable" "inline" "name" ]; }]
else []) secrets);
};
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment