Created
July 10, 2024 21:56
-
-
Save growler/8007301c6e83870c779066632d39f6ff to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| {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