diff --git a/main.py b/main.py index 78e6eb6..38fb4da 100644 --- a/main.py +++ b/main.py @@ -187,6 +187,12 @@ async def _collect_instance(inst) -> dict | None: except Exception as e: errors.append(f"agents: {e}") + try: + agent_policies = await client.fetch_agent_policies() + except Exception as e: + errors.append(f"agent policies: {e}") + agent_policies = [] + for s in sessions_data: if isinstance(s.get("result"), dict): s["result"] = s["result"].get("result") or s["result"].get("Result") or "unknown" @@ -255,6 +261,7 @@ async def _collect_instance(inst) -> dict | None: "repository_states": repo_states, "alarms": alarms_data, "agents": agents_data, + "agent_policies": agent_policies, } await set_cache(inst.id, "dashboard", result) @@ -277,6 +284,7 @@ async def _collect_instance(inst) -> dict | None: "repository_states": [], "alarms": [], "agents": [], + "agent_policies": [], } return error_result finally: diff --git a/static/index.html b/static/index.html index f3f0d03..a3241ee 100644 --- a/static/index.html +++ b/static/index.html @@ -483,7 +483,7 @@ function renderJobsTable(inst) { if (!jobs.length) return '
Нет данных о политиках
'; const enabled = (js.total || 0) - (js.disabled || 0); let header = '
Всего: ' + (js.total || 0) + ' Включено: ' + enabled + ' Выключено: ' + (js.disabled || 0) + ''; - if (js.disabled > 0) header += ' ⚠ ВНИМАНИЕ! ЕСТЬ ВЫКЛЮЧЕННЫЕ ПОЛИТИКИ!'; + if (js.disabled > 0) header += ' ⚠ ВНИМАНИЕ! ЕСТЬ ВЫКЛЮЧЕННЫЕ!'; header += '
'; let rows = ''; for (const j of jobs) { @@ -497,7 +497,22 @@ function renderJobsTable(inst) { rows += '' + (isDisabled ? 'выключена' : 'включена') + ''; rows += ''; } - return header + '
' + rows + '
ИмяТипТочки восст.Последний бэкапРасписание
'; + let html = header + '
' + rows + '
ИмяТипТочки восст.Последний бэкапРасписание
'; + const policies = inst.agent_policies || []; + if (policies.length) { + html += '

Агентские политики

'; + html += '
'; + for (const p of policies) { + const isDisabled = p.schedule_enabled === false || (p.state || '').toLowerCase() === 'disabled'; + html += ''; + html += ''; + html += ''; + html += ''; + html += ''; + } + html += '
ИмяТипРасписание
' + esc(p.name || p.Name || '—') + '' + esc(p.type || p.jobType || '—') + '' + (isDisabled ? 'выключена' : 'включена') + '
'; + } + return html; } function renderSessionsTable(inst) { diff --git a/veeam_client.py b/veeam_client.py index 34a9eed..a84ad3a 100644 --- a/veeam_client.py +++ b/veeam_client.py @@ -297,14 +297,26 @@ class VeeamClient: async def fetch_agent_policies(self) -> list[dict]: if self._is_v12(): - for path in ( - "/api/v1/agents/policies/states", - "/api/v1/agents/policies", - ): - try: - return await self._fetch_json_list(path) - except Exception: - continue + seen: set[str] = set() + all_policies: list[dict] = [] + policy_types = [ + "WindowsAgentBackupWorkstationPolicy", + "LinuxAgentBackupWorkstationPolicy", + "WindowsAgentBackupServerPolicy", + "LinuxAgentBackupServerPolicy", + ] + for t in policy_types: + for base in ("/api/v1/jobs/states", "/api/v1/jobs"): + try: + items = await self._fetch_json_list(f"{base}?typeFilter={t}") + for p in items: + pid = p.get("id") or p.get("Id") or "" + if pid and pid not in seen: + seen.add(pid) + all_policies.append(p) + except Exception: + continue + return all_policies return [] async def _fetch_json_list(self, path: str) -> list[dict]: