5
5
"encoding/json"
6
6
"fmt"
7
7
"regexp"
8
+ "sort"
8
9
"strconv"
9
10
"strings"
10
11
@@ -13,11 +14,14 @@ import (
13
14
appsv1 "k8s.io/api/apps/v1"
14
15
"k8s.io/apimachinery/pkg/util/sets"
15
16
"k8s.io/client-go/kubernetes"
17
+ "k8s.io/component-base/featuregate"
16
18
"k8s.io/klog/v2"
17
19
20
+ configv1 "github.com/openshift/api/config/v1"
18
21
operatorv1 "github.com/openshift/api/operator/v1"
19
22
"github.com/openshift/library-go/pkg/controller/factory"
20
23
libgoetcd "github.com/openshift/library-go/pkg/operator/configobserver/etcd"
24
+ "github.com/openshift/library-go/pkg/operator/configobserver/featuregates"
21
25
"github.com/openshift/library-go/pkg/operator/events"
22
26
"github.com/openshift/library-go/pkg/operator/resource/resourceapply"
23
27
"github.com/openshift/library-go/pkg/operator/resource/resourcehash"
@@ -51,6 +55,8 @@ type OAuthAPIServerWorkload struct {
51
55
operatorImagePullSpec string
52
56
kubeClient kubernetes.Interface
53
57
versionRecorder status.VersionGetter
58
+
59
+ featureGates featuregates.FeatureGate
54
60
}
55
61
56
62
// NewOAuthAPIServerWorkload creates new OAuthAPIServerWorkload struct
@@ -61,6 +67,7 @@ func NewOAuthAPIServerWorkload(
61
67
targetNamespace string ,
62
68
targetImagePullSpec string ,
63
69
operatorImagePullSpec string ,
70
+ featureGates featuregates.FeatureGate ,
64
71
kubeClient kubernetes.Interface ,
65
72
versionRecorder status.VersionGetter ,
66
73
) * OAuthAPIServerWorkload {
@@ -71,6 +78,7 @@ func NewOAuthAPIServerWorkload(
71
78
targetNamespace : targetNamespace ,
72
79
targetImagePullSpec : targetImagePullSpec ,
73
80
operatorImagePullSpec : operatorImagePullSpec ,
81
+ featureGates : featureGates ,
74
82
kubeClient : kubeClient ,
75
83
versionRecorder : versionRecorder ,
76
84
}
@@ -157,6 +165,11 @@ func (c *OAuthAPIServerWorkload) syncDeployment(ctx context.Context, operatorSpe
157
165
// log level verbosity is taken from the spec always
158
166
args ["v" ] = []string {loglevelToKlog (operatorSpec .LogLevel )}
159
167
168
+ // Set feature gates
169
+ if features := getFeatureGates (c .featureGates ); len (features ) > 0 {
170
+ args ["feature-gates" ] = []string {strings .Join (features , "," )}
171
+ }
172
+
160
173
// use string replacer for simple things
161
174
r := strings .NewReplacer (
162
175
"${IMAGE}" , c .targetImagePullSpec ,
@@ -287,3 +300,33 @@ func GetAPIServerArgumentsRaw(authOperatorSpec operatorv1.OperatorSpec) (map[str
287
300
288
301
return cfgUnstructured .APIServerArguments , nil
289
302
}
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
+ }
0 commit comments