Skip to content

Commit 47827f4

Browse files
Merge branch 'master' into feat/time-retrieval-bigquery
2 parents 67773b7 + 43263a6 commit 47827f4

9 files changed

Lines changed: 2465 additions & 339 deletions

File tree

infra/feast-operator/cmd/main.go

Lines changed: 79 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ limitations under the License.
1717
package main
1818

1919
import (
20+
"context"
2021
"crypto/tls"
2122
"flag"
2223
"os"
@@ -25,12 +26,16 @@ import (
2526
// to ensure that exec-entrypoint and run can make use of them.
2627
_ "k8s.io/client-go/plugin/pkg/client/auth"
2728

29+
configv1 "github.com/openshift/api/config/v1"
30+
tlspkg "github.com/openshift/controller-runtime-common/pkg/tls"
2831
appsv1 "k8s.io/api/apps/v1"
2932
autoscalingv2 "k8s.io/api/autoscaling/v2"
3033
batchv1 "k8s.io/api/batch/v1"
3134
corev1 "k8s.io/api/core/v1"
3235
policyv1 "k8s.io/api/policy/v1"
3336
rbacv1 "k8s.io/api/rbac/v1"
37+
apierrors "k8s.io/apimachinery/pkg/api/errors"
38+
apimeta "k8s.io/apimachinery/pkg/api/meta"
3439
"k8s.io/apimachinery/pkg/labels"
3540
"k8s.io/apimachinery/pkg/runtime"
3641
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
@@ -61,6 +66,7 @@ var (
6166

6267
func init() {
6368
utilruntime.Must(clientgoscheme.AddToScheme(scheme))
69+
utilruntime.Must(configv1.Install(scheme))
6470
utilruntime.Must(routev1.AddToScheme(scheme))
6571
utilruntime.Must(feastdevv1alpha1.AddToScheme(scheme))
6672
utilruntime.Must(feastdevv1.AddToScheme(scheme))
@@ -95,7 +101,6 @@ func main() {
95101
var enableLeaderElection bool
96102
var probeAddr string
97103
var secureMetrics bool
98-
var enableHTTP2 bool
99104
var featureStoreMetrics bool
100105
var tlsOpts []func(*tls.Config)
101106
flag.StringVar(&metricsAddr, "metrics-bind-address", "0", "The address the metrics endpoint binds to. "+
@@ -106,8 +111,6 @@ func main() {
106111
"Enabling this will ensure there is only one active controller manager.")
107112
flag.BoolVar(&secureMetrics, "metrics-secure", true,
108113
"If set, the metrics endpoint is served securely via HTTPS. Use --metrics-secure=false to use HTTP instead.")
109-
flag.BoolVar(&enableHTTP2, "enable-http2", false,
110-
"If set, HTTP/2 will be enabled for the metrics and webhook servers")
111114
flag.BoolVar(&featureStoreMetrics, "feature-store-metrics", true,
112115
"Enable Prometheus gauges exposing online/offline store and registry configuration per FeatureStore. "+
113116
"Disable with --feature-store-metrics=false.")
@@ -119,21 +122,55 @@ func main() {
119122

120123
ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts)))
121124

122-
// if the enable-http2 flag is false (the default), http/2 should be disabled
123-
// due to its vulnerabilities. More specifically, disabling http/2 will
124-
// prevent from being vulnerable to the HTTP/2 Stream Cancellation and
125-
// Rapid Reset CVEs. For more information see:
126-
// - https://github.com/advisories/GHSA-qppj-fm5r-hxr3
127-
// - https://github.com/advisories/GHSA-4374-p667-p6c8
128-
disableHTTP2 := func(c *tls.Config) {
129-
setupLog.Info("disabling http/2")
130-
c.NextProtos = []string{"http/1.1"}
125+
// Fetch cluster TLS profile from apiservers.config.openshift.io/cluster
126+
cfg := ctrl.GetConfigOrDie()
127+
bootstrapClient, err := client.New(cfg, client.Options{Scheme: scheme})
128+
if err != nil {
129+
setupLog.Error(err, "unable to create bootstrap client for TLS profile fetch")
130+
os.Exit(1)
131131
}
132132

133-
if !enableHTTP2 {
134-
tlsOpts = append(tlsOpts, disableHTTP2)
133+
tlsProfileFetched := false
134+
tlsProfile, err := tlspkg.FetchAPIServerTLSProfile(context.Background(), bootstrapClient)
135+
if err != nil {
136+
switch {
137+
case apimeta.IsNoMatchError(err):
138+
setupLog.Info("TLS profile not available, using hardened defaults (non-OpenShift cluster)")
139+
case apierrors.IsNotFound(err):
140+
setupLog.Info("APIServer resource not found, using hardened defaults")
141+
default:
142+
setupLog.Error(err, "unable to read APIServer TLS profile, refusing to start with unknown TLS posture")
143+
os.Exit(1)
144+
}
145+
} else {
146+
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)
152+
}
153+
154+
tlsAdherenceFetched := false
155+
tlsAdherence, err := tlspkg.FetchAPIServerTLSAdherencePolicy(context.Background(), bootstrapClient)
156+
if err != nil {
157+
switch {
158+
case apimeta.IsNoMatchError(err):
159+
setupLog.Info("TLS adherence policy not available (non-OpenShift cluster)")
160+
case apierrors.IsNotFound(err):
161+
setupLog.Info("APIServer resource not found, skipping adherence policy")
162+
default:
163+
setupLog.Error(err, "unable to read APIServer TLS adherence policy, refusing to start")
164+
os.Exit(1)
165+
}
166+
} else {
167+
tlsAdherenceFetched = true
135168
}
136169

170+
tlsOpts = append(tlsOpts, func(c *tls.Config) {
171+
c.NextProtos = []string{"h2", "http/1.1"}
172+
})
173+
137174
webhookServer := webhook.NewServer(webhook.Options{
138175
TLSOpts: tlsOpts,
139176
})
@@ -162,7 +199,7 @@ func main() {
162199
metricsServerOptions.FilterProvider = filters.WithAuthenticationAndAuthorization
163200
}
164201

165-
mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
202+
mgr, err := ctrl.NewManager(cfg, ctrl.Options{
166203
Scheme: scheme,
167204
Metrics: metricsServerOptions,
168205
WebhookServer: webhookServer,
@@ -230,6 +267,32 @@ func main() {
230267
}
231268
// +kubebuilder:scaffold:builder
232269

270+
// Register SecurityProfileWatcher to restart on TLS profile changes
271+
ctx, cancel := context.WithCancel(ctrl.SetupSignalHandler())
272+
defer cancel()
273+
274+
if tlsProfileFetched {
275+
watcher := &tlspkg.SecurityProfileWatcher{
276+
Client: mgr.GetClient(),
277+
InitialTLSProfileSpec: tlsProfile,
278+
OnProfileChange: func(_ context.Context, _, _ configv1.TLSProfileSpec) {
279+
setupLog.Info("TLS profile changed, initiating shutdown to reload")
280+
cancel()
281+
},
282+
}
283+
if tlsAdherenceFetched {
284+
watcher.InitialTLSAdherencePolicy = tlsAdherence
285+
watcher.OnAdherencePolicyChange = func(_ context.Context, _, _ configv1.TLSAdherencePolicy) {
286+
setupLog.Info("TLS adherence policy changed, initiating shutdown to reload")
287+
cancel()
288+
}
289+
}
290+
if err := watcher.SetupWithManager(mgr); err != nil {
291+
setupLog.Error(err, "unable to set up TLS profile watcher")
292+
os.Exit(1)
293+
}
294+
}
295+
233296
if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {
234297
setupLog.Error(err, "unable to set up health check")
235298
os.Exit(1)
@@ -240,7 +303,7 @@ func main() {
240303
}
241304

242305
setupLog.Info("starting manager")
243-
if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {
306+
if err := mgr.Start(ctx); err != nil {
244307
setupLog.Error(err, "problem running manager")
245308
os.Exit(1)
246309
}

0 commit comments

Comments
 (0)