Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 79 additions & 16 deletions infra/feast-operator/cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package main

import (
"context"
"crypto/tls"
"flag"
"os"
Expand All @@ -25,12 +26,16 @@ import (
// to ensure that exec-entrypoint and run can make use of them.
_ "k8s.io/client-go/plugin/pkg/client/auth"

configv1 "github.com/openshift/api/config/v1"
tlspkg "github.com/openshift/controller-runtime-common/pkg/tls"
appsv1 "k8s.io/api/apps/v1"
autoscalingv2 "k8s.io/api/autoscaling/v2"
batchv1 "k8s.io/api/batch/v1"
corev1 "k8s.io/api/core/v1"
policyv1 "k8s.io/api/policy/v1"
rbacv1 "k8s.io/api/rbac/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
apimeta "k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
Expand Down Expand Up @@ -61,6 +66,7 @@ var (

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

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

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

if !enableHTTP2 {
tlsOpts = append(tlsOpts, disableHTTP2)
tlsProfileFetched := false
tlsProfile, err := tlspkg.FetchAPIServerTLSProfile(context.Background(), bootstrapClient)
if err != nil {
switch {
case apimeta.IsNoMatchError(err):
setupLog.Info("TLS profile not available, using hardened defaults (non-OpenShift cluster)")
case apierrors.IsNotFound(err):
setupLog.Info("APIServer resource not found, using hardened defaults")
default:
setupLog.Error(err, "unable to read APIServer TLS profile, refusing to start with unknown TLS posture")
os.Exit(1)
}
} else {
tlsProfileFetched = true
tlsConfigFn, unsupported := tlspkg.NewTLSConfigFromProfile(tlsProfile)
if len(unsupported) > 0 {
setupLog.Info("TLS profile contains ciphers unsupported by Go", "unsupported", unsupported)
}
tlsOpts = append(tlsOpts, tlsConfigFn)
}

tlsAdherenceFetched := false
tlsAdherence, err := tlspkg.FetchAPIServerTLSAdherencePolicy(context.Background(), bootstrapClient)
if err != nil {
switch {
case apimeta.IsNoMatchError(err):
setupLog.Info("TLS adherence policy not available (non-OpenShift cluster)")
case apierrors.IsNotFound(err):
setupLog.Info("APIServer resource not found, skipping adherence policy")
default:
setupLog.Error(err, "unable to read APIServer TLS adherence policy, refusing to start")
os.Exit(1)
}
} else {
tlsAdherenceFetched = true
}

tlsOpts = append(tlsOpts, func(c *tls.Config) {
c.NextProtos = []string{"h2", "http/1.1"}
})

webhookServer := webhook.NewServer(webhook.Options{
TLSOpts: tlsOpts,
})
Expand Down Expand Up @@ -162,7 +199,7 @@ func main() {
metricsServerOptions.FilterProvider = filters.WithAuthenticationAndAuthorization
}

mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
mgr, err := ctrl.NewManager(cfg, ctrl.Options{
Scheme: scheme,
Metrics: metricsServerOptions,
WebhookServer: webhookServer,
Expand Down Expand Up @@ -230,6 +267,32 @@ func main() {
}
// +kubebuilder:scaffold:builder

// Register SecurityProfileWatcher to restart on TLS profile changes
ctx, cancel := context.WithCancel(ctrl.SetupSignalHandler())
defer cancel()

if tlsProfileFetched {
watcher := &tlspkg.SecurityProfileWatcher{
Client: mgr.GetClient(),
InitialTLSProfileSpec: tlsProfile,
OnProfileChange: func(_ context.Context, _, _ configv1.TLSProfileSpec) {
setupLog.Info("TLS profile changed, initiating shutdown to reload")
cancel()
},
}
if tlsAdherenceFetched {
watcher.InitialTLSAdherencePolicy = tlsAdherence
watcher.OnAdherencePolicyChange = func(_ context.Context, _, _ configv1.TLSAdherencePolicy) {
setupLog.Info("TLS adherence policy changed, initiating shutdown to reload")
cancel()
}
}
if err := watcher.SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to set up TLS profile watcher")
os.Exit(1)
}
}

if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {
setupLog.Error(err, "unable to set up health check")
os.Exit(1)
Expand All @@ -240,7 +303,7 @@ func main() {
}

setupLog.Info("starting manager")
if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {
if err := mgr.Start(ctx); err != nil {
setupLog.Error(err, "problem running manager")
os.Exit(1)
}
Expand Down
Loading
Loading