forked from clan/clan-core
factstore: secret backends now can return the path to a secret dynamically
try to move path function out
This commit is contained in:
parent
faaf6649c5
commit
0d4e1f870b
@ -20,7 +20,11 @@
|
||||
renderClanOptions =
|
||||
let
|
||||
docs = pkgs.nixosOptionsDoc {
|
||||
options = (pkgs.nixos { imports = [ self.nixosModules.clanCore ]; }).options;
|
||||
options =
|
||||
(pkgs.nixos {
|
||||
imports = [ self.nixosModules.clanCore ];
|
||||
clanCore.clanDir = ./.;
|
||||
}).options;
|
||||
warningsAreErrors = false;
|
||||
};
|
||||
in
|
||||
|
@ -16,7 +16,10 @@
|
||||
{ nixpkgs.hostPlatform = "x86_64-linux"; }
|
||||
];
|
||||
|
||||
clanCoreNixosModules = [ self.nixosModules.clanCore ] ++ allNixosModules;
|
||||
clanCoreNixosModules = [
|
||||
self.nixosModules.clanCore
|
||||
{ clanCore.clanDir = ./.; }
|
||||
] ++ allNixosModules;
|
||||
|
||||
# TODO: optimally we would not have to evaluate all nixos modules for every page
|
||||
# but some of our module options secretly depend on nixos modules.
|
||||
|
@ -16,17 +16,10 @@
|
||||
"secretStore"
|
||||
]
|
||||
)
|
||||
(lib.mkRenamedOptionModule
|
||||
[
|
||||
"clanCore"
|
||||
"secretsDirectory"
|
||||
]
|
||||
[
|
||||
"clanCore"
|
||||
"facts"
|
||||
"secretDirectory"
|
||||
]
|
||||
)
|
||||
(lib.mkRemovedOptionModule [
|
||||
"clanCore"
|
||||
"secretsDirectory"
|
||||
] "clancore.secretsDirectory was removed. Use clanCore.facts.secretPathFunction instead")
|
||||
(lib.mkRenamedOptionModule
|
||||
[
|
||||
"clanCore"
|
||||
@ -86,50 +79,43 @@
|
||||
}
|
||||
);
|
||||
};
|
||||
secrets =
|
||||
let
|
||||
config' = config;
|
||||
in
|
||||
lib.mkOption {
|
||||
default = { };
|
||||
type = lib.types.attrsOf (
|
||||
lib.types.submodule (
|
||||
{ config, name, ... }:
|
||||
secrets = lib.mkOption {
|
||||
default = { };
|
||||
type = lib.types.attrsOf (
|
||||
lib.types.submodule (secret: {
|
||||
options =
|
||||
{
|
||||
options =
|
||||
{
|
||||
name = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
name of the secret
|
||||
'';
|
||||
default = name;
|
||||
};
|
||||
path = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
path to a secret which is generated by the generator
|
||||
'';
|
||||
default = "${config'.clanCore.facts.secretDirectory}/${config.name}";
|
||||
defaultText = lib.literalExpression "\${config'.clanCore.facts.secretDirectory}/\${config.name}";
|
||||
};
|
||||
}
|
||||
// lib.optionalAttrs (config'.clanCore.facts.secretStore == "sops") {
|
||||
groups = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = config'.clanCore.sops.defaultGroups;
|
||||
description = ''
|
||||
Groups to decrypt the secret for. By default we always use the user's key.
|
||||
'';
|
||||
};
|
||||
};
|
||||
name = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
name of the secret
|
||||
'';
|
||||
default = secret.name;
|
||||
};
|
||||
path = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
description = ''
|
||||
path to a secret which is generated by the generator
|
||||
'';
|
||||
default = config.clanCore.facts.secretPathFunction secret;
|
||||
defaultText = lib.literalExpression "config.clanCore.facts.secretPathFunction secret";
|
||||
};
|
||||
}
|
||||
)
|
||||
);
|
||||
description = ''
|
||||
path where the secret is located in the filesystem
|
||||
'';
|
||||
};
|
||||
// lib.optionalAttrs (config.clanCore.facts.secretStore == "sops") {
|
||||
groups = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = config.clanCore.sops.defaultGroups;
|
||||
description = ''
|
||||
Groups to decrypt the secret for. By default we always use the user's key.
|
||||
'';
|
||||
};
|
||||
};
|
||||
})
|
||||
);
|
||||
description = ''
|
||||
path where the secret is located in the filesystem
|
||||
'';
|
||||
};
|
||||
facts = lib.mkOption {
|
||||
default = { };
|
||||
type = lib.types.attrsOf (
|
||||
|
@ -19,6 +19,7 @@
|
||||
custom can be used to define a custom secret fact store.
|
||||
'';
|
||||
};
|
||||
|
||||
secretModule = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
internal = true;
|
||||
@ -26,12 +27,7 @@
|
||||
the python import path to the secret module
|
||||
'';
|
||||
};
|
||||
secretDirectory = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
description = ''
|
||||
The directory where secrets are installed to. This is backend specific.
|
||||
'';
|
||||
};
|
||||
|
||||
secretUploadDirectory = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.path;
|
||||
default = null;
|
||||
@ -40,6 +36,15 @@
|
||||
'';
|
||||
};
|
||||
|
||||
secretPathFunction = lib.mkOption {
|
||||
type = lib.types.raw;
|
||||
description = ''
|
||||
The function to use to generate the path for a secret.
|
||||
The default function will use the path attribute of the secret.
|
||||
The function will be called with the secret submodule as an argument.
|
||||
'';
|
||||
};
|
||||
|
||||
publicStore = lib.mkOption {
|
||||
type = lib.types.enum [
|
||||
"in_repo"
|
||||
@ -150,7 +155,7 @@
|
||||
description = ''
|
||||
path to a secret which is generated by the generator
|
||||
'';
|
||||
default = "${config.clanCore.facts.secretDirectory}/${secret.config.name}";
|
||||
default = config.clanCore.facts.secretPathFunction secret;
|
||||
};
|
||||
}
|
||||
// lib.optionalAttrs (config.clanCore.facts.secretModule == "clan_cli.facts.secret_modules.sops") {
|
||||
|
@ -7,8 +7,9 @@
|
||||
The directory where the password store is uploaded to.
|
||||
'';
|
||||
};
|
||||
|
||||
config = lib.mkIf (config.clanCore.facts.secretStore == "password-store") {
|
||||
clanCore.facts.secretDirectory = config.clan.password-store.targetDirectory;
|
||||
clanCore.facts.secretPathFunction = secret: "/etc/secrets/${secret.config.name}";
|
||||
clanCore.facts.secretUploadDirectory = config.clan.password-store.targetDirectory;
|
||||
clanCore.facts.secretModule = "clan_cli.facts.secret_modules.password_store";
|
||||
};
|
||||
|
@ -41,12 +41,14 @@ in
|
||||
description = "The default groups to for encryption use when no groups are specified.";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf (config.clanCore.facts.secretStore == "sops") {
|
||||
clanCore.facts.secretDirectory = "/run/secrets";
|
||||
# Before we generate a secret we cannot know the path yet, so we need to set it to an empty string
|
||||
clanCore.facts.secretPathFunction =
|
||||
secret: config.sops.secrets.${secret.config.name}.path or "/no-such-path";
|
||||
clanCore.facts.secretModule = "clan_cli.facts.secret_modules.sops";
|
||||
clanCore.facts.secretUploadDirectory = lib.mkDefault "/var/lib/sops-nix";
|
||||
sops.secrets = builtins.mapAttrs (name: _: {
|
||||
name = lib.strings.removePrefix "${config.clanCore.machineName}-" name;
|
||||
sopsFile = config.clanCore.clanDir + "/sops/secrets/${name}/secret";
|
||||
format = "binary";
|
||||
}) secrets;
|
||||
|
@ -1,7 +1,7 @@
|
||||
{ config, lib, ... }:
|
||||
{
|
||||
config = lib.mkIf (config.clanCore.facts.secretStore == "vm") {
|
||||
clanCore.facts.secretDirectory = "/etc/secrets";
|
||||
clanCore.facts.secretPathFunction = secret: "/etc/secrets/${secret.config.name}";
|
||||
clanCore.facts.secretUploadDirectory = "/etc/secrets";
|
||||
clanCore.facts.secretModule = "clan_cli.facts.secret_modules.vm";
|
||||
};
|
||||
|
@ -65,7 +65,14 @@
|
||||
# optimization for faster secret generate/upload and machines update
|
||||
config = {
|
||||
system.clan.deployment.data = {
|
||||
inherit (config.clanCore) facts;
|
||||
facts = {
|
||||
inherit (config.clanCore.facts)
|
||||
secretUploadDirectory
|
||||
secretModule
|
||||
publicModule
|
||||
services
|
||||
;
|
||||
};
|
||||
inherit (config.clan.networking) targetHost buildHost;
|
||||
inherit (config.clan.deployment) requireExplicitUpdate;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user