Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 11 additions & 12 deletions dashboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -1281,14 +1281,14 @@ function updateStatistics() {
});

// Calculate total unique regions from Nodes and K8s clusters
// Use provider:region composite key to avoid counting same-named regions across different CSPs as one.
const regions = new Set();

// Add regions from Nodes
nodeData.forEach(nd => {
let region = null;

// Extract region information - try multiple sources
// Note: JSON field is lowercase 'region' (from Go struct tag `json:"region"`)
const provider = nd.connectionConfig && nd.connectionConfig.providerName ? nd.connectionConfig.providerName : '';

if (nd.region && nd.region.region) {
region = nd.region.region;
} else if (nd.location && nd.location.region) {
Expand All @@ -1298,28 +1298,27 @@ function updateStatistics() {
} else if (nd.regionZoneInfoList && nd.regionZoneInfoList.length > 0 && nd.regionZoneInfoList[0].regionName) {
region = nd.regionZoneInfoList[0].regionName;
}

if (region) {
regions.add(region);
regions.add(provider ? `${provider}:${region}` : region);
}
});

// Add regions from K8s clusters
k8sData.forEach(cluster => {
let region = null;

// Extract region information from cluster
// Note: JSON field is lowercase 'region' (from Go struct tag `json:"region"`)
const provider = cluster.connectionConfig && cluster.connectionConfig.providerName ? cluster.connectionConfig.providerName : '';

if (cluster.region && cluster.region.region) {
region = cluster.region.region;
} else if (cluster.location && cluster.location.region) {
region = cluster.location.region;
} else if (cluster.connectionConfig && cluster.connectionConfig.regionZoneInfo && cluster.connectionConfig.regionZoneInfo.region) {
region = cluster.connectionConfig.regionZoneInfo.region;
}

if (region) {
regions.add(region);
regions.add(provider ? `${provider}:${region}` : region);
}
});

Expand Down
44 changes: 29 additions & 15 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5752,12 +5752,8 @@ function reviewInfraConfiguration(createInfraReq, hostname, port, username, pass
});
}

// Region breakdown
if (rs.regionNames && Array.isArray(rs.regionNames)) {
rs.regionNames.forEach(region => {
resourceSummary.regionBreakdown[region] = (resourceSummary.regionBreakdown[region] || 0) + 1;
});
}
// regionBreakdown is rebuilt from nodeReviews below using provider+region keys
// to avoid counting same-named regions across different CSPs as one region.

