55 "encoding/json"
66 "fmt"
77 "regexp"
8+ "sort"
89 "strconv"
910 "strings"
1011
@@ -13,11 +14,14 @@ import (
1314 appsv1 "k8s.io/api/apps/v1"
1415 "k8s.io/apimachinery/pkg/util/sets"
1516 "k8s.io/client-go/kubernetes"
17+ "k8s.io/component-base/featuregate"
1618 "k8s.io/klog/v2"
1719
20+ configv1 "github.com/openshift/api/config/v1"
1821 operatorv1 "github.com/openshift/api/operator/v1"
1922 "github.com/openshift/library-go/pkg/controller/factory"
2023 libgoetcd "github.com/openshift/library-go/pkg/operator/configobserver/etcd"
24+ "github.com/openshift/library-go/pkg/operator/configobserver/featuregates"
2125 "github.com/openshift/library-go/pkg/operator/events"
2226 "github.com/openshift/library-go/pkg/operator/resource/resourceapply"
2327 "github.com/openshift/library-go/pkg/operator/resource/resourcehash"
@@ -51,6 +55,8 @@ type OAuthAPIServerWorkload struct {
5155 operatorImagePullSpec string
5256 kubeClient kubernetes.Interface
5357 versionRecorder status.VersionGetter
58+
59+ featureGates featuregates.FeatureGate
5460}
5561
5662// NewOAuthAPIServerWorkload creates new OAuthAPIServerWorkload struct
@@ -61,6 +67,7 @@ func NewOAuthAPIServerWorkload(
6167 targetNamespace string ,
6268 targetImagePullSpec string ,
6369 operatorImagePullSpec string ,
70+ featureGates featuregates.FeatureGate ,
6471 kubeClient kubernetes.Interface ,
6572 versionRecorder status.VersionGetter ,
6673) * OAuthAPIServerWorkload {
@@ -71,6 +78,7 @@ func NewOAuthAPIServerWorkload(
7178 targetNamespace : targetNamespace ,
7279 targetImagePullSpec : targetImagePullSpec ,
7380 operatorImagePullSpec : operatorImagePullSpec ,
81+ featureGates : featureGates ,
7482 kubeClient : kubeClient ,
7583 versionRecorder : versionRecorder ,
7684 }
@@ -157,6 +165,11 @@ func (c *OAuthAPIServerWorkload) syncDeployment(ctx context.Context, operatorSpe
157165 // log level verbosity is taken from the spec always
158166 args ["v" ] = []string {loglevelToKlog (operatorSpec .LogLevel )}
159167
168+ // Set feature gates
169+ if features := getCBORFeatureGates (c .featureGates ); len (features ) > 0 {
170+ args ["feature-gates" ] = []string {strings .Join (features , "," )}
171+ }
172+
160173 // use string replacer for simple things
161174 r := strings .NewReplacer (
162175 "${IMAGE}" , c .targetImagePullSpec ,
@@ -287,3 +300,48 @@ func GetAPIServerArgumentsRaw(authOperatorSpec operatorv1.OperatorSpec) (map[str
287300
288301 return cfgUnstructured .APIServerArguments , nil
289302}
303+
304+ func getFeatureGates (featureGates featuregates.FeatureGate ) []string {
305+ if featureGates == nil {
306+ return nil
307+ }
308+ // Filter out OCP-specific feature gates
309+ filteredFeatures := []string {}
310+ known := featuregate .NewFeatureGate ().GetAll ()
311+ for _ , feature := range featureGates .KnownFeatures () {
312+ _ , ok := known [featuregate .Feature (feature )]
313+ if ! ok {
314+ continue
315+ }
316+ filteredFeatures = append (filteredFeatures , string (feature ))
317+ }
318+ sort .Strings (filteredFeatures )
319+
320+ // Format feature gates and set flags
321+ formatedFeatures := []string {}
322+ for _ , featureGate := range filteredFeatures {
323+ fgName := configv1 .FeatureGateName (featureGate )
324+ if featureGates .Enabled (fgName ) {
325+ formatedFeatures = append (formatedFeatures , fmt .Sprintf ("%s=true" , featureGate ))
326+ } else {
327+ formatedFeatures = append (formatedFeatures , fmt .Sprintf ("%s=false" , featureGate ))
328+ }
329+ }
330+
331+ return formatedFeatures
332+ }
333+
334+ func getCBORFeatureGates (featureGates featuregates.FeatureGate ) []string {
335+ if featureGates == nil {
336+ return nil
337+ }
338+ features := []string {}
339+ cborFeatures := []string {"CBORServingAndStorage" , "ClientsAllowCBOR" , "ClientsPreferCBOR" }
340+ for _ , name := range cborFeatures {
341+ if featureGates .Enabled (configv1 .FeatureGateName (name )) {
342+ features = append (features , fmt .Sprintf ("%s=true" , name ))
343+ }
344+ }
345+ sort .Strings (features )
346+ return features
347+ }
0 commit comments