From 2c279320ceff3d20f8c6faa3e30c6e8d3a475659 Mon Sep 17 00:00:00 2001 From: sva-e025532 Date: Wed, 3 Sep 2025 09:48:55 +0200 Subject: [PATCH] Add "Host" column to the inventory table in `/X/Inventory.php` and introduce VM issue metrics (Unclustered, Wrong Owner) in Hyper-V clusters report with refined query logic. --- Hyper-V/{clusters.php => Clusters.php} | 95 ++++++++++++++++---------- X/Inventory.php | 3 + 2 files changed, 63 insertions(+), 35 deletions(-) rename Hyper-V/{clusters.php => Clusters.php} (80%) diff --git a/Hyper-V/clusters.php b/Hyper-V/Clusters.php similarity index 80% rename from Hyper-V/clusters.php rename to Hyper-V/Clusters.php index bcc3a48..cb6d71e 100644 --- a/Hyper-V/clusters.php +++ b/Hyper-V/Clusters.php @@ -6,40 +6,29 @@ - Web Infra Reports - - - - - - -
+
- -
- -
- +
+
-

Hyper-V Clusters

@@ -48,7 +37,7 @@ // STEP 1: Fetch all required data with minimal database queries // ================================================================= - // Query 1: Get aggregated data for all clusters at once. + // Query 1: Get aggregated data for all clusters at once. (Unchanged) $cluster_query = " SELECT cluster, @@ -73,7 +62,7 @@ "; $all_clusters_data = Invoke_Infra($cluster_query); - // Query 2: Get VM distribution for all relevant clusters at once. + // Query 2: Get VM distribution for all relevant clusters at once. (Unchanged) $vm_repart_query = " SELECT v.Cluster, @@ -96,7 +85,6 @@ "; $raw_vm_distribution = Invoke_Infra($vm_repart_query); - // Process the VM distribution data into an easy-to-use associative array $vm_distribution = []; if (is_array($raw_vm_distribution)) { foreach ($raw_vm_distribution as $repart) { @@ -106,6 +94,37 @@ ]; } } + + // MODIFICATION : Requête finale sans la jointure pour éviter les doublons + $vm_issues_query = " + SELECT + v.Cluster, + SUM(CASE WHEN v.IsClustered = 'False' THEN 1 ELSE 0 END) as unclustered_count, + SUM(CASE WHEN v.IsClustered = 'True' AND v.Owner <> v.PreferredOwner THEN 1 ELSE 0 END) as wrong_owner_count + FROM + cmdb_vms v + WHERE + v.decomtime IS NULL + AND v.Cluster <> '' + AND v.Cluster NOT LIKE '%-WM%' + AND v.Cluster NOT LIKE '%-C1MAS%' + AND v.Cluster NOT LIKE '%-vrs%' + AND (v.Cluster LIKE 'DUN%' OR v.Cluster LIKE 'DMV%') + GROUP BY + v.Cluster + "; + $raw_vm_issues = Invoke_Infra($vm_issues_query); + + $vm_issues = []; + if (is_array($raw_vm_issues)) { + foreach ($raw_vm_issues as $issue) { + $vm_issues[$issue['Cluster']] = [ + 'unclustered' => $issue['unclustered_count'], + 'wrong_owner' => $issue['wrong_owner_count'] + ]; + } + } + // ================================================================= // STEP 2: Loop through the pre-fetched data and display it // ================================================================= @@ -136,17 +155,13 @@ $capacity_gb = 0; $free_gb = 0; if (!empty($cluster_data['all_csvs'])) { - // Explode the big string into an array of all CSV entries (with duplicates) $all_csv_entries = explode("|", $cluster_data['all_csvs']); - // Create a new array containing only the unique CSV entries $unique_csv_entries = array_unique($all_csv_entries); - // Loop through the UNIQUE entries to perform the calculation foreach ($unique_csv_entries as $csv_string) { if (str_contains($csv_string, ';')) { $parts = explode(";", $csv_string); if(count($parts) >= 3) { $capacity_gb += (int)$parts[1]; - // Free space is Total Capacity (parts[1]) - Used Space (parts[2]) $free_gb += (int)$parts[1] - (int)$parts[2]; } } @@ -155,10 +170,6 @@ $free_gb = max(0, $free_gb); $free_storage_percentage = ($capacity_gb > 0) ? round($free_gb / $capacity_gb * 100) : 0; - // IOPS Calculation - $avg_io = ($node_count > 0) ? round((float)$cluster_data['total_io_disk'] / $node_count * 1024) : 0; - $io_display = ($avg_io == 0) ? "?" : $avg_io; - // VMs Left Calculation $vms_left_by_mem = ($free_mem > 0) ? floor($free_mem / 16) : 0; $vms_left_by_storage = ($free_gb > 0) ? floor($free_gb / 110) : 0; @@ -168,7 +179,7 @@ // --- Display Logic --- if ($vms_left > 2) { $vleft_html = "(" . $vms_left . " VMs left)"; - } elseif ($vms_left >= 1) { // Handles 1 and 2 + } elseif ($vms_left >= 1) { $vleft_html = "(" . $vms_left . " VMs left)"; } else { $vleft_html = "(" . $vms_left . " VMs left)"; @@ -193,14 +204,12 @@ $owner1_count = $dist_data[0]['vm_count']; $owner2_name = isset($dist_data[1]) ? $dist_data[1]['owner'] : 'N/A'; $owner2_count = isset($dist_data[1]) ? $dist_data[1]['vm_count'] : 0; - $p1 = ($total_vms > 0) ? ($owner1_count / $total_vms) * 100 : 0; $p2 = ($total_vms > 0) ? ($owner2_count / $total_vms) * 100 : 0; - $vm_dist_html = "
-
$owner1_name
-
$owner2_name
-
"; +
$owner1_name
+
$owner2_name
+
"; } } echo $vm_dist_html; @@ -244,7 +253,25 @@
-
CSV I/O (24h):
KB/s
+ +
+ 0) { + echo "
Unclustered: $unclustered_count
"; + }else{ + echo "
Unclustered: $unclustered_count
"; + } + + if ($wrong_owner_count > 0) { + echo "
Wrong Owner: {$wrong_owner_count}
"; + }else{ + echo "
Wrong Owner: {$wrong_owner_count}
"; + } + ?> +
@@ -262,10 +289,8 @@ - - - + \ No newline at end of file diff --git a/X/Inventory.php b/X/Inventory.php index 2e572a1..df8a044 100644 --- a/X/Inventory.php +++ b/X/Inventory.php @@ -56,6 +56,7 @@ Name + Host OS Type Distrib Last reboot @@ -77,6 +78,8 @@ $name = $s['hostname']; echo "$name"; + //Host + echo "".$s['Owner'].""; //OS Type $typ = match ($s['type'] ?? null) { 'AIX' => 'AIX',