strtotime('1990-01-01')) ? date('Y-m-d H:i', $ts) : '-'; } function fmt_lastgood($dateStr) { $days = days_since($dateStr); if ($days === null || $days > 365) return 'NEVER'; return date('Y-m-d H:i', strtotime($dateStr)) . " ({$days}J)"; } /* ------------------------------------------------------- active inventory */ $activeRows = Invoke_Infra("SELECT name FROM cmdb_vms WHERE CAST(lastinventory AS DATETIME) > DATEADD(DAY, -2, GETDATE())"); $active = []; foreach ($activeRows as $r) { $active[strtoupper(trim($r['name']))] = true; } /* -------------------------------------------------------------- 1. Veeam */ $veeam = []; $rows = Invoke_Infra("SELECT * FROM Veeam_Reporting"); foreach ($rows as $row) { $key = strtoupper(trim($row['ClientName'])); if (!isset($active[$key])) continue; $ageGood = days_since($row['LastSuccess']); $status = trim((string) $row['LastStatus']); if ($status === 'Failed' || $status === 'Unknown' || $status === '') { $cat = 'error'; $cls = 'table-danger'; } elseif ($status === 'Warning') { $cat = 'warning'; $cls = 'table-warning'; } elseif ($ageGood === null || $ageGood >= backup_tolerance_days()) { $cat = 'outdated'; $cls = 'table-info'; } else { $cat = 'ok'; $cls = 'table-success'; } $veeam[$key] = [ 'cat' => $cat, 'row_class' => $cls, 'ts' => strtotime((string) $row['LastRun']) ?: 0, 'vm' => $row['ClientName'], 'last_run' => fmt_datetime($row['LastRun']), 'status' => $status, 'last_good' => fmt_lastgood($row['LastSuccess']), 'size' => $row['SizeGB'], 'extra' => $row['Duration'], 'policy' => $row['PolicyName'], 'message' => $row['ErrorMessage'], ]; } /* ---------------------------------------------------------- 2. NetBackup */ $netbackup = []; $rows = Invoke_Infra("SELECT * FROM VMs_Backup WHERE (Owner LIKE 'DUN-VMH%' OR Owner LIKE 'MDK-VMH%') AND name NOT LIKE 'WS%' AND owner NOT LIKE '%WKG%' AND owner NOT LIKE '%VMH-WM%' ORDER BY name"); foreach ($rows as $row) { $key = strtoupper(trim($row['Name'])); $excluded = trim((string) $row['Exclusion']) !== ''; // Excluded VMs are listed even when no longer inventoried, like on the old page. if (!$excluded && !isset($active[$key])) continue; $result = trim((string) $row['LastResult']); $ageGood = days_since($row['LastKnownGood']); if ($excluded) { $cat = 'excluded'; $cls = 'table-secondary'; } elseif ($result !== 'OK') { // A failed job with a still fresh good copy is only a warning. if ($ageGood === null || $ageGood >= backup_tolerance_days()) { $cat = 'error'; $cls = 'table-danger'; } else { $cat = 'warning'; $cls = 'table-warning'; } } elseif ($ageGood === null || $ageGood >= backup_tolerance_days()) { $cat = 'outdated'; $cls = 'table-info'; } else { $cat = 'ok'; $cls = 'table-success'; } $netbackup[$key] = [ 'cat' => $cat, 'row_class' => $cls, 'excluded' => $excluded, 'ts' => strtotime(trim($row['LastBackup'] . ' ' . $row['TimeStamp'])) ?: 0, 'vm' => $row['Name'], 'last_run' => $excluded ? 'Tag NoBackup' : fmt_datetime($row['LastBackup'] . ' ' . $row['TimeStamp']), 'status' => $excluded ? 'Tag NoBackup' : ($result !== '' ? $result : 'Unknown'), 'last_good' => $excluded ? 'Tag NoBackup' : fmt_lastgood($row['LastKnownGood']), 'size' => $excluded ? '' : $row['LastSize'], 'extra' => $row['Owner'], 'policy' => $row['Policy'], 'message' => '', ]; } /* ------------------------------------------- 3. Migration de-duplication */ // A VM present on both sides is kept where the most recent backup lives. $migrated = 0; foreach (array_keys($netbackup) as $key) { if (!isset($veeam[$key])) continue; if ($netbackup[$key]['excluded'] || $veeam[$key]['ts'] >= $netbackup[$key]['ts']) { unset($netbackup[$key]); // Veeam has taken over $migrated++; } else { unset($veeam[$key]); // NetBackup is still the live copy } } /* -------------------------------------------------------- 4. Bucketing */ $buckets = [ 'veeam' => ['error' => [], 'warning' => [], 'outdated' => [], 'ok' => []], 'nb' => ['error' => [], 'warning' => [], 'outdated' => [], 'ok' => [], 'excluded' => []], ]; foreach ($veeam as $e) { $buckets['veeam'][$e['cat']][] = $e; } foreach ($netbackup as $e) { $buckets['nb'][$e['cat']][] = $e; } foreach ($buckets as $src => $cats) { foreach ($cats as $cat => $list) { usort($list, fn($a, $b) => strcasecmp($a['vm'], $b['vm'])); $buckets[$src][$cat] = $list; } } $veeamTotal = count($veeam); $nbTotal = count($netbackup); /* -------------------------------------------------------- 5. Rendering */ $blockMeta = [ 'error' => ['label' => 'Error', 'badge' => 'bg-danger', 'icon' => 'bi-x-octagon'], 'warning' => ['label' => 'Warning', 'badge' => 'bg-warning text-dark', 'icon' => 'bi-exclamation-triangle'], 'outdated' => ['label' => 'Outdated', 'badge' => 'bg-info text-dark', 'icon' => 'bi-clock-history'], 'ok' => ['label' => 'OK', 'badge' => 'bg-success', 'icon' => 'bi-check-circle'], 'excluded' => ['label' => 'Excluded', 'badge' => 'bg-secondary', 'icon' => 'bi-slash-circle'], ]; /** * Render one accordion item holding a bootstrap-table. * $extraLabel is "Duration" for Veeam and "Host" for NetBackup. */ function render_block($blockId, $meta, $rows, $extraLabel, $expanded = false) { $count = count($rows); $collapsed = $expanded ? '' : 'collapsed'; $show = $expanded ? 'show' : ''; $aria = $expanded ? 'true' : 'false'; ?>
>
Aucune VM dans cette catégorie.
(GB)
Message
VM Backup —
Veeam
/
NetBackup
—
Error
-
Warning
-
Outdated
VEEAM
VMs
NETBACKUP
VMs