from __future__ import annotations import logging from datetime import datetime, timezone from app.clients.base import BaseHTTPClient from app.config import Settings from app.models.sources import BackrestSnapshot logger = logging.getLogger(__name__) class BackrestClient(BaseHTTPClient): def __init__(self, settings: Settings) -> None: super().__init__(settings, "backrest", settings.backrest_base_url) async def fetch_status(self) -> BackrestSnapshot: snapshot = BackrestSnapshot() if not self.base_url: logger.info("backrest skipped: base URL missing") return snapshot try: data = await self._request_json("GET", "/v1/config") except Exception as exc: logger.warning("backrest fetch_status /v1/config failed: %s", exc) return snapshot if not isinstance(data, dict): return snapshot repos = data.get("repos") or [] repo_count = len(repos) if isinstance(repos, list) else 0 # Fetch operation log for recent backup status last_backup_age_hours: float | None = None error_count = 0 last_backup_status = "unknown" try: ops_data = await self._request_json( "POST", "/v1/operations", json={"last_n": 20}, ) ops = ops_data.get("operations") or [] if isinstance(ops_data, dict) else [] backup_ops = [ op for op in ops if isinstance(op, dict) and op.get("op", {}).get("backupOp") is not None ] error_ops = [op for op in backup_ops if op.get("status") == "STATUS_ERROR"] error_count = len(error_ops) if backup_ops: latest = backup_ops[0] ts = latest.get("unixTimeEndMs") if ts: ended = datetime.fromtimestamp(int(ts) / 1000, tz=timezone.utc) now = datetime.now(timezone.utc) last_backup_age_hours = round((now - ended).total_seconds() / 3600, 1) status_str = latest.get("status", "") last_backup_status = "ok" if status_str == "STATUS_SUCCESS" else "error" if status_str == "STATUS_ERROR" else "unknown" except Exception as exc: logger.warning("backrest fetch_status /v1/operations failed: %s", exc) return BackrestSnapshot( source_status="online", repo_count=repo_count, last_backup_age_hours=last_backup_age_hours, last_backup_status=last_backup_status, error_count=error_count, )