Fix: Cross-cluster data bleeding + Enhanced SSL dropdown UI

🐛 Critical Cross-Cluster Data Bleeding - System-Wide Fix:
Fixed old cluster's data appearing when switching clusters across 4 components

Root Cause:
- User switches from Cluster A to Cluster B
- Old cluster data remains in React state during API fetch
- Race condition: UI shows Cluster A data while fetching Cluster B
- Backend page: Data persisted after fetch
- Frontend page: Data briefly appeared then disappeared

 Components Fixed (State Clearing on Cluster Change):

1. BackendServers.js (Line 115-122)
   - Clear: backends, filteredBackends, frontends, sslCertificates

2. FrontendManagement.js (Line 150-157)
   - Clear: frontends, filteredFrontends, backends, sslCertificates

3. WAFManagement.js (Line 277-282)
   - Clear: rules, filteredRules, frontends

4. DashboardV2.js (Line 402-407)
   - Clear: statsData, frontendOptions, backendOptions, backendHealth, slowestBackends

Already Had State Clearing:
  ✓ SSLManagement.js
  ✓ AgentManagement.js
  ✓ Configuration.js
  ✓ ApplyManagement.js

 UI Enhancement: Backend Server SSL Dropdown

Redesigned to match Frontend SSL dropdown design:

Before:
  star-burgan-com-tr - *.burgan.com.tr (Expires: 2/25/2026)

After:
  star-burgan-com-tr - *.burgan.com.tr [🌍 Global]  (125 days)
  demo-cert - *.apps.cluster.example.com [📍 Cluster]  (1502 days)

Features Added:
   Status icons: valid, ⚠️ expiring soon,  expired
   Days until expiry countdown
   SSL type tags: 🌍 Global (blue) or 📍 Cluster (green)
   Better layout with flex spacing
   optionLabelProp for compact selected view

🎯 Impact Analysis - All Components Safe:

Tested 8 components with selectedCluster dependency:
  ✓ BackendServers - State clearing added
  ✓ FrontendManagement - State clearing added
  ✓ WAFManagement - State clearing added
  ✓ DashboardV2 - State clearing added
  ✓ SSLManagement - Already had clearing
  ✓ AgentManagement - Already had clearing
  ✓ Configuration - Already had clearing
  ✓ ApplyManagement - Already had clearing

No Breaking Changes:
  - Only added state clearing in useEffect
  - Fetch logic unchanged
  - Response handling unchanged
  - UI components unchanged (except SSL dropdown enhancement)

 Cross-cluster data bleeding completely resolved
This commit is contained in:
taylanbakircioglu
2025-11-07 11:51:14 +03:00
parent 199ade8ce5
commit 8c4d7c246c
4 changed files with 65 additions and 7 deletions
+42 -7
View File
@@ -112,6 +112,15 @@ const BackendServers = () => {
};
useEffect(() => {
// CRITICAL FIX: Clear state when cluster changes to prevent showing other cluster's data
// Race condition: Old cluster data remains visible while new cluster data is fetching
if (selectedCluster) {
setBackends([]);
setFilteredBackends([]);
setFrontends([]);
setSslCertificates([]);
}
fetchBackends();
fetchFrontends();
fetchSSLCertificates();
@@ -1932,15 +1941,41 @@ const BackendServers = () => {
placeholder="Select an SSL certificate (optional unless verify=required)"
showSearch
filterOption={(input, option) =>
option.children.toLowerCase().includes(input.toLowerCase())
(option.label || '').toLowerCase().includes(input.toLowerCase())
}
optionLabelProp="label"
>
{sslCertificates.map((cert) => (
<Option key={cert.id} value={cert.id}>
{cert.name} - {cert.domain}
{cert.expiry_date && ` (Expires: ${new Date(cert.expiry_date).toLocaleDateString()})`}
</Option>
))}
{sslCertificates.map((cert) => {
// Status icon based on certificate validity
const statusIcon = cert.status === 'valid' ? '✅' :
cert.status === 'expiring_soon' ? '⚠️' : '❌';
const expiryInfo = cert.days_until_expiry !== undefined ?
`(${cert.days_until_expiry} days)` : '';
const sslTypeTag = cert.ssl_type === 'Global' ? '🌍 Global' : '📍 Cluster';
return (
<Option
key={cert.id}
value={cert.id}
label={`${cert.name} - ${cert.domain}`}
>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<span>
<strong>{cert.name}</strong> - {cert.domain}
<Tag
color={cert.ssl_type === 'Global' ? 'blue' : 'green'}
style={{ marginLeft: 8, fontSize: '10px' }}
>
{sslTypeTag}
</Tag>
</span>
<span style={{ fontSize: '12px', color: '#666', marginLeft: 12 }}>
{statusIcon} {expiryInfo}
</span>
</div>
</Option>
);
})}
</Select>
</Form.Item>
</Col>
+7
View File
@@ -399,6 +399,13 @@ const DashboardV2 = () => {
useEffect(() => {
if (!selectedCluster) return;
// CRITICAL FIX: Clear all dashboard state when cluster changes
setStatsData({});
setFrontendOptions([]);
setBackendOptions([]);
setBackendHealth([]);
setSlowestBackends([]);
let isMounted = true;
const loadInitialData = async () => {
@@ -147,6 +147,15 @@ const FrontendManagement = () => {
};
useEffect(() => {
// CRITICAL FIX: Clear state when cluster changes to prevent showing other cluster's data
// Race condition: Old cluster data remains visible while new cluster data is fetching
if (selectedCluster) {
setFrontends([]);
setFilteredFrontends([]);
setBackends([]);
setSslCertificates([]);
}
fetchFrontends();
fetchBackends();
fetchSSLCertificates();
+7
View File
@@ -274,6 +274,13 @@ const WAFManagement = () => {
};
useEffect(() => {
// CRITICAL FIX: Clear state when cluster changes to prevent showing other cluster's data
if (selectedCluster) {
setRules([]);
setFilteredRules([]);
setFrontends([]);
}
fetchRules();
fetchStats();
checkPendingChanges();