update security
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
#!/usr/bin/env bash
|
||||
set -u -o pipefail
|
||||
|
||||
TEST_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
source "${TEST_ROOT}/tests/testlib.sh"
|
||||
source "${TEST_ROOT}/inc/cluster-update.inc"
|
||||
|
||||
nodes_json='[
|
||||
{"node":"pve3","status":"offline"},
|
||||
{"node":"pve1","status":"online"},
|
||||
{"node":"pve2","status":"online"},
|
||||
{"node":"bad node","status":"online"}
|
||||
]'
|
||||
expected=$'pve1\tonline\npve2\tonline\npve3\toffline'
|
||||
assert_equal "$expected" \
|
||||
"$(printf '%s' "$nodes_json" | TAPM_CLUSTER_NODES_FROM_JSON)" \
|
||||
"cluster node discovery filters and sorts API output"
|
||||
|
||||
wrapped_json='{"data":[{"node":"pve2.example","status":"ONLINE"}]}'
|
||||
assert_equal $'pve2.example\tonline' \
|
||||
"$(printf '%s' "$wrapped_json" | TAPM_CLUSTER_NODES_FROM_JSON)" \
|
||||
"wrapped API response and normalized status"
|
||||
|
||||
if printf '%s' 'not-json' | TAPM_CLUSTER_NODES_FROM_JSON 2>/dev/null; then
|
||||
printf 'FAIL: malformed cluster JSON was accepted\n' >&2
|
||||
exit 1
|
||||
fi
|
||||
assert_failure "remote node rejects shell characters" \
|
||||
TAPM_UPDATE_REMOTE_NODE 'pve1;reboot'
|
||||
|
||||
test_dir="$(mktemp -d)"
|
||||
trap 'rm -rf "$test_dir"' EXIT
|
||||
TAPM_COROSYNC_CONFIG="${test_dir}/corosync.conf"
|
||||
printf 'totem {}\n' >"$TAPM_COROSYNC_CONFIG"
|
||||
update_log="${test_dir}/updates"
|
||||
LightCyan=0
|
||||
LightYellow=0
|
||||
Green=0
|
||||
Red=0
|
||||
Default=0
|
||||
idsCL[0]=''
|
||||
pvesh() {
|
||||
return 0
|
||||
}
|
||||
TAPM_CLUSTER_NODE_ROWS() {
|
||||
printf 'pve1\tonline\npve2\tonline\npve3\toffline\n'
|
||||
}
|
||||
TAPM_LOCAL_CLUSTER_NODE() {
|
||||
printf 'pve1\n'
|
||||
}
|
||||
TAPM_UPDATE_REMOTE_NODE() {
|
||||
printf 'remote:%s\n' "$1" >>"$update_log"
|
||||
}
|
||||
INSTALL_LOCAL_UPDATES() {
|
||||
printf 'local:pve1\n' >>"$update_log"
|
||||
}
|
||||
if INSTALL_CLUSTER_UPDATES >/dev/null; then
|
||||
printf 'FAIL: cluster update ignored an offline node\n' >&2
|
||||
exit 1
|
||||
fi
|
||||
assert_equal $'remote:pve2\nlocal:pve1' \
|
||||
"$(cat "$update_log")" \
|
||||
"online remotes and initiating node update once"
|
||||
|
||||
finish_tests
|
||||
@@ -0,0 +1,89 @@
|
||||
#!/usr/bin/env bash
|
||||
set -u -o pipefail
|
||||
|
||||
TEST_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
test_dir="$(mktemp -d)"
|
||||
trap 'rm -rf "$test_dir"' EXIT
|
||||
|
||||
TAPM_FLEET_STATE_DIR="${test_dir}/state"
|
||||
TAPM_FLEET_IDENTITY_FILE="${TAPM_FLEET_STATE_DIR}/identity.env"
|
||||
TAPM_BROKER_URL='https://tapm.example.com'
|
||||
source "${TEST_ROOT}/inc/fleet.inc"
|
||||
|
||||
TAPM_FLEET_ENSURE_IDENTITY
|
||||
if ! TAPM_FLEET_VALID_IDENTITY; then
|
||||
printf 'FAIL: generated fleet identity is invalid\n' >&2
|
||||
exit 1
|
||||
fi
|
||||
if stat -c '%a' "$TAPM_FLEET_IDENTITY_FILE" >/dev/null 2>&1; then
|
||||
identity_mode="$(stat -c '%a' "$TAPM_FLEET_IDENTITY_FILE")"
|
||||
else
|
||||
identity_mode="$(stat -f '%Lp' "$TAPM_FLEET_IDENTITY_FILE")"
|
||||
fi
|
||||
if [[ "$identity_mode" != 600 ]]; then
|
||||
printf 'FAIL: fleet identity mode is not 600\n' >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
TAPM_FLEET_VERSION='2026.7.26-7'
|
||||
TAPM_FLEET_GIT_COMMIT='0123456789abcdef0123456789abcdef01234567'
|
||||
TAPM_FLEET_PVE_VERSION='pve-manager/9.0.3/abc~1'
|
||||
TAPM_FLEET_OS_VERSION='Debian GNU/Linux 13 (trixie)'
|
||||
TAPM_FLEET_KERNEL_VERSION='6.14.11-2-pve'
|
||||
TAPM_FLEET_ARCHITECTURE='amd64'
|
||||
TAPM_FLEET_CLUSTERED=true
|
||||
|
||||
registration_json="$(
|
||||
TAPM_FLEET_INCLUDE_CREDENTIAL=1 TAPM_FLEET_JSON installed success
|
||||
)"
|
||||
REGISTRATION_JSON="$registration_json" python3 -c '
|
||||
import json, os
|
||||
payload = json.loads(os.environ["REGISTRATION_JSON"])
|
||||
assert payload["installation_id"]
|
||||
assert len(payload["credential"]) == 64
|
||||
assert payload["proxmenu_version"] == "2026.7.26-7"
|
||||
assert payload["clustered"] is True
|
||||
'
|
||||
|
||||
printf '0\n' >"${test_dir}/curl-count"
|
||||
curl() {
|
||||
local count data_path='' previous='' argument=''
|
||||
count="$(cat "${test_dir}/curl-count")"
|
||||
count="$((count + 1))"
|
||||
printf '%s\n' "$count" >"${test_dir}/curl-count"
|
||||
for argument in "$@"; do
|
||||
if [[ "$previous" == '--data-binary' ]]; then
|
||||
data_path="${argument#@}"
|
||||
fi
|
||||
previous="$argument"
|
||||
done
|
||||
if [[ -n "$data_path" ]]; then
|
||||
cp "$data_path" "${test_dir}/curl-body-${count}.json"
|
||||
fi
|
||||
cat >"${test_dir}/curl-config-${count}"
|
||||
return 0
|
||||
}
|
||||
|
||||
TAPM_FLEET_REGISTERED=1
|
||||
TAPM_FLEET_EVENT_SEND run_completed success '' 12
|
||||
EVENT_BODY="$(cat "${test_dir}/curl-body-1.json")" \
|
||||
EVENT_CONFIG="$(cat "${test_dir}/curl-config-1")" \
|
||||
EXPECTED_CREDENTIAL="$TAPM_FLEET_CREDENTIAL" \
|
||||
python3 -c '
|
||||
import json, os
|
||||
payload = json.loads(os.environ["EVENT_BODY"])
|
||||
assert payload["event"] == "run_completed"
|
||||
assert payload["result"] == "success"
|
||||
assert payload["duration_seconds"] == 12
|
||||
assert "credential" not in payload
|
||||
config = os.environ["EVENT_CONFIG"]
|
||||
assert "Authorization: Bearer " + os.environ["EXPECTED_CREDENTIAL"] in config
|
||||
assert "https://tapm.example.com/api/v1/hosts/events" in config
|
||||
'
|
||||
|
||||
if compgen -G "${TMPDIR:-/tmp}/tapm-fleet-event.*" >/dev/null; then
|
||||
printf 'FAIL: fleet event left a temporary payload file\n' >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
printf 'PASS: fleet identity and event client\n'
|
||||
Reference in New Issue
Block a user