cluster/services/locksmith: implement provider options
This commit is contained in:
parent
e791be03a4
commit
2d7d0a4a8a
2 changed files with 113 additions and 4 deletions
|
@ -2,9 +2,17 @@
|
||||||
|
|
||||||
{
|
{
|
||||||
services.locksmith = {
|
services.locksmith = {
|
||||||
nodes.receiver = config.services.consul.nodes.agent;
|
nodes = {
|
||||||
nixos.receiver = [
|
receiver = config.services.consul.nodes.agent;
|
||||||
./receiver.nix
|
provider = config.services.consul.nodes.agent;
|
||||||
];
|
};
|
||||||
|
nixos = {
|
||||||
|
receiver = [
|
||||||
|
./receiver.nix
|
||||||
|
];
|
||||||
|
provider = [
|
||||||
|
./provider.nix
|
||||||
|
];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
101
cluster/services/locksmith/provider.nix
Normal file
101
cluster/services/locksmith/provider.nix
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
{ config, depot, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
kvRoot = "secrets/locksmith";
|
||||||
|
activeProvders = lib.filterAttrs (_: cfg: lib.any (secret: secret.nodes != []) (lib.attrValues cfg.secrets)) config.services.locksmith.providers;
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
options.services.locksmith = with lib; {
|
||||||
|
providers = mkOption {
|
||||||
|
type = types.attrsOf (types.submodule ({ ... }: {
|
||||||
|
options = {
|
||||||
|
wantedBy = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [];
|
||||||
|
};
|
||||||
|
after = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [];
|
||||||
|
};
|
||||||
|
secrets = mkOption {
|
||||||
|
type = types.attrsOf (types.submodule ({ ... }: {
|
||||||
|
options = {
|
||||||
|
nodes = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [];
|
||||||
|
};
|
||||||
|
command = mkOption {
|
||||||
|
type = types.coercedTo types.str (package: "${package}") types.package;
|
||||||
|
};
|
||||||
|
owner = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "root";
|
||||||
|
};
|
||||||
|
group = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "root";
|
||||||
|
};
|
||||||
|
mode = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "0400";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config.systemd.services = lib.mapAttrs' (providerName: providerConfig: {
|
||||||
|
name = "locksmith-provider-${providerName}";
|
||||||
|
value = let
|
||||||
|
providerRoot = "${kvRoot}/${providerName}";
|
||||||
|
in {
|
||||||
|
description = "Locksmith Provider | ${providerName}";
|
||||||
|
distributed.enable = true;
|
||||||
|
inherit (providerConfig) wantedBy after;
|
||||||
|
serviceConfig = {
|
||||||
|
PrivateTmp = true;
|
||||||
|
LoadCredential = lib.mkForce [];
|
||||||
|
};
|
||||||
|
path = [
|
||||||
|
config.services.consul.package
|
||||||
|
pkgs.age
|
||||||
|
];
|
||||||
|
script = let
|
||||||
|
activeSecrets = lib.filterAttrs (_: secret: secret.nodes != []) providerConfig.secrets;
|
||||||
|
activeNodes = lib.unique (lib.flatten (lib.mapAttrsToList (_: secret: secret.nodes) activeSecrets));
|
||||||
|
secretNames = map (name: "${providerRoot}-${name}/") (lib.attrNames activeSecrets);
|
||||||
|
|
||||||
|
createSecret = { path, nodes, owner, mode, group, command }: ''
|
||||||
|
consul kv put ${lib.escapeShellArg path}/mode ${lib.escapeShellArg mode}
|
||||||
|
consul kv put ${lib.escapeShellArg path}/owner ${lib.escapeShellArg owner}
|
||||||
|
consul kv put ${lib.escapeShellArg path}/group ${lib.escapeShellArg group}
|
||||||
|
${lib.concatStringsSep "\n" (map (node: ''
|
||||||
|
consul kv put ${lib.escapeShellArg path}/recipient/${node} "$( (${command}) | age --encrypt --armor -r ${lib.escapeShellArg depot.hours.${node}.ssh.id.publicKey})"
|
||||||
|
'') nodes)}
|
||||||
|
'';
|
||||||
|
in ''
|
||||||
|
# create/update secrets
|
||||||
|
${lib.pipe activeSecrets [
|
||||||
|
(lib.mapAttrsToList (secretName: secretConfig: createSecret {
|
||||||
|
path = "${providerRoot}-${secretName}";
|
||||||
|
inherit (secretConfig) nodes mode owner group command;
|
||||||
|
}))
|
||||||
|
(lib.concatStringsSep "\n")
|
||||||
|
]}
|
||||||
|
|
||||||
|
# delete leftover secrets of this provider
|
||||||
|
consul kv get --keys '${providerRoot}-' | grep -v ${lib.concatStringsSep " \\\n " (map (secret: "-e ${lib.escapeShellArg secret}") secretNames)} | xargs --no-run-if-empty -n1 consul kv delete --recurse
|
||||||
|
|
||||||
|
# notify
|
||||||
|
${lib.pipe activeNodes [
|
||||||
|
(map (node: "consul event --name=chant:locksmith --node=${node}"))
|
||||||
|
(lib.concatStringsSep "\n")
|
||||||
|
]}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}) activeProvders;
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue