ui: show backend traffic audit in dialog log
This commit is contained in:
@@ -173,6 +173,15 @@ class TrafficAppProfileSaveResult:
|
||||
profile: Optional[TrafficAppProfile] = None
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class TrafficAudit:
|
||||
ok: bool
|
||||
message: str
|
||||
now: str
|
||||
pretty: str
|
||||
issues: List[str]
|
||||
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class TrafficCandidateSubnet:
|
||||
@@ -1041,6 +1050,22 @@ class ApiClient:
|
||||
stderr="",
|
||||
)
|
||||
|
||||
def traffic_audit_get(self) -> TrafficAudit:
|
||||
data = cast(
|
||||
Dict[str, Any],
|
||||
self._json(self._request("GET", "/api/v1/traffic/audit")) or {},
|
||||
)
|
||||
raw_issues = data.get("issues") or []
|
||||
if not isinstance(raw_issues, list):
|
||||
raw_issues = []
|
||||
return TrafficAudit(
|
||||
ok=bool(data.get("ok", False)),
|
||||
message=strip_ansi(str(data.get("message") or "").strip()),
|
||||
now=str(data.get("now") or "").strip(),
|
||||
pretty=strip_ansi(str(data.get("pretty") or "").strip()),
|
||||
issues=[strip_ansi(str(x)).strip() for x in raw_issues if str(x).strip()],
|
||||
)
|
||||
|
||||
# DNS / SmartDNS
|
||||
def dns_upstreams_get(self) -> DnsUpstreams:
|
||||
data = cast(Dict[str, Any], self._json(self._request("GET", "/api/v1/dns-upstreams")) or {})
|
||||
|
||||
@@ -37,6 +37,7 @@ from api_client import (
|
||||
TrafficAppMarkItem,
|
||||
TrafficAppProfile,
|
||||
TrafficAppProfileSaveResult,
|
||||
TrafficAudit,
|
||||
TrafficInterfaces,
|
||||
TrafficModeStatus,
|
||||
TraceDump,
|
||||
@@ -767,6 +768,9 @@ class DashboardController:
|
||||
def traffic_app_profile_delete(self, id: str) -> CmdResult:
|
||||
return self.client.traffic_app_profile_delete(id)
|
||||
|
||||
def traffic_audit(self) -> TrafficAudit:
|
||||
return self.client.traffic_audit_get()
|
||||
|
||||
def routes_nft_progress_from_event(self, ev: Event) -> RoutesNftProgressView:
|
||||
"""
|
||||
Превращает Event(kind='routes_nft_progress') в удобную модель
|
||||
|
||||
@@ -580,6 +580,16 @@ RU: Восстанавливает маршруты/nft из последнег
|
||||
self.txt_app.setReadOnly(True)
|
||||
tab_log = QWidget()
|
||||
tab_log_layout = QVBoxLayout(tab_log)
|
||||
row_log = QHBoxLayout()
|
||||
self.btn_app_audit = QPushButton("Run audit")
|
||||
self.btn_app_audit.setToolTip(
|
||||
"EN: Runs backend traffic audit (duplicates + nft consistency) and prints it here.\n"
|
||||
"RU: Запускает backend-аудит трафика (дубли + nft консистентность) и печатает сюда."
|
||||
)
|
||||
self.btn_app_audit.clicked.connect(self.on_app_audit)
|
||||
row_log.addWidget(self.btn_app_audit)
|
||||
row_log.addStretch(1)
|
||||
tab_log_layout.addLayout(row_log)
|
||||
tab_log_layout.addWidget(self.txt_app, stretch=1)
|
||||
self.apps_tabs.addTab(tab_log, "Log")
|
||||
|
||||
@@ -1742,6 +1752,22 @@ RU: Применяет policy-rules и проверяет health. При оши
|
||||
|
||||
self._safe(work, title="App picker error")
|
||||
|
||||
def on_app_audit(self) -> None:
|
||||
def work() -> None:
|
||||
audit = self.ctrl.traffic_audit()
|
||||
pretty = (getattr(audit, "pretty", "") or "").strip()
|
||||
if not pretty:
|
||||
pretty = f"ok={getattr(audit, 'ok', False)} message={getattr(audit, 'message', '')}"
|
||||
self._append_app_log("[audit]\n" + pretty)
|
||||
issues = list(getattr(audit, "issues", []) or [])
|
||||
ok = bool(getattr(audit, "ok", False)) and len(issues) == 0
|
||||
if issues:
|
||||
self._set_action_status(f"Audit: issues={len(issues)}", ok=False)
|
||||
else:
|
||||
self._set_action_status("Audit: OK", ok=True)
|
||||
|
||||
self._safe(work, title="Traffic audit error")
|
||||
|
||||
def _run_systemd_unit(self, cmdline: str, *, unit: str) -> tuple[str, str]:
|
||||
args = shlex.split(cmdline or "")
|
||||
if not args:
|
||||
|
||||
Reference in New Issue
Block a user