feat(syslog): list patterns and add a ready-made one through MCP
CI / lint (push) Successful in 1s
CI / unit (push) Failing after 1m35s
CI / integration (push) Successful in 1m47s
CI / publish (push) Skipped

Patterns could only be added on the Syslog page, so an agent asked to map
them on the NASes couldn't. list_syslog_patterns gives each pattern's metric
and the ready-made ones not added; add_syslog_preset (admin, audited) adds one.
The key-picking helper moves beside the patterns for both callers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-30 19:04:34 -04:00
co-authored by Claude Opus 5.5
parent 4cce3f0d12
commit 45aae6d585
6 changed files with 99 additions and 16 deletions
+32
View File
@@ -290,6 +290,38 @@ def test_a_source_page_filters_its_lines_and_hosts_show_them(app):
asyncio.run(go())
def test_a_preset_is_added_once_through_mcp(app):
from sqlalchemy import delete
from steward.core.api_tokens import Caller
from steward.mcp import _context
from steward.models.users import UserRole
tools = _mod("mcp_tools")
SyslogPattern = _mod("models").SyslogPattern
async def go():
_context._app_ctx.set(app)
_context._caller_ctx.set(Caller(user_id=None, username="admin", role=UserRole.admin, token_id=0))
async with app.db_sessionmaker() as s:
async with s.begin():
await s.execute(delete(SyslogPattern).where(SyslogPattern.key == "nfs"))
with pytest.raises(ValueError, match="No preset"):
await tools.add_syslog_preset("no-such-preset")
added = await tools.add_syslog_preset("nfs")
assert added["metric"] == "lines_matching_nfs"
listed = await tools.list_syslog_patterns()
assert "nfs" in {p["key"] for p in listed["patterns"]}
assert "nfs" not in {p["key"] for p in listed["presets_not_added"]}
with pytest.raises(ValueError, match="already added"):
await tools.add_syslog_preset("nfs")
async with app.db_sessionmaker() as s:
async with s.begin():
await s.execute(delete(SyslogPattern).where(SyslogPattern.key == "nfs"))
asyncio.run(go())
def test_search_syslog_filters_and_pages(app):
from steward.core.api_tokens import Caller
from steward.mcp import _context