@serve.zone/dcrouter 13.19.1 → 13.20.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 +315 -305
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/config/classes.route-config-manager.js +9 -2
- package/dist_ts_web/00_commitinfo_data.js +1 -1
- package/dist_ts_web/elements/network/ops-view-routes.js +70 -10
- package/package.json +1 -1
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/config/classes.route-config-manager.ts +10 -1
- package/ts_web/00_commitinfo_data.ts +1 -1
- package/ts_web/elements/network/ops-view-routes.ts +71 -8
|
@@ -43,22 +43,28 @@ function parseTargetPort(value: any): number | undefined {
|
|
|
43
43
|
|
|
44
44
|
function getRouteTargetInputs(formEl: any) {
|
|
45
45
|
const textInputs = Array.from(formEl.querySelectorAll('dees-input-text')) as any[];
|
|
46
|
+
const checkboxInputs = Array.from(formEl.querySelectorAll('dees-input-checkbox')) as any[];
|
|
46
47
|
return {
|
|
47
48
|
hostInput: textInputs.find((input) => input.key === 'targetHost'),
|
|
48
49
|
portInput: textInputs.find((input) => input.key === 'targetPort'),
|
|
50
|
+
preservePortInput: checkboxInputs.find((input) => input.key === 'preserveMatchPort'),
|
|
49
51
|
};
|
|
50
52
|
}
|
|
51
53
|
|
|
52
54
|
function setupTargetInputState(formEl: any) {
|
|
53
55
|
const updateState = async () => {
|
|
54
56
|
const data = await formEl.collectFormData();
|
|
57
|
+
const contentEl = formEl.closest('.content') || formEl.parentElement;
|
|
55
58
|
const usesNetworkTarget = !!getDropdownKey(data.networkTargetRef);
|
|
56
|
-
const
|
|
59
|
+
const preserveMatchPort = !usesNetworkTarget && Boolean(data.preserveMatchPort);
|
|
60
|
+
const { hostInput, portInput, preservePortInput } = getRouteTargetInputs(formEl);
|
|
57
61
|
const hostDescription = usesNetworkTarget
|
|
58
62
|
? 'Controlled by the selected network target'
|
|
59
63
|
: 'Used when no network target is selected';
|
|
60
64
|
const portDescription = usesNetworkTarget
|
|
61
65
|
? 'Controlled by the selected network target'
|
|
66
|
+
: preserveMatchPort
|
|
67
|
+
? 'Forwarded to the backend on the same port the client matched'
|
|
62
68
|
: 'Used when no network target is selected';
|
|
63
69
|
|
|
64
70
|
if (hostInput) {
|
|
@@ -67,10 +73,24 @@ function setupTargetInputState(formEl: any) {
|
|
|
67
73
|
hostInput.description = hostDescription;
|
|
68
74
|
}
|
|
69
75
|
if (portInput) {
|
|
70
|
-
portInput.disabled = usesNetworkTarget;
|
|
71
|
-
portInput.required = !usesNetworkTarget;
|
|
76
|
+
portInput.disabled = usesNetworkTarget || preserveMatchPort;
|
|
77
|
+
portInput.required = !usesNetworkTarget && !preserveMatchPort;
|
|
72
78
|
portInput.description = portDescription;
|
|
73
79
|
}
|
|
80
|
+
if (preservePortInput) {
|
|
81
|
+
preservePortInput.disabled = usesNetworkTarget;
|
|
82
|
+
preservePortInput.description = usesNetworkTarget
|
|
83
|
+
? 'Unavailable when a network target is selected'
|
|
84
|
+
: 'Forward to the backend using the same port that matched this route';
|
|
85
|
+
if (usesNetworkTarget) {
|
|
86
|
+
preservePortInput.value = false;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const remoteIngressGroup = contentEl?.querySelector('.remoteIngressGroup') as HTMLElement | null;
|
|
91
|
+
if (remoteIngressGroup) {
|
|
92
|
+
remoteIngressGroup.style.display = Boolean(data.remoteIngressEnabled) ? 'flex' : 'none';
|
|
93
|
+
}
|
|
74
94
|
|
|
75
95
|
await formEl.updateRequiredStatus?.();
|
|
76
96
|
};
|
|
@@ -465,10 +485,13 @@ export class OpsViewRoutes extends DeesElement {
|
|
|
465
485
|
? (Array.isArray(route.match.domains) ? route.match.domains : [route.match.domains])
|
|
466
486
|
: [];
|
|
467
487
|
const firstTarget = route.action.targets?.[0];
|
|
488
|
+
const currentPreserveMatchPort = firstTarget?.port === 'preserve';
|
|
468
489
|
const currentTargetHost = firstTarget
|
|
469
490
|
? (Array.isArray(firstTarget.host) ? firstTarget.host[0] : firstTarget.host)
|
|
470
491
|
: '';
|
|
471
|
-
const currentTargetPort = firstTarget?.port
|
|
492
|
+
const currentTargetPort = typeof firstTarget?.port === 'number' ? String(firstTarget.port) : '';
|
|
493
|
+
const currentRemoteIngressEnabled = route.remoteIngress?.enabled === true;
|
|
494
|
+
const currentEdgeFilter = route.remoteIngress?.edgeFilter || [];
|
|
472
495
|
|
|
473
496
|
// Compute current TLS state for pre-population
|
|
474
497
|
const currentTls = (route.action as any).tls;
|
|
@@ -493,6 +516,11 @@ export class OpsViewRoutes extends DeesElement {
|
|
|
493
516
|
<dees-input-dropdown .key=${'networkTargetRef'} .label=${'Network Target'} .options=${targetOptions} .selectedOption=${targetOptions.find((o) => o.key === (merged.metadata?.networkTargetRef || '')) || null}></dees-input-dropdown>
|
|
494
517
|
<dees-input-text .key=${'targetHost'} .label=${'Target Host'} .description=${'Used when no network target is selected'} .value=${currentTargetHost}></dees-input-text>
|
|
495
518
|
<dees-input-text .key=${'targetPort'} .label=${'Target Port'} .description=${'Used when no network target is selected'} .value=${currentTargetPort}></dees-input-text>
|
|
519
|
+
<dees-input-checkbox .key=${'preserveMatchPort'} .label=${'Preserve incoming port'} .value=${currentPreserveMatchPort}></dees-input-checkbox>
|
|
520
|
+
<dees-input-checkbox .key=${'remoteIngressEnabled'} .label=${'Enable Remote Ingress'} .value=${currentRemoteIngressEnabled}></dees-input-checkbox>
|
|
521
|
+
<div class="remoteIngressGroup" style="display: ${currentRemoteIngressEnabled ? 'flex' : 'none'}; flex-direction: column; gap: 16px;">
|
|
522
|
+
<dees-input-list .key=${'remoteIngressEdgeFilter'} .label=${'Edge Filter'} .description=${'Optional edge IDs or tags. Leave empty to allow all edges.'} .placeholder=${'Add edge ID or tag...'} .value=${currentEdgeFilter}></dees-input-list>
|
|
523
|
+
</div>
|
|
496
524
|
<dees-input-dropdown .key=${'tlsMode'} .label=${'TLS Mode'} .options=${tlsModeOptions} .selectedOption=${tlsModeOptions.find((o) => o.key === currentTlsMode) || tlsModeOptions[0]}></dees-input-dropdown>
|
|
497
525
|
<div class="tlsCertificateGroup" style="display: ${needsCert ? 'flex' : 'none'}; flex-direction: column; gap: 16px;">
|
|
498
526
|
<dees-input-dropdown .key=${'tlsCertificate'} .label=${'Certificate'} .options=${tlsCertOptions} .selectedOption=${tlsCertOptions.find((o) => o.key === currentTlsCert) || tlsCertOptions[0]}></dees-input-dropdown>
|
|
@@ -526,14 +554,22 @@ export class OpsViewRoutes extends DeesElement {
|
|
|
526
554
|
|
|
527
555
|
const profileKey = getDropdownKey(formData.sourceProfileRef);
|
|
528
556
|
const targetKey = getDropdownKey(formData.networkTargetRef);
|
|
529
|
-
const
|
|
530
|
-
|
|
557
|
+
const preserveMatchPort = !targetKey && Boolean(formData.preserveMatchPort);
|
|
558
|
+
const targetPort = preserveMatchPort
|
|
559
|
+
? 'preserve'
|
|
560
|
+
: parseTargetPort(formData.targetPort)
|
|
561
|
+
?? (targetKey ? parseTargetPort(currentTargetPort) ?? ports[0] : undefined);
|
|
531
562
|
|
|
532
563
|
if (targetPort === undefined) {
|
|
533
564
|
alert('Target Port must be a valid port number when no network target is selected.');
|
|
534
565
|
return;
|
|
535
566
|
}
|
|
536
567
|
|
|
568
|
+
const remoteIngressEnabled = Boolean(formData.remoteIngressEnabled);
|
|
569
|
+
const remoteIngressEdgeFilter: string[] = Array.isArray(formData.remoteIngressEdgeFilter)
|
|
570
|
+
? formData.remoteIngressEdgeFilter.filter(Boolean)
|
|
571
|
+
: [];
|
|
572
|
+
|
|
537
573
|
const updatedRoute: any = {
|
|
538
574
|
name: formData.name,
|
|
539
575
|
match: {
|
|
@@ -549,6 +585,12 @@ export class OpsViewRoutes extends DeesElement {
|
|
|
549
585
|
},
|
|
550
586
|
],
|
|
551
587
|
},
|
|
588
|
+
remoteIngress: remoteIngressEnabled
|
|
589
|
+
? {
|
|
590
|
+
enabled: true,
|
|
591
|
+
...(remoteIngressEdgeFilter.length > 0 ? { edgeFilter: remoteIngressEdgeFilter } : {}),
|
|
592
|
+
}
|
|
593
|
+
: null,
|
|
552
594
|
...(priority != null && !isNaN(priority) ? { priority } : {}),
|
|
553
595
|
};
|
|
554
596
|
|
|
@@ -640,6 +682,11 @@ export class OpsViewRoutes extends DeesElement {
|
|
|
640
682
|
<dees-input-dropdown .key=${'networkTargetRef'} .label=${'Network Target'} .options=${targetOptions}></dees-input-dropdown>
|
|
641
683
|
<dees-input-text .key=${'targetHost'} .label=${'Target Host'} .description=${'Used when no network target is selected'} .value=${'localhost'}></dees-input-text>
|
|
642
684
|
<dees-input-text .key=${'targetPort'} .label=${'Target Port'} .description=${'Used when no network target is selected'}></dees-input-text>
|
|
685
|
+
<dees-input-checkbox .key=${'preserveMatchPort'} .label=${'Preserve incoming port'} .value=${false}></dees-input-checkbox>
|
|
686
|
+
<dees-input-checkbox .key=${'remoteIngressEnabled'} .label=${'Enable Remote Ingress'} .value=${false}></dees-input-checkbox>
|
|
687
|
+
<div class="remoteIngressGroup" style="display: none; flex-direction: column; gap: 16px;">
|
|
688
|
+
<dees-input-list .key=${'remoteIngressEdgeFilter'} .label=${'Edge Filter'} .description=${'Optional edge IDs or tags. Leave empty to allow all edges.'} .placeholder=${'Add edge ID or tag...'}></dees-input-list>
|
|
689
|
+
</div>
|
|
643
690
|
<dees-input-dropdown .key=${'tlsMode'} .label=${'TLS Mode'} .options=${tlsModeOptions} .selectedOption=${tlsModeOptions[0]}></dees-input-dropdown>
|
|
644
691
|
<div class="tlsCertificateGroup" style="display: none; flex-direction: column; gap: 16px;">
|
|
645
692
|
<dees-input-dropdown .key=${'tlsCertificate'} .label=${'Certificate'} .options=${tlsCertOptions} .selectedOption=${tlsCertOptions[0]}></dees-input-dropdown>
|
|
@@ -673,14 +720,22 @@ export class OpsViewRoutes extends DeesElement {
|
|
|
673
720
|
|
|
674
721
|
const profileKey = getDropdownKey(formData.sourceProfileRef);
|
|
675
722
|
const targetKey = getDropdownKey(formData.networkTargetRef);
|
|
676
|
-
const
|
|
677
|
-
|
|
723
|
+
const preserveMatchPort = !targetKey && Boolean(formData.preserveMatchPort);
|
|
724
|
+
const targetPort = preserveMatchPort
|
|
725
|
+
? 'preserve'
|
|
726
|
+
: parseTargetPort(formData.targetPort)
|
|
727
|
+
?? (targetKey ? ports[0] : undefined);
|
|
678
728
|
|
|
679
729
|
if (targetPort === undefined) {
|
|
680
730
|
alert('Target Port must be a valid port number when no network target is selected.');
|
|
681
731
|
return;
|
|
682
732
|
}
|
|
683
733
|
|
|
734
|
+
const remoteIngressEnabled = Boolean(formData.remoteIngressEnabled);
|
|
735
|
+
const remoteIngressEdgeFilter: string[] = Array.isArray(formData.remoteIngressEdgeFilter)
|
|
736
|
+
? formData.remoteIngressEdgeFilter.filter(Boolean)
|
|
737
|
+
: [];
|
|
738
|
+
|
|
684
739
|
const route: any = {
|
|
685
740
|
name: formData.name,
|
|
686
741
|
match: {
|
|
@@ -696,6 +751,14 @@ export class OpsViewRoutes extends DeesElement {
|
|
|
696
751
|
},
|
|
697
752
|
],
|
|
698
753
|
},
|
|
754
|
+
...(remoteIngressEnabled
|
|
755
|
+
? {
|
|
756
|
+
remoteIngress: {
|
|
757
|
+
enabled: true,
|
|
758
|
+
...(remoteIngressEdgeFilter.length > 0 ? { edgeFilter: remoteIngressEdgeFilter } : {}),
|
|
759
|
+
},
|
|
760
|
+
}
|
|
761
|
+
: {}),
|
|
699
762
|
...(priority != null && !isNaN(priority) ? { priority } : {}),
|
|
700
763
|
};
|
|
701
764
|
|