Skip to content

Commit

Permalink
+ refine needByUser module options
Browse files Browse the repository at this point in the history
  • Loading branch information
oluceps committed Nov 15, 2024
1 parent a281ace commit 194026f
Show file tree
Hide file tree
Showing 11 changed files with 308 additions and 233 deletions.
2 changes: 2 additions & 0 deletions dev/check.nix
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
disko.tests = {
extraChecks = ''
machine.succeed("test -e /run/vaultix.d/0")
machine.succeed("test -e /run/vaultix.d/1")
machine.succeed("test -e ${config.vaultix.secrets.test-secret-1.path}")
machine.succeed("test -e ${config.vaultix.secrets.test-secret-2.path}")
machine.succeed("test -e ${config.vaultix.templates.template-test.path}")
machine.succeed("md5sum -c ${pkgs.writeText "checksum-list" ''
2e57c2db0f491eba1d4e496a076cdff7 ${config.vaultix.secrets.test-secret-1.path}
2e57c2db0f491eba1d4e496a076cdff7 ${config.vaultix.secrets.test-secret-2.path}
ba1efe71bd3d4a9a491d74df5c23e177 ${config.vaultix.templates.template-test.path}
''}")
'';
Expand Down
3 changes: 2 additions & 1 deletion dev/test.nix
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
vaultix = {
settings.hostPubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEu8luSFCts3g367nlKBrxMdLyOy4Awfo5Rb397ef2AR";

needByUser = [ "test-secret-2" ];

# secret example
secrets.test-secret-1 = {
file = ./secrets/there-is-a-secret.age;
Expand All @@ -56,7 +58,6 @@
owner = "root";
group = "users";
path = "/home/1.txt";
neededForUser = true;
};

# template example
Expand Down
13 changes: 10 additions & 3 deletions doc/src/nixos-option.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Configurable option could be divided into 3 parts:
settings = { ... };
secrets = { ... };
templates = { ... };
needByUser = [...];
};
}
```
Expand Down Expand Up @@ -93,15 +94,13 @@ secrets = {
group = "users";
name = "example.toml";
path = "/some/place";
neededForUser = false;
};
};
```

This part basically keeps identical with `agenix`. But has few diffs:

+ no `symlink: bool` option, since it has an systemd function called [tmpfiles.d](https://www.freedesktop.org/software/systemd/man/latest/tmpfiles.d.html).
+ added `neededForUser: bool` option, for deploying secrets and templates that required before user init.

### path: path str

Expand Down Expand Up @@ -129,7 +128,6 @@ templates = {
group = "users";
name = "example.toml";
path = "/some/place";
neededForUser = false;
};
}
```
Expand All @@ -142,6 +140,8 @@ To insert secrets in this string, insert `config.vaultix.placeholder.example`.

This pretend the secret which `id` (the keyof attribute of secrets) was defined.

<div id="id-state"></div>

```nix
secrets = {
# the id is 'example'. despite `name`.
Expand All @@ -167,3 +167,10 @@ TO BE NOTICE that the source secret file may have trailing `\n`:
default true;

Removing trailing and leading whitespace by default.


## needByUser: [str]

For deploying secrets and templates that required before user init.

List of [id](#id-state) of templates or secrets.
100 changes: 12 additions & 88 deletions module/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,10 @@ let
inherit (lib)
types
mkOption
filterAttrs
isPath
readFile
literalMD
warn
mkEnableOption
literalExpression
mkIf
assertMsg
Expand Down Expand Up @@ -146,69 +144,7 @@ let
};
});

secretType = types.submodule (submod: {
options = {
id = mkOption {
type = types.str;
default = submod.config._module.args.name;
readOnly = true;
description = "The true identifier of this secret as used in `age.secrets`.";
};
name = mkOption {
type = types.str;
default = submod.config._module.args.name;
defaultText = literalExpression "submod.config._module.args.name";
description = ''
Name of the file used in {option}`vaultix.settings.decryptedDir`
'';
};
file = mkOption {
type = types.path;
description = ''
Age file the secret is loaded from.
'';
};
path = mkOption {
type = types.str;
default =
if submod.config.neededForUser then
"${cfg.settings.decryptedDirForUser}/${submod.config.name}"
else
"${cfg.settings.decryptedDir}/${submod.config.name}";
defaultText = literalExpression ''
"''${cfg.settings.decryptedDir}/''${config.name}"
'';
description = ''
Path where the decrypted secret is installed.
'';
};
mode = mkOption {
type = types.str;
default = "0400";
description = ''
Permissions mode of the decrypted secret in a format understood by chmod.
'';
};
owner = mkOption {
type = types.str;
default = "root";
description = ''
User of the decrypted secret.
'';
};
group = mkOption {
type = types.str;
default = users.${submod.config.owner}.group or "root";
defaultText = literalExpression ''
users.''${config.owner}.group or "root"
'';
description = ''
Group of the decrypted secret.
'';
};
neededForUser = mkEnableOption { };
};
});
inherit (import ./secretType.nix { inherit lib cfg users; }) secretType;
in
{
imports = [ ./template.nix ];
Expand All @@ -232,6 +168,14 @@ in
Attrset of secrets.
'';
};

