@serve.zone/dcrouter 13.13.0 → 13.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist_serve/bundle.js +811 -803
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/monitoring/classes.metricsmanager.d.ts +26 -0
- package/dist_ts/monitoring/classes.metricsmanager.js +72 -2
- package/dist_ts/opsserver/handlers/security.handler.js +27 -23
- package/dist_ts/opsserver/handlers/stats.handler.js +22 -3
- package/dist_ts_interfaces/data/stats.d.ts +17 -1
- package/dist_ts_interfaces/requests/stats.d.ts +9 -0
- package/dist_ts_oci_container/plugins.d.ts +3 -0
- package/dist_ts_oci_container/plugins.js +4 -0
- package/dist_ts_web/00_commitinfo_data.js +1 -1
- package/dist_ts_web/appstate.d.ts +7 -0
- package/dist_ts_web/appstate.js +45 -54
- package/dist_ts_web/elements/domains/ops-view-domains.js +9 -11
- package/dist_ts_web/elements/network/ops-view-network-activity.d.ts +2 -20
- package/dist_ts_web/elements/network/ops-view-network-activity.js +65 -115
- package/package.json +1 -1
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/monitoring/classes.metricsmanager.ts +77 -1
- package/ts/opsserver/handlers/security.handler.ts +27 -23
- package/ts/opsserver/handlers/stats.handler.ts +22 -2
- package/ts_web/00_commitinfo_data.ts +1 -1
- package/ts_web/appstate.ts +53 -63
- package/ts_web/elements/domains/ops-view-domains.ts +8 -10
- package/ts_web/elements/network/ops-view-network-activity.ts +67 -132
|
@@ -553,12 +553,14 @@ export class MetricsManager {
|
|
|
553
553
|
connectionsByIP: new Map<string, number>(),
|
|
554
554
|
throughputRate: { bytesInPerSecond: 0, bytesOutPerSecond: 0 },
|
|
555
555
|
topIPs: [] as Array<{ ip: string; count: number }>,
|
|
556
|
+
topIPsByBandwidth: [] as Array<{ ip: string; count: number; bwIn: number; bwOut: number }>,
|
|
556
557
|
totalDataTransferred: { bytesIn: 0, bytesOut: 0 },
|
|
557
558
|
throughputHistory: [] as Array<{ timestamp: number; in: number; out: number }>,
|
|
558
559
|
throughputByIP: new Map<string, { in: number; out: number }>(),
|
|
559
560
|
requestsPerSecond: 0,
|
|
560
561
|
requestsTotal: 0,
|
|
561
562
|
backends: [] as Array<any>,
|
|
563
|
+
domainActivity: [] as Array<{ domain: string; bytesInPerSecond: number; bytesOutPerSecond: number; activeConnections: number; routeCount: number }>,
|
|
562
564
|
};
|
|
563
565
|
}
|
|
564
566
|
|
|
@@ -572,7 +574,7 @@ export class MetricsManager {
|
|
|
572
574
|
bytesOutPerSecond: instantThroughput.out
|
|
573
575
|
};
|
|
574
576
|
|
|
575
|
-
// Get top IPs
|
|
577
|
+
// Get top IPs by connection count
|
|
576
578
|
const topIPs = proxyMetrics.connections.topIPs(10);
|
|
577
579
|
|
|
578
580
|
// Get total data transferred
|
|
@@ -699,10 +701,83 @@ export class MetricsManager {
|
|
|
699
701
|
}
|
|
700
702
|
}
|
|
701
703
|
|
|
704
|
+
// Build top 10 IPs by bandwidth (sorted by total throughput desc)
|
|
705
|
+
const allIPData = new Map<string, { count: number; bwIn: number; bwOut: number }>();
|
|
706
|
+
for (const [ip, count] of connectionsByIP) {
|
|
707
|
+
allIPData.set(ip, { count, bwIn: 0, bwOut: 0 });
|
|
708
|
+
}
|
|
709
|
+
for (const [ip, tp] of throughputByIP) {
|
|
710
|
+
const existing = allIPData.get(ip);
|
|
711
|
+
if (existing) {
|
|
712
|
+
existing.bwIn = tp.in;
|
|
713
|
+
existing.bwOut = tp.out;
|
|
714
|
+
} else {
|
|
715
|
+
allIPData.set(ip, { count: 0, bwIn: tp.in, bwOut: tp.out });
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
const topIPsByBandwidth = Array.from(allIPData.entries())
|
|
719
|
+
.sort((a, b) => (b[1].bwIn + b[1].bwOut) - (a[1].bwIn + a[1].bwOut))
|
|
720
|
+
.slice(0, 10)
|
|
721
|
+
.map(([ip, data]) => ({ ip, count: data.count, bwIn: data.bwIn, bwOut: data.bwOut }));
|
|
722
|
+
|
|
723
|
+
// Build domain activity from per-route metrics
|
|
724
|
+
const connectionsByRoute = proxyMetrics.connections.byRoute();
|
|
725
|
+
const throughputByRoute = proxyMetrics.throughput.byRoute();
|
|
726
|
+
|
|
727
|
+
// Map route name → primary domain using dcrouter's route configs
|
|
728
|
+
const routeToDomain = new Map<string, string>();
|
|
729
|
+
if (this.dcRouter.smartProxy) {
|
|
730
|
+
for (const route of this.dcRouter.smartProxy.routeManager.getRoutes()) {
|
|
731
|
+
if (!route.name || !route.match.domains) continue;
|
|
732
|
+
const domains = Array.isArray(route.match.domains)
|
|
733
|
+
? route.match.domains
|
|
734
|
+
: [route.match.domains];
|
|
735
|
+
if (domains.length > 0) {
|
|
736
|
+
routeToDomain.set(route.name, domains[0]);
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
// Aggregate metrics by domain
|
|
742
|
+
const domainAgg = new Map<string, {
|
|
743
|
+
activeConnections: number;
|
|
744
|
+
bytesInPerSec: number;
|
|
745
|
+
bytesOutPerSec: number;
|
|
746
|
+
routeCount: number;
|
|
747
|
+
}>();
|
|
748
|
+
for (const [routeName, activeConns] of connectionsByRoute) {
|
|
749
|
+
const domain = routeToDomain.get(routeName) || routeName;
|
|
750
|
+
const tp = throughputByRoute.get(routeName) || { in: 0, out: 0 };
|
|
751
|
+
const existing = domainAgg.get(domain);
|
|
752
|
+
if (existing) {
|
|
753
|
+
existing.activeConnections += activeConns;
|
|
754
|
+
existing.bytesInPerSec += tp.in;
|
|
755
|
+
existing.bytesOutPerSec += tp.out;
|
|
756
|
+
existing.routeCount++;
|
|
757
|
+
} else {
|
|
758
|
+
domainAgg.set(domain, {
|
|
759
|
+
activeConnections: activeConns,
|
|
760
|
+
bytesInPerSec: tp.in,
|
|
761
|
+
bytesOutPerSec: tp.out,
|
|
762
|
+
routeCount: 1,
|
|
763
|
+
});
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
const domainActivity = Array.from(domainAgg.entries())
|
|
767
|
+
.map(([domain, data]) => ({
|
|
768
|
+
domain,
|
|
769
|
+
bytesInPerSecond: data.bytesInPerSec,
|
|
770
|
+
bytesOutPerSecond: data.bytesOutPerSec,
|
|
771
|
+
activeConnections: data.activeConnections,
|
|
772
|
+
routeCount: data.routeCount,
|
|
773
|
+
}))
|
|
774
|
+
.sort((a, b) => (b.bytesInPerSecond + b.bytesOutPerSecond) - (a.bytesInPerSecond + a.bytesOutPerSecond));
|
|
775
|
+
|
|
702
776
|
return {
|
|
703
777
|
connectionsByIP,
|
|
704
778
|
throughputRate,
|
|
705
779
|
topIPs,
|
|
780
|
+
topIPsByBandwidth,
|
|
706
781
|
totalDataTransferred,
|
|
707
782
|
throughputHistory,
|
|
708
783
|
throughputByIP,
|
|
@@ -711,6 +786,7 @@ export class MetricsManager {
|
|
|
711
786
|
backends,
|
|
712
787
|
frontendProtocols,
|
|
713
788
|
backendProtocols,
|
|
789
|
+
domainActivity,
|
|
714
790
|
};
|
|
715
791
|
}, 1000); // 1s cache — matches typical dashboard poll interval
|
|
716
792
|
}
|
|
@@ -51,8 +51,8 @@ export class SecurityHandler {
|
|
|
51
51
|
startTime: conn.startTime,
|
|
52
52
|
protocol: conn.type === 'http' ? 'https' : conn.type as any,
|
|
53
53
|
state: conn.status as any,
|
|
54
|
-
bytesReceived:
|
|
55
|
-
bytesSent:
|
|
54
|
+
bytesReceived: (conn as any)._throughputIn || 0,
|
|
55
|
+
bytesSent: (conn as any)._throughputOut || 0,
|
|
56
56
|
}));
|
|
57
57
|
|
|
58
58
|
const summary = {
|
|
@@ -96,9 +96,11 @@ export class SecurityHandler {
|
|
|
96
96
|
connectionsByIP: Array.from(networkStats.connectionsByIP.entries()).map(([ip, count]) => ({ ip, count })),
|
|
97
97
|
throughputRate: networkStats.throughputRate,
|
|
98
98
|
topIPs: networkStats.topIPs,
|
|
99
|
+
topIPsByBandwidth: networkStats.topIPsByBandwidth,
|
|
99
100
|
totalDataTransferred: networkStats.totalDataTransferred,
|
|
100
101
|
throughputHistory: networkStats.throughputHistory || [],
|
|
101
102
|
throughputByIP,
|
|
103
|
+
domainActivity: networkStats.domainActivity || [],
|
|
102
104
|
requestsPerSecond: networkStats.requestsPerSecond || 0,
|
|
103
105
|
requestsTotal: networkStats.requestsTotal || 0,
|
|
104
106
|
backends: networkStats.backends || [],
|
|
@@ -110,9 +112,11 @@ export class SecurityHandler {
|
|
|
110
112
|
connectionsByIP: [],
|
|
111
113
|
throughputRate: { bytesInPerSecond: 0, bytesOutPerSecond: 0 },
|
|
112
114
|
topIPs: [],
|
|
115
|
+
topIPsByBandwidth: [],
|
|
113
116
|
totalDataTransferred: { bytesIn: 0, bytesOut: 0 },
|
|
114
117
|
throughputHistory: [],
|
|
115
118
|
throughputByIP: [],
|
|
119
|
+
domainActivity: [],
|
|
116
120
|
requestsPerSecond: 0,
|
|
117
121
|
requestsTotal: 0,
|
|
118
122
|
backends: [],
|
|
@@ -251,31 +255,31 @@ export class SecurityHandler {
|
|
|
251
255
|
const connectionInfo = await this.opsServerRef.dcRouterRef.metricsManager.getConnectionInfo();
|
|
252
256
|
const networkStats = await this.opsServerRef.dcRouterRef.metricsManager.getNetworkStats();
|
|
253
257
|
|
|
254
|
-
//
|
|
258
|
+
// One aggregate row per IP with real throughput data
|
|
255
259
|
if (networkStats.connectionsByIP && networkStats.connectionsByIP.size > 0) {
|
|
256
260
|
let connIndex = 0;
|
|
257
261
|
const publicIp = this.opsServerRef.dcRouterRef.options.publicIp || 'server';
|
|
258
|
-
|
|
262
|
+
|
|
259
263
|
for (const [ip, count] of networkStats.connectionsByIP) {
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
})
|
|
278
|
-
}
|
|
264
|
+
const tp = networkStats.throughputByIP?.get(ip);
|
|
265
|
+
connections.push({
|
|
266
|
+
id: `ip-${connIndex++}`,
|
|
267
|
+
type: 'http',
|
|
268
|
+
source: {
|
|
269
|
+
ip: ip,
|
|
270
|
+
port: 0,
|
|
271
|
+
},
|
|
272
|
+
destination: {
|
|
273
|
+
ip: publicIp,
|
|
274
|
+
port: 443,
|
|
275
|
+
service: 'proxy',
|
|
276
|
+
},
|
|
277
|
+
startTime: 0,
|
|
278
|
+
bytesTransferred: count, // Store connection count here
|
|
279
|
+
status: 'active',
|
|
280
|
+
// Attach real throughput for the handler mapping
|
|
281
|
+
...(tp ? { _throughputIn: tp.in, _throughputOut: tp.out } : {}),
|
|
282
|
+
} as any);
|
|
279
283
|
}
|
|
280
284
|
} else if (connectionInfo.length > 0) {
|
|
281
285
|
// Fallback to route-based connection info if no IP data available
|
|
@@ -291,6 +291,20 @@ export class StatsHandler {
|
|
|
291
291
|
}
|
|
292
292
|
}
|
|
293
293
|
|
|
294
|
+
// Build connectionDetails from real per-IP data
|
|
295
|
+
const connectionDetails: interfaces.data.IConnectionDetails[] = [];
|
|
296
|
+
for (const [ip, count] of stats.connectionsByIP) {
|
|
297
|
+
const tp = stats.throughputByIP?.get(ip);
|
|
298
|
+
connectionDetails.push({
|
|
299
|
+
remoteAddress: ip,
|
|
300
|
+
protocol: 'https',
|
|
301
|
+
state: 'connected',
|
|
302
|
+
startTime: 0,
|
|
303
|
+
bytesIn: tp?.in || 0,
|
|
304
|
+
bytesOut: tp?.out || 0,
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
|
|
294
308
|
metrics.network = {
|
|
295
309
|
totalBandwidth: {
|
|
296
310
|
in: stats.throughputRate.bytesInPerSecond,
|
|
@@ -301,12 +315,18 @@ export class StatsHandler {
|
|
|
301
315
|
out: stats.totalDataTransferred.bytesOut,
|
|
302
316
|
},
|
|
303
317
|
activeConnections: serverStats.activeConnections,
|
|
304
|
-
connectionDetails
|
|
318
|
+
connectionDetails,
|
|
305
319
|
topEndpoints: stats.topIPs.map(ip => ({
|
|
306
320
|
endpoint: ip.ip,
|
|
307
|
-
|
|
321
|
+
connections: ip.count,
|
|
308
322
|
bandwidth: ipBandwidth.get(ip.ip) || { in: 0, out: 0 },
|
|
309
323
|
})),
|
|
324
|
+
topEndpointsByBandwidth: stats.topIPsByBandwidth.map(ip => ({
|
|
325
|
+
endpoint: ip.ip,
|
|
326
|
+
connections: ip.count,
|
|
327
|
+
bandwidth: { in: ip.bwIn, out: ip.bwOut },
|
|
328
|
+
})),
|
|
329
|
+
domainActivity: stats.domainActivity || [],
|
|
310
330
|
throughputHistory: stats.throughputHistory || [],
|
|
311
331
|
requestsPerSecond: stats.requestsPerSecond || 0,
|
|
312
332
|
requestsTotal: stats.requestsTotal || 0,
|
package/ts_web/appstate.ts
CHANGED
|
@@ -52,7 +52,9 @@ export interface INetworkState {
|
|
|
52
52
|
throughputRate: { bytesInPerSecond: number; bytesOutPerSecond: number };
|
|
53
53
|
totalBytes: { in: number; out: number };
|
|
54
54
|
topIPs: Array<{ ip: string; count: number }>;
|
|
55
|
+
topIPsByBandwidth: Array<{ ip: string; count: number; bwIn: number; bwOut: number }>;
|
|
55
56
|
throughputByIP: Array<{ ip: string; in: number; out: number }>;
|
|
57
|
+
domainActivity: interfaces.data.IDomainActivity[];
|
|
56
58
|
throughputHistory: Array<{ timestamp: number; in: number; out: number }>;
|
|
57
59
|
requestsPerSecond: number;
|
|
58
60
|
requestsTotal: number;
|
|
@@ -160,7 +162,9 @@ export const networkStatePart = await appState.getStatePart<INetworkState>(
|
|
|
160
162
|
throughputRate: { bytesInPerSecond: 0, bytesOutPerSecond: 0 },
|
|
161
163
|
totalBytes: { in: 0, out: 0 },
|
|
162
164
|
topIPs: [],
|
|
165
|
+
topIPsByBandwidth: [],
|
|
163
166
|
throughputByIP: [],
|
|
167
|
+
domainActivity: [],
|
|
164
168
|
throughputHistory: [],
|
|
165
169
|
requestsPerSecond: 0,
|
|
166
170
|
requestsTotal: 0,
|
|
@@ -518,14 +522,13 @@ export const fetchNetworkStatsAction = networkStatePart.createAction(async (stat
|
|
|
518
522
|
});
|
|
519
523
|
|
|
520
524
|
// Get network stats for throughput and IP data
|
|
521
|
-
const networkStatsRequest = new plugins.domtools.plugins.typedrequest.TypedRequest
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
525
|
+
const networkStatsRequest = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
|
526
|
+
interfaces.requests.IReq_GetNetworkStats
|
|
527
|
+
>('/typedrequest', 'getNetworkStats');
|
|
528
|
+
|
|
526
529
|
const networkStatsResponse = await networkStatsRequest.fire({
|
|
527
530
|
identity: context.identity,
|
|
528
|
-
})
|
|
531
|
+
});
|
|
529
532
|
|
|
530
533
|
// Use the connections data for the connection list
|
|
531
534
|
// and network stats for throughput and IP analytics
|
|
@@ -552,7 +555,9 @@ export const fetchNetworkStatsAction = networkStatePart.createAction(async (stat
|
|
|
552
555
|
? { in: networkStatsResponse.totalDataTransferred.bytesIn, out: networkStatsResponse.totalDataTransferred.bytesOut }
|
|
553
556
|
: { in: 0, out: 0 },
|
|
554
557
|
topIPs: networkStatsResponse.topIPs || [],
|
|
558
|
+
topIPsByBandwidth: networkStatsResponse.topIPsByBandwidth || [],
|
|
555
559
|
throughputByIP: networkStatsResponse.throughputByIP || [],
|
|
560
|
+
domainActivity: networkStatsResponse.domainActivity || [],
|
|
556
561
|
throughputHistory: networkStatsResponse.throughputHistory || [],
|
|
557
562
|
requestsPerSecond: networkStatsResponse.requestsPerSecond || 0,
|
|
558
563
|
requestsTotal: networkStatsResponse.requestsTotal || 0,
|
|
@@ -2649,67 +2654,52 @@ async function dispatchCombinedRefreshActionInner() {
|
|
|
2649
2654
|
if (combinedResponse.metrics.network && currentView === 'network') {
|
|
2650
2655
|
const network = combinedResponse.metrics.network;
|
|
2651
2656
|
const connectionsByIP: { [ip: string]: number } = {};
|
|
2652
|
-
|
|
2653
|
-
//
|
|
2657
|
+
|
|
2658
|
+
// Build connectionsByIP from connectionDetails (now populated with real per-IP data)
|
|
2654
2659
|
network.connectionDetails.forEach(conn => {
|
|
2655
2660
|
connectionsByIP[conn.remoteAddress] = (connectionsByIP[conn.remoteAddress] || 0) + 1;
|
|
2656
2661
|
});
|
|
2657
2662
|
|
|
2658
|
-
//
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
},
|
|
2699
|
-
totalBytes: network.totalBytes || { in: 0, out: 0 },
|
|
2700
|
-
topIPs: network.topEndpoints.map(e => ({ ip: e.endpoint, count: e.requests })),
|
|
2701
|
-
throughputByIP: network.topEndpoints.map(e => ({ ip: e.endpoint, in: e.bandwidth?.in || 0, out: e.bandwidth?.out || 0 })),
|
|
2702
|
-
throughputHistory: network.throughputHistory || [],
|
|
2703
|
-
requestsPerSecond: network.requestsPerSecond || 0,
|
|
2704
|
-
requestsTotal: network.requestsTotal || 0,
|
|
2705
|
-
backends: network.backends || [],
|
|
2706
|
-
frontendProtocols: network.frontendProtocols || null,
|
|
2707
|
-
backendProtocols: network.backendProtocols || null,
|
|
2708
|
-
lastUpdated: Date.now(),
|
|
2709
|
-
isLoading: false,
|
|
2710
|
-
error: null,
|
|
2711
|
-
});
|
|
2712
|
-
}
|
|
2663
|
+
// Build connections from connectionDetails (real per-IP aggregates)
|
|
2664
|
+
const connections: interfaces.data.IConnectionInfo[] = network.connectionDetails.map((conn, i) => ({
|
|
2665
|
+
id: `ip-${conn.remoteAddress}`,
|
|
2666
|
+
remoteAddress: conn.remoteAddress,
|
|
2667
|
+
localAddress: 'server',
|
|
2668
|
+
startTime: conn.startTime,
|
|
2669
|
+
protocol: conn.protocol as any,
|
|
2670
|
+
state: conn.state as any,
|
|
2671
|
+
bytesReceived: conn.bytesIn,
|
|
2672
|
+
bytesSent: conn.bytesOut,
|
|
2673
|
+
}));
|
|
2674
|
+
|
|
2675
|
+
networkStatePart.setState({
|
|
2676
|
+
...networkStatePart.getState()!,
|
|
2677
|
+
connections,
|
|
2678
|
+
connectionsByIP,
|
|
2679
|
+
throughputRate: {
|
|
2680
|
+
bytesInPerSecond: network.totalBandwidth.in,
|
|
2681
|
+
bytesOutPerSecond: network.totalBandwidth.out,
|
|
2682
|
+
},
|
|
2683
|
+
totalBytes: network.totalBytes || { in: 0, out: 0 },
|
|
2684
|
+
topIPs: network.topEndpoints.map(e => ({ ip: e.endpoint, count: e.connections })),
|
|
2685
|
+
topIPsByBandwidth: (network.topEndpointsByBandwidth || []).map(e => ({
|
|
2686
|
+
ip: e.endpoint,
|
|
2687
|
+
count: e.connections,
|
|
2688
|
+
bwIn: e.bandwidth?.in || 0,
|
|
2689
|
+
bwOut: e.bandwidth?.out || 0,
|
|
2690
|
+
})),
|
|
2691
|
+
throughputByIP: network.topEndpoints.map(e => ({ ip: e.endpoint, in: e.bandwidth?.in || 0, out: e.bandwidth?.out || 0 })),
|
|
2692
|
+
domainActivity: network.domainActivity || [],
|
|
2693
|
+
throughputHistory: network.throughputHistory || [],
|
|
2694
|
+
requestsPerSecond: network.requestsPerSecond || 0,
|
|
2695
|
+
requestsTotal: network.requestsTotal || 0,
|
|
2696
|
+
backends: network.backends || [],
|
|
2697
|
+
frontendProtocols: network.frontendProtocols || null,
|
|
2698
|
+
backendProtocols: network.backendProtocols || null,
|
|
2699
|
+
lastUpdated: Date.now(),
|
|
2700
|
+
isLoading: false,
|
|
2701
|
+
error: null,
|
|
2702
|
+
});
|
|
2713
2703
|
}
|
|
2714
2704
|
|
|
2715
2705
|
// Refresh certificate data if on Domains > Certificates subview
|
|
@@ -323,16 +323,14 @@ export class OpsViewDomains extends DeesElement {
|
|
|
323
323
|
|
|
324
324
|
// Build target options based on current source
|
|
325
325
|
const targetOptions: { option: string; key: string }[] = [];
|
|
326
|
-
if (domain.source === 'provider') {
|
|
327
|
-
targetOptions.push({ option: 'DcRouter (authoritative)', key: 'dcrouter' });
|
|
328
|
-
}
|
|
329
|
-
// Add all providers (except the current one if already provider-managed)
|
|
330
326
|
for (const p of providers) {
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
327
|
+
// Skip current source
|
|
328
|
+
if (p.builtIn && domain.source === 'dcrouter') continue;
|
|
329
|
+
if (!p.builtIn && domain.source === 'provider' && domain.providerId === p.id) continue;
|
|
330
|
+
|
|
331
|
+
const label = p.builtIn ? 'DcRouter (self)' : `${p.name} (${p.type})`;
|
|
332
|
+
const key = p.builtIn ? 'dcrouter' : `provider:${p.id}`;
|
|
333
|
+
targetOptions.push({ option: label, key });
|
|
336
334
|
}
|
|
337
335
|
|
|
338
336
|
if (targetOptions.length === 0) {
|
|
@@ -345,7 +343,7 @@ export class OpsViewDomains extends DeesElement {
|
|
|
345
343
|
}
|
|
346
344
|
|
|
347
345
|
const currentLabel = domain.source === 'dcrouter'
|
|
348
|
-
? 'DcRouter (
|
|
346
|
+
? 'DcRouter (self)'
|
|
349
347
|
: providers.find((p) => p.id === domain.providerId)?.name || 'Provider';
|
|
350
348
|
|
|
351
349
|
DeesModal.createAndShow({
|