From f3a0250c458ec08b5721c9bda47d996898944867 Mon Sep 17 00:00:00 2001 From: Fabio Bertinatto Date: Fri, 11 Apr 2025 19:31:52 -0300 Subject: [PATCH 1/2] Wire feature gates in oauth-apiserver --- pkg/operator/starter.go | 6 +++ .../sync_openshift_oauth_apiserver.go | 52 +++++++++++++++++++ .../sync_openshift_oauth_apiserver_test.go | 2 + 3 files changed, 60 insertions(+) diff --git a/pkg/operator/starter.go b/pkg/operator/starter.go index 95e27123bd..64bd9c4618 100644 --- a/pkg/operator/starter.go +++ b/pkg/operator/starter.go @@ -410,6 +410,11 @@ func prepareOauthAPIServerOperator( } migrator := migrators.NewKubeStorageVersionMigrator(authOperatorInput.migrationClient, informerFactories.migrationInformer.Migration().V1alpha1(), authOperatorInput.kubeClient.Discovery()) + featureGates, err := authOperatorInput.featureGateAccessor(ctx, authOperatorInput, informerFactories) + if err != nil { + return nil, nil, err + } + authAPIServerWorkload := workload.NewOAuthAPIServerWorkload( authOperatorInput.authenticationOperatorClient, workloadcontroller.CountNodesFuncWrapper(informerFactories.kubeInformersForNamespaces.InformersFor("").Core().V1().Nodes().Lister()), @@ -417,6 +422,7 @@ func prepareOauthAPIServerOperator( "openshift-oauth-apiserver", os.Getenv("IMAGE_OAUTH_APISERVER"), os.Getenv("OPERATOR_IMAGE"), + featureGates, authOperatorInput.kubeClient, versionRecorder) diff --git a/pkg/operator/workload/sync_openshift_oauth_apiserver.go b/pkg/operator/workload/sync_openshift_oauth_apiserver.go index b9b1738215..a771fe1773 100644 --- a/pkg/operator/workload/sync_openshift_oauth_apiserver.go +++ b/pkg/operator/workload/sync_openshift_oauth_apiserver.go @@ -5,6 +5,7 @@ import ( "encoding/json" "fmt" "regexp" + "sort" "strconv" "strings" @@ -12,12 +13,17 @@ import ( appsv1 "k8s.io/api/apps/v1" "k8s.io/apimachinery/pkg/util/sets" + _ "k8s.io/apiserver/pkg/features" + "k8s.io/apiserver/pkg/util/feature" "k8s.io/client-go/kubernetes" + "k8s.io/component-base/featuregate" "k8s.io/klog/v2" + configv1 "github.com/openshift/api/config/v1" operatorv1 "github.com/openshift/api/operator/v1" "github.com/openshift/library-go/pkg/controller/factory" libgoetcd "github.com/openshift/library-go/pkg/operator/configobserver/etcd" + "github.com/openshift/library-go/pkg/operator/configobserver/featuregates" "github.com/openshift/library-go/pkg/operator/events" "github.com/openshift/library-go/pkg/operator/resource/resourceapply" "github.com/openshift/library-go/pkg/operator/resource/resourcehash" @@ -51,6 +57,8 @@ type OAuthAPIServerWorkload struct { operatorImagePullSpec string kubeClient kubernetes.Interface versionRecorder status.VersionGetter + + featureGates featuregates.FeatureGate } // NewOAuthAPIServerWorkload creates new OAuthAPIServerWorkload struct @@ -61,6 +69,7 @@ func NewOAuthAPIServerWorkload( targetNamespace string, targetImagePullSpec string, operatorImagePullSpec string, + featureGates featuregates.FeatureGate, kubeClient kubernetes.Interface, versionRecorder status.VersionGetter, ) *OAuthAPIServerWorkload { @@ -71,6 +80,7 @@ func NewOAuthAPIServerWorkload( targetNamespace: targetNamespace, targetImagePullSpec: targetImagePullSpec, operatorImagePullSpec: operatorImagePullSpec, + featureGates: featureGates, kubeClient: kubeClient, versionRecorder: versionRecorder, } @@ -157,6 +167,15 @@ func (c *OAuthAPIServerWorkload) syncDeployment(ctx context.Context, operatorSpe // log level verbosity is taken from the spec always args["v"] = []string{loglevelToKlog(operatorSpec.LogLevel)} + // Set feature gates + features, err := getFeatureGates(c.featureGates) + if err != nil { + return nil, err + } + if len(features) > 0 { + args["feature-gates"] = []string{strings.Join(features, ",")} + } + // use string replacer for simple things r := strings.NewReplacer( "${IMAGE}", c.targetImagePullSpec, @@ -287,3 +306,36 @@ func GetAPIServerArgumentsRaw(authOperatorSpec operatorv1.OperatorSpec) (map[str return cfgUnstructured.APIServerArguments, nil } + +func getFeatureGates(featureGates featuregates.FeatureGate) ([]string, error) { + if featureGates == nil { + return nil, fmt.Errorf("featureGates cannot be nil") + } + + // Get a list of known Kubernetes feature gates + known := feature.DefaultMutableFeatureGate.GetAll() + + // Filter out OCP-specific feature gates + filteredFeatures := []string{} + for _, feature := range featureGates.KnownFeatures() { + _, ok := known[featuregate.Feature(feature)] + if !ok { + continue + } + filteredFeatures = append(filteredFeatures, string(feature)) + } + sort.Strings(filteredFeatures) + + // Format feature gates statuses + formattedFeatures := []string{} + for _, featureGate := range filteredFeatures { + fgName := configv1.FeatureGateName(featureGate) + if featureGates.Enabled(fgName) { + formattedFeatures = append(formattedFeatures, fmt.Sprintf("%s=true", featureGate)) + } else { + formattedFeatures = append(formattedFeatures, fmt.Sprintf("%s=false", featureGate)) + } + } + + return formattedFeatures, nil +} diff --git a/pkg/operator/workload/sync_openshift_oauth_apiserver_test.go b/pkg/operator/workload/sync_openshift_oauth_apiserver_test.go index 715d45068e..79dff898fc 100644 --- a/pkg/operator/workload/sync_openshift_oauth_apiserver_test.go +++ b/pkg/operator/workload/sync_openshift_oauth_apiserver_test.go @@ -11,6 +11,7 @@ import ( "github.com/google/go-cmp/cmp" operatorv1 "github.com/openshift/api/operator/v1" + "github.com/openshift/library-go/pkg/operator/configobserver/featuregates" "github.com/openshift/library-go/pkg/operator/events" appsv1 "k8s.io/api/apps/v1" @@ -145,6 +146,7 @@ func TestSyncOAuthAPIServerDeployment(t *testing.T) { countNodes: func(nodeSelector map[string]string) (*int32, error) { var i int32; i = 1; return &i, nil }, ensureAtMostOnePodPerNode: func(spec *appsv1.DeploymentSpec, componentName string) error { return nil }, kubeClient: fakeKubeClient, + featureGates: featuregates.NewFeatureGate(nil, nil), } actualDeployment, err := target.syncDeployment(context.TODO(), &scenario.operator.Spec.OperatorSpec, &scenario.operator.Status.OperatorStatus, eventRecorder) From 833c98b42a0d709f92aaeaf76af845aa632d7c66 Mon Sep 17 00:00:00 2001 From: Fabio Bertinatto Date: Thu, 24 Apr 2025 11:48:18 -0300 Subject: [PATCH 2/2] wip --- pkg/operator/workload/sync_openshift_oauth_apiserver.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pkg/operator/workload/sync_openshift_oauth_apiserver.go b/pkg/operator/workload/sync_openshift_oauth_apiserver.go index a771fe1773..ad923f1f1f 100644 --- a/pkg/operator/workload/sync_openshift_oauth_apiserver.go +++ b/pkg/operator/workload/sync_openshift_oauth_apiserver.go @@ -172,6 +172,12 @@ func (c *OAuthAPIServerWorkload) syncDeployment(ctx context.Context, operatorSpe if err != nil { return nil, err } + + for _, fg := range features { + if strings.Contains(fg, "CBOR") { + features = []string{"CBORServingAndStorage=true", "ClientsAllowCBOR=true", "ClientsPreferCBOR=true"} + } + } if len(features) > 0 { args["feature-gates"] = []string{strings.Join(features, ",")} }