Skip to content

Commit f3a0250

Browse files
committed
Wire feature gates in oauth-apiserver
1 parent 8febe2b commit f3a0250

File tree

3 files changed

+60
-0
lines changed

3 files changed

+60
-0
lines changed

pkg/operator/starter.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,13 +410,19 @@ func prepareOauthAPIServerOperator(
410410
}
411411
migrator := migrators.NewKubeStorageVersionMigrator(authOperatorInput.migrationClient, informerFactories.migrationInformer.Migration().V1alpha1(), authOperatorInput.kubeClient.Discovery())
412412

413+
featureGates, err := authOperatorInput.featureGateAccessor(ctx, authOperatorInput, informerFactories)
414+
if err != nil {
415+
return nil, nil, err
416+
}
417+
413418
authAPIServerWorkload := workload.NewOAuthAPIServerWorkload(
414419
authOperatorInput.authenticationOperatorClient,
415420
workloadcontroller.CountNodesFuncWrapper(informerFactories.kubeInformersForNamespaces.InformersFor("").Core().V1().Nodes().Lister()),
416421
workloadcontroller.EnsureAtMostOnePodPerNode,
417422
"openshift-oauth-apiserver",
418423
os.Getenv("IMAGE_OAUTH_APISERVER"),
419424
os.Getenv("OPERATOR_IMAGE"),
425+
featureGates,
420426
authOperatorInput.kubeClient,
421427
versionRecorder)
422428

pkg/operator/workload/sync_openshift_oauth_apiserver.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,25 @@ import (
55
"encoding/json"
66
"fmt"
77
"regexp"
8+
"sort"
89
"strconv"
910
"strings"
1011

1112
"github.com/openshift/library-go/pkg/operator/v1helpers"
1213

1314
appsv1 "k8s.io/api/apps/v1"
1415
"k8s.io/apimachinery/pkg/util/sets"
16+
_ "k8s.io/apiserver/pkg/features"
17+
"k8s.io/apiserver/pkg/util/feature"
1518
"k8s.io/client-go/kubernetes"
19+
"k8s.io/component-base/featuregate"
1620
"k8s.io/klog/v2"
1721

22+
configv1 "github.com/openshift/api/config/v1"
1823
operatorv1 "github.com/openshift/api/operator/v1"
1924
"github.com/openshift/library-go/pkg/controller/factory"
2025
libgoetcd "github.com/openshift/library-go/pkg/operator/configobserver/etcd"
26+
"github.com/openshift/library-go/pkg/operator/configobserver/featuregates"
2127
"github.com/openshift/library-go/pkg/operator/events"
2228
"github.com/openshift/library-go/pkg/operator/resource/resourceapply"
2329
"github.com/openshift/library-go/pkg/operator/resource/resourcehash"
@@ -51,6 +57,8 @@ type OAuthAPIServerWorkload struct {
5157
operatorImagePullSpec string
5258
kubeClient kubernetes.Interface
5359
versionRecorder status.VersionGetter
60+
61+
featureGates featuregates.FeatureGate
5462
}
5563

5664
// NewOAuthAPIServerWorkload creates new OAuthAPIServerWorkload struct
@@ -61,6 +69,7 @@ func NewOAuthAPIServerWorkload(
6169
targetNamespace string,
6270
targetImagePullSpec string,
6371
operatorImagePullSpec string,
72+
featureGates featuregates.FeatureGate,
6473
kubeClient kubernetes.Interface,
6574
versionRecorder status.VersionGetter,
6675
) *OAuthAPIServerWorkload {
@@ -71,6 +80,7 @@ func NewOAuthAPIServerWorkload(
7180
targetNamespace: targetNamespace,
7281
targetImagePullSpec: targetImagePullSpec,
7382
operatorImagePullSpec: operatorImagePullSpec,
83+
featureGates: featureGates,
7484
kubeClient: kubeClient,
7585
versionRecorder: versionRecorder,
7686
}
@@ -157,6 +167,15 @@ func (c *OAuthAPIServerWorkload) syncDeployment(ctx context.Context, operatorSpe
157167
// log level verbosity is taken from the spec always
158168
args["v"] = []string{loglevelToKlog(operatorSpec.LogLevel)}
159169

170+
// Set feature gates
171+
features, err := getFeatureGates(c.featureGates)
172+
if err != nil {
173+
return nil, err
174+
}
175+
if len(features) > 0 {
176+
args["feature-gates"] = []string{strings.Join(features, ",")}
177+
}
178+
160179
// use string replacer for simple things
161180
r := strings.NewReplacer(
162181
"${IMAGE}", c.targetImagePullSpec,
@@ -287,3 +306,36 @@ func GetAPIServerArgumentsRaw(authOperatorSpec operatorv1.OperatorSpec) (map[str
287306

288307
return cfgUnstructured.APIServerArguments, nil
289308
}
309+
310+
func getFeatureGates(featureGates featuregates.FeatureGate) ([]string, error) {
311+
if featureGates == nil {
312+
return nil, fmt.Errorf("featureGates cannot be nil")
313+
}
314+
315+
// Get a list of known Kubernetes feature gates
316+
known := feature.DefaultMutableFeatureGate.GetAll()
317+
318+
// Filter out OCP-specific feature gates
319+
filteredFeatures := []string{}
320+
for _, feature := range featureGates.KnownFeatures() {
321+
_, ok := known[featuregate.Feature(feature)]
322+
if !ok {
323+
continue
324+
}
325+
filteredFeatures = append(filteredFeatures, string(feature))
326+
}
327+
sort.Strings(filteredFeatures)
328+
329+
// Format feature gates statuses
330+
formattedFeatures := []string{}
331+
for _, featureGate := range filteredFeatures {
332+
fgName := configv1.FeatureGateName(featureGate)
333+
if featureGates.Enabled(fgName) {
334+
formattedFeatures = append(formattedFeatures, fmt.Sprintf("%s=true", featureGate))
335+
} else {
336+
formattedFeatures = append(formattedFeatures, fmt.Sprintf("%s=false", featureGate))
337+
}
338+
}
339+
340+
return formattedFeatures, nil
341+
}

pkg/operator/workload/sync_openshift_oauth_apiserver_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"github.com/google/go-cmp/cmp"
1212

1313
operatorv1 "github.com/openshift/api/operator/v1"
14+
"github.com/openshift/library-go/pkg/operator/configobserver/featuregates"
1415
"github.com/openshift/library-go/pkg/operator/events"
1516

1617
appsv1 "k8s.io/api/apps/v1"
@@ -145,6 +146,7 @@ func TestSyncOAuthAPIServerDeployment(t *testing.T) {
145146
countNodes: func(nodeSelector map[string]string) (*int32, error) { var i int32; i = 1; return &i, nil },
146147
ensureAtMostOnePodPerNode: func(spec *appsv1.DeploymentSpec, componentName string) error { return nil },
147148
kubeClient: fakeKubeClient,
149+
featureGates: featuregates.NewFeatureGate(nil, nil),
148150
}
149151

150152
actualDeployment, err := target.syncDeployment(context.TODO(), &scenario.operator.Spec.OperatorSpec, &scenario.operator.Status.OperatorStatus, eventRecorder)

0 commit comments

Comments
 (0)