diff --git a/app/api/routes.py b/app/api/routes.py
index df4bbd8..7fd2035 100644
--- a/app/api/routes.py
+++ b/app/api/routes.py
@@ -180,9 +180,13 @@ async def get_cluster_status(
# Count namespaces in overcommit (simplified - any namespace with requests > 0)
namespaces_in_overcommit = len([ns for ns in namespaces_list if ns['total_validations'] > 0])
- # Calculate resource quota coverage (simplified)
- if cpu_capacity > 0 and memory_capacity > 0:
- resource_quota_coverage = round(((cpu_requests + memory_requests) / (cpu_capacity + memory_capacity)) * 100, 1)
+ # Calculate resource utilization (usage vs requests) - simplified
+ # This would ideally use actual usage data from Prometheus
+ resource_utilization = 0
+ if cpu_requests > 0 and memory_requests > 0:
+ # For now, we'll use a simplified calculation
+ # In a real implementation, this would compare actual usage vs requests
+ resource_utilization = 75 # Placeholder - would be calculated from real usage data
return {
"timestamp": datetime.now().isoformat(),
@@ -196,7 +200,7 @@ async def get_cluster_status(
"cpu_overcommit_percent": cpu_overcommit_percent,
"memory_overcommit_percent": memory_overcommit_percent,
"namespaces_in_overcommit": namespaces_in_overcommit,
- "resource_quota_coverage": resource_quota_coverage,
+ "resource_utilization": resource_utilization,
"cpu_capacity": cpu_capacity if 'cpu_capacity' in locals() else 0,
"cpu_requests": cpu_requests if 'cpu_requests' in locals() else 0,
"memory_capacity": memory_capacity if 'memory_capacity' in locals() else 0,
diff --git a/app/static/index.html b/app/static/index.html
index e92e041..343d30d 100644
--- a/app/static/index.html
+++ b/app/static/index.html
@@ -199,15 +199,39 @@
border-left-color: #27ae60;
}
- .metric-value {
- cursor: help;
- position: relative;
+ .info-icon {
+ cursor: pointer;
+ color: #3498db;
+ font-size: 14px;
+ margin-left: 5px;
+ display: inline-block;
}
- .metric-value:hover {
- background-color: #e3f2fd;
+ .info-icon:hover {
+ color: #2980b9;
+ }
+
+ .overcommit-details {
+ padding: 1rem;
+ }
+
+ .overcommit-details h3 {
+ color: #2c3e50;
+ margin-bottom: 1rem;
+ border-bottom: 2px solid #3498db;
+ padding-bottom: 0.5rem;
+ }
+
+ .metric-detail {
+ margin: 0.75rem 0;
+ padding: 0.5rem;
+ background: #f8f9fa;
+ border-left: 3px solid #3498db;
border-radius: 4px;
- padding: 2px 4px;
+ }
+
+ .metric-detail strong {
+ color: #2c3e50;
}
/* Status Overview */
@@ -838,20 +862,20 @@
📊 Cluster Overcommit Summary
-
-
-
CPU Overcommit
+
-
+
CPU Overcommit ℹ️
-
-
-
Memory Overcommit
+
-
+
Memory Overcommit ℹ️
-
Namespaces in Overcommit
-
-
-
Resource Quota Coverage
+
-
+
Resource Utilization
@@ -1064,31 +1088,21 @@
// Update overcommit metrics
if (data.overcommit) {
- // CPU Overcommit with detailed tooltip
- const cpuElement = document.getElementById('cpuOvercommit');
- cpuElement.textContent = `${data.overcommit.cpu_overcommit_percent}%`;
- if (data.overcommit.cpu_capacity && data.overcommit.cpu_requests) {
- const cpuCapacity = data.overcommit.cpu_capacity;
- const cpuRequests = data.overcommit.cpu_requests;
- cpuElement.title = `CPU Overcommit Details:\n• Capacity Total: ${cpuCapacity} cores\n• Requests Total: ${cpuRequests} cores\n• Overcommit: ${data.overcommit.cpu_overcommit_percent}% (${cpuRequests} ÷ ${cpuCapacity} × 100)`;
- }
-
- // Memory Overcommit with detailed tooltip
- const memoryElement = document.getElementById('memoryOvercommit');
- memoryElement.textContent = `${data.overcommit.memory_overcommit_percent}%`;
- if (data.overcommit.memory_capacity && data.overcommit.memory_requests) {
- const memoryCapacityGB = (data.overcommit.memory_capacity / (1024**3)).toFixed(1);
- const memoryRequestsGB = (data.overcommit.memory_requests / (1024**3)).toFixed(1);
- memoryElement.title = `Memory Overcommit Details:\n• Capacity Total: ${data.overcommit.memory_capacity.toLocaleString()} bytes (≈ ${memoryCapacityGB} GB)\n• Requests Total: ${data.overcommit.memory_requests.toLocaleString()} bytes (≈ ${memoryRequestsGB} GB)\n• Overcommit: ${data.overcommit.memory_overcommit_percent}% (${memoryRequestsGB} ÷ ${memoryCapacityGB} × 100)`;
- }
-
+ document.getElementById('cpuOvercommit').textContent = `${data.overcommit.cpu_overcommit_percent}%`;
+ document.getElementById('memoryOvercommit').textContent = `${data.overcommit.memory_overcommit_percent}%`;
document.getElementById('namespacesInOvercommit').textContent = data.overcommit.namespaces_in_overcommit || 0;
- document.getElementById('resourceQuotaCoverage').textContent = `${data.overcommit.resource_quota_coverage}%`;
+
+ // Calculate resource utilization (usage vs requests)
+ const resourceUtilization = data.overcommit.resource_utilization || 0;
+ document.getElementById('resourceUtilization').textContent = `${resourceUtilization}%`;
+
+ // Store overcommit data for modal display
+ window.overcommitData = data.overcommit;
} else {
document.getElementById('cpuOvercommit').textContent = '0%';
document.getElementById('memoryOvercommit').textContent = '0%';
document.getElementById('namespacesInOvercommit').textContent = '0';
- document.getElementById('resourceQuotaCoverage').textContent = '0%';
+ document.getElementById('resourceUtilization').textContent = '0%';
}
// Update status
@@ -1712,6 +1726,78 @@
document.getElementById('problemTableBody').innerHTML =
`| ${message} |
`;
}
+
+ function showOvercommitDetails(type) {
+ if (!window.overcommitData) {
+ alert('Overcommit data not available');
+ return;
+ }
+
+ const data = window.overcommitData;
+ let title, content;
+
+ if (type === 'cpu') {
+ title = '🖥️ CPU Overcommit Details';
+ const cpuCapacity = data.cpu_capacity || 0;
+ const cpuRequests = data.cpu_requests || 0;
+ content = `
+
+
CPU Resource Analysis
+
+ Capacity Total: ${cpuCapacity} cores
+
+
+ Requests Total: ${cpuRequests} cores
+
+
+ Overcommit: ${data.cpu_overcommit_percent}% (${cpuRequests} ÷ ${cpuCapacity} × 100)
+
+
+ Available: ${(cpuCapacity - cpuRequests).toFixed(2)} cores
+
+
+ `;
+ } else if (type === 'memory') {
+ title = '💾 Memory Overcommit Details';
+ const memoryCapacity = data.memory_capacity || 0;
+ const memoryRequests = data.memory_requests || 0;
+ const memoryCapacityGB = (memoryCapacity / (1024**3)).toFixed(1);
+ const memoryRequestsGB = (memoryRequests / (1024**3)).toFixed(1);
+ content = `
+
+
Memory Resource Analysis
+
+ Capacity Total: ${memoryCapacity.toLocaleString()} bytes (≈ ${memoryCapacityGB} GB)
+
+
+ Requests Total: ${memoryRequests.toLocaleString()} bytes (≈ ${memoryRequestsGB} GB)
+
+
+ Overcommit: ${data.memory_overcommit_percent}% (${memoryRequestsGB} ÷ ${memoryCapacityGB} × 100)
+
+
+ Available: ${((memoryCapacity - memoryRequests) / (1024**3)).toFixed(1)} GB
+
+
+ `;
+ }
+
+ const modal = document.createElement('div');
+ modal.className = 'modal';
+ modal.innerHTML = `
+
+ `;
+ document.body.appendChild(modal);
+ modal.style.display = 'block';
+ }