Self-hosted, Docker-based agentic troubleshooting platform: FastAPI backend + LangGraph agent, Next.js UI, tiered LLM routing (local Ollama -> Gemini -> DeepSeek -> OpenRouter), MCP server manager, encrypted device credentials, RBAC, audit log, project-memory + Obsidian integrations, and editable troubleshooting decision rules tuned for the GeneseasX vessel stack. Co-authored-by: Cursor <cursoragent@cursor.com>
85 lines
2.9 KiB
Python
85 lines
2.9 KiB
Python
"""Asterisk deployment profiles and connect playbooks."""
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
import shlex
|
|
|
|
from app.agent.device_connect import ssh_connect_args
|
|
|
|
# Only one Asterisk slot allowed per vessel.
|
|
ASTERISK_CATALOG_KEYS = frozenset({"asterisk", "asterisk_geneseasx", "asterisk_satbox"})
|
|
|
|
GENESEASX_KEYS = frozenset({"asterisk", "asterisk_geneseasx"})
|
|
SATBOX_KEYS = frozenset({"asterisk_satbox"})
|
|
|
|
|
|
def asterisk_container_name(catalog_key: str | None) -> str:
|
|
"""Docker container name for GeneseasX Asterisk (default: voip)."""
|
|
if catalog_key not in GENESEASX_KEYS:
|
|
return ""
|
|
return (
|
|
os.environ.get("DEVICE_ASTERISK_GENESEASX_CONTAINER", "").strip()
|
|
or os.environ.get("DEVICE_ASTERISK_CONTAINER", "").strip()
|
|
or "voip"
|
|
)
|
|
|
|
|
|
def _ssh_connect(ctx: dict) -> dict:
|
|
port = ctx.get("port")
|
|
if port is None:
|
|
port_raw = os.environ.get("DEVICE_ASTERISK_GENESEASX_PORT", "").strip()
|
|
port = int(port_raw) if port_raw.isdigit() else 6022
|
|
return ssh_connect_args({**ctx, "port": port})
|
|
|
|
|
|
def _docker_asterisk(command: str):
|
|
def builder(c: dict) -> dict:
|
|
container = c.get("asterisk_container") or asterisk_container_name(c.get("catalog_key")) or "voip"
|
|
return {"command": f"docker exec {container} asterisk -rx {shlex.quote(command)}"}
|
|
|
|
return builder
|
|
|
|
|
|
def _asterisk_cli(command: str):
|
|
return lambda c: {"command": f'asterisk -rx "{command}"'}
|
|
|
|
|
|
# Native Debian host diagnostics (TMGeneseas / satbox) via SSH.
|
|
SATBOX_ASTERISK_DIAGNOSTICS = [
|
|
("ssh_run", _asterisk_cli("pjsip show registrations")),
|
|
("ssh_run", _asterisk_cli("pjsip show endpoints")),
|
|
("ssh_run", _asterisk_cli("core show channels")),
|
|
("ssh_run", lambda c: {"command": "tail -n 100 /var/log/asterisk/full 2>/dev/null || journalctl -u asterisk -n 100 --no-pager 2>/dev/null || true"}),
|
|
]
|
|
|
|
# GeneseasX: SSH to Docker VM, docker exec into voip (password auth via ssh-generic-mcp).
|
|
GENESEASX_ASTERISK_DIAGNOSTICS = [
|
|
("ssh_run", _docker_asterisk("pjsip show registrations")),
|
|
("ssh_run", _docker_asterisk("pjsip show endpoints")),
|
|
("ssh_run", _docker_asterisk("core show channels")),
|
|
("ssh_run", lambda c: {
|
|
"command": (
|
|
f"docker logs --tail 100 {shlex.quote(c.get('asterisk_container') or 'voip')} 2>&1 | tail -100"
|
|
)
|
|
}),
|
|
]
|
|
|
|
ASTERISK_PLAYBOOKS: dict[str, dict] = {
|
|
"asterisk_geneseasx": {
|
|
"mcp_server": "ssh-generic-mcp",
|
|
"connect": ("ssh_connect", _ssh_connect),
|
|
"diagnostics": GENESEASX_ASTERISK_DIAGNOSTICS,
|
|
},
|
|
# Legacy catalog key — same as GeneseasX
|
|
"asterisk": {
|
|
"mcp_server": "ssh-generic-mcp",
|
|
"connect": ("ssh_connect", _ssh_connect),
|
|
"diagnostics": GENESEASX_ASTERISK_DIAGNOSTICS,
|
|
},
|
|
"asterisk_satbox": {
|
|
"mcp_server": "ssh-generic-mcp",
|
|
"connect": ("ssh_connect", _ssh_connect),
|
|
"diagnostics": SATBOX_ASTERISK_DIAGNOSTICS,
|
|
},
|
|
}
|