diff --git a/dashboard.js b/dashboard.js index 978b783..92d7099 100644 --- a/dashboard.js +++ b/dashboard.js @@ -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) { @@ -1298,18 +1298,17 @@ 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) { @@ -1317,9 +1316,9 @@ function updateStatistics() { } 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); } }); diff --git a/index.js b/index.js index 1139915..4f7ecae 100644 --- a/index.js +++ b/index.js @@ -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)) { @@ -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 = { @@ -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) { @@ -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 => { @@ -6241,8 +6255,8 @@ function reviewInfraConfiguration(createInfraReq, hostname, port, username, pass Cloud Providers - ${Object.entries(resourceSummary.providerBreakdown).map(([provider, count]) => - `${provider}: ${count}` + ${Object.entries(resourceSummary.providerBreakdown).map(([provider, count]) => + `${window.escapeHtml(provider)}: ${count}` ).join('')} ` : ''} @@ -6250,8 +6264,8 @@ function reviewInfraConfiguration(createInfraReq, hostname, port, username, pass Regions - ${Object.entries(resourceSummary.regionBreakdown).map(([region, count]) => - `${region}: ${count}` + ${Object.entries(resourceSummary.regionBreakdown).map(([region, count]) => + `${window.escapeHtml(region)}: ${count}` ).join('')} ` : ''} @@ -6476,19 +6490,19 @@ function reviewInfraConfiguration(createInfraReq, hostname, port, username, pass
Cloud Provider Distribution:
- ${Object.entries(resourceSummary.providerBreakdown).map(([provider, count]) => - `${provider}: ${count}` + ${Object.entries(resourceSummary.providerBreakdown).map(([provider, count]) => + `${window.escapeHtml(provider)}: ${count}` ).join('')}
` : ''} - + ${Object.keys(resourceSummary.regionBreakdown).length > 0 ? `
Region Distribution:
- ${Object.entries(resourceSummary.regionBreakdown).map(([region, count]) => - `${region}: ${count}` + ${Object.entries(resourceSummary.regionBreakdown).map(([region, count]) => + `${window.escapeHtml(region)}: ${count}` ).join('')}