Skip to content

Commit 846c5a6

Browse files
ugiordanclaude
andcommitted
feat: apply Intermediate TLS defaults on API fallback and handle transient errors
Follow-up to #6567. Two fixes: 1. Move NewTLSConfigFromProfile outside the if/else so it runs on all code paths. Previously, error paths skipped TLS configuration entirely, leaving the operator running with Go's bare defaults (no MinVersion, no cipher restrictions). Now all error paths explicitly fall back to the Intermediate TLS profile. 2. Handle transient API errors (ServiceUnavailable, Timeout, TooManyRequests) gracefully instead of crashing with os.Exit(1). These set tlsProfileFetched=true so the SecurityProfileWatcher self-heals when the API recovers. Also adds a 10-second context timeout on bootstrap API calls and applies the same transient error handling to the TLS adherence policy fetch. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Signed-off-by: Ugo Giordano <ugiordan@redhat.com>
1 parent f296d4b commit 846c5a6

1 file changed

Lines changed: 26 additions & 11 deletions

File tree

infra/feast-operator/cmd/main.go

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"crypto/tls"
2222
"flag"
2323
"os"
24+
"time"
2425

2526
// Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.)
2627
// to ensure that exec-entrypoint and run can make use of them.
@@ -102,7 +103,7 @@ func main() {
102103
var probeAddr string
103104
var secureMetrics bool
104105
var featureStoreMetrics bool
105-
var tlsOpts []func(*tls.Config)
106+
tlsOpts := make([]func(*tls.Config), 0, 2)
106107
flag.StringVar(&metricsAddr, "metrics-bind-address", "0", "The address the metrics endpoint binds to. "+
107108
"Use :8443 for HTTPS or :8080 for HTTP, or leave as 0 to disable the metrics service.")
108109
flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.")
@@ -130,37 +131,51 @@ func main() {
130131
os.Exit(1)
131132
}
132133

134+
bootstrapCtx, cancelBootstrap := context.WithTimeout(context.Background(), 10*time.Second)
135+
defer cancelBootstrap()
136+
133137
tlsProfileFetched := false
134-
tlsProfile, err := tlspkg.FetchAPIServerTLSProfile(context.Background(), bootstrapClient)
138+
tlsProfile, err := tlspkg.FetchAPIServerTLSProfile(bootstrapCtx, bootstrapClient)
135139
if err != nil {
136140
switch {
137141
case apimeta.IsNoMatchError(err):
138-
setupLog.Info("TLS profile not available, using hardened defaults (non-OpenShift cluster)")
142+
setupLog.Info("TLS profile not available, using Intermediate defaults (non-OpenShift cluster)")
139143
case apierrors.IsNotFound(err):
140-
setupLog.Info("APIServer resource not found, using hardened defaults")
144+
setupLog.Info("APIServer resource not found, using Intermediate defaults")
145+
case apierrors.IsServiceUnavailable(err),
146+
apierrors.IsTimeout(err),
147+
apierrors.IsTooManyRequests(err):
148+
setupLog.Info("Transient API error reading TLS profile, using Intermediate defaults", "error", err)
149+
tlsProfileFetched = true // watcher self-heals when the API recovers
141150
default:
142151
setupLog.Error(err, "unable to read APIServer TLS profile, refusing to start with unknown TLS posture")
143152
os.Exit(1)
144153
}
154+
tlsProfile = *configv1.TLSProfiles[configv1.TLSProfileIntermediateType]
145155
} else {
146156
tlsProfileFetched = true
147-
tlsConfigFn, unsupported := tlspkg.NewTLSConfigFromProfile(tlsProfile)
148-
if len(unsupported) > 0 {
149-
setupLog.Info("TLS profile contains ciphers unsupported by Go", "unsupported", unsupported)
150-
}
151-
tlsOpts = append(tlsOpts, tlsConfigFn)
152157
}
158+
tlsConfigFn, unsupported := tlspkg.NewTLSConfigFromProfile(tlsProfile)
159+
if len(unsupported) > 0 {
160+
setupLog.Info("TLS profile contains ciphers unsupported by Go", "unsupported", unsupported)
161+
}
162+
tlsOpts = append(tlsOpts, tlsConfigFn)
153163

154164
tlsAdherenceFetched := false
155-
tlsAdherence, err := tlspkg.FetchAPIServerTLSAdherencePolicy(context.Background(), bootstrapClient)
165+
tlsAdherence, err := tlspkg.FetchAPIServerTLSAdherencePolicy(bootstrapCtx, bootstrapClient)
156166
if err != nil {
157167
switch {
158168
case apimeta.IsNoMatchError(err):
159169
setupLog.Info("TLS adherence policy not available (non-OpenShift cluster)")
160170
case apierrors.IsNotFound(err):
161171
setupLog.Info("APIServer resource not found, skipping adherence policy")
172+
case apierrors.IsServiceUnavailable(err),
173+
apierrors.IsTimeout(err),
174+
apierrors.IsTooManyRequests(err):
175+
setupLog.Info("Transient API error reading TLS adherence policy, skipping", "error", err)
176+
tlsAdherenceFetched = true // watcher self-heals when the API recovers
162177
default:
163-
setupLog.Error(err, "unable to read APIServer TLS adherence policy, refusing to start")
178+
setupLog.Error(err, "unable to fetch TLS adherence policy")
164179
os.Exit(1)
165180
}
166181
} else {

0 commit comments

Comments
 (0)