// Spec breakdown
if (rs.uniqueSpecs && Array.isArray(rs.uniqueSpecs)) {
Expand All @@ -5773,6 +5769,7 @@ function reviewInfraConfiguration(createInfraReq, hostname, port, username, pass

// Group Nodes by NodeGroup name for better organization
var nodeGroupVMs = {};
var nodeGroupRegions = {}; // nodeGroupName -> {provider, region}

reviewData.nodeReviews.forEach((nodeReview, index) => {
var nodeDetails = {
Expand Down Expand Up @@ -5807,6 +5804,14 @@ function reviewInfraConfiguration(createInfraReq, hostname, port, username, pass
nodeGroupVMs[groupKey] = [];
}
nodeGroupVMs[groupKey].push(nodeDetails);

// Record provider+region for this nodegroup (first occurrence wins)
if (!nodeGroupRegions[groupKey] && nodeReview.regionName) {
nodeGroupRegions[groupKey] = {
provider: nodeReview.providerName || '',
region: nodeReview.regionName
};
}

// Spec validation details
if (nodeReview.specValidation) {
Expand Down Expand Up @@ -5913,6 +5918,15 @@ function reviewInfraConfiguration(createInfraReq, hostname, port, username, pass
});
}

// Build regionBreakdown using provider+region keys to correctly distinguish
// same-named regions across different CSPs (e.g., alibaba ap-northeast-2 vs aws ap-northeast-2)
if (nodeGroupRegions) {
Object.values(nodeGroupRegions).forEach(function(info) {
var key = info.provider ? (info.provider + ' (' + info.region + ')') : info.region;
resourceSummary.regionBreakdown[key] = (resourceSummary.regionBreakdown[key] || 0) + 1;
});
}

// Extract recommendations
if (reviewData.recommendations && Array.isArray(reviewData.recommendations)) {
reviewData.recommendations.forEach(rec => {
Expand Down Expand Up @@ -6241,17 +6255,17 @@ function reviewInfraConfiguration(createInfraReq, hostname, port, username, pass
<tr>
<td style="border: 1px solid #ddd; padding: 8px; color: #666;">Cloud Providers</td>
<td style="border: 1px solid #ddd; padding: 8px; color: #333;">
${Object.entries(resourceSummary.providerBreakdown).map(([provider, count]) =>
`<span style="margin-right: 10px;"><strong>${provider}:</strong> ${count}</span>`
${Object.entries(resourceSummary.providerBreakdown).map(([provider, count]) =>
`<span style="margin-right: 10px;"><strong>${window.escapeHtml(provider)}:</strong> ${count}</span>`
).join('')}
</td>
</tr>` : ''}
${Object.keys(resourceSummary.regionBreakdown).length > 0 ? `
<tr>
<td style="border: 1px solid #ddd; padding: 8px; color: #666;">Regions</td>
<td style="border: 1px solid #ddd; padding: 8px; color: #333;">
${Object.entries(resourceSummary.regionBreakdown).map(([region, count]) =>
`<span style="margin-right: 10px;"><strong>${region}:</strong> ${count}</span>`
${Object.entries(resourceSummary.regionBreakdown).map(([region, count]) =>
`<span style="margin-right: 10px;"><strong>${window.escapeHtml(region)}:</strong> ${count}</span>`
).join('')}
</td>
</tr>` : ''}
Expand Down Expand Up @@ -6476,19 +6490,19 @@ function reviewInfraConfiguration(createInfraReq, hostname, port, username, pass
<div style="margin: 8px 0;">
<strong style="font-size: 0.9em; color: #333;">Cloud Provider Distribution:</strong>
<div style="margin-top: 4px;">
${Object.entries(resourceSummary.providerBreakdown).map(([provider, count]) =>
`<span style="display: inline-block; margin: 2px 4px; padding: 3px 8px; background: #f0f8ff; border: 1px solid #007bff; border-radius: 12px; font-size: 0.8em; color: #007bff;">${provider}: ${count}</span>`
${Object.entries(resourceSummary.providerBreakdown).map(([provider, count]) =>
`<span style="display: inline-block; margin: 2px 4px; padding: 3px 8px; background: #f0f8ff; border: 1px solid #007bff; border-radius: 12px; font-size: 0.8em; color: #007bff;">${window.escapeHtml(provider)}: ${count}</span>`
).join('')}
</div>
</div>
` : ''}

${Object.keys(resourceSummary.regionBreakdown).length > 0 ? `
<div style="margin: 8px 0;">
<strong style="font-size: 0.9em; color: #333;">Region Distribution:</strong>
<div style="margin-top: 4px;">
${Object.entries(resourceSummary.regionBreakdown).map(([region, count]) =>
`<span style="display: inline-block; margin: 2px 4px; padding: 3px 8px; background: #f0f8f0; border: 1px solid #28a745; border-radius: 12px; font-size: 0.8em; color: #28a745;">${region}: ${count}</span>`
${Object.entries(resourceSummary.regionBreakdown).map(([region, count]) =>
`<span style="display: inline-block; margin: 2px 4px; padding: 3px 8px; background: #f0f8f0; border: 1px solid #28a745; border-radius: 12px; font-size: 0.8em; color: #28a745;">${window.escapeHtml(region)}: ${count}</span>`
).join('')}
</div>
</div>
Expand Down
Loading