Skip to content

Commit ce021d5

Browse files
committed
feat/config-sync: setting up feature gate acessor
Enabling feature gate acessor to the cloud-config sync controller.
1 parent 73b368b commit ce021d5

File tree

4 files changed

+81
-9
lines changed

4 files changed

+81
-9
lines changed

cmd/config-sync-controllers/main.go

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626

2727
// Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.)
2828
// to ensure that exec-entrypoint and run can make use of them.
29+
"k8s.io/client-go/kubernetes"
2930
_ "k8s.io/client-go/plugin/pkg/client/auth"
3031

3132
"k8s.io/apimachinery/pkg/runtime"
@@ -40,6 +41,11 @@ import (
4041
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
4142

4243
configv1 "github.com/openshift/api/config/v1"
44+
"github.com/openshift/library-go/pkg/operator/configobserver/featuregates"
45+
"github.com/openshift/library-go/pkg/operator/events"
46+
47+
configv1client "github.com/openshift/client-go/config/clientset/versioned"
48+
configinformers "github.com/openshift/client-go/config/informers/externalversions"
4349

4450
"github.com/openshift/cluster-cloud-controller-manager-operator/pkg/controllers"
4551
"github.com/openshift/cluster-cloud-controller-manager-operator/pkg/restmapper"
@@ -79,6 +85,12 @@ func main() {
7985
"The namespace for managed objects, target cloud-conf in particular.",
8086
)
8187

88+
recorderName := "cloud-controller-manager-operator-cloud-config-sync-controller"
89+
missingVersion := "0.0.1-snapshot"
90+
desiredVersion := controllers.GetReleaseVersion()
91+
sharedClock := clock.RealClock{}
92+
ctx := ctrl.SetupSignalHandler()
93+
8294
// Once all the flags are regitered, switch to pflag
8395
// to allow leader lection flags to be bound
8496
pflag.CommandLine.AddGoFlagSet(flag.CommandLine)
@@ -131,7 +143,36 @@ func main() {
131143
os.Exit(1)
132144
}
133145

134-
sharedClock := clock.RealClock{}
146+
// Feature gate accessor
147+
configClient, err := configv1client.NewForConfig(mgr.GetConfig())
148+
if err != nil {
149+
setupLog.Error(err, "unable to create config client")
150+
os.Exit(1)
151+
}
152+
kubeClient, err := kubernetes.NewForConfig(mgr.GetConfig())
153+
if err != nil {
154+
setupLog.Error(err, "unable to create kube client")
155+
os.Exit(1)
156+
}
157+
158+
configInformers := configinformers.NewSharedInformerFactory(configClient, 10*time.Minute)
159+
controllerRef, err := events.GetControllerReferenceForCurrentPod(ctx, kubeClient, *managedNamespace, nil)
160+
if err != nil {
161+
klog.Warningf("unable to get owner reference (falling back to namespace): %v", err)
162+
}
163+
164+
featureGateAccessor := featuregates.NewFeatureGateAccess(
165+
desiredVersion, missingVersion,
166+
configInformers.Config().V1().ClusterVersions(), configInformers.Config().V1().FeatureGates(),
167+
events.NewKubeRecorder(kubeClient.CoreV1().Events(*managedNamespace), recorderName, controllerRef, sharedClock),
168+
)
169+
featureGateAccessor.SetChangeHandler(func(featureChange featuregates.FeatureChange) {
170+
// Do nothing here. The controller watches feature gate changes and will react to them.
171+
klog.InfoS("FeatureGates changed", "enabled", featureChange.New.Enabled, "disabled", featureChange.New.Disabled)
172+
})
173+
go featureGateAccessor.Run(ctx)
174+
go configInformers.Start(ctx.Done())
175+
135176
if err = (&controllers.CloudConfigReconciler{
136177
ClusterOperatorStatusClient: controllers.ClusterOperatorStatusClient{
137178
Client: mgr.GetClient(),
@@ -140,7 +181,8 @@ func main() {
140181
ReleaseVersion: controllers.GetReleaseVersion(),
141182
ManagedNamespace: *managedNamespace,
142183
},
143-
Scheme: mgr.GetScheme(),
184+
Scheme: mgr.GetScheme(),
185+
FeatureGateAccess: featureGateAccessor,
144186
}).SetupWithManager(mgr); err != nil {
145187
setupLog.Error(err, "unable to create cloud-config sync controller", "controller", "ClusterOperator")
146188
os.Exit(1)
@@ -171,7 +213,7 @@ func main() {
171213
}
172214

173215
setupLog.Info("starting manager")
174-
if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {
216+
if err := mgr.Start(ctx); err != nil {
175217
setupLog.Error(err, "problem running manager")
176218
os.Exit(1)
177219
}

pkg/controllers/cloud_config_sync_controller.go

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
"sigs.k8s.io/controller-runtime/pkg/predicate"
1717

1818
configv1 "github.com/openshift/api/config/v1"
19+
"github.com/openshift/library-go/pkg/operator/configobserver/featuregates"
1920

2021
"github.com/openshift/cluster-cloud-controller-manager-operator/pkg/cloud"
2122
)
@@ -32,7 +33,8 @@ const (
3233

3334
type CloudConfigReconciler struct {
3435
ClusterOperatorStatusClient
35-
Scheme *runtime.Scheme
36+
Scheme *runtime.Scheme
37+
FeatureGateAccess featuregates.FeatureGateAccess
3638
}
3739

3840
func (r *CloudConfigReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
@@ -133,11 +135,29 @@ func (r *CloudConfigReconciler) Reconcile(ctx context.Context, req ctrl.Request)
133135
return ctrl.Result{}, err
134136
}
135137

138+
// Check if FeatureGateAccess is configured
139+
if r.FeatureGateAccess == nil {
140+
klog.Errorf("FeatureGateAccess is not configured")
141+
if err := r.setDegradedCondition(ctx); err != nil {
142+
return ctrl.Result{}, fmt.Errorf("failed to set conditions for cloud config controller: %v", err)
143+
}
144+
return ctrl.Result{}, fmt.Errorf("FeatureGateAccess is not configured")
145+
}
146+
147+
features, err := r.FeatureGateAccess.CurrentFeatureGates()
148+
if err != nil {
149+
klog.Errorf("unable to get feature gates: %v", err)
150+
if errD := r.setDegradedCondition(ctx); errD != nil {
151+
return ctrl.Result{}, fmt.Errorf("failed to set conditions for cloud config controller: %v", errD)
152+
}
153+
return ctrl.Result{}, err
154+
}
155+
136156
if cloudConfigTransformerFn != nil {
137157
// We ignore stuff in sourceCM.BinaryData. This isn't allowed to
138158
// contain any key that overlaps with those found in sourceCM.Data and
139159
// we're not expecting users to put their data in the former.
140-
output, err := cloudConfigTransformerFn(sourceCM.Data[defaultConfigKey], infra, network)
160+
output, err := cloudConfigTransformerFn(sourceCM.Data[defaultConfigKey], infra, network, features)
141161
if err != nil {
142162
if err := r.setDegradedCondition(ctx); err != nil {
143163
return ctrl.Result{}, fmt.Errorf("failed to set conditions for cloud config controller: %v", err)

pkg/controllers/cloud_config_sync_controller_test.go

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ import (
2121
"sigs.k8s.io/controller-runtime/pkg/manager"
2222
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
2323
"sigs.k8s.io/controller-runtime/pkg/reconcile"
24+
25+
"github.com/openshift/library-go/pkg/operator/configobserver/featuregates"
2426
)
2527

2628
const (
@@ -112,7 +114,9 @@ func makeManagedCloudConfig(platform configv1.PlatformType) *corev1.ConfigMap {
112114
}
113115

114116
var _ = Describe("isCloudConfigEqual reconciler method", func() {
115-
reconciler := &CloudConfigReconciler{}
117+
reconciler := &CloudConfigReconciler{
118+
FeatureGateAccess: featuregates.NewHardcodedFeatureGateAccessForTesting(nil, nil, nil, nil),
119+
}
116120

117121
It("should return 'true' if ConfigMaps content are equal", func() {
118122
Expect(reconciler.isCloudConfigEqual(makeManagedCloudConfig(configv1.AzurePlatformType), makeManagedCloudConfig(configv1.AzurePlatformType))).Should(BeTrue())
@@ -130,7 +134,9 @@ var _ = Describe("isCloudConfigEqual reconciler method", func() {
130134
})
131135

132136
var _ = Describe("prepareSourceConfigMap reconciler method", func() {
133-
reconciler := &CloudConfigReconciler{}
137+
reconciler := &CloudConfigReconciler{
138+
FeatureGateAccess: featuregates.NewHardcodedFeatureGateAccessForTesting(nil, nil, nil, nil),
139+
}
134140
infra := makeInfrastructureResource(configv1.AzurePlatformType)
135141
infraCloudConfig := makeInfraCloudConfig(configv1.AzurePlatformType)
136142
managedCloudConfig := makeManagedCloudConfig(configv1.AzurePlatformType)
@@ -199,7 +205,8 @@ var _ = Describe("Cloud config sync controller", func() {
199205
Clock: clocktesting.NewFakePassiveClock(time.Now()),
200206
ManagedNamespace: targetNamespaceName,
201207
},
202-
Scheme: scheme.Scheme,
208+
Scheme: scheme.Scheme,
209+
FeatureGateAccess: featuregates.NewHardcodedFeatureGateAccessForTesting(nil, nil, nil, nil),
203210
}
204211
Expect(reconciler.SetupWithManager(mgr)).To(Succeed())
205212

@@ -284,6 +291,7 @@ var _ = Describe("Cloud config sync controller", func() {
284291
By("Creating needed ConfigMaps")
285292
infraCloudConfig = makeInfraCloudConfig(configv1.AzurePlatformType)
286293
managedCloudConfig = makeManagedCloudConfig(configv1.AzurePlatformType)
294+
287295
Expect(cl.Create(ctx, infraCloudConfig)).To(Succeed())
288296
Expect(cl.Create(ctx, managedCloudConfig)).To(Succeed())
289297
})
@@ -400,7 +408,8 @@ var _ = Describe("Cloud config sync reconciler", func() {
400408
Clock: clocktesting.NewFakePassiveClock(time.Now()),
401409
ManagedNamespace: targetNamespaceName,
402410
},
403-
Scheme: scheme.Scheme,
411+
Scheme: scheme.Scheme,
412+
FeatureGateAccess: featuregates.NewHardcodedFeatureGateAccessForTesting(nil, nil, nil, nil),
404413
}
405414

406415
networkResource := makeNetworkResource()

pkg/controllers/trusted_ca_bundle_controller_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ var _ = Describe("Trusted CA bundle sync controller", func() {
134134
additionalCAConfigMap, err = makeValidUserCAConfigMap(additionalAmazonCAPemPath)
135135
syncedCloudConfigConfigMap = makeSyncedCloudConfig(targetNamespaceName, map[string]string{})
136136
Expect(err).NotTo(HaveOccurred())
137+
137138
Expect(cl.Create(ctx, proxyResource)).To(Succeed())
138139
Expect(cl.Create(ctx, additionalCAConfigMap)).To(Succeed())
139140
Expect(cl.Create(ctx, syncedCloudConfigConfigMap)).To(Succeed())

0 commit comments

Comments
 (0)