This commit is contained in:
Juergen Kunz
2025-07-17 15:34:58 +00:00
parent 82df9a6f52
commit b26abbfd87
7 changed files with 38 additions and 37 deletions

View File

@@ -18,29 +18,29 @@ Implement enhanced routing structure with multiple targets per route, sub-matchi
### 3. Implementation Steps ### 3. Implementation Steps
#### Phase 1: Type Updates #### Phase 1: Type Updates
- [ ] Update `IRouteTarget` interface in `route-types.ts` - [x] Update `IRouteTarget` interface in `route-types.ts`
- Add `match?: ITargetMatch` property - Add `match?: ITargetMatch` property
- Add override properties (tls, websocket, etc.) - Add override properties (tls, websocket, etc.)
- Add `priority?: number` field - Add `priority?: number` field
- [ ] Create `ITargetMatch` interface for sub-matching criteria - [x] Create `ITargetMatch` interface for sub-matching criteria
- [ ] Update `IRouteAction` to use only `targets: IRouteTarget[]` - [x] Update `IRouteAction` to use only `targets: IRouteTarget[]`
#### Phase 2: Route Resolution Logic #### Phase 2: Route Resolution Logic
- [ ] Update route matching logic to handle multiple targets - [x] Update route matching logic to handle multiple targets
- [ ] Implement target sub-matching algorithm: - [x] Implement target sub-matching algorithm:
1. Sort targets by priority (highest first) 1. Sort targets by priority (highest first)
2. For each target with a match property, check if request matches 2. For each target with a match property, check if request matches
3. Use first matching target, or fallback to target without match 3. Use first matching target, or fallback to target without match
- [ ] Ensure target-specific settings override route-level settings - [x] Ensure target-specific settings override route-level settings
#### Phase 3: Code Migration #### Phase 3: Code Migration
- [ ] Find all occurrences of `action.target` and update to `action.targets[0]` - [x] Find all occurrences of `action.target` and update to use `action.targets`
- [ ] Update route helpers and utilities - [x] Update route helpers and utilities
- [ ] Update certificate manager to handle multiple targets - [x] Update certificate manager to handle multiple targets
- [ ] Update connection handlers - [x] Update connection handlers
#### Phase 4: Testing #### Phase 4: Testing
- [ ] Update existing tests to use new format - [x] Update existing tests to use new format
- [ ] Add tests for multi-target scenarios - [ ] Add tests for multi-target scenarios
- [ ] Add tests for sub-matching logic - [ ] Add tests for sub-matching logic
- [ ] Add tests for setting overrides - [ ] Add tests for setting overrides

View File

