Add Asterisk configuration and diagnostics support
- Updated .env.example to include Asterisk templates path. - Modified docker-compose.yml to mount the templates directory. - Enhanced backend Dockerfile to copy templates into the container. - Introduced Asterisk diagnostics functionality in asterisk_profiles.py, allowing for baseline checks and diagnostics reporting. - Integrated Asterisk diagnostics into the device diagnostics workflow in graph.py. - Added formatting for Asterisk baseline drift reports in diagnostic_format.py. - Updated SKILL.md to document new config baseline drift feature for Asterisk. This commit enhances the system's capabilities for managing Asterisk configurations and diagnostics, improving overall troubleshooting processes.
This commit is contained in:
138
backend/tests/test_asterisk_baseline.py
Normal file
138
backend/tests/test_asterisk_baseline.py
Normal file
@@ -0,0 +1,138 @@
|
||||
"""Tests for Asterisk golden config baseline."""
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
os.environ.setdefault("SECRET_KEY", "test-secret-key-for-unit-tests-only")
|
||||
_test_dir = Path(__file__).resolve().parent
|
||||
_repo_root = _test_dir.parent.parent
|
||||
_templates_root = _repo_root / "templates" / "asterisk"
|
||||
if not _templates_root.is_dir():
|
||||
_templates_root = _test_dir.parent / "templates" / "asterisk"
|
||||
os.environ["ASTERISK_TEMPLATES_PATH"] = str(_templates_root)
|
||||
|
||||
from app.services.asterisk_baseline import ( # noqa: E402
|
||||
compare_against_baseline,
|
||||
compare_file,
|
||||
invalidate_manifest_cache,
|
||||
profile_for_catalog,
|
||||
resolve_variables,
|
||||
substitute,
|
||||
)
|
||||
from app.services.diagnostic_format import format_tool_output_markdown # noqa: E402
|
||||
|
||||
|
||||
def test_profile_for_geneseasx_catalog():
|
||||
invalidate_manifest_cache()
|
||||
assert profile_for_catalog("asterisk_geneseasx") == "geneseasx"
|
||||
assert profile_for_catalog("asterisk") == "geneseasx"
|
||||
assert profile_for_catalog("asterisk_satbox") is None
|
||||
|
||||
|
||||
def test_substitute_variables():
|
||||
assert substitute("local_net={{PHONE_SUBNET}}", {"PHONE_SUBNET": "192.168.0.0/24"}) == (
|
||||
"local_net=192.168.0.0/24"
|
||||
)
|
||||
|
||||
|
||||
def test_compare_file_detects_missing_line():
|
||||
live = """
|
||||
[transport-udp]
|
||||
type=transport
|
||||
local_net=10.20.30.0/24
|
||||
external_media_address=10.20.30.222
|
||||
"""
|
||||
spec = {
|
||||
"path": "pjsip.conf",
|
||||
"description": "test",
|
||||
"required_lines": [
|
||||
"local_net={{PHONE_SUBNET}}",
|
||||
"local_net={{VOIP_SUBNET}}",
|
||||
],
|
||||
}
|
||||
variables = {"PHONE_SUBNET": "192.168.0.0/24", "VOIP_SUBNET": "10.20.30.0/24"}
|
||||
result = compare_file(live, spec, variables)
|
||||
assert result.ok is False
|
||||
assert any(not c.ok for c in result.checks)
|
||||
|
||||
|
||||
def test_compare_file_passes_golden_pjsip():
|
||||
live = """
|
||||
[transport-udp]
|
||||
type=transport
|
||||
protocol=udp
|
||||
local_net=192.168.0.0/24
|
||||
local_net=10.20.30.0/24
|
||||
external_media_address=10.20.30.222
|
||||
external_signaling_address=10.20.30.222
|
||||
"""
|
||||
spec = {
|
||||
"path": "pjsip.conf",
|
||||
"required_lines": [
|
||||
"local_net={{PHONE_SUBNET}}",
|
||||
"local_net={{VOIP_SUBNET}}",
|
||||
"external_media_address={{ASTERISK_IP}}",
|
||||
"external_signaling_address={{ASTERISK_IP}}",
|
||||
],
|
||||
}
|
||||
variables = {
|
||||
"PHONE_SUBNET": "192.168.0.0/24",
|
||||
"VOIP_SUBNET": "10.20.30.0/24",
|
||||
"ASTERISK_IP": "10.20.30.222",
|
||||
}
|
||||
result = compare_file(live, spec, variables)
|
||||
assert result.ok is True
|
||||
|
||||
|
||||
def test_compare_against_baseline_full_report():
|
||||
invalidate_manifest_cache()
|
||||
live_files = {
|
||||
"pjsip.conf": """
|
||||
local_net=192.168.0.0/24
|
||||
local_net=10.20.30.0/24
|
||||
external_media_address=10.20.30.222
|
||||
external_signaling_address=10.20.30.222
|
||||
""",
|
||||
"rtp.conf": "rtpstart=10000\nrtpend=10029\n",
|
||||
"extensions.conf": "[public]\nexten => _7XXXX,1,NoOp(trunk)\n",
|
||||
}
|
||||
report = compare_against_baseline(live_files, profile="geneseasx")
|
||||
assert report is not None
|
||||
assert report.ok is True
|
||||
assert "6/6" in report.summary or "checks passed" in report.summary
|
||||
|
||||
|
||||
def test_env_override_variables(monkeypatch):
|
||||
invalidate_manifest_cache()
|
||||
from app.services.asterisk_baseline import load_manifest
|
||||
|
||||
manifest = load_manifest("geneseasx", force=True)
|
||||
monkeypatch.setenv("ASTERISK_BASELINE_ASTERISK_IP", "10.99.99.99")
|
||||
vars = resolve_variables(manifest or {}, {})
|
||||
assert vars["ASTERISK_IP"] == "10.99.99.99"
|
||||
|
||||
|
||||
def test_baseline_markdown_formatting():
|
||||
payload = {
|
||||
"profile": "geneseasx",
|
||||
"summary": "Config baseline: 5/6 checks passed",
|
||||
"variables": {"ASTERISK_IP": "10.20.30.222"},
|
||||
"files": [
|
||||
{
|
||||
"path": "pjsip.conf",
|
||||
"missing": False,
|
||||
"checks": [
|
||||
{
|
||||
"kind": "required_line",
|
||||
"expected": "local_net=192.168.0.0/24",
|
||||
"ok": False,
|
||||
}
|
||||
],
|
||||
}
|
||||
],
|
||||
}
|
||||
md = format_tool_output_markdown("asterisk_config_baseline", json.dumps(payload))
|
||||
assert "DRIFT" in md
|
||||
assert "pjsip.conf" in md
|
||||
Reference in New Issue
Block a user