This commit is contained in:
e025532
2025-04-29 15:25:31 +02:00
parent 20e3d5a1b0
commit a2dddd8f57
9 changed files with 1498 additions and 374 deletions

View File

@@ -104,9 +104,49 @@
echo "</tr>"; echo "</tr>";
} }
// Backup OK // Outdated
$outdated = 0; $outdated = 0;
$answers = 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%' and Exclusion ='' and LastResult = 'OK' order by name"); $answers = 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%' and Exclusion ='' and LastResult = 'OK' and TRY_CAST(lastknowngood AS DATE) < CAST(DATEADD(DAY, -2, GETDATE()) AS DATE) order by name");
foreach ($answers as $row) {
$date1 = date_create($row['LastKnownGood']); $diff = date_diff($date1, date_create(date("Y-m-d")));
if(date('w') >= 2 && date('w') <= 6 ){
if ($diff->format("%R%a") >= 2){
echo "<tr class='table-warning'>";
}else{
echo "<tr class='table-success'>";
}
}else{
if((date('w') < 2 || date('w') == 7)){
if($diff->format("%R%a") <= 3){
echo "<tr class='table-success'>";
}else{
echo "<tr class='table-warning'>";
}
}
}
if($diff->format("%R%a") == "-0"){$LastGood = $row['LastKnownGood'];}else{$LastGood = $row['LastKnownGood']." (".$diff->format("%R%a")."J)";}
echo "<td><b>".$row['Name']."<b></td>";
echo "<td>".$row['LastBackup']." ".$row['TimeStamp']."</td>";
echo "<td>".$row['LastResult']."</td>";
if (date('w') >= 2 && date('w') <= 6 && $diff->format("%R%a") < 1){
echo "<td>".$LastGood."</td>";
}else{
if ((date('w') == 1 || date('w') == 7) && $diff->format("%R%a") <= 3){
echo "<td>".$LastGood."</td>";
}else{
echo "<td class='table-warning'>".$LastGood."</td>";
$outdated++;
}
}
echo "<td>".$row['LastSize']."</td>";
echo "<td>".$row['Owner']."</td>";
echo "<td>".$row['Policy']."</td>";
echo "</tr>";
}
// Backup OK
$answers = 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%' and Exclusion ='' and LastResult = 'OK' and TRY_CAST(lastknowngood AS DATE) >= CAST(DATEADD(DAY, -2, GETDATE()) AS DATE) order by name");
$total = count($answers); $total = count($answers);
foreach ($answers as $row) { foreach ($answers as $row) {
$date1 = date_create($row['LastKnownGood']); $diff = date_diff($date1, date_create(date("Y-m-d"))); $date1 = date_create($row['LastKnownGood']); $diff = date_diff($date1, date_create(date("Y-m-d")));

246
Hyper-V/VMs-Backups2.php Normal file
View File

@@ -0,0 +1,246 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Page Title -->
<title>Web Infra Reports IT</title>
<link rel="shortcut icon" type="image/png" href="/include/favicon-32x32.png">
<!-- JQuery -->
<script src="/js/jquery-3.6.1.min.js"></script>
<!-- Bootstrap -->
<link rel="stylesheet" href="/css/bootstrap.min.css">
<link rel="stylesheet" href="/css/bootstrap-icons/bootstrap-icons.css">
<link rel="stylesheet" href="/css/preloader.css">
<script src="/js/bootstrap.bundle.min.js"></script>
<!-- Bootstrap-tables -->
<link rel="stylesheet" href="/css/bootstrap-table.min.css">
<script src="/js/bootstrap-table.min.js"></script>
<script src="/js/bootstrap-table-fr-FR.min.js"></script>
<script src="/js/tableExport.min.js"></script>
<script src="/js/bootstrap-table-export.min.js"></script>
<script src="/js/libs/js-xlsx/xlsx.core.min.js"></script>
</head>
<body class="bg-light text-dark">
<?php include $_SERVER['DOCUMENT_ROOT'] . "/include/all.php"; ?> <!-- Include All -->
<?php // DATA
//$answers = Invoke_infra("SELECT * FROM VMs_Backup where Owner like 'DUN-VMH%' and name not like 'WS%' and owner not like '%WKG%' and Exclusion ='' and LastResult <> 'OK' order by lastresult,name");
//$answers += Invoke_infra("SELECT * FROM VMs_Backup where Owner like 'DUN-VMH%' and name not like 'WS%' and owner not like '%WKG%' and Exclusion <>'' order by name");
?>
<!-- HTML -->
<div class="container-fluid" id="content">
<div class="row flex-nowrap">
<!-- Left NAVBAR -->
<div class="col-auto col-md-2 col-xl-2 px-sm-2 px-0 bg-dark" style="-ms-flex: 0 0 230px;flex: 0 0 230px;">
<?php include $_SERVER['DOCUMENT_ROOT'] . "/navbar.html"; ?>
</div>
<!-- Display -->
<div class="col py-3">
<!-- Page Title -->
<h2><span class="badge text-bg-secondary " style="width:100%;" id="ERR"></span></h2>
<!-- Main content -->
<div class="container-fluid">
<!-- MODAL WAIT -->
<div class="modal fade bs-example-modal-sm" id="wait" tabindex="-1" role="dialog" aria-hidden="true" data-backdrop="static" style="padding-top: 15%;">
<div class="modal-dialog modal-sm">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title mb-1 text-dark text-uppercase">
<center><i class="bi bi-hourglass-split"></i><br> Work in progress ...</center>
</h4>
</div>
<div class="modal-body">
<div class="progress">
<div class="progress-bar progress-bar-secondary progress-bar-striped progress-bar-animated" style="width: 100%"></div>
</div>
</div>
</div>
</div>
</div>
<!-- TABLE -->
<div>
<table class='table table-bordered table-hover table-sm' id='t1' data-height="620" data-toggle="table" data-search="true" data-show-columns="true" data-export-types="['xlsx','csv','json']" data-show-export="true" data-sortable="true" data-sort-name="VM">
<thead> <!-- Header -->
<th data-field='vm' data-sortable='true'>VM</th>
<th data-field='Last Backup' data-sortable='true'>Last Backup</th>
<th data-field='Last Result' data-sortable='true'>Last Result</th>
<th data-field='Last Good' data-sortable='true'>Last Good Backup</th>
<th data-field='Size' data-sortable='true'>Size</th>
<th data-field='Host' data-sortable='true'>Host</th>
<th data-field='Policy' data-sortable='true' data-visible='false'>Policy</th>
</thead>
<tbody> <!-- Body -->
<?php
// NO Backup or Backup with Errors
$er = 0;
$answers = 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%' and Exclusion ='' and (LastResult <> 'OK' or lastresult is null) order by lastresult,name");
foreach ($answers as $row) {
$er++;
$date1 = date_create($row['LastKnownGood']); $diff = date_diff($date1, date_create(date("Y-m-d")));
if ($diff->format("%R%a") >= 2 || $row['LastKnownGood'] == ''){
echo "<tr class='table-danger'>";
}else{
echo "<tr class='table-warning'>";
}
if($diff->format("%R%a") == "-0"){$LastGood = "NEVER";}else{$LastGood = $row['LastKnownGood']." (".$diff->format("%R%a")."J)";}
echo "<td><b>".$row['Name']."<b></td>";
echo "<td>".$row['LastBackup']." ".$row['TimeStamp']."</td>";
echo "<td>".$row['LastResult']."</td>";
echo "<td>".$LastGood."</td>";
echo "<td>".$row['LastSize']."</td>";
echo "<td>".$row['Owner']."</td>";
echo "<td>".$row['Policy']."</td>";
echo "</tr>";
}
// Outdated
$outdated = 0;
$answers = 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%' and Exclusion ='' and LastResult = 'OK' and TRY_CAST(lastknowngood AS DATE) < CAST(DATEADD(DAY, -2, GETDATE()) AS DATE) order by name");
foreach ($answers as $row) {
$date1 = date_create($row['LastKnownGood']); $diff = date_diff($date1, date_create(date("Y-m-d")));
if(date('w') >= 2 && date('w') <= 6 ){
if ($diff->format("%R%a") >= 2){
echo "<tr class='table-warning'>";
}else{
echo "<tr class='table-success'>";
}
}else{
if((date('w') < 2 || date('w') == 7)){
if($diff->format("%R%a") <= 3){
echo "<tr class='table-success'>";
}else{
echo "<tr class='table-warning'>";
}
}
}
if($diff->format("%R%a") == "-0"){$LastGood = $row['LastKnownGood'];}else{$LastGood = $row['LastKnownGood']." (".$diff->format("%R%a")."J)";}
echo "<td><b>".$row['Name']."<b></td>";
echo "<td>".$row['LastBackup']." ".$row['TimeStamp']."</td>";
echo "<td>".$row['LastResult']."</td>";
if (date('w') >= 2 && date('w') <= 6 && $diff->format("%R%a") < 1){
echo "<td>".$LastGood."</td>";
}else{
if ((date('w') == 1 || date('w') == 7) && $diff->format("%R%a") <= 3){
echo "<td>".$LastGood."</td>";
}else{
echo "<td class='table-warning'>".$LastGood."</td>";
$outdated++;
}
}
echo "<td>".$row['LastSize']."</td>";
echo "<td>".$row['Owner']."</td>";
echo "<td>".$row['Policy']."</td>";
echo "</tr>";
}
// Backup OK
$answers = 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%' and Exclusion ='' and LastResult = 'OK' and TRY_CAST(lastknowngood AS DATE) >= CAST(DATEADD(DAY, -2, GETDATE()) AS DATE) order by name");
$total = count($answers);
foreach ($answers as $row) {
$date1 = date_create($row['LastKnownGood']); $diff = date_diff($date1, date_create(date("Y-m-d")));
if(date('w') >= 2 && date('w') <= 6 ){
if ($diff->format("%R%a") >= 2){
echo "<tr class='table-warning'>";
}else{
echo "<tr class='table-success'>";
}
}else{
if((date('w') < 2 || date('w') == 7)){
if($diff->format("%R%a") <= 3){
echo "<tr class='table-success'>";
}else{
echo "<tr class='table-warning'>";
}
}
}
if($diff->format("%R%a") == "-0"){$LastGood = $row['LastKnownGood'];}else{$LastGood = $row['LastKnownGood']." (".$diff->format("%R%a")."J)";}
echo "<td><b>".$row['Name']."<b></td>";
echo "<td>".$row['LastBackup']." ".$row['TimeStamp']."</td>";
echo "<td>".$row['LastResult']."</td>";
if (date('w') >= 2 && date('w') <= 6 && $diff->format("%R%a") < 1){
echo "<td>".$LastGood."</td>";
}else{
if ((date('w') == 1 || date('w') == 7) && $diff->format("%R%a") <= 3){
echo "<td>".$LastGood."</td>";
}else{
echo "<td class='table-warning'>".$LastGood."</td>";
$outdated++;
}
}
echo "<td>".$row['LastSize']."</td>";
echo "<td>".$row['Owner']."</td>";
echo "<td>".$row['Policy']."</td>";
echo "</tr>";
}
// Backup OK
$excluded = 0;
$answers = 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%' and Exclusion <> '' order by name");
foreach ($answers as $row) {
$excluded++;
echo "<tr class='table-secondary'>";
echo "<td><b>".$row['Name']."<b></td>";
echo "<td>Tag NoBackup</td>";
echo "<td>Tag NoBackup</td>";
echo "<td>Tag NoBackup</td>";
echo "<td>Tag NoBackup</td>";
echo "<td>".$row['Owner']."</td>";
echo "<td>".$row['Policy']."</td>";
echo "</tr>";
}
?>
</tbody>
</table>
<br>
</div>
</div>
<!-- End of main content -->
</div>
</div>
</div>
<?php
$success = $total - $er - $outdated -$excluded ;
$ERR = "VMs backups (<span class='text-light'>".$total." Success</span> - <span class='text-danger'>".$er." issues</span> - <span class='text-warning'>".$outdated." outdated </span>- <span class='text-info'>".$excluded.' excluded</span>)';
?>
</body>
<script src="/js/switch.js"></script>
</HTML>
<SCRIPT>
$(document).ready(function() {
$('#t1').DataTable({
scrollY: '50vh',
scrollCollapse: true,
paging: false,
});
});
$(function () {
var options = $('#t1').bootstrapTable('getOptions');
options.height= document.getElementById('content').clientHeight-170;
$('#t1').bootstrapTable('refreshOptions',options);
});
function tableresize() {
var options = $('#t1').bootstrapTable('getOptions');
options.height= document.getElementById('content').clientHeight-170;
$('#t1').bootstrapTable('refreshOptions',options);
};
window.addEventListener("resize", tableresize);
document.getElementById("ERR").innerHTML = "<?php echo $ERR ; ?>";
</script>

View File

@@ -97,9 +97,10 @@
echo "</div>"; echo "</div>";
echo "<div class='col'>"; echo "<div class='col'>";
echo " echo "
<div class='progress' style='border: 1px solid grey; height: 25px;'> <div class='progress' style='position: relative; border: 1px solid grey; height: 25px;'>
<div class='progress-bar bg-dark progress-bar-striped' role='progressbar' style='width: $pcent_restant%;' aria-valuenow='$pcent_restant' aria-valuemin='0' aria-valuemax='100'></div> <div class='progress-bar bg-dark progress-bar-striped' role='progressbar' style='width:". $pcent_restant ."%;' aria-valuenow='".$pcent_restant."' aria-valuemin='0' aria-valuemax='100'></div>
<div class='progress-bar $color' role='progressbar' style='width: $pcent%;' aria-valuenow='$pcent' aria-valuemin='0' aria-valuemax='100'></div> <div class='progress-bar ".$color."' role='progressbar' style='width: ".$pcent."%;' aria-valuenow='".$pcent."' aria-valuemin='0' aria-valuemax='100'></div>
<div style='position: absolute; left: 50%; transform: translateX(-50%); top: -2px; height: 33px; width: 2px; background-color: orange;'></div>
</div>"; </div>";
echo "</div>"; echo "</div>";
echo "</div>" ; echo "</div>" ;

View File

@@ -161,7 +161,7 @@
</div> </div>
</div> </div>
</div> </div>
<script src="fillchart.js"></script> <script src="fillchart2.js"></script>
</div> </div>
<!-- Drives --> <!-- Drives -->

139
Inventory/fillchart2.js Normal file
View File

@@ -0,0 +1,139 @@
let typ = document.getElementById("type").dataset.value;
let computer = document.getElementById("computer").dataset.value;
async function fetchAndDisplayData() {
try {
const response = await fetch(`z_data_${typ}.php?c=${computer}`);
const jsonData = await response.json();
const data = jsonData.data || jsonData; // Utilisation plus robuste
const cpuKey = Object.keys(data).find(key => key.includes('CPU'));
const ramKey = Object.keys(data).find(key => key.includes('Memory'));
// Utilisation d'un Set pour collecter les labels uniques plus efficacement
const uniqueLabels = new Set();
if (cpuKey && data[cpuKey]) {
data[cpuKey].forEach(point => uniqueLabels.add(point.datetime));
}
if (ramKey && data[ramKey]) {
data[ramKey].forEach(point => uniqueLabels.add(point.datetime));
}
const labels = Array.from(uniqueLabels).sort(); // Conversion en Array et tri
// Fonction pour créer une map de données
const createDataMap = (key, rawData) => {
const map = {};
if (key && rawData[key]) {
rawData[key].forEach(point => {
map[point.datetime] = parseFloat(point.avg_value);
});
}
return map;
};
const cpuDataMap = createDataMap(cpuKey, data);
const ramDataMap = createDataMap(ramKey, data);
// Fonction pour générer les données du graphique
const getChartData = (map, sortedLabels) => sortedLabels.map(label => map[label] ?? null);
const cpuChartData = getChartData(cpuDataMap, labels);
const ramChartData = getChartData(ramDataMap, labels);
// Formatage des labels pour l'axe X
const formattedLabels = labels.map(label => {
const date = new Date(label);
return !isNaN(date)
? date.toLocaleTimeString('fr-FR', { hour: '2-digit', minute: '2-digit' })
: 'Invalid Date';
});
// *** Fonction pour créer un graphique (adaptée pour v2.x) ***
const createChartV2 = (canvasId, label, chartData, formattedLabels) => {
const ctx = document.getElementById(canvasId)?.getContext('2d');
if (!ctx) {
console.error(`Canvas element with id "${canvasId}" not found.`);
return null;
}
return new Chart(ctx, {
type: 'line',
data: {
labels: formattedLabels,
datasets: [{
label: label, // Garde le label pour l'infobulle
data: chartData,
borderColor: 'rgb(54, 162, 235)',
backgroundColor: 'rgba(54, 162, 235, 0.1)',
fill: true,
tension: 0.3,
pointRadius: 0
}]
},
options: {
legend: {
display: false // Cacher la légende en v2
},
responsive: true,
maintainAspectRatio: false,
scales: {
yAxes: [{ // *** Utilisation de yAxes (tableau) pour v2.x ***
ticks: {
beginAtZero: true,
// Ajout de la fonction callback pour formater les labels de l'axe Y
callback: function(value, index, values) { // Note: le 3ème argument est 'values' en v2
return value + '%'; // Ajoute le symbole %
}
// max: 100, // Optionnel mais recommandé pour les pourcentages
// stepSize: 5 // Optionnel: pour suggérer un intervalle
}
// scaleLabel: { // Si vous vouliez un titre d'axe en v2 (ce que vous ne voulez pas)
// display: false,
// labelString: 'Utilisation (%)'
// }
}],
xAxes: [{ // *** xAxes doit aussi être dans un tableau en v2.x ***
// ... autres options pour l'axe X si nécessaire ...
}]
},
tooltips: { // *** 'tooltips' au pluriel en v2.x ***
callbacks: {
label: function(tooltipItem, data) { // Arguments différents en v2
let label = data.datasets[tooltipItem.datasetIndex].label || '';
if (label) {
label += ': ';
}
// tooltipItem.yLabel contient la valeur numérique en v2
if (tooltipItem.yLabel !== null && typeof tooltipItem.yLabel !== 'undefined') {
label += tooltipItem.yLabel + '%';
}
return label;
}
}
}
}
});
};
// Création des graphiques en utilisant la fonction adaptée pour v2.x
if (cpuKey && data[cpuKey]?.length > 0) {
createChartV2('cpuChart', 'CPU (%)', cpuChartData, formattedLabels);
} else {
const cpuChartElement = document.getElementById('cpuChart');
if (cpuChartElement) cpuChartElement.style.display = 'none';
console.log("Pas de données CPU à afficher.");
}
if (ramKey && data[ramKey]?.length > 0) {
createChartV2('ramChart', 'Memory (%)', ramChartData, formattedLabels);
} else {
const ramChartElement = document.getElementById('ramChart');
if (ramChartElement) ramChartElement.style.display = 'none';
console.log("Pas de données RAM à afficher.");
}
} catch (error) {
console.error('Erreur lors de la récupération ou de l\'affichage des données:', error);
}
}
window.addEventListener('load', fetchAndDisplayData);

194
Storage/D.php Normal file
View File

@@ -0,0 +1,194 @@
<?php
include $_SERVER['DOCUMENT_ROOT']."/include/all.php";
$json = json_decode(PostJson("$bdnuss/Storage/SVC/SVC_INVENTORY.php",''),true);
$poolsData = $json['Data']['Pools'];
function formatBytes($bytes, $precision = 2) {
if ($bytes == 0) return '0 octets';
$base = 1024;
$size = $bytes / pow($base, 4);
return round($size, $precision) . ' Tio';
}
$seriesData = [
'V5100' => [
'physical_used' => 0, 'physical_free' => 0, 'physical_total_api' => 0,
'virtual_total' => 0, 'written_total' => 0, 'compressed_total' => 0,
'dedup_savings' => 0
],
'V5030' => [
'physical_used' => 0, 'physical_free' => 0, 'physical_total_api' => 0,
'virtual_total' => 0, 'written_total' => 0, 'compressed_total' => 0,
'dedup_savings' => 0
],
];
foreach ($poolsData as $poolName => $poolDetails) {
$currentSeries = null;
if (strpos($poolName, 'V5100') !== false) {
$currentSeries = 'V5100';
} elseif (strpos($poolName, 'V5030') !== false) {
$currentSeries = 'V5030';
}
if ($currentSeries) {
$used_capacity = (float) $poolDetails['used_capacity'];
$free_capacity = (float) $poolDetails['free_capacity'];
$capacity = (float) $poolDetails['capacity'];
$virtual_cap = (float) $poolDetails['virtual_capacity'];
$uncomp_cap = (float) $poolDetails['compression_uncompressed_capacity'];
$comp_cap = (float) $poolDetails['compression_compressed_capacity'];
$dedup_sav = (float) $poolDetails['deduplication_capacity_saving'];
$seriesData[$currentSeries]['physical_used'] += $used_capacity;
$seriesData[$currentSeries]['physical_free'] += $free_capacity;
$seriesData[$currentSeries]['physical_total_api'] += $capacity;
$seriesData[$currentSeries]['virtual_total'] += $virtual_cap;
$seriesData[$currentSeries]['written_total'] += $uncomp_cap;
$seriesData[$currentSeries]['compressed_total'] += $comp_cap;
$seriesData[$currentSeries]['dedup_savings'] += $dedup_sav;
}
}
foreach ($seriesData as $series => &$data) {
$data['physical_total_calc'] = ($data['physical_used'] + ($data['physical_free'] /2));
$data['physical_used_percent'] = ($data['physical_total_calc'] > 0) ? ($data['physical_used'] / $data['physical_total_calc']) * 100 : 0;
$data['physical_free_percent'] = 100 - $data['physical_used_percent'];
$data['volume_written_percent'] = ($data['virtual_total'] > 0) ? ($data['written_total'] / $data['virtual_total']) * 100 : 0;
$data['compression_savings'] = $data['written_total'] - $data['compressed_total'];
$data['thin_savings'] = $data['virtual_total'] - $data['written_total'];
$data['total_savings'] = $data['compression_savings'] + $data['dedup_savings'] + $data['thin_savings'];
$data['compression_ratio'] = ($data['compressed_total'] > 0) ? ($data['written_total'] / $data['compressed_total']) : 0;
$data['compression_savings_percent'] = ($data['written_total'] > 0) ? ($data['compression_savings'] / $data['written_total']) * 100 : 0;
$data['dedup_savings_percent'] = ($data['written_total'] > 0) ? ($data['dedup_savings'] / $data['written_total']) * 100 : 0;
$data['thin_savings_percent'] = ($data['virtual_total'] > 0) ? ($data['thin_savings'] / $data['virtual_total']) * 100 : 0;
$data['total_savings_percent'] = ($data['virtual_total'] > 0) ? ($data['total_savings'] / $data['virtual_total']) * 100 : 0;
}
unset($data);
?>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Dashboard Capacité SVC</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
<style>
.capacity-block .value {
font-size: 1.8rem;
font-weight: bold;
}
.capacity-block .percent {
font-size: 1rem;
font-weight: bold;
color: #555;
}
.capacity-block .label {
font-size: 0.9rem;
color: #6c757d; /* text-muted */
}
.capacity-block .sub-value {
font-size: 1.1rem;
font-weight: normal;
display: block; /* Pour mettre les valeurs de gains les unes sous les autres */
margin-bottom: 0.3rem;
}
.card-body {
min-height: 150px; /* Hauteur minimale pour aligner les cartes */
display: flex;
flex-direction: column;
justify-content: space-between;
}
.gain-item {
display: flex;
justify-content: space-between;
margin-bottom: 5px;
font-size: 0.9rem;
}
.gain-item span:last-child {
font-weight: bold;
}
</style>
</head>
<body>
<div class="container mt-4">
<h1>Synthèse Capacité IBM Spectrum Virtualize</h1>
<hr>
<?php foreach ($seriesData as $series => $data): ?>
<h2 class="mt-5">Statistiques Baies <?= $series ?></h2>
<div class="row g-4">
<div class="col-lg-4">
<div class="card h-100">
<div class="card-body capacity-block">
<div>
<h5 class="card-title">Capacité physique</h5>
<div class="d-flex justify-content-between align-items-start mb-2">
<div>
<span class="percent"><?= number_format($data['physical_used_percent'], 0) ?>%</span>
<div class="value"><?= formatBytes($data['physical_used']) ?></div>
</div>
<div class="text-end">
<span class="percent"><?= number_format($data['physical_free_percent'], 0) ?>%</span>
<div class="value"><?= formatBytes($data['physical_free']/2) ?></div>
</div>
</div>
<div class="progress" style="height: 20px;">
<div class="progress-bar" role="progressbar" style="width: <?= $data['physical_used_percent'] ?>%;" aria-valuenow="<?= $data['physical_used_percent'] ?>" aria-valuemin="0" aria-valuemax="100"></div>
</div>
</div>
</div>
</div>
</div>
<div class="col-lg-4">
<div class="card h-100">
<div class="card-body capacity-block">
<div>
<h5 class="card-title">Capacité de volume</h5>
<div class="d-flex justify-content-between align-items-start mb-2">
<div>
<span class="percent"><?= number_format($data['volume_written_percent'], 0) ?>%</span>
<div class="value"><?= formatBytes($data['written_total']) ?></div>
</div>
</div>
<div class="progress" style="height: 20px;">
<div class="progress-bar" role="progressbar" style="width: <?= $data['volume_written_percent'] ?>%;" aria-valuenow="<?= $data['volume_written_percent'] ?>" aria-valuemin="0" aria-valuemax="100"></div>
</div>
</div>
</div>
</div>
</div>
<div class="col-lg-4">
<div class="card ">
<div class="card-body capacity-block">
<div>
<h5 class="card-title">Gains de capacité</h5>
<div class="gain-item">
<span><?= number_format($data['compression_savings_percent'], 0) ?>% Compression</span>
<span><?= formatBytes($data['compression_savings']) ?></span>
</div>
<div class="gain-item">
<span><?= number_format($data['thin_savings_percent'], 0) ?>% Allocation dynamique</span>
<span><?= formatBytes($data['thin_savings']) ?></span>
</div>
<hr>
<div class="gain-item">
<span>Taux compression</span>
<span><?= number_format($data['compression_ratio'], 1) ?>:1</span>
</div>
</div>
</div>
</div>
</div>
</div> <?php endforeach; ?>
</div> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
</body>
</html>

View File

@@ -1,5 +1,86 @@
<?php
include $_SERVER['DOCUMENT_ROOT'] . "/include/all.php";
$json = json_decode(PostJson("$bdnuss/Storage/SVC/SVC_INVENTORY.php", ''), true);
$poolsData = $json['Data']['Pools'];
function formatBytes($bytes, $precision = 2)
{
if ($bytes == 0)
return '0 octets';
$base = 1024;
$size = $bytes / pow($base, 4);
return round($size, $precision) . ' Tio';
}
$seriesData = [
'V5100' => [
'physical_used' => 0,
'physical_free' => 0,
'physical_total_api' => 0,
'virtual_total' => 0,
'written_total' => 0,
'compressed_total' => 0,
'dedup_savings' => 0
],
'V5030' => [
'physical_used' => 0,
'physical_free' => 0,
'physical_total_api' => 0,
'virtual_total' => 0,
'written_total' => 0,
'compressed_total' => 0,
'dedup_savings' => 0
],
];
foreach ($poolsData as $poolName => $poolDetails) {
$currentSeries = null;
if (strpos($poolName, 'V5100') !== false) {
$currentSeries = 'V5100';
} elseif (strpos($poolName, 'V5030') !== false) {
$currentSeries = 'V5030';
}
if ($currentSeries) {
$used_capacity = (float) $poolDetails['used_capacity'];
$free_capacity = (float) $poolDetails['free_capacity'];
$capacity = (float) $poolDetails['capacity'];
$virtual_cap = (float) $poolDetails['virtual_capacity'];
$uncomp_cap = (float) $poolDetails['compression_uncompressed_capacity'];
$comp_cap = (float) $poolDetails['compression_compressed_capacity'];
$dedup_sav = (float) $poolDetails['deduplication_capacity_saving'];
$seriesData[$currentSeries]['physical_used'] += $used_capacity;
$seriesData[$currentSeries]['physical_free'] += $free_capacity;
$seriesData[$currentSeries]['physical_total_api'] += $capacity;
$seriesData[$currentSeries]['virtual_total'] += $virtual_cap;
$seriesData[$currentSeries]['written_total'] += $uncomp_cap;
$seriesData[$currentSeries]['compressed_total'] += $comp_cap;
$seriesData[$currentSeries]['dedup_savings'] += $dedup_sav;
}
}
foreach ($seriesData as $series => &$data) {
$data['physical_total_calc'] = ($data['physical_used'] + ($data['physical_free'] / 2));
$data['physical_used_percent'] = ($data['physical_total_calc'] > 0) ? ($data['physical_used'] / $data['physical_total_calc']) * 100 : 0;
$data['physical_free_percent'] = 100 - $data['physical_used_percent'];
$data['volume_written_percent'] = ($data['virtual_total'] > 0) ? ($data['written_total'] / $data['virtual_total']) * 100 : 0;
$data['compression_savings'] = $data['written_total'] - $data['compressed_total'];
$data['thin_savings'] = $data['virtual_total'] - $data['written_total'];
$data['total_savings'] = $data['compression_savings'] + $data['dedup_savings'] + $data['thin_savings'];
$data['compression_ratio'] = ($data['compressed_total'] > 0) ? ($data['written_total'] / $data['compressed_total']) : 0;
$data['compression_savings_percent'] = ($data['written_total'] > 0) ? ($data['compression_savings'] / $data['written_total']) * 100 : 0;
$data['dedup_savings_percent'] = ($data['written_total'] > 0) ? ($data['dedup_savings'] / $data['written_total']) * 100 : 0;
$data['thin_savings_percent'] = ($data['virtual_total'] > 0) ? ($data['thin_savings'] / $data['virtual_total']) * 100 : 0;
$data['total_savings_percent'] = ($data['virtual_total'] > 0) ? ($data['total_savings'] / $data['virtual_total']) * 100 : 0;
}
unset($data);
?>
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
@@ -22,10 +103,47 @@
<!-- Chart --> <!-- Chart -->
<script src="/js/chart.min.js"></script> <script src="/js/chart.min.js"></script>
<style>
.capacity-block .value {
font-size: 1.8rem;
font-weight: bold;
}
.capacity-block .percent {
font-size: 1rem;
font-weight: bold;
color: #555;
}
.capacity-block .label {
font-size: 0.9rem;
color: #6c757d;
/* text-muted */
}
.capacity-block .sub-value {
font-size: 1.1rem;
font-weight: normal;
display: block;
margin-bottom: 0.3rem;
}
.gain-item {
display: flex;
justify-content: space-between;
margin-bottom: 5px;
font-size: 0.9rem;
}
.gain-item span:last-child {
font-weight: bold;
}
</style>
</head> </head>
<body class="bg-light text-dark"> <body class="bg-light text-dark">
<?php include $_SERVER['DOCUMENT_ROOT']."/include/all.php" ; ?>
<div class="container-fluid"> <div class="container-fluid">
<div class="row flex-nowrap"> <div class="row flex-nowrap">
<!-- Left NAVBAR --> <!-- Left NAVBAR -->
@@ -48,7 +166,8 @@
$json = json_decode(PostJson("$bdnuss/Storage/SVC/SVC_INVENTORY.php", ''), true); $json = json_decode(PostJson("$bdnuss/Storage/SVC/SVC_INVENTORY.php", ''), true);
// Sum LUN Size by Bay // Sum LUN Size by Bay
$lunsGold = 0 ; $lunsSilver = 0 ; $lunsGold = 0;
$lunsSilver = 0;
try { try {
foreach ($json['Data']['VolumeCopies'] as $data) { foreach ($json['Data']['VolumeCopies'] as $data) {
if (strpos($data['mdisk_grp_name'], "5100") !== false) { if (strpos($data['mdisk_grp_name'], "5100") !== false) {
@@ -57,10 +176,14 @@
$lunsSilver += $data['capacity']; $lunsSilver += $data['capacity'];
} }
} }
}catch(Exception $e){} } catch (Exception $e) {
}
// Get Full Capacity // Get Full Capacity
$goldCapacity = 0 ; $silverCapacity = 0 ; $GoldCompression = 0;$SilverCompression = 0; $goldCapacity = 0;
$silverCapacity = 0;
$GoldCompression = 0;
$SilverCompression = 0;
foreach ($json['Data']['Pools'] as $data) { foreach ($json['Data']['Pools'] as $data) {
if (strpos($data['name'], "5100") !== false) { if (strpos($data['name'], "5100") !== false) {
$goldCapacity += $data['capacity']; $goldCapacity += $data['capacity'];
@@ -90,7 +213,11 @@
$cuc = "bg-success"; $cuc = "bg-success";
$lLUN = ""; $lLUN = "";
foreach ($json['Data']['Volumes'] as $volume) { foreach ($json['Data']['Volumes'] as $volume) {
if($volume['protocol'] != "scsi"){$unnasigned++;$cuc = "bg-warning";$lLUN .= $volume['name']."<br>";} if ($volume['protocol'] != "scsi") {
$unnasigned++;
$cuc = "bg-warning";
$lLUN .= $volume['name'] . "<br>";
}
} }
// Orphan Hosts // Orphan Hosts
@@ -98,11 +225,19 @@
$chc = "bg-success"; $chc = "bg-success";
$lHOST = ""; $lHOST = "";
foreach ($json['Data']['Hosts'] as $host) { foreach ($json['Data']['Hosts'] as $host) {
if($host['protocol'] != "scsi"){$orphanHosts++;$chc = "bg-warning";$lHOST .= $host['name']."<br>";} if ($host['protocol'] != "scsi") {
$orphanHosts++;
$chc = "bg-warning";
$lHOST .= $host['name'] . "<br>";
}
} }
if ($json['Data']['Hostclusters']) { if ($json['Data']['Hostclusters']) {
foreach ($json['Data']['Hostclusters'] as $host) { foreach ($json['Data']['Hostclusters'] as $host) {
if($host['protocol'] != "scsi"){$orphanHosts++;$chc = "bg-warning";$lHOST .= $host['name']."<br>";} if ($host['protocol'] != "scsi") {
$orphanHosts++;
$chc = "bg-warning";
$lHOST .= $host['name'] . "<br>";
}
} }
} }
?> ?>
@@ -115,35 +250,80 @@
<i class="fs-4 bi-server text-black"></i><b> Gold (V5100)</b> <i class="fs-4 bi-server text-black"></i><b> Gold (V5100)</b>
</div> </div>
<div class="card-body bg-dark fs-4"> <div class="card-body bg-dark fs-4">
<div class="row"> <div class="row g-4">
<div class="col"> <?php $data = $seriesData['V5100']; ?>
<b>Total Capacity : </b><?php echo round($goldCapacity / $TB,2); ?> TB <div class="col-lg-4">
<div class="card h-100" style="border: none">
<div class="card-body capacity-block bg-dark">
<div>
<h5 class="card-title">Physical Capacity</h5>
<div class="d-flex justify-content-between align-items-start mb-2">
<div>
<span class="percent"><?= number_format($data['physical_used_percent'], 0) ?>%</span>
<div class="value"><?= formatBytes($data['physical_used']) ?></div>
</div> </div>
<div class="col"> <div class="text-end">
<b>Used (raw) : </b><?php echo round($lunsGold / $TB,2); ?> TB (<?php echo $goldPercentUsed ;?>% ) <span class="percent"><?= number_format($data['physical_free_percent'], 0) ?>%</span>
</div> <div class="value"><?= formatBytes($data['physical_free'] / 2) ?></div>
<div class="col">
<b>Free (raw) : </b><?php echo round($GoldFree / $TB,2); ?> TB
</div> </div>
</div> </div>
<div class="row"> <div class="progress" style="height:30px;">
<div class="col"></div> <div class="progress-bar" role="progressbar"
<div class="col"> style="width: <?= $data['physical_used_percent'] ?>%;"
<b>Compression : </b><?php echo number_format($GoldCompression, 2, ',', '') ; ?>:1 aria-valuenow="<?= $data['physical_used_percent'] ?>" aria-valuemin="0" aria-valuemax="100">
</div>
<div class="col">
<b>Free (estimated) : </b><?php echo round($GoldFree * $GoldCompression / $TB,2) ; ?> TB
</div> </div>
</div> </div>
<br> </div>
<div class="progress border border-light" style="height: 40px;"> </div>
<?php </div>
$pbc = "bg-success"; </div>
if($goldPercentUsed >= 75){$pbc = "bg-warning";}
if($goldPercentUsed >= 90){$pbc = "bg-danger";} <div class="col-lg-4">
?> <div class="card h-100" style="border: none">
<div class="progress-bar <?php echo $pbc; ?>" role="progressbar" style="width: <?php echo $goldPercentUsed ;?>%;" aria-valuenow="<?php echo $goldPercentUsed ;?>" aria-valuemin="0" aria-valuemax="100"></div> <div class="card-body capacity-block bg-dark">
<div class="progress-bar bg-black bg-gradient" role="progressbar" style="width: <?php echo 100 - $goldPercentUsed ;?>%;" aria-valuenow="<?php echo 100 - $goldPercentUsed ;?>" aria-valuemin="0" aria-valuemax="100"></div> <div>
<h5 class="card-title">Volume Capacity</h5>
<div class="d-flex justify-content-between align-items-start mb-2">
<div>
<span class="percent"><?= number_format($data['volume_written_percent'], 0) ?>%</span>
<div class="value"><?= formatBytes($data['written_total']) ?></div>
</div>
</div>
<div class="progress" style="height: 30px;">
<div class="progress-bar" role="progressbar"
style="width: <?= $data['volume_written_percent'] ?>%;"
aria-valuenow="<?= $data['volume_written_percent'] ?>" aria-valuemin="0" aria-valuemax="100">
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-lg-4">
<div class="card h-100" style="border: none">
<div class="card-body capacity-block bg-dark">
<div>
<h5 class="card-title">Capacity gain</h5>
<div class="gain-item">
<span><?= number_format($data['compression_savings_percent'], 0) ?>% Compression</span>
<span><?= formatBytes($data['compression_savings']) ?></span>
</div>
<div class="gain-item">
<span><?= number_format($data['thin_savings_percent'], 0) ?>% Thin provisioning</span>
<span><?= formatBytes($data['thin_savings']) ?></span>
</div>
<hr>
<div class="gain-item">
<span>Compression</span>
<span><?= number_format($data['compression_ratio'], 1) ?>:1</span>
</div>
</div>
</div>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
@@ -154,38 +334,84 @@
<i class="fs-4 bi-server text-black"></i><b> Silver (V5030)</b> <i class="fs-4 bi-server text-black"></i><b> Silver (V5030)</b>
</div> </div>
<div class="card-body bg-dark fs-4"> <div class="card-body bg-dark fs-4">
<div class="row"> <div class="row g-4">
<div class="col"> <?php $data = $seriesData['V5030']; ?>
<b>Total Capacity : </b><?php echo round($silverCapacity / $TB,2); ?> TB <div class="col-lg-4">
<div class="card h-100" style="border: none">
<div class="card-body capacity-block bg-dark">
<div>
<h5 class="card-title">Physical Capacity</h5>
<div class="d-flex justify-content-between align-items-start mb-2">
<div>
<span class="percent"><?= number_format($data['physical_used_percent'], 0) ?>%</span>
<div class="value"><?= formatBytes($data['physical_used']) ?></div>
</div> </div>
<div class="col"> <div class="text-end">
<b>Used (raw) : </b><?php echo round($lunsSilver / $TB,2); ?> TB (<?php echo $silverPercentUsed ;?>% ) <span class="percent"><?= number_format($data['physical_free_percent'], 0) ?>%</span>
</div> <div class="value"><?= formatBytes($data['physical_free'] / 2) ?></div>
<div class="col">
<b>Free (raw) : </b><?php echo round($SilverFree / $TB,2); ?> TB
</div> </div>
</div> </div>
<div class="row"> <div class="progress" style="height: 30px;">
<div class="col"></div> <div class="progress-bar" role="progressbar"
<div class="col"> style="width: <?= $data['physical_used_percent'] ?>%;"
<b>Compression : </b><?php echo number_format($SilverCompression, 2, ',', ''); ?>:1 aria-valuenow="<?= $data['physical_used_percent'] ?>" aria-valuemin="0" aria-valuemax="100">
</div>
<div class="col">
<b>Free (estimated) : </b><?php echo round($SilverFree * $SilverCompression / $TB,2) ; ?> TB
</div>
</div>
<br>
<div class="progress border border-light" style="height: 40px;">
<?php
$pbc = "bg-success";
if($silverPercentUsed >= 75){$pbc = "bg-warning";}
if($silverPercentUsed >= 90){$pbc = "bg-danger";}
?>
<div class="progress-bar <?php echo $pbc; ?>" role="progressbar" style="width: <?php echo $silverPercentUsed ;?>%;" aria-valuenow="<?php echo $silverPercentUsed ;?>" aria-valuemin="0" aria-valuemax="100"></div>
<div class="progress-bar bg-black bg-gradient" role="progressbar" style="width: <?php echo 100 - $silverPercentUsed ;?>%;" aria-valuenow="<?php echo 100 - $silverPercentUsed ;?>" aria-valuemin="0" aria-valuemax="100"></div>
</div> </div>
</div> </div>
</div> </div>
</div>
</div>
</div>
<div class="col-lg-4">
<div class="card h-100" style="border: none">
<div class="card-body capacity-block bg-dark">
<div>
<h5 class="card-title">Volume Capacity</h5>
<div class="d-flex justify-content-between align-items-start mb-2">
<div>
<span class="percent"><?= number_format($data['volume_written_percent'], 0) ?>%</span>
<div class="value"><?= formatBytes($data['written_total']) ?></div>
</div>
</div>
<div class="progress" style="height: 30px;">
<div class="progress-bar" role="progressbar"
style="width: <?= $data['volume_written_percent'] ?>%;"
aria-valuenow="<?= $data['volume_written_percent'] ?>" aria-valuemin="0" aria-valuemax="100">
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-lg-4">
<div class="card h-100" style="border: none">
<div class="card-body capacity-block bg-dark">
<div>
<h5 class="card-title">Capacity gain</h5>
<div class="gain-item">
<span><?= number_format($data['compression_savings_percent'], 0) ?>% Compression</span>
<span><?= formatBytes($data['compression_savings']) ?></span>
</div>
<div class="gain-item">
<span><?= number_format($data['thin_savings_percent'], 0) ?>% Thin provisioning</span>
<span><?= formatBytes($data['thin_savings']) ?></span>
</div>
<hr>
<div class="gain-item">
<span>Compression</span>
<span><?= number_format($data['compression_ratio'], 1) ?>:1</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<hr> <hr>
<!-- IO_grp --> <!-- IO_grp -->
<div class="row flex-nowrap text-center"> <div class="row flex-nowrap text-center">
@@ -228,7 +454,8 @@
<h5><i class="fs-4 bi-hdd text-black"></i> Unnasigned LUNs</h5> <h5><i class="fs-4 bi-hdd text-black"></i> Unnasigned LUNs</h5>
</div> </div>
<div class="card-body bg-dark text-center fs-2"> <div class="card-body bg-dark text-center fs-2">
<button type="button" class="btn btn-secondary" data-bs-html="true" data-toggle="tooltip" data-placement="top" title="<?php echo $lLUN;?>"><b><?php echo $unnasigned; ?></b></button> <button type="button" class="btn btn-secondary" data-bs-html="true" data-toggle="tooltip"
data-placement="top" title="<?php echo $lLUN; ?>"><b><?php echo $unnasigned; ?></b></button>
</div> </div>
</div> </div>
</div> </div>
@@ -238,7 +465,8 @@
<h5><i class="fs-4 bi-hdd text-black"></i> Hosts w/o LUNs</h5> <h5><i class="fs-4 bi-hdd text-black"></i> Hosts w/o LUNs</h5>
</div> </div>
<div class="card-body bg-dark text-center fs-2"> <div class="card-body bg-dark text-center fs-2">
<button type="button" class="btn btn-secondary" data-bs-html="true" data-toggle="tooltip" data-placement="top" title="<?php echo $lHOST;?>"><b><?php echo $orphanHosts; ?></b></button> <button type="button" class="btn btn-secondary" data-bs-html="true" data-toggle="tooltip"
data-placement="top" title="<?php echo $lHOST; ?>"><b><?php echo $orphanHosts; ?></b></button>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -1,5 +1,86 @@
<?php
include $_SERVER['DOCUMENT_ROOT'] . "/include/all.php";
$json = json_decode(PostJson("$bdnuss/Storage/SVC/SVC_INVENTORY.php", ''), true);
$poolsData = $json['Data']['Pools'];
function formatBytes($bytes, $precision = 2)
{
if ($bytes == 0)
return '0 octets';
$base = 1024;
$size = $bytes / pow($base, 4);
return round($size, $precision) . ' Tio';
}
$seriesData = [
'V5100' => [
'physical_used' => 0,
'physical_free' => 0,
'physical_total_api' => 0,
'virtual_total' => 0,
'written_total' => 0,
'compressed_total' => 0,
'dedup_savings' => 0
],
'V5030' => [
'physical_used' => 0,
'physical_free' => 0,
'physical_total_api' => 0,
'virtual_total' => 0,
'written_total' => 0,
'compressed_total' => 0,
'dedup_savings' => 0
],
];
foreach ($poolsData as $poolName => $poolDetails) {
$currentSeries = null;
if (strpos($poolName, 'V5100') !== false) {
$currentSeries = 'V5100';
} elseif (strpos($poolName, 'V5030') !== false) {
$currentSeries = 'V5030';
}
if ($currentSeries) {
$used_capacity = (float) $poolDetails['used_capacity'];
$free_capacity = (float) $poolDetails['free_capacity'];
$capacity = (float) $poolDetails['capacity'];
$virtual_cap = (float) $poolDetails['virtual_capacity'];
$uncomp_cap = (float) $poolDetails['compression_uncompressed_capacity'];
$comp_cap = (float) $poolDetails['compression_compressed_capacity'];
$dedup_sav = (float) $poolDetails['deduplication_capacity_saving'];
$seriesData[$currentSeries]['physical_used'] += $used_capacity;
$seriesData[$currentSeries]['physical_free'] += $free_capacity;
$seriesData[$currentSeries]['physical_total_api'] += $capacity;
$seriesData[$currentSeries]['virtual_total'] += $virtual_cap;
$seriesData[$currentSeries]['written_total'] += $uncomp_cap;
$seriesData[$currentSeries]['compressed_total'] += $comp_cap;
$seriesData[$currentSeries]['dedup_savings'] += $dedup_sav;
}
}
foreach ($seriesData as $series => &$data) {
$data['physical_total_calc'] = ($data['physical_used'] + ($data['physical_free'] / 2));
$data['physical_used_percent'] = ($data['physical_total_calc'] > 0) ? ($data['physical_used'] / $data['physical_total_calc']) * 100 : 0;
$data['physical_free_percent'] = 100 - $data['physical_used_percent'];
$data['volume_written_percent'] = ($data['virtual_total'] > 0) ? ($data['written_total'] / $data['virtual_total']) * 100 : 0;
$data['compression_savings'] = $data['written_total'] - $data['compressed_total'];
$data['thin_savings'] = $data['virtual_total'] - $data['written_total'];
$data['total_savings'] = $data['compression_savings'] + $data['dedup_savings'] + $data['thin_savings'];
$data['compression_ratio'] = ($data['compressed_total'] > 0) ? ($data['written_total'] / $data['compressed_total']) : 0;
$data['compression_savings_percent'] = ($data['written_total'] > 0) ? ($data['compression_savings'] / $data['written_total']) * 100 : 0;
$data['dedup_savings_percent'] = ($data['written_total'] > 0) ? ($data['dedup_savings'] / $data['written_total']) * 100 : 0;
$data['thin_savings_percent'] = ($data['virtual_total'] > 0) ? ($data['thin_savings'] / $data['virtual_total']) * 100 : 0;
$data['total_savings_percent'] = ($data['virtual_total'] > 0) ? ($data['total_savings'] / $data['virtual_total']) * 100 : 0;
}
unset($data);
?>
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
@@ -22,10 +103,47 @@
<!-- Chart --> <!-- Chart -->
<script src="/js/chart.min.js"></script> <script src="/js/chart.min.js"></script>
<style>
.capacity-block .value {
font-size: 1.8rem;
font-weight: bold;
}
.capacity-block .percent {
font-size: 1rem;
font-weight: bold;
color: #555;
}
.capacity-block .label {
font-size: 0.9rem;
color: #6c757d;
/* text-muted */
}
.capacity-block .sub-value {
font-size: 1.1rem;
font-weight: normal;
display: block;
margin-bottom: 0.3rem;
}
.gain-item {
display: flex;
justify-content: space-between;
margin-bottom: 5px;
font-size: 0.9rem;
}
.gain-item span:last-child {
font-weight: bold;
}
</style>
</head> </head>
<body class="bg-light text-dark"> <body class="bg-light text-dark">
<?php include $_SERVER['DOCUMENT_ROOT']."/include/all.php" ; ?>
<div class="container-fluid"> <div class="container-fluid">
<div class="row flex-nowrap"> <div class="row flex-nowrap">
<!-- Left NAVBAR --> <!-- Left NAVBAR -->
@@ -48,7 +166,9 @@
$json = json_decode(PostJson("$bdnuss/Storage/SVC/SVC_INVENTORY.php", ''), true); $json = json_decode(PostJson("$bdnuss/Storage/SVC/SVC_INVENTORY.php", ''), true);
// Sum LUN Size by Bay // Sum LUN Size by Bay
$lunsGold = 0 ; $lunsSilver = 0 ; $lunsGold = 0;
$lunsSilver = 0;
try {
foreach ($json['Data']['VolumeCopies'] as $data) { foreach ($json['Data']['VolumeCopies'] as $data) {
if (strpos($data['mdisk_grp_name'], "5100") !== false) { if (strpos($data['mdisk_grp_name'], "5100") !== false) {
$lunsGold += $data['capacity']; $lunsGold += $data['capacity'];
@@ -56,18 +176,27 @@
$lunsSilver += $data['capacity']; $lunsSilver += $data['capacity'];
} }
} }
} catch (Exception $e) {
}
// Get Full Capacity // Get Full Capacity
$goldCapacity = 0 ; $silverCapacity = 0 ; $GoldCompression = 0;$SilverCompression = 0; $goldCapacity = 0;
$silverCapacity = 0;
$GoldCompression = 0;
$SilverCompression = 0;
foreach ($json['Data']['Pools'] as $data) { foreach ($json['Data']['Pools'] as $data) {
if (strpos($data['name'], "5100") !== false) { if (strpos($data['name'], "5100") !== false) {
$goldCapacity += $data['capacity']; $goldCapacity += $data['capacity'];
if ($data['used_capacity'] > 0) {
$GoldCompression += ($data['real_capacity'] / $data['used_capacity']); $GoldCompression += ($data['real_capacity'] / $data['used_capacity']);
}
} else { } else {
$silverCapacity += $data['capacity']; $silverCapacity += $data['capacity'];
if ($data['used_capacity'] > 0) {
$SilverCompression += ($data['real_capacity'] / $data['used_capacity']); $SilverCompression += ($data['real_capacity'] / $data['used_capacity']);
} }
} }
}
// Datas // Datas
$goldCapacity = $goldCapacity / 2; $goldCapacity = $goldCapacity / 2;
@@ -82,8 +211,34 @@
// Unnasigned Luns // Unnasigned Luns
$unnasigned = 0; $unnasigned = 0;
$cuc = "bg-success"; $cuc = "bg-success";
$lLUN = "";
foreach ($json['Data']['Volumes'] as $volume) { foreach ($json['Data']['Volumes'] as $volume) {
if($volume['protocol'] != "scsi"){$unnasigned++;$cuc = "bg-warning";} if ($volume['protocol'] != "scsi") {
$unnasigned++;
$cuc = "bg-warning";
$lLUN .= $volume['name'] . "<br>";
}
}
// Orphan Hosts
$orphanHosts = 0;
$chc = "bg-success";
$lHOST = "";
foreach ($json['Data']['Hosts'] as $host) {
if ($host['protocol'] != "scsi") {
$orphanHosts++;
$chc = "bg-warning";
$lHOST .= $host['name'] . "<br>";
}
}
if ($json['Data']['Hostclusters']) {
foreach ($json['Data']['Hostclusters'] as $host) {
if ($host['protocol'] != "scsi") {
$orphanHosts++;
$chc = "bg-warning";
$lHOST .= $host['name'] . "<br>";
}
}
} }
?> ?>
@@ -95,29 +250,80 @@
<i class="fs-4 bi-server text-black"></i><b> Gold (V5100)</b> <i class="fs-4 bi-server text-black"></i><b> Gold (V5100)</b>
</div> </div>
<div class="card-body bg-dark fs-4"> <div class="card-body bg-dark fs-4">
<div class="row"> <div class="row g-4">
<div class="col"> <?php $data = $seriesData['V5100']; ?>
<b>Total Capacity : </b><?php echo round($goldCapacity / $TB,2); ?> TB <div class="col-lg-4">
<div class="card h-100" style="border: none">
<div class="card-body capacity-block bg-dark">
<div>
<h5 class="card-title">Physical Capacity</h5>
<div class="d-flex justify-content-between align-items-start mb-2">
<div>
<span class="percent"><?= number_format($data['physical_used_percent'], 0) ?>%</span>
<div class="value"><?= formatBytes($data['physical_used']) ?></div>
</div> </div>
<div class="col"> <div class="text-end">
<b>Used : </b><?php echo round($lunsGold / $TB,2); ?> TB (<?php echo $goldPercentUsed ;?>% ) <span class="percent"><?= number_format($data['physical_free_percent'], 0) ?>%</span>
</div> <div class="value"><?= formatBytes($data['physical_free'] / 2) ?></div>
<div class="col">
<b>Free : </b><?php echo round($GoldFree / $TB,2); ?> TB
</div>
<div class="col">
<b>Compression : </b><?php echo $GoldCompression ; ?>:1
</div> </div>
</div> </div>
<br> <div class="progress" style="height:30px;">
<div class="progress border border-light" style="height: 40px;"> <div class="progress-bar" role="progressbar"
<?php style="width: <?= $data['physical_used_percent'] ?>%;"
$pbc = "bg-success"; aria-valuenow="<?= $data['physical_used_percent'] ?>" aria-valuemin="0" aria-valuemax="100">
if($goldPercentUsed >= 75){$pbc = "bg-warning";} </div>
if($goldPercentUsed >= 90){$pbc = "bg-danger";} </div>
?> </div>
<div class="progress-bar <?php echo $pbc; ?>" role="progressbar" style="width: <?php echo $goldPercentUsed ;?>%;" aria-valuenow="<?php echo $goldPercentUsed ;?>" aria-valuemin="0" aria-valuemax="100"></div> </div>
<div class="progress-bar bg-black bg-gradient" role="progressbar" style="width: <?php echo 100 - $goldPercentUsed ;?>%;" aria-valuenow="<?php echo 100 - $goldPercentUsed ;?>" aria-valuemin="0" aria-valuemax="100"></div> </div>
</div>
<div class="col-lg-4">
<div class="card h-100" style="border: none">
<div class="card-body capacity-block bg-dark">
<div>
<h5 class="card-title">Volume Capacity</h5>
<div class="d-flex justify-content-between align-items-start mb-2">
<div>
<span class="percent"><?= number_format($data['volume_written_percent'], 0) ?>%</span>
<div class="value"><?= formatBytes($data['written_total']) ?></div>
</div>
</div>
<div class="progress" style="height: 30px;">
<div class="progress-bar" role="progressbar"
style="width: <?= $data['volume_written_percent'] ?>%;"
aria-valuenow="<?= $data['volume_written_percent'] ?>" aria-valuemin="0" aria-valuemax="100">
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-lg-4">
<div class="card h-100" style="border: none">
<div class="card-body capacity-block bg-dark">
<div>
<h5 class="card-title">Capacity gain</h5>
<div class="gain-item">
<span><?= number_format($data['compression_savings_percent'], 0) ?>% Compression</span>
<span><?= formatBytes($data['compression_savings']) ?></span>
</div>
<div class="gain-item">
<span><?= number_format($data['thin_savings_percent'], 0) ?>% Thin provisioning</span>
<span><?= formatBytes($data['thin_savings']) ?></span>
</div>
<hr>
<div class="gain-item">
<span>Compression</span>
<span><?= number_format($data['compression_ratio'], 1) ?>:1</span>
</div>
</div>
</div>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
@@ -125,35 +331,87 @@
<!-- Carte Silver --> <!-- Carte Silver -->
<div class="card mb-3" style="border: 3px solid black"> <div class="card mb-3" style="border: 3px solid black">
<div class="card-header text-dark text-center fs-3 bg-info"> <div class="card-header text-dark text-center fs-3 bg-info">
<i class="fs-4 bi-server text-black"></i><b> Silver (V5030)</b> <i class="fs-4 bi-server text-black"></i><b> Gold (V5100)</b>
</div> </div>
<div class="card-body bg-dark fs-4"> <div class="card-body bg-dark fs-4">
<div class="row"> <div class="row g-4">
<div class="col"> <?php $data = $seriesData['V5030']; ?>
<b>Total Capacity : </b><?php echo round($silverCapacity / $TB,2); ?> TB <div class="col-lg-4">
<div class="card h-100" style="border: none">
<div class="card-body capacity-block bg-dark">
<div>
<h5 class="card-title">Physical Capacity</h5>
<div class="d-flex justify-content-between align-items-start mb-2">
<div>
<span class="percent"><?= number_format($data['physical_used_percent'], 0) ?>%</span>
<div class="value"><?= formatBytes($data['physical_used']) ?></div>
</div> </div>
<div class="col"> <div class="text-end">
<b>Used : </b><?php echo round($lunsSilver / $TB,2); ?> TB (<?php echo $silverPercentUsed ;?>% ) <span class="percent"><?= number_format($data['physical_free_percent'], 0) ?>%</span>
</div> <div class="value"><?= formatBytes($data['physical_free'] / 2) ?></div>
<div class="col">
<b>Free : </b><?php echo round($SilverFree / $TB,2); ?> TB
</div>
<div class="col">
<b>Compression : </b><?php echo $SilverCompression ; ?>:1
</div> </div>
</div> </div>
<br> <div class="progress" style="height: 30px;">
<div class="progress border border-light" style="height: 40px;"> <div class="progress-bar" role="progressbar"
<?php style="width: <?= $data['physical_used_percent'] ?>%;"
$pbc = "bg-success"; aria-valuenow="<?= $data['physical_used_percent'] ?>" aria-valuemin="0" aria-valuemax="100">
if($silverPercentUsed >= 75){$pbc = "bg-warning";}
if($silverPercentUsed >= 90){$pbc = "bg-danger";}
?>
<div class="progress-bar <?php echo $pbc; ?>" role="progressbar" style="width: <?php echo $silverPercentUsed ;?>%;" aria-valuenow="<?php echo $silverPercentUsed ;?>" aria-valuemin="0" aria-valuemax="100"></div>
<div class="progress-bar bg-black bg-gradient" role="progressbar" style="width: <?php echo 100 - $silverPercentUsed ;?>%;" aria-valuenow="<?php echo 100 - $silverPercentUsed ;?>" aria-valuemin="0" aria-valuemax="100"></div>
</div> </div>
</div> </div>
</div> </div>
</div>
</div>
</div>
<div class="col-lg-4">
<div class="card h-100" style="border: none">
<div class="card-body capacity-block bg-dark">
<div>
<h5 class="card-title">Volume Capacity</h5>
<div class="d-flex justify-content-between align-items-start mb-2">
<div>
<span class="percent"><?= number_format($data['volume_written_percent'], 0) ?>%</span>
<div class="value"><?= formatBytes($data['written_total']) ?></div>
</div>
</div>
<div class="progress" style="height: 30px;">
<div class="progress-bar" role="progressbar"
style="width: <?= $data['volume_written_percent'] ?>%;"
aria-valuenow="<?= $data['volume_written_percent'] ?>" aria-valuemin="0" aria-valuemax="100">
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-lg-4">
<div class="card h-100" style="border: none">
<div class="card-body capacity-block bg-dark">
<div>
<h5 class="card-title">Capacity gain</h5>
<div class="gain-item">
<span><?= number_format($data['compression_savings_percent'], 0) ?>% Compression</span>
<span><?= formatBytes($data['compression_savings']) ?></span>
</div>
<div class="gain-item">
<span><?= number_format($data['thin_savings_percent'], 0) ?>% Thin provisioning</span>
<span><?= formatBytes($data['thin_savings']) ?></span>
</div>
<hr>
<div class="gain-item">
<span>Compression</span>
<span><?= number_format($data['compression_ratio'], 1) ?>:1</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<hr> <hr>
<!-- IO_grp --> <!-- IO_grp -->
<div class="row flex-nowrap text-center"> <div class="row flex-nowrap text-center">
@@ -196,7 +454,19 @@
<h5><i class="fs-4 bi-hdd text-black"></i> Unnasigned LUNs</h5> <h5><i class="fs-4 bi-hdd text-black"></i> Unnasigned LUNs</h5>
</div> </div>
<div class="card-body bg-dark text-center fs-2"> <div class="card-body bg-dark text-center fs-2">
<b><?php echo $unnasigned; ?></b> <button type="button" class="btn btn-secondary" data-bs-html="true" data-toggle="tooltip"
data-placement="top" title="<?php echo $lLUN; ?>"><b><?php echo $unnasigned; ?></b></button>
</div>
</div>
</div>
<div class="col"><!-- Orphan Hosts -->
<div class="card border-secondary mb-3">
<div class="card-header text-dark text-center <?php echo $chc; ?>">
<h5><i class="fs-4 bi-hdd text-black"></i> Hosts w/o LUNs</h5>
</div>
<div class="card-body bg-dark text-center fs-2">
<button type="button" class="btn btn-secondary" data-bs-html="true" data-toggle="tooltip"
data-placement="top" title="<?php echo $lHOST; ?>"><b><?php echo $orphanHosts; ?></b></button>
</div> </div>
</div> </div>
</div> </div>
@@ -208,3 +478,8 @@
</div> </div>
<script src="/js/switch.js"></script> <script src="/js/switch.js"></script>
</body> </body>
<script>
$(function () {
$('[data-toggle="tooltip"]').tooltip()
})
</script>

1
js/chart.min.4.js Normal file

File diff suppressed because one or more lines are too long