fix: fallback to derive jobs from sessions when API fails
- veeam_client: try 6 URL variants (states/config with source/typeFilter), then legacy on 9419, then legacy on port 9398 - main.py: if jobs_data empty but sessions available, aggregate sessions by jobName to build synthetic job list with name/type/result/state - Ensures jobs tab always shows data even when API has FileBackup enum bug
This commit is contained in:
21
main.py
21
main.py
@@ -146,6 +146,27 @@ async def _collect_instance(inst) -> dict | None:
|
||||
except Exception as e:
|
||||
errors.append(f"sessions: {e}")
|
||||
|
||||
if not jobs_data and sessions_data:
|
||||
job_map: dict[str, dict] = {}
|
||||
for s in sessions_data:
|
||||
name = s.get("jobName") or s.get("name") or s.get("Name") or ""
|
||||
if not name:
|
||||
continue
|
||||
ts = s.get("endTime") or s.get("creationTime") or ""
|
||||
if name not in job_map or ts > (job_map[name].get("_ts") or ""):
|
||||
job_map[name] = {
|
||||
"name": name,
|
||||
"type": s.get("jobType") or s.get("type") or "",
|
||||
"result": s.get("result") or "",
|
||||
"state": s.get("state") or "",
|
||||
"last_backup": ts,
|
||||
"schedule_enabled": True,
|
||||
"_ts": ts,
|
||||
}
|
||||
for j in job_map.values():
|
||||
j.pop("_ts", None)
|
||||
jobs_data = list(job_map.values())
|
||||
|
||||
try:
|
||||
repos_data = await client.fetch_repositories()
|
||||
except Exception as e:
|
||||
|
||||
@@ -204,14 +204,35 @@ class VeeamClient:
|
||||
|
||||
async def fetch_jobs(self) -> list[dict]:
|
||||
if self._is_v12():
|
||||
last_err = None
|
||||
for url in ("/api/v1/jobs/states", "/api/v1/jobs", "/api/v1/jobs/states?typeFilter=Backup"):
|
||||
for path in (
|
||||
"/api/v1/jobs/states",
|
||||
"/api/v1/jobs",
|
||||
"/api/v1/jobs/states?source=Backup",
|
||||
"/api/v1/jobs?source=Backup",
|
||||
"/api/v1/jobs/states?typeFilter=Backup",
|
||||
"/api/v1/jobs?typeFilter=Backup",
|
||||
):
|
||||
try:
|
||||
return await self._fetch_json_list(url)
|
||||
except Exception as e:
|
||||
last_err = e
|
||||
return await self._fetch_json_list(path)
|
||||
except Exception:
|
||||
continue
|
||||
raise ConnectionError(f"all job endpoints failed: {last_err}")
|
||||
try:
|
||||
return await self._fetch_legacy_jobs()
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
legacy_url = f"https://{self.host}:9398/api/jobs"
|
||||
resp = await self._http.get(legacy_url, headers={"Accept": "application/json"})
|
||||
if resp.status_code < 400:
|
||||
data = self._parse(resp)
|
||||
jobs = data.get("Jobs") or data.get("jobs") or data.get("Refs", {}).get("Job") or []
|
||||
if isinstance(jobs, dict):
|
||||
jobs = [jobs]
|
||||
if jobs:
|
||||
return [self._normalize_legacy_job(j) for j in jobs]
|
||||
except Exception:
|
||||
pass
|
||||
raise ConnectionError("all job endpoints failed (v12 REST + legacy XML)")
|
||||
return await self._fetch_legacy_jobs()
|
||||
|
||||
async def fetch_sessions(self, limit: int = 50) -> list[dict]:
|
||||
|
||||
Reference in New Issue
Block a user