mirror of
https://cgit.krebsco.de/krops
synced 2024-11-22 19:19:46 +01:00
populate: add passage source type
This commit is contained in:
parent
cbc475bdf4
commit
a6c7ecd8ba
3 changed files with 82 additions and 1 deletions
24
README.md
24
README.md
|
@ -6,6 +6,7 @@ krops is a lightweight toolkit to deploy NixOS systems, remotely or locally.
|
||||||
## Some Features
|
## Some Features
|
||||||
|
|
||||||
- store your secrets in [password store](https://www.passwordstore.org/)
|
- store your secrets in [password store](https://www.passwordstore.org/)
|
||||||
|
or [passage](https://github.com/FiloSottile/passage)
|
||||||
- build your systems remotely
|
- build your systems remotely
|
||||||
- minimal overhead (it's basically just `nixos-rebuild switch`!)
|
- minimal overhead (it's basically just `nixos-rebuild switch`!)
|
||||||
- run from custom nixpkgs branch/checkout/fork
|
- run from custom nixpkgs branch/checkout/fork
|
||||||
|
@ -298,6 +299,29 @@ Supported attributes:
|
||||||
sub-directory in the password store.
|
sub-directory in the password store.
|
||||||
|
|
||||||
|
|
||||||
|
### `passage`
|
||||||
|
|
||||||
|
The passage source type decrypts files from a local
|
||||||
|
[passage store](https://github.com/FiloSottile/passage)
|
||||||
|
and transfers them to the target using
|
||||||
|
[`rsync`](https://rsync.samba.org/).
|
||||||
|
|
||||||
|
Supported attributes:
|
||||||
|
|
||||||
|
* `dir` -
|
||||||
|
Path to the passage store.
|
||||||
|
For a partial transfer, this may point to a subdirectory.
|
||||||
|
Example: `~/.passage/store/hosts/MYHOSTNAME`
|
||||||
|
|
||||||
|
* `identities_file` (optional) -
|
||||||
|
Path to the identities file.
|
||||||
|
Defaults to `~/.passage/identities`.
|
||||||
|
|
||||||
|
* `age` (optional) -
|
||||||
|
Path of the age binary.
|
||||||
|
Defaults to `age` (absolute path gets resolved using `passage`'s search path.)
|
||||||
|
|
||||||
|
|
||||||
### `pipe`
|
### `pipe`
|
||||||
|
|
||||||
Executes a local command, capture its stdout, and send that as a file to the
|
Executes a local command, capture its stdout, and send that as a file to the
|
||||||
|
|
|
@ -39,6 +39,17 @@
|
||||||
default = null;
|
default = null;
|
||||||
type = lib.types.nullOr source-types.pass;
|
type = lib.types.nullOr source-types.pass;
|
||||||
};
|
};
|
||||||
|
passage = lib.mkOption {
|
||||||
|
apply = x:
|
||||||
|
if lib.types.pathname.check x
|
||||||
|
then { dir = x; }
|
||||||
|
else x;
|
||||||
|
default = null;
|
||||||
|
type = lib.types.nullOr (lib.types.oneOf [
|
||||||
|
lib.types.pathname
|
||||||
|
source-types.passage
|
||||||
|
]);
|
||||||
|
};
|
||||||
pipe = lib.mkOption {
|
pipe = lib.mkOption {
|
||||||
apply = x:
|
apply = x:
|
||||||
if lib.types.absolute-pathname.check x
|
if lib.types.absolute-pathname.check x
|
||||||
|
@ -160,6 +171,21 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
passage = lib.types.submodule {
|
||||||
|
options = {
|
||||||
|
age = lib.mkOption {
|
||||||
|
default = "age";
|
||||||
|
type = lib.types.pathname;
|
||||||
|
};
|
||||||
|
dir = lib.mkOption {
|
||||||
|
type = lib.types.pathname;
|
||||||
|
};
|
||||||
|
identities_file = lib.mkOption {
|
||||||
|
default = toString ~/.passage/identities;
|
||||||
|
type = lib.types.pathname;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
pipe = lib.types.submodule {
|
pipe = lib.types.submodule {
|
||||||
options = {
|
options = {
|
||||||
command = lib.mkOption {
|
command = lib.mkOption {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
with import ../../lib;
|
with import ../../lib;
|
||||||
with shell;
|
with shell;
|
||||||
|
|
||||||
{ coreutils, dash, findutils, git, jq, openssh, pass, rsync, writers }:
|
{ coreutils, dash, findutils, git, jq, openssh, pass, passage, rsync, writers }:
|
||||||
|
|
||||||
let
|
let
|
||||||
check = { force, target }: let
|
check = { force, target }: let
|
||||||
|
@ -171,6 +171,37 @@ let
|
||||||
${rsync' target rsyncDefaultConfig /* sh */ "$tmp_dir"}
|
${rsync' target rsyncDefaultConfig /* sh */ "$tmp_dir"}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
pop.passage = target: source: /* sh */ ''
|
||||||
|
set -efu
|
||||||
|
|
||||||
|
export PASSAGE_AGE=${quote source.age}
|
||||||
|
export PASSAGE_DIR=${quote source.dir}
|
||||||
|
export PASSAGE_IDENTITIES_FILE=${quote source.identities_file}
|
||||||
|
|
||||||
|
umask 0077
|
||||||
|
|
||||||
|
tmp_dir=$(${coreutils}/bin/mktemp -dt populate-passage.XXXXXXXX)
|
||||||
|
trap cleanup EXIT
|
||||||
|
cleanup() {
|
||||||
|
rm -fR "$tmp_dir"
|
||||||
|
}
|
||||||
|
|
||||||
|
${findutils}/bin/find "$PASSAGE_DIR" -type f -name \*.age -follow |
|
||||||
|
while read -r age_path; do
|
||||||
|
|
||||||
|
rel_name=''${age_path#$PASSAGE_DIR}
|
||||||
|
rel_name=''${rel_name%.age}
|
||||||
|
|
||||||
|
tmp_path=$tmp_dir/$rel_name
|
||||||
|
|
||||||
|
${coreutils}/bin/mkdir -p "$(${coreutils}/bin/dirname "$tmp_path")"
|
||||||
|
${passage}/bin/passage show "$rel_name" > "$tmp_path"
|
||||||
|
${coreutils}/bin/touch -r "$age_path" "$tmp_path"
|
||||||
|
done
|
||||||
|
|
||||||
|
${rsync' target rsyncDefaultConfig /* sh */ "$tmp_dir"}
|
||||||
|
'';
|
||||||
|
|
||||||
pop.pipe = target: source: /* sh */ ''
|
pop.pipe = target: source: /* sh */ ''
|
||||||
${quote source.command} | {
|
${quote source.command} | {
|
||||||
${runShell target /* sh */ "cat > ${quote target.path}"}
|
${runShell target /* sh */ "cat > ${quote target.path}"}
|
||||||
|
|
Loading…
Reference in a new issue