mirror of
https://github.com/Mic92/sops-nix.git
synced 2024-12-15 17:50:51 +00:00
add sops.templates
This commit is contained in:
parent
9e98f7a442
commit
c4c39450b1
3 changed files with 126 additions and 0 deletions
|
@ -294,6 +294,7 @@ in {
|
|||
};
|
||||
};
|
||||
imports = [
|
||||
./templates
|
||||
(mkRenamedOptionModule [ "sops" "gnupgHome" ] [ "sops" "gnupg" "home" ])
|
||||
(mkRenamedOptionModule [ "sops" "sshKeyPaths" ] [ "sops" "gnupg" "sshKeyPaths" ])
|
||||
];
|
||||
|
|
108
modules/sops/templates/default.nix
Normal file
108
modules/sops/templates/default.nix
Normal file
|
@ -0,0 +1,108 @@
|
|||
{ config, pkgs, lib, options, ... }:
|
||||
with lib;
|
||||
with lib.types;
|
||||
with builtins;
|
||||
let
|
||||
cfg = config.sops;
|
||||
secretsForUsers = lib.filterAttrs (_: v: v.neededForUsers) cfg.secrets;
|
||||
users = config.users.users;
|
||||
substitute = pkgs.writers.writePython3 "substitute" { }
|
||||
(replaceStrings [ "@subst@" ] [ "${subst-pairs}" ] (readFile ./subs.py));
|
||||
subst-pairs = pkgs.writeText "pairs" (concatMapStringsSep "\n" (name:
|
||||
"${toString config.sops.placeholder.${name}} ${
|
||||
config.sops.secrets.${name}.path
|
||||
}") (attrNames config.sops.secrets));
|
||||
coercibleToString = mkOptionType {
|
||||
name = "coercibleToString";
|
||||
description = "value that can be coerced to string";
|
||||
check = strings.isCoercibleToString;
|
||||
merge = mergeEqualOption;
|
||||
};
|
||||
templateType = submodule ({ config, ... }: {
|
||||
options = {
|
||||
name = mkOption {
|
||||
type = str;
|
||||
default = config._module.args.name;
|
||||
description = ''
|
||||
Name of the file used in /run/secrets-rendered
|
||||
'';
|
||||
};
|
||||
path = mkOption {
|
||||
type = str;
|
||||
default = "/run/secrets-rendered/${config.name}";
|
||||
};
|
||||
content = mkOption {
|
||||
type = lines;
|
||||
default = "";
|
||||
description = ''
|
||||
Content of the file
|
||||
'';
|
||||
};
|
||||
mode = mkOption {
|
||||
type = str;
|
||||
default = "0400";
|
||||
description = ''
|
||||
Permissions mode of the in octal.
|
||||
'';
|
||||
};
|
||||
owner = mkOption {
|
||||
type = str;
|
||||
default = "root";
|
||||
description = ''
|
||||
User of the file.
|
||||
'';
|
||||
};
|
||||
group = mkOption {
|
||||
type = str;
|
||||
default = users.${config.owner}.group;
|
||||
description = ''
|
||||
Group of the file.
|
||||
'';
|
||||
};
|
||||
file = mkOption {
|
||||
type = types.path;
|
||||
default = pkgs.writeText config.name config.content;
|
||||
visible = false;
|
||||
readOnly = true;
|
||||
};
|
||||
};
|
||||
});
|
||||
in {
|
||||
options.sops = {
|
||||
templates = mkOption {
|
||||
type = attrsOf templateType;
|
||||
default = { };
|
||||
};
|
||||
placeholder = mkOption {
|
||||
type = attrsOf coercibleToString;
|
||||
default = { };
|
||||
visible = false;
|
||||
};
|
||||
substituteCmd = mkOption {
|
||||
type = types.path;
|
||||
default = substitute;
|
||||
};
|
||||
};
|
||||
|
||||
config = optionalAttrs (options ? sops.secrets)
|
||||
(mkIf (config.sops.templates != { }) {
|
||||
sops.placeholder = mapAttrs
|
||||
(name: _: mkDefault "<SOPS:${hashString "sha256" name}:PLACEHOLDER>")
|
||||
config.sops.secrets;
|
||||
|
||||
system.activationScripts.renderSecrets = mkIf (cfg.templates != { })
|
||||
(stringAfter ([ "setupSecrets" ]
|
||||
++ optional (secretsForUsers != { }) "setupSecretsForUsers") ''
|
||||
echo Setting up sops templates...
|
||||
${concatMapStringsSep "\n" (name:
|
||||
let tpl = config.sops.templates.${name};
|
||||
in ''
|
||||
mkdir -p "${dirOf tpl.path}"
|
||||
${config.sops.substituteCmd} ${tpl.file} > ${tpl.path}
|
||||
chmod "${tpl.mode}" "${tpl.path}"
|
||||
chown "${tpl.owner}" "${tpl.path}"
|
||||
chgrp "${tpl.group}" "${tpl.path}"
|
||||
'') (attrNames config.sops.templates)}
|
||||
'');
|
||||
});
|
||||
}
|
17
modules/sops/templates/subs.py
Normal file
17
modules/sops/templates/subs.py
Normal file
|
@ -0,0 +1,17 @@
|
|||
from sys import argv
|
||||
|
||||
target = argv[1]
|
||||
subst = "@subst@"
|
||||
|
||||
with open(target) as f:
|
||||
content = f.read()
|
||||
|
||||
with open(subst) as f:
|
||||
subst_pairs = f.read().splitlines()
|
||||
|
||||
for pair in subst_pairs:
|
||||
placeholder, path = pair.split()
|
||||
with open(path) as f:
|
||||
content = content.replace(placeholder, f.read())
|
||||
|
||||
print(content)
|
Loading…
Reference in a new issue