mirror of
https://github.com/ryantm/agenix.git
synced 2024-11-21 17:20:47 +03:00
contrib: format Nix code with Alejandra
This commit is contained in:
parent
99e0963743
commit
16bef569f4
6 changed files with 245 additions and 226 deletions
|
@ -1,14 +1,17 @@
|
||||||
{ config, options, lib, pkgs, ... }:
|
{
|
||||||
|
config,
|
||||||
with lib;
|
options,
|
||||||
|
lib,
|
||||||
let
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
with lib; let
|
||||||
cfg = config.age;
|
cfg = config.age;
|
||||||
|
|
||||||
# we need at least rage 0.5.0 to support ssh keys
|
# we need at least rage 0.5.0 to support ssh keys
|
||||||
rage =
|
rage =
|
||||||
if lib.versionOlder pkgs.rage.version "0.5.0"
|
if lib.versionOlder pkgs.rage.version "0.5.0"
|
||||||
then pkgs.callPackage ../pkgs/rage.nix { }
|
then pkgs.callPackage ../pkgs/rage.nix {}
|
||||||
else pkgs.rage;
|
else pkgs.rage;
|
||||||
ageBin = config.age.ageBin;
|
ageBin = config.age.ageBin;
|
||||||
|
|
||||||
|
@ -28,11 +31,15 @@ let
|
||||||
identities = builtins.concatStringsSep " " (map (path: "-i ${path}") cfg.identityPaths);
|
identities = builtins.concatStringsSep " " (map (path: "-i ${path}") cfg.identityPaths);
|
||||||
|
|
||||||
setTruePath = secretType: ''
|
setTruePath = secretType: ''
|
||||||
${if secretType.symlink then ''
|
${
|
||||||
_truePath="${cfg.secretsMountPoint}/$_agenix_generation/${secretType.name}"
|
if secretType.symlink
|
||||||
'' else ''
|
then ''
|
||||||
_truePath="${secretType.path}"
|
_truePath="${cfg.secretsMountPoint}/$_agenix_generation/${secretType.name}"
|
||||||
''}
|
''
|
||||||
|
else ''
|
||||||
|
_truePath="${secretType.path}"
|
||||||
|
''
|
||||||
|
}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
installSecret = secretType: ''
|
installSecret = secretType: ''
|
||||||
|
@ -55,9 +62,11 @@ let
|
||||||
''}
|
''}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
testIdentities = map (path: ''
|
testIdentities =
|
||||||
test -f ${path} || echo '[agenix] WARNING: config.age.identityPaths entry ${path} not present!'
|
map (path: ''
|
||||||
'') cfg.identityPaths;
|
test -f ${path} || echo '[agenix] WARNING: config.age.identityPaths entry ${path} not present!'
|
||||||
|
'')
|
||||||
|
cfg.identityPaths;
|
||||||
|
|
||||||
cleanupAndLink = ''
|
cleanupAndLink = ''
|
||||||
_agenix_generation="$(basename "$(readlink ${cfg.secretsDir})" || echo 0)"
|
_agenix_generation="$(basename "$(readlink ${cfg.secretsDir})" || echo 0)"
|
||||||
|
@ -72,10 +81,10 @@ let
|
||||||
'';
|
'';
|
||||||
|
|
||||||
installSecrets = builtins.concatStringsSep "\n" (
|
installSecrets = builtins.concatStringsSep "\n" (
|
||||||
[ "echo '[agenix] decrypting secrets...'" ]
|
["echo '[agenix] decrypting secrets...'"]
|
||||||
++ testIdentities
|
++ testIdentities
|
||||||
++ (map installSecret (builtins.attrValues cfg.secrets))
|
++ (map installSecret (builtins.attrValues cfg.secrets))
|
||||||
++ [ cleanupAndLink ]
|
++ [cleanupAndLink]
|
||||||
);
|
);
|
||||||
|
|
||||||
chownSecret = secretType: ''
|
chownSecret = secretType: ''
|
||||||
|
@ -90,11 +99,12 @@ let
|
||||||
'';
|
'';
|
||||||
|
|
||||||
chownSecrets = builtins.concatStringsSep "\n" (
|
chownSecrets = builtins.concatStringsSep "\n" (
|
||||||
[ "echo '[agenix] chowning...'" ]
|
["echo '[agenix] chowning...'"]
|
||||||
++ [ chownMountPoint ]
|
++ [chownMountPoint]
|
||||||
++ (map chownSecret (builtins.attrValues cfg.secrets)));
|
++ (map chownSecret (builtins.attrValues cfg.secrets))
|
||||||
|
);
|
||||||
|
|
||||||
secretType = types.submodule ({ config, ... }: {
|
secretType = types.submodule ({config, ...}: {
|
||||||
options = {
|
options = {
|
||||||
name = mkOption {
|
name = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
|
@ -137,14 +147,12 @@ let
|
||||||
Group of the decrypted secret.
|
Group of the decrypted secret.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
symlink = mkEnableOption "symlinking secrets to their destination" // { default = true; };
|
symlink = mkEnableOption "symlinking secrets to their destination" // {default = true;};
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
in
|
in {
|
||||||
{
|
|
||||||
|
|
||||||
imports = [
|
imports = [
|
||||||
(mkRenamedOptionModule [ "age" "sshKeyPaths" ] [ "age" "identityPaths" ])
|
(mkRenamedOptionModule ["age" "sshKeyPaths"] ["age" "identityPaths"])
|
||||||
];
|
];
|
||||||
|
|
||||||
options.age = {
|
options.age = {
|
||||||
|
@ -157,7 +165,7 @@ in
|
||||||
};
|
};
|
||||||
secrets = mkOption {
|
secrets = mkOption {
|
||||||
type = types.attrsOf secretType;
|
type = types.attrsOf secretType;
|
||||||
default = { };
|
default = {};
|
||||||
description = ''
|
description = ''
|
||||||
Attrset of secrets.
|
Attrset of secrets.
|
||||||
'';
|
'';
|
||||||
|
@ -170,11 +178,13 @@ in
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
secretsMountPoint = mkOption {
|
secretsMountPoint = mkOption {
|
||||||
type = types.addCheck types.str
|
type =
|
||||||
|
types.addCheck types.str
|
||||||
(s:
|
(s:
|
||||||
(builtins.match "[ \t\n]*" s) == null # non-empty
|
(builtins.match "[ \t\n]*" s)
|
||||||
&& (builtins.match ".+/" s) == null) # without trailing slash
|
== null # non-empty
|
||||||
// { description = "${types.str.description} (with check: non-empty without trailing slash)"; };
|
&& (builtins.match ".+/" s) == null) # without trailing slash
|
||||||
|
// {description = "${types.str.description} (with check: non-empty without trailing slash)";};
|
||||||
default = "/run/agenix.d";
|
default = "/run/agenix.d";
|
||||||
defaultText = "/run/agenix.d";
|
defaultText = "/run/agenix.d";
|
||||||
description = ''
|
description = ''
|
||||||
|
@ -184,20 +194,22 @@ in
|
||||||
identityPaths = mkOption {
|
identityPaths = mkOption {
|
||||||
type = types.listOf types.path;
|
type = types.listOf types.path;
|
||||||
default =
|
default =
|
||||||
if config.services.openssh.enable then
|
if config.services.openssh.enable
|
||||||
map (e: e.path) (lib.filter (e: e.type == "rsa" || e.type == "ed25519") config.services.openssh.hostKeys)
|
then map (e: e.path) (lib.filter (e: e.type == "rsa" || e.type == "ed25519") config.services.openssh.hostKeys)
|
||||||
else [ ];
|
else [];
|
||||||
description = ''
|
description = ''
|
||||||
Path to SSH keys to be used as identities in age decryption.
|
Path to SSH keys to be used as identities in age decryption.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf (cfg.secrets != { }) {
|
config = mkIf (cfg.secrets != {}) {
|
||||||
assertions = [{
|
assertions = [
|
||||||
assertion = cfg.identityPaths != [ ];
|
{
|
||||||
message = "age.identityPaths must be set.";
|
assertion = cfg.identityPaths != [];
|
||||||
}];
|
message = "age.identityPaths must be set.";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
# Create a new directory full of secrets for symlinking (this helps
|
# Create a new directory full of secrets for symlinking (this helps
|
||||||
# ensure removed secrets are actually removed, or at least become
|
# ensure removed secrets are actually removed, or at least become
|
||||||
|
@ -218,7 +230,7 @@ in
|
||||||
};
|
};
|
||||||
|
|
||||||
# So user passwords can be encrypted.
|
# So user passwords can be encrypted.
|
||||||
system.activationScripts.users.deps = [ "agenixInstall" ];
|
system.activationScripts.users.deps = ["agenixInstall"];
|
||||||
|
|
||||||
# Change ownership and group after users and groups are made.
|
# Change ownership and group after users and groups are made.
|
||||||
system.activationScripts.agenixChown = {
|
system.activationScripts.agenixChown = {
|
||||||
|
@ -232,8 +244,7 @@ in
|
||||||
# So other activation scripts can depend on agenix being done.
|
# So other activation scripts can depend on agenix being done.
|
||||||
system.activationScripts.agenix = {
|
system.activationScripts.agenix = {
|
||||||
text = "";
|
text = "";
|
||||||
deps = [ "agenixChown"];
|
deps = ["agenixChown"];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
final: prev:
|
final: prev: {
|
||||||
{
|
agenix = prev.callPackage ./pkgs/agenix.nix {};
|
||||||
agenix = prev.callPackage ./pkgs/agenix.nix { };
|
|
||||||
}
|
}
|
||||||
|
|
318
pkgs/agenix.nix
318
pkgs/agenix.nix
|
@ -13,177 +13,175 @@
|
||||||
if rage.version < "0.5.0"
|
if rage.version < "0.5.0"
|
||||||
then callPackage ./rage.nix {}
|
then callPackage ./rage.nix {}
|
||||||
else rage
|
else rage
|
||||||
}/bin/rage"
|
}/bin/rage",
|
||||||
} :
|
}: let
|
||||||
let
|
|
||||||
sedBin = "${gnused}/bin/sed";
|
sedBin = "${gnused}/bin/sed";
|
||||||
nixInstantiate = "${nix}/bin/nix-instantiate";
|
nixInstantiate = "${nix}/bin/nix-instantiate";
|
||||||
mktempBin = "${mktemp}/bin/mktemp";
|
mktempBin = "${mktemp}/bin/mktemp";
|
||||||
diffBin = "${diffutils}/bin/diff";
|
diffBin = "${diffutils}/bin/diff";
|
||||||
in
|
in
|
||||||
lib.recursiveUpdate (writeShellScriptBin "agenix" ''
|
lib.recursiveUpdate (writeShellScriptBin "agenix" ''
|
||||||
set -Eeuo pipefail
|
set -Eeuo pipefail
|
||||||
|
|
||||||
PACKAGE="agenix"
|
PACKAGE="agenix"
|
||||||
|
|
||||||
function show_help () {
|
function show_help () {
|
||||||
echo "$PACKAGE - edit and rekey age secret files"
|
echo "$PACKAGE - edit and rekey age secret files"
|
||||||
echo " "
|
echo " "
|
||||||
echo "$PACKAGE -e FILE [-i PRIVATE_KEY]"
|
echo "$PACKAGE -e FILE [-i PRIVATE_KEY]"
|
||||||
echo "$PACKAGE -r [-i PRIVATE_KEY]"
|
echo "$PACKAGE -r [-i PRIVATE_KEY]"
|
||||||
echo ' '
|
echo ' '
|
||||||
echo 'options:'
|
echo 'options:'
|
||||||
echo '-h, --help show help'
|
echo '-h, --help show help'
|
||||||
echo '-e, --edit FILE edits FILE using $EDITOR'
|
echo '-e, --edit FILE edits FILE using $EDITOR'
|
||||||
echo '-r, --rekey re-encrypts all secrets with specified recipients'
|
echo '-r, --rekey re-encrypts all secrets with specified recipients'
|
||||||
echo '-i, --identity identity to use when decrypting'
|
echo '-i, --identity identity to use when decrypting'
|
||||||
echo '-v, --verbose verbose output'
|
echo '-v, --verbose verbose output'
|
||||||
echo ' '
|
echo ' '
|
||||||
echo 'FILE an age-encrypted file'
|
echo 'FILE an age-encrypted file'
|
||||||
echo ' '
|
echo ' '
|
||||||
echo 'PRIVATE_KEY a path to a private SSH key used to decrypt file'
|
echo 'PRIVATE_KEY a path to a private SSH key used to decrypt file'
|
||||||
echo ' '
|
echo ' '
|
||||||
echo 'EDITOR environment variable of editor to use when editing FILE'
|
echo 'EDITOR environment variable of editor to use when editing FILE'
|
||||||
echo ' '
|
echo ' '
|
||||||
echo 'RULES environment variable with path to Nix file specifying recipient public keys.'
|
echo 'RULES environment variable with path to Nix file specifying recipient public keys.'
|
||||||
echo "Defaults to './secrets.nix'"
|
echo "Defaults to './secrets.nix'"
|
||||||
echo ' '
|
echo ' '
|
||||||
echo "agenix version: 0.13.0"
|
echo "agenix version: 0.13.0"
|
||||||
echo "age binary path: ${ageBin}"
|
echo "age binary path: ${ageBin}"
|
||||||
echo "age version: $(${ageBin} --version)"
|
echo "age version: $(${ageBin} --version)"
|
||||||
}
|
}
|
||||||
|
|
||||||
test $# -eq 0 && (show_help && exit 1)
|
test $# -eq 0 && (show_help && exit 1)
|
||||||
|
|
||||||
REKEY=0
|
REKEY=0
|
||||||
DEFAULT_DECRYPT=(--decrypt)
|
DEFAULT_DECRYPT=(--decrypt)
|
||||||
|
|
||||||
while test $# -gt 0; do
|
while test $# -gt 0; do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
-h|--help)
|
-h|--help)
|
||||||
show_help
|
show_help
|
||||||
exit 0
|
exit 0
|
||||||
;;
|
;;
|
||||||
-e|--edit)
|
-e|--edit)
|
||||||
shift
|
shift
|
||||||
if test $# -gt 0; then
|
if test $# -gt 0; then
|
||||||
export FILE=$1
|
export FILE=$1
|
||||||
else
|
else
|
||||||
echo "no FILE specified"
|
echo "no FILE specified"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
-i|--identity)
|
-i|--identity)
|
||||||
shift
|
shift
|
||||||
if test $# -gt 0; then
|
if test $# -gt 0; then
|
||||||
DEFAULT_DECRYPT+=(--identity "$1")
|
DEFAULT_DECRYPT+=(--identity "$1")
|
||||||
else
|
else
|
||||||
echo "no PRIVATE_KEY specified"
|
echo "no PRIVATE_KEY specified"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
-r|--rekey)
|
-r|--rekey)
|
||||||
shift
|
shift
|
||||||
REKEY=1
|
REKEY=1
|
||||||
;;
|
;;
|
||||||
-v|--verbose)
|
-v|--verbose)
|
||||||
shift
|
shift
|
||||||
set -x
|
set -x
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
show_help
|
show_help
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
RULES=''${RULES:-./secrets.nix}
|
|
||||||
|
|
||||||
function cleanup {
|
|
||||||
if [ ! -z ''${CLEARTEXT_DIR+x} ]
|
|
||||||
then
|
|
||||||
rm -rf "$CLEARTEXT_DIR"
|
|
||||||
fi
|
|
||||||
if [ ! -z ''${REENCRYPTED_DIR+x} ]
|
|
||||||
then
|
|
||||||
rm -rf "$REENCRYPTED_DIR"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
trap "cleanup" 0 2 3 15
|
|
||||||
|
|
||||||
function edit {
|
|
||||||
FILE=$1
|
|
||||||
KEYS=$((${nixInstantiate} --eval -E "(let rules = import $RULES; in builtins.concatStringsSep \"\n\" rules.\"$FILE\".publicKeys)" | ${sedBin} 's/"//g' | ${sedBin} 's/\\n/\n/g') | ${sedBin} '/^$/d' || exit 1)
|
|
||||||
|
|
||||||
if [ -z "$KEYS" ]
|
|
||||||
then
|
|
||||||
>&2 echo "There is no rule for $FILE in $RULES."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
CLEARTEXT_DIR=$(${mktempBin} -d)
|
|
||||||
CLEARTEXT_FILE="$CLEARTEXT_DIR/$(basename "$FILE")"
|
|
||||||
|
|
||||||
if [ -f "$FILE" ]
|
|
||||||
then
|
|
||||||
DECRYPT=("''${DEFAULT_DECRYPT[@]}")
|
|
||||||
if [ -f "$HOME/.ssh/id_rsa" ]; then
|
|
||||||
DECRYPT+=(--identity "$HOME/.ssh/id_rsa")
|
|
||||||
fi
|
|
||||||
if [ -f "$HOME/.ssh/id_ed25519" ]; then
|
|
||||||
DECRYPT+=(--identity "$HOME/.ssh/id_ed25519")
|
|
||||||
fi
|
|
||||||
if [[ "''${DECRYPT[*]}" != *"--identity"* ]]; then
|
|
||||||
echo "No identity found to decrypt $FILE. Try adding an SSH key at $HOME/.ssh/id_rsa or $HOME/.ssh/id_ed25519 or using the --identity flag to specify a file."
|
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
;;
|
||||||
DECRYPT+=(-o "$CLEARTEXT_FILE" "$FILE")
|
esac
|
||||||
${ageBin} "''${DECRYPT[@]}" || exit 1
|
|
||||||
cp "$CLEARTEXT_FILE" "$CLEARTEXT_FILE.before"
|
|
||||||
fi
|
|
||||||
|
|
||||||
$EDITOR "$CLEARTEXT_FILE"
|
|
||||||
|
|
||||||
if [ ! -f "$CLEARTEXT_FILE" ]
|
|
||||||
then
|
|
||||||
echo "$FILE wasn't created."
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
[ -f "$FILE" ] && [ "$EDITOR" != ":" ] && ${diffBin} "$CLEARTEXT_FILE.before" "$CLEARTEXT_FILE" 1>/dev/null && echo "$FILE wasn't changed, skipping re-encryption." && return
|
|
||||||
|
|
||||||
ENCRYPT=()
|
|
||||||
while IFS= read -r key
|
|
||||||
do
|
|
||||||
ENCRYPT+=(--recipient "$key")
|
|
||||||
done <<< "$KEYS"
|
|
||||||
|
|
||||||
REENCRYPTED_DIR=$(${mktempBin} -d)
|
|
||||||
REENCRYPTED_FILE="$REENCRYPTED_DIR/$(basename "$FILE")"
|
|
||||||
|
|
||||||
ENCRYPT+=(-o "$REENCRYPTED_FILE")
|
|
||||||
|
|
||||||
${ageBin} "''${ENCRYPT[@]}" <"$CLEARTEXT_FILE" || exit 1
|
|
||||||
|
|
||||||
mv -f "$REENCRYPTED_FILE" "$1"
|
|
||||||
}
|
|
||||||
|
|
||||||
function rekey {
|
|
||||||
FILES=$((${nixInstantiate} --eval -E "(let rules = import $RULES; in builtins.concatStringsSep \"\n\" (builtins.attrNames rules))" | ${sedBin} 's/"//g' | ${sedBin} 's/\\n/\n/g') || exit 1)
|
|
||||||
|
|
||||||
for FILE in $FILES
|
|
||||||
do
|
|
||||||
echo "rekeying $FILE..."
|
|
||||||
EDITOR=: edit "$FILE"
|
|
||||||
cleanup
|
|
||||||
done
|
done
|
||||||
}
|
|
||||||
|
|
||||||
[ $REKEY -eq 1 ] && rekey && exit 0
|
RULES=''${RULES:-./secrets.nix}
|
||||||
edit "$FILE" && cleanup && exit 0
|
|
||||||
'')
|
|
||||||
|
|
||||||
{
|
function cleanup {
|
||||||
meta.description = "age-encrypted secrets for NixOS";
|
if [ ! -z ''${CLEARTEXT_DIR+x} ]
|
||||||
}
|
then
|
||||||
|
rm -rf "$CLEARTEXT_DIR"
|
||||||
|
fi
|
||||||
|
if [ ! -z ''${REENCRYPTED_DIR+x} ]
|
||||||
|
then
|
||||||
|
rm -rf "$REENCRYPTED_DIR"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
trap "cleanup" 0 2 3 15
|
||||||
|
|
||||||
|
function edit {
|
||||||
|
FILE=$1
|
||||||
|
KEYS=$((${nixInstantiate} --eval -E "(let rules = import $RULES; in builtins.concatStringsSep \"\n\" rules.\"$FILE\".publicKeys)" | ${sedBin} 's/"//g' | ${sedBin} 's/\\n/\n/g') | ${sedBin} '/^$/d' || exit 1)
|
||||||
|
|
||||||
|
if [ -z "$KEYS" ]
|
||||||
|
then
|
||||||
|
>&2 echo "There is no rule for $FILE in $RULES."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
CLEARTEXT_DIR=$(${mktempBin} -d)
|
||||||
|
CLEARTEXT_FILE="$CLEARTEXT_DIR/$(basename "$FILE")"
|
||||||
|
|
||||||
|
if [ -f "$FILE" ]
|
||||||
|
then
|
||||||
|
DECRYPT=("''${DEFAULT_DECRYPT[@]}")
|
||||||
|
if [ -f "$HOME/.ssh/id_rsa" ]; then
|
||||||
|
DECRYPT+=(--identity "$HOME/.ssh/id_rsa")
|
||||||
|
fi
|
||||||
|
if [ -f "$HOME/.ssh/id_ed25519" ]; then
|
||||||
|
DECRYPT+=(--identity "$HOME/.ssh/id_ed25519")
|
||||||
|
fi
|
||||||
|
if [[ "''${DECRYPT[*]}" != *"--identity"* ]]; then
|
||||||
|
echo "No identity found to decrypt $FILE. Try adding an SSH key at $HOME/.ssh/id_rsa or $HOME/.ssh/id_ed25519 or using the --identity flag to specify a file."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
DECRYPT+=(-o "$CLEARTEXT_FILE" "$FILE")
|
||||||
|
${ageBin} "''${DECRYPT[@]}" || exit 1
|
||||||
|
cp "$CLEARTEXT_FILE" "$CLEARTEXT_FILE.before"
|
||||||
|
fi
|
||||||
|
|
||||||
|
$EDITOR "$CLEARTEXT_FILE"
|
||||||
|
|
||||||
|
if [ ! -f "$CLEARTEXT_FILE" ]
|
||||||
|
then
|
||||||
|
echo "$FILE wasn't created."
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
[ -f "$FILE" ] && [ "$EDITOR" != ":" ] && ${diffBin} "$CLEARTEXT_FILE.before" "$CLEARTEXT_FILE" 1>/dev/null && echo "$FILE wasn't changed, skipping re-encryption." && return
|
||||||
|
|
||||||
|
ENCRYPT=()
|
||||||
|
while IFS= read -r key
|
||||||
|
do
|
||||||
|
ENCRYPT+=(--recipient "$key")
|
||||||
|
done <<< "$KEYS"
|
||||||
|
|
||||||
|
REENCRYPTED_DIR=$(${mktempBin} -d)
|
||||||
|
REENCRYPTED_FILE="$REENCRYPTED_DIR/$(basename "$FILE")"
|
||||||
|
|
||||||
|
ENCRYPT+=(-o "$REENCRYPTED_FILE")
|
||||||
|
|
||||||
|
${ageBin} "''${ENCRYPT[@]}" <"$CLEARTEXT_FILE" || exit 1
|
||||||
|
|
||||||
|
mv -f "$REENCRYPTED_FILE" "$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
function rekey {
|
||||||
|
FILES=$((${nixInstantiate} --eval -E "(let rules = import $RULES; in builtins.concatStringsSep \"\n\" (builtins.attrNames rules))" | ${sedBin} 's/"//g' | ${sedBin} 's/\\n/\n/g') || exit 1)
|
||||||
|
|
||||||
|
for FILE in $FILES
|
||||||
|
do
|
||||||
|
echo "rekeying $FILE..."
|
||||||
|
EDITOR=: edit "$FILE"
|
||||||
|
cleanup
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
[ $REKEY -eq 1 ] && rekey && exit 0
|
||||||
|
edit "$FILE" && cleanup && exit 0
|
||||||
|
'')
|
||||||
|
{
|
||||||
|
meta.description = "age-encrypted secrets for NixOS";
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
{ stdenv, rustPlatform, fetchFromGitHub, installShellFiles, darwin }:
|
{
|
||||||
|
stdenv,
|
||||||
|
rustPlatform,
|
||||||
|
fetchFromGitHub,
|
||||||
|
installShellFiles,
|
||||||
|
darwin,
|
||||||
|
}:
|
||||||
rustPlatform.buildRustPackage rec {
|
rustPlatform.buildRustPackage rec {
|
||||||
pname = "rage";
|
pname = "rage";
|
||||||
version = "0.5.0";
|
version = "0.5.0";
|
||||||
|
@ -13,12 +18,13 @@ rustPlatform.buildRustPackage rec {
|
||||||
|
|
||||||
cargoSha256 = "sha256-GPr5zxeODAjD+ynp/nned9gZUiReYcdzosuEbLIKZSs=";
|
cargoSha256 = "sha256-GPr5zxeODAjD+ynp/nned9gZUiReYcdzosuEbLIKZSs=";
|
||||||
|
|
||||||
nativeBuildInputs = [ installShellFiles ];
|
nativeBuildInputs = [installShellFiles];
|
||||||
|
|
||||||
buildInputs = with darwin.apple_sdk.frameworks; stdenv.lib.optionals stdenv.isDarwin [
|
buildInputs = with darwin.apple_sdk.frameworks;
|
||||||
Security
|
stdenv.lib.optionals stdenv.isDarwin [
|
||||||
Foundation
|
Security
|
||||||
];
|
Foundation
|
||||||
|
];
|
||||||
|
|
||||||
# cargo test has an x86-only dependency
|
# cargo test has an x86-only dependency
|
||||||
doCheck = stdenv.hostPlatform.isx86;
|
doCheck = stdenv.hostPlatform.isx86;
|
||||||
|
@ -37,7 +43,7 @@ rustPlatform.buildRustPackage rec {
|
||||||
description = "A simple, secure and modern encryption tool with small explicit keys, no config options, and UNIX-style composability";
|
description = "A simple, secure and modern encryption tool with small explicit keys, no config options, and UNIX-style composability";
|
||||||
homepage = "https://github.com/str4d/rage";
|
homepage = "https://github.com/str4d/rage";
|
||||||
changelog = "https://github.com/str4d/rage/releases/tag/v${version}";
|
changelog = "https://github.com/str4d/rage/releases/tag/v${version}";
|
||||||
license = with licenses; [ asl20 mit ]; # either at your option
|
license = with licenses; [asl20 mit]; # either at your option
|
||||||
maintainers = with maintainers; [ marsam ryantm ];
|
maintainers = with maintainers; [marsam ryantm];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# Do not copy this! It is insecure. This is only okay because we are testing.
|
# Do not copy this! It is insecure. This is only okay because we are testing.
|
||||||
{
|
{
|
||||||
system.activationScripts.agenixInstall.deps = [ "installSSHHostKeys" ];
|
system.activationScripts.agenixInstall.deps = ["installSSHHostKeys"];
|
||||||
|
|
||||||
system.activationScripts.installSSHHostKeys.text = ''
|
system.activationScripts.installSSHHostKeys.text = ''
|
||||||
mkdir -p /etc/ssh
|
mkdir -p /etc/ssh
|
||||||
|
|
|
@ -1,14 +1,20 @@
|
||||||
{
|
{
|
||||||
nixpkgs ? <nixpkgs>,
|
nixpkgs ? <nixpkgs>,
|
||||||
pkgs ? import <nixpkgs> { inherit system; config = {}; },
|
pkgs ?
|
||||||
system ? builtins.currentSystem
|
import <nixpkgs> {
|
||||||
} @args:
|
inherit system;
|
||||||
|
config = {};
|
||||||
import "${nixpkgs}/nixos/tests/make-test-python.nix" ({ pkgs, ...}: {
|
},
|
||||||
|
system ? builtins.currentSystem,
|
||||||
|
} @ args:
|
||||||
|
import "${nixpkgs}/nixos/tests/make-test-python.nix" ({pkgs, ...}: {
|
||||||
name = "agenix-integration";
|
name = "agenix-integration";
|
||||||
|
|
||||||
nodes.system1 = { config, lib, ... }: {
|
nodes.system1 = {
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}: {
|
||||||
imports = [
|
imports = [
|
||||||
../modules/age.nix
|
../modules/age.nix
|
||||||
./install_ssh_host_keys.nix
|
./install_ssh_host_keys.nix
|
||||||
|
@ -30,11 +36,9 @@ import "${nixpkgs}/nixos/tests/make-test-python.nix" ({ pkgs, ...}: {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
testScript =
|
testScript = let
|
||||||
let
|
|
||||||
user = "user1";
|
user = "user1";
|
||||||
password = "password1234";
|
password = "password1234";
|
||||||
in ''
|
in ''
|
||||||
|
@ -55,4 +59,5 @@ import "${nixpkgs}/nixos/tests/make-test-python.nix" ({ pkgs, ...}: {
|
||||||
system1.wait_for_file("/tmp/1")
|
system1.wait_for_file("/tmp/1")
|
||||||
assert "${user}" in system1.succeed("cat /tmp/1")
|
assert "${user}" in system1.succeed("cat /tmp/1")
|
||||||
'';
|
'';
|
||||||
}) args
|
})
|
||||||
|
args
|
||||||
|
|
Loading…
Reference in a new issue