@@ -82,7 +82,7 @@ tap.test('Route-level connection limits', async () => {
const route: IRouteConfig = { const route: IRouteConfig = {
name: 'test-route', name: 'test-route',
match: { ports: 443 }, match: { ports: 443 },
action: { type: 'forward', target: { host: 'localhost', port: 8080 } }, action: { type: 'forward', targets: [{ host: 'localhost', port: 8080 }] },
security: { security: {
maxConnections: 3 maxConnections: 3
} }

View File

@@ -400,9 +400,9 @@ tap.test('should use round robin for multiple target hosts in domain config', as
// For route-based approach, the actual round-robin logic happens in connection handling // For route-based approach, the actual round-robin logic happens in connection handling
// Just make sure our config has the expected hosts // Just make sure our config has the expected hosts
expect(Array.isArray(routeConfig.action.target.host)).toBeTrue(); expect(Array.isArray(routeConfig.action.targets[0].host)).toBeTrue();
expect(routeConfig.action.target.host).toContain('hostA'); expect(routeConfig.action.targets[0].host).toContain('hostA');
expect(routeConfig.action.target.host).toContain('hostB'); expect(routeConfig.action.targets[0].host).toContain('hostB');
}); });
// CLEANUP: Tear down all servers and proxies // CLEANUP: Tear down all servers and proxies

View File

@@ -247,7 +247,8 @@ export interface IRouteAction {
type: TRouteActionType; type: TRouteActionType;
// Targets for forwarding (array supports multiple targets with sub-matching) // Targets for forwarding (array supports multiple targets with sub-matching)
targets: IRouteTarget[]; // Required for 'forward' action type
targets?: IRouteTarget[];
// TLS handling (default for all targets, can be overridden per target) // TLS handling (default for all targets, can be overridden per target)
tls?: IRouteTls; tls?: IRouteTls;

View File

@@ -922,7 +922,7 @@ export class RouteConnectionHandler {
routeContext.targetHost = selectedHost; routeContext.targetHost = selectedHost;
// Get effective settings (target overrides route-level settings) // Get effective settings (target overrides route-level settings)
const effectiveTls = selectedTarget.tls || effectiveTls; const effectiveTls = selectedTarget.tls || action.tls;
const effectiveWebsocket = selectedTarget.websocket || action.websocket; const effectiveWebsocket = selectedTarget.websocket || action.websocket;
const effectiveSendProxyProtocol = selectedTarget.sendProxyProtocol !== undefined const effectiveSendProxyProtocol = selectedTarget.sendProxyProtocol !== undefined
? selectedTarget.sendProxyProtocol ? selectedTarget.sendProxyProtocol

View File

@@ -42,7 +42,7 @@ export function createHttpRoute(
// Create route action // Create route action
const action: IRouteAction = { const action: IRouteAction = {
type: 'forward', type: 'forward',
target targets: [target]
}; };
// Create the route config // Create the route config
@@ -82,7 +82,7 @@ export function createHttpsTerminateRoute(
// Create route action // Create route action
const action: IRouteAction = { const action: IRouteAction = {
type: 'forward', type: 'forward',
target, targets: [target],
tls: { tls: {
mode: options.reencrypt ? 'terminate-and-reencrypt' : 'terminate', mode: options.reencrypt ? 'terminate-and-reencrypt' : 'terminate',
certificate: options.certificate || 'auto' certificate: options.certificate || 'auto'
@@ -152,7 +152,7 @@ export function createHttpsPassthroughRoute(
// Create route action // Create route action
const action: IRouteAction = { const action: IRouteAction = {
type: 'forward', type: 'forward',
target, targets: [target],
tls: { tls: {
mode: 'passthrough' mode: 'passthrough'
} }
@@ -243,7 +243,7 @@ export function createLoadBalancerRoute(
// Create route action // Create route action
const action: IRouteAction = { const action: IRouteAction = {
type: 'forward', type: 'forward',
target targets: [target]
}; };
// Add TLS configuration if provided // Add TLS configuration if provided
@@ -303,7 +303,7 @@ export function createApiRoute(
// Create route action // Create route action
const action: IRouteAction = { const action: IRouteAction = {
type: 'forward', type: 'forward',
target targets: [target]
}; };
// Add TLS configuration if using HTTPS // Add TLS configuration if using HTTPS
@@ -374,7 +374,7 @@ export function createWebSocketRoute(
// Create route action // Create route action
const action: IRouteAction = { const action: IRouteAction = {
type: 'forward', type: 'forward',
target, targets: [target],
websocket: { websocket: {
enabled: true, enabled: true,
pingInterval: options.pingInterval || 30000, // 30 seconds pingInterval: options.pingInterval || 30000, // 30 seconds
@@ -432,10 +432,10 @@ export function createPortMappingRoute(options: {
// Create route action // Create route action
const action: IRouteAction = { const action: IRouteAction = {
type: 'forward', type: 'forward',
target: { targets: [{
host: options.targetHost, host: options.targetHost,
port: options.portMapper port: options.portMapper
} }]
}; };
// Create the route config // Create the route config
@@ -500,10 +500,10 @@ export function createDynamicRoute(options: {
// Create route action // Create route action
const action: IRouteAction = { const action: IRouteAction = {
type: 'forward', type: 'forward',
target: { targets: [{
host: options.targetHost, host: options.targetHost,
port: options.portMapper port: options.portMapper
} }]
}; };
// Create the route config // Create the route config
@@ -548,10 +548,10 @@ export function createSmartLoadBalancer(options: {
// Create route action // Create route action
const action: IRouteAction = { const action: IRouteAction = {
type: 'forward', type: 'forward',
target: { targets: [{
host: hostSelector, host: hostSelector,
port: options.portMapper port: options.portMapper
} }]
}; };
// Create the route config // Create the route config
@@ -609,10 +609,10 @@ export function createNfTablesRoute(
// Create route action // Create route action
const action: IRouteAction = { const action: IRouteAction = {
type: 'forward', type: 'forward',
target: { targets: [{
host: target.host, host: target.host,
port: target.port port: target.port
}, }],
forwardingEngine: 'nftables', forwardingEngine: 'nftables',
nftables: { nftables: {
protocol: options.protocol || 'tcp', protocol: options.protocol || 'tcp',

View File

@@ -24,10 +24,10 @@ export function createHttpRoute(
}, },
action: { action: {
type: 'forward', type: 'forward',
target: { targets: [{
host: target.host, host: target.host,
port: target.port port: target.port
} }]
}, },
name: options.name || `HTTP: ${Array.isArray(domains) ? domains.join(', ') : domains}` name: options.name || `HTTP: ${Array.isArray(domains) ? domains.join(', ') : domains}`
}; };
@@ -53,10 +53,10 @@ export function createHttpsTerminateRoute(
}, },
action: { action: {
type: 'forward', type: 'forward',
target: { targets: [{
host: target.host, host: target.host,
port: target.port port: target.port
}, }],
tls: { tls: {
mode: options.reencrypt ? 'terminate-and-reencrypt' : 'terminate', mode: options.reencrypt ? 'terminate-and-reencrypt' : 'terminate',
certificate: options.certificate || 'auto' certificate: options.certificate || 'auto'
@@ -83,10 +83,10 @@ export function createHttpsPassthroughRoute(
}, },
action: { action: {
type: 'forward', type: 'forward',
target: { targets: [{
host: target.host, host: target.host,
port: target.port port: target.port
}, }],
tls: { tls: {
mode: 'passthrough' mode: 'passthrough'
} }