Production readiness hardening and ops tooling
This commit is contained in:
71
scripts/check-mqtt-acl.mjs
Normal file
71
scripts/check-mqtt-acl.mjs
Normal file
@ -0,0 +1,71 @@
|
||||
#!/usr/bin/env node
|
||||
import fs from "node:fs";
|
||||
|
||||
const args = process.argv.slice(2);
|
||||
|
||||
function getArg(name) {
|
||||
const index = args.indexOf(name);
|
||||
return index >= 0 ? args[index + 1] : undefined;
|
||||
}
|
||||
|
||||
function hasFlag(name) {
|
||||
return args.includes(name);
|
||||
}
|
||||
|
||||
function usage() {
|
||||
console.log(`Usage:
|
||||
node scripts/check-mqtt-acl.mjs --file /etc/mosquitto/acl
|
||||
node scripts/check-mqtt-acl.mjs --print-template
|
||||
|
||||
Required Mosquitto ACL rules:
|
||||
pattern readwrite devices/%u/uplink/#
|
||||
pattern read devices/%u/downlink/#
|
||||
user qris-backend
|
||||
topic read devices/+/uplink/#
|
||||
topic write devices/+/downlink/#
|
||||
`);
|
||||
}
|
||||
|
||||
const requiredLines = [
|
||||
"pattern readwrite devices/%u/uplink/#",
|
||||
"pattern read devices/%u/downlink/#",
|
||||
"user qris-backend",
|
||||
"topic read devices/+/uplink/#",
|
||||
"topic write devices/+/downlink/#"
|
||||
];
|
||||
|
||||
if (hasFlag("--help") || hasFlag("-h")) {
|
||||
usage();
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
if (hasFlag("--print-template")) {
|
||||
console.log(`# QRIS Soundbox Mosquitto ACL
|
||||
# Device username must equal platform device_id.
|
||||
${requiredLines.join("\n")}
|
||||
`);
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
const aclFile = getArg("--file") || process.env.MOSQUITTO_ACL_FILE;
|
||||
if (!aclFile) {
|
||||
usage();
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const content = fs.readFileSync(aclFile, "utf8");
|
||||
const normalized = content
|
||||
.split(/\r?\n/)
|
||||
.map((line) => line.trim())
|
||||
.filter((line) => line && !line.startsWith("#"));
|
||||
|
||||
const missing = requiredLines.filter((line) => !normalized.includes(line));
|
||||
const result = {
|
||||
file: aclFile,
|
||||
ok: missing.length === 0,
|
||||
missing,
|
||||
required: requiredLines
|
||||
};
|
||||
|
||||
console.log(JSON.stringify(result, null, 2));
|
||||
process.exit(result.ok ? 0 : 1);
|
||||
Reference in New Issue
Block a user