Add MQTT broker smoke-test script
Creates a throwaway dynsec client+role scoped to a private topic, publishes/subscribes to confirm round-trip delivery, checks a bogus login is rejected, then cleans up. Syntax verified against a real eclipse-mosquitto:2 + dynamic-security broker locally before writing. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
7e9fe62e1c
commit
8b2dce9714
1 changed files with 84 additions and 0 deletions
84
scripts/test-mqtt-broker.sh
Normal file
84
scripts/test-mqtt-broker.sh
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
#!/usr/bin/env bash
|
||||
# Smoke-test the shared MQTT broker (LXC 104 · hotel-manage-mqtt-broker).
|
||||
#
|
||||
# Verifies the broker actually authenticates and round-trips messages, not
|
||||
# just that the process is up: creates a throwaway dynsec client + role
|
||||
# scoped to a private "smoketest/#" topic, publishes a retained message,
|
||||
# confirms it's delivered back via subscribe, then deletes the throwaway
|
||||
# client/role again. Also checks that a bogus login is rejected, proving
|
||||
# allow_anonymous=false is actually enforced.
|
||||
#
|
||||
# Run on the Proxmox host:
|
||||
# bash <(curl -fsSL https://git.pterois.co.uk/hotel-manage-stack/stack-init/raw/branch/main/scripts/test-mqtt-broker.sh)
|
||||
set -euo pipefail
|
||||
|
||||
CREDS_FILE=/root/hotel-manage-credentials.txt
|
||||
[[ -f "$CREDS_FILE" ]] || { echo "No credentials file at $CREDS_FILE — has the stack been installed?"; exit 1; }
|
||||
|
||||
MQTT_ADMIN_USER=$(sed -n 's/^MQTT_ADMIN_USER=//p' "$CREDS_FILE" | head -1)
|
||||
MQTT_ADMIN_PASS=$(sed -n 's/^MQTT_ADMIN_PASS=//p' "$CREDS_FILE" | head -1)
|
||||
[[ -n "$MQTT_ADMIN_USER" && -n "$MQTT_ADMIN_PASS" ]] || {
|
||||
echo "MQTT_ADMIN_USER/PASS not found in $CREDS_FILE — has the broker been deployed (--only mqtt-broker)?"
|
||||
exit 1
|
||||
}
|
||||
|
||||
pct exec 104 -- docker inspect hotel-manage-mqtt-broker &>/dev/null || {
|
||||
echo "Container hotel-manage-mqtt-broker not found on LXC 104 — is it deployed?"
|
||||
exit 1
|
||||
}
|
||||
|
||||
NET="--network container:hotel-manage-mqtt-broker"
|
||||
IMG="eclipse-mosquitto:2"
|
||||
TEST_USER="smoketest-$$"
|
||||
TEST_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c 18)
|
||||
TEST_ROLE="smoketest-role-$$"
|
||||
TOPIC="smoketest/$$"
|
||||
PAYLOAD="hello-$$"
|
||||
|
||||
ctrl() {
|
||||
pct exec 104 -- docker run --rm $NET "$IMG" \
|
||||
mosquitto_ctrl -h 127.0.0.1 -p 1883 -u "$MQTT_ADMIN_USER" -P "$MQTT_ADMIN_PASS" dynsec "$@" 2>/dev/null
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
ctrl deleteClient "$TEST_USER" &>/dev/null || true
|
||||
ctrl deleteRole "$TEST_ROLE" &>/dev/null || true
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
echo "== Creating throwaway client + role scoped to ${TOPIC} =="
|
||||
ctrl createClient "$TEST_USER" -p "$TEST_PASS"
|
||||
ctrl createRole "$TEST_ROLE"
|
||||
ctrl addRoleACL "$TEST_ROLE" publishClientSend "$TOPIC" allow
|
||||
ctrl addRoleACL "$TEST_ROLE" publishClientReceive "$TOPIC" allow
|
||||
ctrl addRoleACL "$TEST_ROLE" subscribePattern "$TOPIC" allow
|
||||
ctrl addClientRole "$TEST_USER" "$TEST_ROLE"
|
||||
|
||||
echo "== Publishing retained test message =="
|
||||
pct exec 104 -- docker run --rm $NET "$IMG" \
|
||||
mosquitto_pub -h 127.0.0.1 -p 1883 -u "$TEST_USER" -P "$TEST_PASS" -t "$TOPIC" -m "$PAYLOAD" -r
|
||||
|
||||
echo "== Subscribing to confirm delivery =="
|
||||
RESULT=$(pct exec 104 -- docker run --rm $NET "$IMG" \
|
||||
mosquitto_sub -h 127.0.0.1 -p 1883 -u "$TEST_USER" -P "$TEST_PASS" -t "$TOPIC" -C 1 -W 10 2>/dev/null || true)
|
||||
|
||||
echo "== Clearing retained message =="
|
||||
pct exec 104 -- docker run --rm $NET "$IMG" \
|
||||
mosquitto_pub -h 127.0.0.1 -p 1883 -u "$TEST_USER" -P "$TEST_PASS" -t "$TOPIC" -n -r
|
||||
|
||||
echo "== Confirming a bogus login is rejected (allow_anonymous=false) =="
|
||||
if pct exec 104 -- docker run --rm $NET "$IMG" \
|
||||
mosquitto_pub -h 127.0.0.1 -p 1883 -u "not-a-real-user" -P "wrong-password" -t "$TOPIC" -m "x" &>/dev/null; then
|
||||
echo "FAIL — bogus credentials were accepted, broker auth is not enforced"
|
||||
exit 1
|
||||
fi
|
||||
echo " ok — bogus credentials rejected"
|
||||
|
||||
if [[ "$RESULT" == "$PAYLOAD" ]]; then
|
||||
echo
|
||||
echo "PASS — broker authenticated the throwaway client and round-tripped '$PAYLOAD'"
|
||||
else
|
||||
echo
|
||||
echo "FAIL — expected payload '$PAYLOAD', got: '$RESULT'"
|
||||
exit 1
|
||||
fi
|
||||
Loading…
Add table
Add a link
Reference in a new issue