Joey Hafner 93e8426a43
Feature: Implement new modules for fighter.
- Fighter uses: system, git, sops, docker, networking, and iscsi modules; plus its own stacks module which we've updated to use the new design concept.
  - I can't figure out how to put all of the module code together (importing and defining the vars), so we're compromising.
2025-02-16 01:26:30 -08:00

114 lines
3.7 KiB
Nix

{ sops, pkgs, ... }: {
sops = {
age.sshKeyPaths = [ "/home/${sops.username}/${sops.sshPrivateKey}" ];
age.generateKey = false;
};
home-manager.users.${sops.username}.home.packages = [
pkgs.sops
pkgs.age
pkgs.ssh-to-age
( pkgs.writeShellApplication {
name = "sops-nix";
runtimeInputs = [
pkgs.git
pkgs.ssh-to-age
pkgs.openssh
pkgs.yq ];
text = ''
#! bash
# shellcheck disable=SC2002
# shellcheck disable=SC2016
REPO_ROOT="${sops.repoRoot}"
# shellcheck disable=SC2034
SOPS_AGE_KEY_FILE="/home/${sops.username}/.config/sops/age/keys.txt"
listSecrets () {
# shellcheck disable=SC2002
SOPS_REGEX="$(cat "$REPO_ROOT/.sops.yaml" | yq -y '.creation_rules.[].path_regex' | head -n1)"
find "$REPO_ROOT" -regextype posix-extended -regex "$SOPS_REGEX"
}
getPubkey () {
ADDRESS="$1"
AGE_PUBKEY="$(ssh-keyscan -t ed25519 "$ADDRESS" | ssh-to-age)"
echo "$AGE_PUBKEY"
}
addPubkey () { # Note: Does not edit any files. Prints .sops.yaml with the given key added.
AGE_PUBKEY="$1"
# shellcheck disable=SC2002,SC2016
cat "$REPO_ROOT"/.sops.yaml |\
yq -y --arg key "$AGE_PUBKEY" '.keys += [$key]' |\
yq -y --arg key "$AGE_PUBKEY" '.creation_rules.[].key_groups.[].age += [$key]'
}
updateKey () { # Note: Interactive
sops updatekeys --input-type json "$1"
}
encryptFile () { # Note: All encrypted files are in json format
FILE="$1"
FILE_EXT="''$''\{FILE##*.}"
case "$FILE_EXT" in
"env") FILE_TYPE=dotenv ;;
"json") FILE_TYPE=json ;;
"yaml|yml") FILE_TYPE=yaml ;;
"ini") FILE_TYPE=ini ;;
*) FILE_TYPE=binary ;;
esac
sops --encrypt --config "$REPO_ROOT/.sops.yaml" --input-type "$FILE_TYPE" --output-type json "$FILE"
}
decryptFile () { # Note: All encrypted files are in json format.
# File extension is used as the hint for decrypted file type.
FILE="$1"
FILE_EXT="''$''\{FILE##*.}"
case "$FILE_EXT" in
"env") FILE_TYPE=dotenv ;;
"json") FILE_TYPE=json ;;
"yaml|yml") FILE_TYPE=yaml ;;
"ini") FILE_TYPE=ini ;;
*) FILE_TYPE=binary ;;
esac
sops --decrypt --config "$REPO_ROOT/.sops.yaml" --input-type json --output-type "$FILE_TYPE" "$FILE"
}
isJson () {
FILE="$1"
jq -e . >/dev/null 2>&1 <<<"$(cat "$FILE")" && return 0 || return 1;
}
isEncrypted () {
FILE="$1"
FILE_EXT="''$''\{FILE##*.}"
case "$FILE_EXT" in
"env") FILE_TYPE=dotenv ;;
"json") FILE_TYPE=json ;;
"yaml|yml") FILE_TYPE=yaml ;;
"ini") FILE_TYPE=ini ;;
*) FILE_TYPE=binary ;;
esac
if isJson "$FILE" && [[ "$(sops filestatus "$FILE")" == '{"encrypted":true}' ]]; then echo True; else echo False; fi
}
listSecretStatus () {
for file in $(listSecrets); do
FILE="$(realpath -s --relative-to="$REPO_ROOT" "$file")"
echo -n "$FILE: " |\
xargs echo -n
if sops --decrypt --input-type json "$file" >/dev/null 2>&1; then
echo Decryptable
else
echo "Not decryptable"
fi
done
}
"$@"
'';
} )
];
}