Watch
0
0
Fork
You've already forked hyperhive
0

store_seeded: report a failed read instead of minting over it

This commit is contained in:
atlas 2026-11-03 13:26:02 +01:00 • committed by mara
commit 5f9629dfc7
2 changed files with 113 additions and 14 deletions

View file

@ -11,7 +11,10 @@
let
# `login` answers from `FAKE_BAO_LOGIN_RC`. `kv get` and `kv put -cas=0` act
# on a file per leaf under `FAKE_BAO_KV`; `FAKE_BAO_DENY_READ` and
# `FAKE_BAO_DENY_WRITE` answer 403 as a policy that grants neither does.
# `FAKE_BAO_DENY_WRITE` answer 403 as a policy that grants neither does, and
# `FAKE_BAO_READ_TIMEOUT` is `timeout` ending the read: status 124, silent.
# `FAKE_BAO_READ_5XX` is a server error on the read. A leaf nobody wrote is
# "No value found at <path>", status 2, as `bao kv get` answers it.
# `FAKE_BAO_RACE` has another run create the leaf between this one's read and
# its write. Every call is logged without the value `put` reads from stdin.
fakeBao = pkgs.writeShellScriptBin "bao" ''
@ -24,14 +27,16 @@ let
"kv get")
[ "''${BAO_TOKEN-}" = s.fake ] || { echo "fake bao: kv without the login's token" >&2; exit 97; }
leaf="$FAKE_BAO_KV/$(printf '%s' "$4" | tr / _)"
[ -z "''${FAKE_BAO_READ_TIMEOUT-}" ] || exit 124
[ -z "''${FAKE_BAO_READ_5XX-}" ] || { echo "Error reading secret/data/x: Error making API request. Code: 503. Errors: * Vault is sealed" >&2; exit 2; }
[ -z "''${FAKE_BAO_DENY_READ-}" ] || { echo "fake bao: permission denied" >&2; exit 2; }
if [ -n "''${FAKE_BAO_RACE-}" ] && [ ! -e "$FAKE_BAO_KV/.raced" ]; then
touch "$FAKE_BAO_KV/.raced"
printf '%s' "$FAKE_BAO_RACE" > "$leaf"
echo "fake bao: no value found" >&2
echo "No value found at secret/data/x" >&2
exit 2
fi
[ -e "$leaf" ] || { echo "fake bao: no value found" >&2; exit 2; }
[ -e "$leaf" ] || { echo "No value found at secret/data/x" >&2; exit 2; }
cat "$leaf"
;;
"kv put")
@ -55,7 +60,10 @@ pkgs.runCommand "hyperhive-script-test-store-seeded-secret"
import ../host-modules/lib/store-seeded-secret.nix { }
);
FAKE_BAO_BIN = "${fakeBao}/bin";
nativeBuildInputs = [ pkgs.coreutils ];
nativeBuildInputs = [
pkgs.coreutils
pkgs.gnugrep
];
}
''
${pkgs.bash}/bin/bash ${./store-seeded-secret.sh}

View file

@ -22,7 +22,7 @@ setup() {
dir=$(mktemp -d)
mkdir "$dir/kv"
export FAKE_BAO_KV=$dir/kv FAKE_BAO_LOG=$dir/bao.log FAKE_BAO_LOGIN_RC=0
unset FAKE_BAO_DENY_READ FAKE_BAO_DENY_WRITE FAKE_BAO_RACE
unset FAKE_BAO_DENY_READ FAKE_BAO_DENY_WRITE FAKE_BAO_RACE FAKE_BAO_READ_TIMEOUT FAKE_BAO_READ_5XX
: >"$FAKE_BAO_LOG"
earlier=$dir/earlier
minted=$dir/minted
@ -69,6 +69,19 @@ ran_mint() {
[ -s "$minted" ]
}
no_write() {
if grep -q '^kv put' "$FAKE_BAO_LOG"; then fail "wrote to the store"; fi
}
no_mint() {
if ran_mint; then fail "ran the mint command"; fi
}
# err_has <text>: the run's stderr contains it.
err_has() {
if ! grep -qF -- "$1" "$dir/err"; then fail "stderr lacks '$1': $(cat "$dir/err")"; fi
}
setup "an empty store is seeded from the file, unchanged, and nothing is minted"
printf 'old-value\n' >"$earlier"
run
@ -111,19 +124,80 @@ run
expect 0 winner-value
held winner-value
setup "a store that grants neither read nor write leaves the file's value in use"
setup "a refused read uses the file's value, writes nothing, mints nothing and prints the refusal"
printf 'old-value\n' >"$earlier"
export FAKE_BAO_DENY_READ=1 FAKE_BAO_DENY_WRITE=1
run
expect 0 old-value
held ""
if ran_mint; then fail "minted although the file held a value"; fi
no_write
no_mint
err_has "could not read $leaf from the swarm secret store"
err_has "permission denied"
err_has "using the value of $earlier"
setup "a store that grants neither, and no file, gives no value and mints nothing into it"
setup "a refused read, and no file, fails without writing or minting and prints the refusal"
export FAKE_BAO_DENY_READ=1 FAKE_BAO_DENY_WRITE=1
run
expect 1 ""
held ""
no_write
no_mint
err_has "could not read $leaf from the swarm secret store"
err_has "permission denied"
setup "a read that times out uses the file's value without writing, and says why"
printf 'old-value\n' >"$earlier"
export FAKE_BAO_READ_TIMEOUT=1
run
expect 0 old-value
held ""
no_write
no_mint
err_has "could not read $leaf from the swarm secret store (exit status 124)"
setup "a read that times out, and no file, fails without writing or minting"
export FAKE_BAO_READ_TIMEOUT=1
run
expect 1 ""
held ""
no_write
no_mint
err_has "(exit status 124)"
setup "a read that times out on a leaf the store holds leaves the leaf as it is"
printf 'stored-value' >"$stored"
printf 'old-value\n' >"$earlier"
export FAKE_BAO_READ_TIMEOUT=1
run
expect 0 old-value
held stored-value
no_write
no_mint
setup "a read that gets a server error, and no file, fails without writing and prints the error"
export FAKE_BAO_READ_5XX=1
run
expect 1 ""
held ""
no_write
no_mint
err_has "Code: 503"
setup "a leaf the store does not hold is the only read failure that mints, and no error is printed"
run
expect 0 minted-value
held minted-value
if ! ran_mint; then fail "did not mint"; fi
if grep -q 'could not read' "$dir/err"; then fail "reported a missing leaf as a failed read"; fi
setup "a store that takes no write leaves the file's value in use"
printf 'old-value\n' >"$earlier"
export FAKE_BAO_DENY_WRITE=1
run
expect 0 old-value
held ""
if ran_mint; then fail "minted although the file held a value"; fi
setup "a store that refuses the login leaves the file's value in use and is not called again"
printf 'old-value\n' >"$earlier"