Skip to content

Commit 99a6796

Browse files
authored
Merge pull request openshift#878 from zeeke/us/OCPBUGS-53346
controllers: Use patch to add finalizers
2 parents e0354a3 + c9c3ca1 commit 99a6796

File tree

2 files changed

+84
-20
lines changed

2 files changed

+84
-20
lines changed

controllers/sriovoperatorconfig_controller.go

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ func (r *SriovOperatorConfigReconciler) Reconcile(ctx context.Context, req ctrl.
8585
if err != nil {
8686
if apierrors.IsNotFound(err) {
8787
logger.Info("default SriovOperatorConfig object not found. waiting for creation.")
88-
return reconcile.Result{}, err
88+
return reconcile.Result{}, nil
8989
}
9090
// Error reading the object - requeue the request.
9191
logger.Error(err, "Failed to get default SriovOperatorConfig object")
@@ -99,12 +99,9 @@ func (r *SriovOperatorConfigReconciler) Reconcile(ctx context.Context, req ctrl.
9999
// The object is being deleted
100100
return r.handleSriovOperatorConfigDeletion(ctx, defaultConfig, logger)
101101
}
102-
// add finalizer if needed
103-
if !sriovnetworkv1.StringInArray(sriovnetworkv1.OPERATORCONFIGFINALIZERNAME, defaultConfig.ObjectMeta.Finalizers) {
104-
defaultConfig.ObjectMeta.Finalizers = append(defaultConfig.ObjectMeta.Finalizers, sriovnetworkv1.OPERATORCONFIGFINALIZERNAME)
105-
if err := r.Update(ctx, defaultConfig); err != nil {
106-
return reconcile.Result{}, err
107-
}
102+
103+
if err = r.syncOperatorConfigFinalizers(ctx, defaultConfig, logger); err != nil {
104+
return reconcile.Result{}, err
108105
}
109106

110107
r.FeatureGate.Init(defaultConfig.Spec.FeatureGates)
@@ -448,6 +445,29 @@ func (r *SriovOperatorConfigReconciler) syncOpenShiftSystemdService(ctx context.
448445
return r.setLabelInsideObject(ctx, cr, objs)
449446
}
450447

448+
func (r SriovOperatorConfigReconciler) syncOperatorConfigFinalizers(ctx context.Context, defaultConfig *sriovnetworkv1.SriovOperatorConfig, logger logr.Logger) error {
449+
if sriovnetworkv1.StringInArray(sriovnetworkv1.OPERATORCONFIGFINALIZERNAME, defaultConfig.ObjectMeta.Finalizers) {
450+
return nil
451+
}
452+
453+
newObj := defaultConfig.DeepCopyObject().(client.Object)
454+
newObj.SetFinalizers(
455+
append(newObj.GetFinalizers(), sriovnetworkv1.OPERATORCONFIGFINALIZERNAME),
456+
)
457+
458+
logger.WithName("syncOperatorConfigFinalizers").
459+
Info("Adding finalizer", "key", sriovnetworkv1.OPERATORCONFIGFINALIZERNAME)
460+
461+
patch := client.MergeFrom(defaultConfig)
462+
err := r.Patch(ctx, newObj, patch)
463+
if err != nil {
464+
return fmt.Errorf("can't patch SriovOperatorConfig to add finalizer [%s]: %w", sriovnetworkv1.OPERATORCONFIGFINALIZERNAME, err)
465+
}
466+
467+
// Refresh the defaultConfig object with the latest changes
468+
return r.Get(ctx, types.NamespacedName{Namespace: defaultConfig.Namespace, Name: defaultConfig.Name}, defaultConfig)
469+
}
470+
451471
func (r *SriovOperatorConfigReconciler) handleSriovOperatorConfigDeletion(ctx context.Context,
452472
defaultConfig *sriovnetworkv1.SriovOperatorConfig, logger logr.Logger) (ctrl.Result, error) {
453473
var err error

controllers/sriovoperatorconfig_controller_test.go

Lines changed: 57 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ import (
3030
"github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/platforms/openshift"
3131
"github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/vars"
3232
"github.com/k8snetworkplumbingwg/sriov-network-operator/test/util"
33+
34+
uns "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
3335
)
3436

3537
var _ = Describe("SriovOperatorConfig controller", Ordered, func() {
@@ -117,21 +119,23 @@ var _ = Describe("SriovOperatorConfig controller", Ordered, func() {
117119
BeforeEach(func() {
118120
var err error
119121
config := &sriovnetworkv1.SriovOperatorConfig{}
120-
err = util.WaitForNamespacedObject(config, k8sClient, testNamespace, "default", util.RetryInterval, util.APITimeout)
121-
Expect(err).NotTo(HaveOccurred())
122-
// in case controller yet to add object's finalizer (e.g whenever test deferCleanup is creating new 'default' config object)
123-
if len(config.Finalizers) == 0 {
122+
123+
Eventually(func(g Gomega) {
124124
err = util.WaitForNamespacedObject(config, k8sClient, testNamespace, "default", util.RetryInterval, util.APITimeout)
125+
g.Expect(err).NotTo(HaveOccurred())
126+
// in case controller yet to add object's finalizer (e.g whenever test deferCleanup is creating new 'default' config object)
127+
g.Expect(config.Finalizers).ToNot(BeEmpty())
128+
129+
config.Spec = sriovnetworkv1.SriovOperatorConfigSpec{
130+
EnableInjector: true,
131+
EnableOperatorWebhook: true,
132+
LogLevel: 2,
133+
FeatureGates: map[string]bool{},
134+
}
135+
err = k8sClient.Update(ctx, config)
125136
Expect(err).NotTo(HaveOccurred())
126-
}
127-
config.Spec = sriovnetworkv1.SriovOperatorConfigSpec{
128-
EnableInjector: true,
129-
EnableOperatorWebhook: true,
130-
LogLevel: 2,
131-
FeatureGates: map[string]bool{},
132-
}
133-
err = k8sClient.Update(ctx, config)
134-
Expect(err).NotTo(HaveOccurred())
137+
}).Should(Succeed())
138+
135139
})
136140

137141
It("should have webhook enable", func() {
@@ -291,6 +295,46 @@ var _ = Describe("SriovOperatorConfig controller", Ordered, func() {
291295
}, util.APITimeout, util.RetryInterval).Should(Equal(empty))
292296
})
293297

298+
It("should not remove fields with default values when SriovOperatorConfig is created", func() {
299+
err := k8sClient.Delete(context.Background(), &sriovnetworkv1.SriovOperatorConfig{
300+
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: consts.DefaultConfigName},
301+
})
302+
Expect(err).NotTo(HaveOccurred())
303+
304+
config := &uns.Unstructured{}
305+
config.SetGroupVersionKind(sriovnetworkv1.GroupVersion.WithKind("SriovOperatorConfig"))
306+
config.SetName(consts.DefaultConfigName)
307+
config.SetNamespace(testNamespace)
308+
config.Object["spec"] = map[string]interface{}{
309+
"enableInjector": false,
310+
"enableOperatorWebhook": false,
311+
"logLevel": 0,
312+
"disableDrain": false,
313+
}
314+
315+
Eventually(func() error {
316+
return k8sClient.Create(context.Background(), config)
317+
}).Should(Succeed())
318+
319+
By("Wait for the operator to reconcile the object")
320+
Eventually(func(g Gomega) {
321+
err := k8sClient.Get(context.Background(), types.NamespacedName{Namespace: testNamespace, Name: consts.DefaultConfigName}, config)
322+
g.Expect(err).ToNot(HaveOccurred())
323+
g.Expect(config.GetFinalizers()).To(ContainElement(sriovnetworkv1.OPERATORCONFIGFINALIZERNAME))
324+
}, util.APITimeout, util.RetryInterval).Should(Succeed())
325+
326+
By("Verify default values have not been omitted")
327+
obj := &uns.Unstructured{}
328+
obj.SetGroupVersionKind(sriovnetworkv1.GroupVersion.WithKind("SriovOperatorConfig"))
329+
err = k8sClient.Get(context.Background(), types.NamespacedName{Namespace: testNamespace, Name: consts.DefaultConfigName}, obj)
330+
Expect(err).NotTo(HaveOccurred())
331+
332+
Expect(obj.Object["spec"]).To(HaveKeyWithValue("enableInjector", false))
333+
Expect(obj.Object["spec"]).To(HaveKeyWithValue("enableOperatorWebhook", false))
334+
Expect(obj.Object["spec"]).To(HaveKeyWithValue("logLevel", int64(0)))
335+
Expect(obj.Object["spec"]).To(HaveKeyWithValue("disableDrain", false))
336+
})
337+
294338
It("should be able to update the node selector of sriov-network-config-daemon", func() {
295339
By("specify the configDaemonNodeSelector")
296340
nodeSelector := map[string]string{"node-role.kubernetes.io/worker": ""}

0 commit comments

Comments
 (0)