fix: Skip L7 routes and central TLS in HAProxy when certs don't exist

HAProxy validation fails if the config references cert files that
don't exist (wildcard.pem for L7 routes, domain.pem for central TLS).

Now reconciliation checks for cert existence before including:
- L7 HTTP routes: only generated when wildcard cert exists
- Central domain TLS frontend: only generated when domain cert exists

This ensures HAProxy never enters a failure state due to missing
certs. Once certs are provisioned (via certbot), the next
reconciliation picks them up automatically.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-09 14:15:32 +00:00
parent 53a640c34f
commit 7d5e4f4e29

View File

@@ -60,16 +60,41 @@ func (api *API) reconcileNetworking() {
} }
} }
// Determine central domain for HAProxy // Determine central domain for HAProxy — only if its cert exists
centralDomain := "" centralDomain := ""
if globalCfg.Cloud.Central.Domain != "" { if d := globalCfg.Cloud.Central.Domain; d != "" {
centralDomain = globalCfg.Cloud.Central.Domain if _, err := os.Stat(certbot.HAProxyCertPath(d)); err == nil {
centralDomain = d
} else {
slog.Debug("reconcile: skipping central domain in HAProxy (no cert)", "domain", d)
}
}
// Only include L7 HTTP routes if a wildcard cert exists for TLS termination.
// Without it, HAProxy validation fails and the entire config is rejected.
wildcardCert := "/etc/haproxy/certs/wildcard.pem"
gatewayDomain := ""
if parts := strings.SplitN(globalCfg.Cloud.Central.Domain, ".", 2); len(parts) == 2 {
gatewayDomain = parts[1]
// Also check per-domain cert path
if _, err := os.Stat(certbot.HAProxyCertPath(gatewayDomain)); err == nil {
wildcardCert = certbot.HAProxyCertPath(gatewayDomain)
}
}
activeHTTPRoutes := httpRoutes
if _, err := os.Stat(wildcardCert); err != nil {
if len(httpRoutes) > 0 {
slog.Warn("reconcile: skipping L7 HTTP routes in HAProxy (no wildcard cert)", "path", wildcardCert)
}
activeHTTPRoutes = nil
} }
// Generate and write HAProxy config // Generate and write HAProxy config
haproxyCfg := api.haproxy.GenerateWithOpts(instanceRoutes, nil, haproxy.GenerateOpts{ haproxyCfg := api.haproxy.GenerateWithOpts(instanceRoutes, nil, haproxy.GenerateOpts{
CentralDomain: centralDomain, CentralDomain: centralDomain,
HTTPRoutes: httpRoutes, HTTPRoutes: activeHTTPRoutes,
WildcardCert: wildcardCert,
}) })
if err := api.haproxy.WriteConfig(haproxyCfg); err != nil { if err := api.haproxy.WriteConfig(haproxyCfg); err != nil {