feat(syslog): set-up help on the page, port 5514 published, Docker-hidden senders called out (#6003)
CI / lint (push) Successful in 2s
CI / unit (push) Successful in 1m29s
CI / integration (push) Successful in 1m38s
CI / publish (push) Successful in 20s

The Syslog page says where to send (this server, its port and protocols) and
where the setting is on Synology, QNAP, TrueNAS, OpenWrt, UniFi and rsyslog,
open until a device sends. A sender whose address is on Steward's own
container network (Swarm ingress publishing hides the real sender) is
flagged, with the host-mode ports to publish instead. compose files and the
Dockerfile publish 5514/udp and /tcp; docs/plugins/syslog.md describes the
plugin and the deploy.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-19 07:01:56 -04:00
co-authored by Claude Opus 5.5
parent 96f774ce24
commit ed9da56efa
10 changed files with 221 additions and 5 deletions
+18 -1
View File
@@ -27,7 +27,7 @@ async def _render(app, role, **ctx):
from quart import session
ctx = {"listener": _listener(), "sources": [], "offered": [], "ignored": [],
"hosts": [NS(id="h1", name="SynNAS", address="192.168.0.7")],
"now": datetime.now(timezone.utc), **ctx}
"server": "steward.lan", "now": datetime.now(timezone.utc), **ctx}
async with app.test_request_context("/plugins/syslog/"):
session["user_role"] = role
page = await render_plugin_template(app, "syslog", "syslog/index.html", **ctx)
@@ -62,6 +62,23 @@ async def test_a_port_it_cannot_open_is_said(app):
assert "No sources yet." in page
async def test_setup_help_names_this_server_and_opens_until_a_device_sends(app):
page = await _render(app, "viewer")
assert '<details class="card" id="syslog-setup" open>' in page
assert "send to <span class=\"mono\">steward.lan</span>, port <span class=\"mono\">5514</span>, UDP or TCP" in page
assert "*.* @@steward.lan:5514" in page and "mode: host" in page
added = await _render(app, "viewer", sources=[_source("SynNAS", "accepted")])
assert '<details class="card" id="syslog-setup">' in added # closed once one sends
async def test_a_sender_on_dockers_own_network_is_called_out(app):
hidden = {**_source("ingress", "offered"), "address": "10.0.0.2", "docker_address": True}
page = await _render(app, "admin", offered=[hidden, {**hidden, "id": "id-2"}])
assert "10.0.0.2 is on Steward's own container network" in page
assert page.count("Docker's address, not the device's") == 2
assert "own container network" not in await _render(app, "admin", offered=[_source("synnas", "offered")])
async def test_the_edit_page_has_its_trail_and_a_remove(app):
from quart import session
source = NS(id="s1", name="SynNAS", hostname_seen="synnas", address="192.168.0.7", host_id=None)