needByUser = mkOption {
type = types.listOf types.str;
default = [ ];
description = ''
List of id of items needed before user init
'';
};
};

options.vaultix-debug = mkOption {
Expand All @@ -247,28 +191,8 @@ in
name = "secret-meta-${config.networking.hostName}";
text = builtins.toJSON partial;
};
whatIfPreUser = what: need: filterAttrs (_: v: v.neededForUser == need) what;

secretsPreUser = whatIfPreUser cfg.secrets true;
templatesPreUser = whatIfPreUser cfg.templates true;

regularSecrets = whatIfPreUser cfg.secrets false;
regularTemplates = whatIfPreUser cfg.templates false;

profilePreUser = mkProfile (
cfg
// {
secrets = secretsPreUser;
templates = templatesPreUser;
}
);
profileRegular = mkProfile (
cfg
// {
secrets = regularSecrets;
templates = regularTemplates;
}
);
profile = mkProfile cfg;

checkRencSecsReport =
pkgs.runCommandNoCCLocal "secret-check-report" { }
Expand All @@ -289,7 +213,7 @@ in
serviceConfig = {
Type = "oneshot";
Environment = deployRequisits;
ExecStart = "${lib.getExe cfg.package} -p ${profileRegular} deploy";
ExecStart = "${lib.getExe cfg.package} -p ${profile} deploy";
RemainAfterExit = true;
};
};
Expand All @@ -302,7 +226,7 @@ in
serviceConfig = {
Type = "oneshot";
Environment = deployRequisits;
ExecStart = "${lib.getExe cfg.package} -p ${profilePreUser} deploy";
ExecStart = "${lib.getExe cfg.package} -p ${profile} deploy --early";
RemainAfterExit = true;
};
};
Expand Down
79 changes: 79 additions & 0 deletions module/secretType.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
{
lib,
cfg,
users,
...
}:

let
inherit (lib)
types
elem
mkOption
literalExpression
;
in
{
secretType = types.submodule (submod: {
options = {
id = mkOption {
type = types.str;
default = submod.config._module.args.name;
readOnly = true;
description = "The true identifier of this secret as used in `age.secrets`.";
};
name = mkOption {
type = types.str;
default = submod.config._module.args.name;
defaultText = literalExpression "submod.config._module.args.name";
description = ''
Name of the file used in {option}`vaultix.settings.decryptedDir`
'';
};
file = mkOption {
type = types.path;
description = ''
Age file the secret is loaded from.
'';
};
path = mkOption {
type = types.str;
default =
if elem submod.config._module.args.name cfg.needByUser then
"${cfg.settings.decryptedDirForUser}/${submod.config.name}"
else
"${cfg.settings.decryptedDir}/${submod.config.name}";
defaultText = literalExpression ''
"''${cfg.settings.decryptedDir}/''${config.name}"
'';
description = ''
Path where the decrypted secret is installed.
'';
};
mode = mkOption {
type = types.str;
default = "0400";
description = ''
Permissions mode of the decrypted secret in a format understood by chmod.
'';
};
owner = mkOption {
type = types.str;
default = "root";
description = ''
User of the decrypted secret.
'';
};
group = mkOption {
type = types.str;
default = users.${submod.config.owner}.group or "root";
defaultText = literalExpression ''
users.''${config.owner}.group or "root"
'';
description = ''
Group of the decrypted secret.
'';
};
};
});
}
62 changes: 1 addition & 61 deletions module/template.nix
Original file line number Diff line number Diff line change
Expand Up @@ -8,76 +8,16 @@
let
inherit (lib)
mkOption
mkEnableOption
mkDefault
mapAttrs
types
literalExpression
mkIf
;
inherit (config.users) users;

cfg = config.vaultix;

templateType = types.submodule (submod: {
options = {
content = mkOption {
type = types.str;
default = "";
defaultText = literalExpression "";
description = ''
Content of the template
'';
};
trim = (mkEnableOption { }) // {
default = true;
description = "remove trailing and leading whitespace of the secret content to insert";
};
name = mkOption {
type = types.str;
default = submod.config._module.args.name;
defaultText = literalExpression "submod.config._module.args.name";
description = ''
Name of the file used in {option}`vaultix.settings.decryptedDir`
'';
};
path = mkOption {
type = types.str;
default = "${cfg.settings.decryptedDir}/${submod.config.name}";
defaultText = literalExpression ''
"''${cfg.settings.decryptedDir}/''${config.name}"
'';
description = ''
Path where the built template is installed.
'';
};
mode = mkOption {
type = types.str;
default = "0400";
description = ''
Permissions mode of the built template in a format understood by chmod.
'';
};
owner = mkOption {
type = types.str;
default = "root";
description = ''
User of the built template.
'';
};
group = mkOption {
type = types.str;
default = users.${submod.config.owner}.group or "root";
defaultText = literalExpression ''
users.''${config.owner}.group or "root"
'';
description = ''
Group of the built template.
'';
};
neededForUser = mkEnableOption { };
};
});
inherit (import ./templateType.nix { inherit lib cfg users; }) templateType;

in
{
Expand Down
Loading

0 comments on commit 194026f

Please sign in to comment.