feat: Fix HAProxy ACL ordering + Subdomains field

Rewrite HAProxy config generation with correct ACL ordering:
1. L7 HTTP exact matches first (central, wild-cloud app)
2. L4 exact matches (payne.io, civilsociety.dev)
3. L4 wildcard matches (*.cloud.payne.io) — only when subdomains:true
4. Default → L7 termination

Key changes:
- InstanceRoute: removed ExtraDomains, added Subdomains bool
- GenerateOpts: removed CentralDomain (Central is now just another
  HTTPRoute injected by reconciliation), renamed WildcardCert→CertsDir
- Central's domain comes from config, injected as HTTPRoute with
  the actual running port (no more hardcoded 5055)
- Added API.SetPort() so reconciliation knows the running port
- subdomains:false → exact match only (no *.domain shadowing)

New tests: TestGenerate_WithSubdomains, TestGenerate_ACLOrdering
(verifies L7 exact matches come before L4 wildcards).

Fixes: BUG 1 (central routing to wrong port), BUG 2 (wild-cloud
getting traefik cert), BUG 3 (*.payne.io too broad).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-09 20:29:30 +00:00
parent 8874bc6281
commit 548be903e7
5 changed files with 123 additions and 100 deletions

View File

@@ -150,8 +150,8 @@ func main() {
fmt.Sscanf(v, "%d", &port)
}
// Self-register Wild Central's own domain (idempotent, skips if no domain configured)
api.RegisterSelf(port)
// Tell the API what port it's running on (used for config-driven HAProxy routes)
api.SetPort(port)
addr := fmt.Sprintf("%s:%d", host, port)
slog.Info("wild-central started", "addr", addr, "version", Version)