Skip to content

Commit e064360

Browse files
authored
Add finalizer in deployment to allow cleanup during addon disable (#81)
* add logic to add finalizer in deployment Signed-off-by: Ashima-Ashima1 <[email protected]> * add logic to add finalizer in deployment Signed-off-by: Ashima-Ashima1 <[email protected]> * add logs Signed-off-by: Ashima-Ashima1 <[email protected]> * address review comments Signed-off-by: Ashima-Ashima1 <[email protected]> * address review comments Signed-off-by: Ashima-Ashima1 <[email protected]> * address review comments Signed-off-by: Ashima-Ashima1 <[email protected]> * fix uts Signed-off-by: Ashima-Ashima1 <[email protected]> * address review comments Signed-off-by: Ashima-Ashima1 <[email protected]> --------- Signed-off-by: Ashima-Ashima1 <[email protected]>
1 parent 4036015 commit e064360

File tree

3 files changed

+110
-3
lines changed

3 files changed

+110
-3
lines changed

controllers/constants/constants.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ const (
1414
CSIOperatorNamespace = "ibm-object-csi-operator"
1515
CSIDriverName = "ibm-object-csi-driver"
1616
DriverName = "cos.s3.csi.ibm.io"
17+
DeploymentName = "ibm-object-csi-operator-controller-manager"
1718

1819
RbacAuthorizationAPIGroup = "rbac.authorization.k8s.io"
1920
SecurityOpenshiftAPIGroup = "security.openshift.io"
@@ -115,6 +116,13 @@ const (
115116
NodeServerMemoryLimitCMKey = "CSINodeMemoryLimit"
116117
)
117118

119+
type FinalizerOps int
120+
121+
const (
122+
AddFinalizer FinalizerOps = iota + 1
123+
RemoveFinalizer
124+
)
125+
118126
var CommonCSIResourceLabels = map[string]string{
119127
"app.kubernetes.io/part-of": CSIDriverName,
120128
"app.kubernetes.io/managed-by": CSIOperatorName,

controllers/ibmobjectcsi_controller_test.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,13 @@ var (
3939
reclaimPolicyDelete = corev1.PersistentVolumeReclaimDelete
4040
secrets = crutils.GetImagePullSecrets(ibmObjectCSICR.Spec.ImagePullSecrets)
4141

42+
operatorDeploymnet = &appsv1.Deployment{
43+
ObjectMeta: metav1.ObjectMeta{
44+
Name: constants.DeploymentName,
45+
Namespace: constants.CSIOperatorNamespace,
46+
},
47+
}
48+
4249
ibmObjectCSIReconcileRequest = reconcile.Request{
4350
NamespacedName: types.NamespacedName{
4451
Name: ibmObjectCSICRName,
@@ -503,6 +510,7 @@ func TestIBMObjectCSIReconcile(t *testing.T) {
503510
{
504511
testCaseName: "Positive: Successful",
505512
objects: []runtime.Object{
513+
operatorDeploymnet,
506514
ibmObjectCSICR,
507515
addonConfigMap,
508516
csiNode,
@@ -528,6 +536,7 @@ func TestIBMObjectCSIReconcile(t *testing.T) {
528536
{
529537
testCaseName: "Positive: Sync controller deployment & pod containers and update status in IBMObjectCSI CR",
530538
objects: []runtime.Object{
539+
operatorDeploymnet,
531540
ibmObjectCSICRWithAWSProvider,
532541
addonConfigMap,
533542
csiNode,
@@ -557,6 +566,7 @@ func TestIBMObjectCSIReconcile(t *testing.T) {
557566
{
558567
testCaseName: "Positive: Successfully updated status in IBMObjectCSI CR after validating if pod images are in sync",
559568
objects: []runtime.Object{
569+
operatorDeploymnet,
560570
ibmObjectCSICR,
561571
addonConfigMap,
562572
controllerSA,
@@ -599,6 +609,7 @@ func TestIBMObjectCSIReconcile(t *testing.T) {
599609
{
600610
testCaseName: "Positive: Successfully removed finaliser from IBMObjectCSI CR",
601611
objects: []runtime.Object{
612+
operatorDeploymnet,
602613
ibmObjectCSICRWithDeletionTS,
603614
},
604615
clientFunc: func(objs []runtime.Object) client.WithWatch {
@@ -619,6 +630,7 @@ func TestIBMObjectCSIReconcile(t *testing.T) {
619630
{
620631
testCaseName: "Negative: Failed to Add Finalizer in IBMObjectCSI CR",
621632
objects: []runtime.Object{
633+
operatorDeploymnet,
622634
ibmObjectCSICR,
623635
},
624636
clientFunc: func(objs []runtime.Object) client.WithWatch {
@@ -642,6 +654,7 @@ func TestIBMObjectCSIReconcile(t *testing.T) {
642654
{
643655
testCaseName: "Negative: configmap not found",
644656
objects: []runtime.Object{
657+
operatorDeploymnet,
645658
ibmObjectCSICR,
646659
},
647660
clientFunc: func(objs []runtime.Object) client.WithWatch {
@@ -653,6 +666,7 @@ func TestIBMObjectCSIReconcile(t *testing.T) {
653666
{
654667
testCaseName: "Negative: Failed to update IBMObjectCSI CR as per updated configmap data",
655668
objects: []runtime.Object{
669+
operatorDeploymnet,
656670
ibmObjectCSICR,
657671
addonConfigMapWithUpdatedData,
658672
},
@@ -665,6 +679,7 @@ func TestIBMObjectCSIReconcile(t *testing.T) {
665679
{
666680
testCaseName: "Positive: IBMObjectCSI CR updated as per updated configmap data",
667681
objects: []runtime.Object{
682+
operatorDeploymnet,
668683
ibmObjectCSICR,
669684
addonConfigMapWithUpdatedData,
670685
},
@@ -677,6 +692,7 @@ func TestIBMObjectCSIReconcile(t *testing.T) {
677692
{
678693
testCaseName: "Negative: Failed to create CSI driver while reconciling",
679694
objects: []runtime.Object{
695+
operatorDeploymnet,
680696
ibmObjectCSICR,
681697
addonConfigMap,
682698
},
@@ -689,6 +705,7 @@ func TestIBMObjectCSIReconcile(t *testing.T) {
689705
{
690706
testCaseName: "Negative: Failed to get CSI driver while reconciling",
691707
objects: []runtime.Object{
708+
operatorDeploymnet,
692709
ibmObjectCSICR,
693710
addonConfigMap,
694711
},
@@ -701,6 +718,7 @@ func TestIBMObjectCSIReconcile(t *testing.T) {
701718
{
702719
testCaseName: "Negative: Failed to create service account while reconciling",
703720
objects: []runtime.Object{
721+
operatorDeploymnet,
704722
ibmObjectCSICR,
705723
addonConfigMap,
706724
csiDriver,
@@ -739,6 +757,7 @@ func TestIBMObjectCSIReconcile(t *testing.T) {
739757
{
740758
testCaseName: "Negative: Failed to restart node while reconciling",
741759
objects: []runtime.Object{
760+
operatorDeploymnet,
742761
ibmObjectCSICRWithFinaliser,
743762
addonConfigMap,
744763
csiNode,
@@ -754,6 +773,7 @@ func TestIBMObjectCSIReconcile(t *testing.T) {
754773
{
755774
testCaseName: "Failed to get service account while reconciling",
756775
objects: []runtime.Object{
776+
operatorDeploymnet,
757777
ibmObjectCSICR,
758778
addonConfigMap,
759779
},
@@ -766,6 +786,7 @@ func TestIBMObjectCSIReconcile(t *testing.T) {
766786
{
767787
testCaseName: "Negative: Failed to get controller pod while reconciling",
768788
objects: []runtime.Object{
789+
operatorDeploymnet,
769790
ibmObjectCSICRWithFinaliser,
770791
addonConfigMap,
771792
csiNode,
@@ -794,6 +815,7 @@ func TestIBMObjectCSIReconcile(t *testing.T) {
794815
{
795816
testCaseName: "Negative: Failed to sync CSI Controller",
796817
objects: []runtime.Object{
818+
operatorDeploymnet,
797819
ibmObjectCSICRWithFinaliser,
798820
addonConfigMap,
799821
controllerSA,
@@ -816,6 +838,7 @@ func TestIBMObjectCSIReconcile(t *testing.T) {
816838
{
817839
testCaseName: "Negative: Failed to sync CSI Node",
818840
objects: []runtime.Object{
841+
operatorDeploymnet,
819842
ibmObjectCSICRWithFinaliser,
820843
addonConfigMap,
821844
controllerSA,
@@ -831,6 +854,7 @@ func TestIBMObjectCSIReconcile(t *testing.T) {
831854
{
832855
testCaseName: "Negative: Failed to create storage class while reconciling",
833856
objects: []runtime.Object{
857+
operatorDeploymnet,
834858
ibmObjectCSICRWithAWSProvider,
835859
addonConfigMap,
836860
csiNode,
@@ -846,6 +870,7 @@ func TestIBMObjectCSIReconcile(t *testing.T) {
846870
{
847871
testCaseName: "Negative: Failed to update status in IBMObjectCSI CR",
848872
objects: []runtime.Object{
873+
operatorDeploymnet,
849874
ibmObjectCSICRWithFinaliser,
850875
addonConfigMap,
851876
controllerSA,
@@ -885,6 +910,7 @@ func TestIBMObjectCSIReconcile(t *testing.T) {
885910
{
886911
testCaseName: "Negative: IBMObjectCSI CR is deleted and failed to delete cluster role binding",
887912
objects: []runtime.Object{
913+
operatorDeploymnet,
888914
ibmObjectCSICRWithDeletionTS,
889915
externalProvisionerCRB,
890916
controllerSCCCRB,
@@ -899,6 +925,7 @@ func TestIBMObjectCSIReconcile(t *testing.T) {
899925
{
900926
testCaseName: "Negative: IBMObjectCSI CR is deleted and failed to delete cluster role",
901927
objects: []runtime.Object{
928+
operatorDeploymnet,
902929
ibmObjectCSICRWithDeletionTS,
903930
externalProvisionerCR,
904931
controllerSCCCR,
@@ -913,6 +940,7 @@ func TestIBMObjectCSIReconcile(t *testing.T) {
913940
{
914941
testCaseName: "Negative: IBMObjectCSI CR is deleted and failed to delete storage class",
915942
objects: []runtime.Object{
943+
operatorDeploymnet,
916944
ibmObjectCSICRWithDeletionTS,
917945
rCloneSC,
918946
rCloneRetainSC,
@@ -928,6 +956,7 @@ func TestIBMObjectCSIReconcile(t *testing.T) {
928956
{
929957
testCaseName: "Negative: IBMObjectCSI CR is deleted and failed to delete CSI driver",
930958
objects: []runtime.Object{
959+
operatorDeploymnet,
931960
ibmObjectCSICRWithDeletionTS,
932961
csiDriver,
933962
},
@@ -940,6 +969,7 @@ func TestIBMObjectCSIReconcile(t *testing.T) {
940969
{
941970
testCaseName: "Negative: Failed to get CSI driver while deleting",
942971
objects: []runtime.Object{
972+
operatorDeploymnet,
943973
&v1alpha1.IBMObjectCSI{
944974
ObjectMeta: ibmObjectCSICRWithDeletionTS.ObjectMeta,
945975
Spec: ibmObjectCSICR.Spec,
@@ -954,6 +984,7 @@ func TestIBMObjectCSIReconcile(t *testing.T) {
954984
{
955985
testCaseName: "Negative: Failed to remove finaliser from IBMObjectCSI CR",
956986
objects: []runtime.Object{
987+
operatorDeploymnet,
957988
&v1alpha1.IBMObjectCSI{
958989
ObjectMeta: ibmObjectCSICRWithDeletionTS.ObjectMeta,
959990
Spec: ibmObjectCSICR.Spec,

controllers/util/common/common.go

Lines changed: 71 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"github.com/IBM/ibm-object-csi-driver-operator/controllers/util"
1313
"github.com/go-logr/logr"
1414
openshiftclient "github.com/openshift/client-go/config/clientset/versioned"
15+
appsv1 "k8s.io/api/apps/v1"
1516
corev1 "k8s.io/api/core/v1"
1617
rbacv1 "k8s.io/api/rbac/v1"
1718
storagev1 "k8s.io/api/storage/v1"
@@ -23,6 +24,7 @@ import (
2324
"k8s.io/client-go/rest"
2425
"sigs.k8s.io/controller-runtime/pkg/client"
2526
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
27+
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
2628
)
2729

2830
// ControllerHelper ...
@@ -207,6 +209,11 @@ func (ch *ControllerHelper) AddFinalizerIfNotPresent(instance crutils.Instance,
207209
return err
208210
}
209211

212+
err = ch.updateControllerFinalizer(context.TODO(), constants.AddFinalizer, finalizerName)
213+
if err != nil {
214+
return err
215+
}
216+
210217
if !util.Contains(accessor.GetFinalizers(), finalizerName) {
211218
logger.Info("adding", "finalizer", finalizerName, "on", accessor.GetName())
212219
accessor.SetFinalizers(append(accessor.GetFinalizers(), finalizerName))
@@ -215,6 +222,9 @@ func (ch *ControllerHelper) AddFinalizerIfNotPresent(instance crutils.Instance,
215222
logger.Error(err, "failed to add", "finalizer", finalizerName, "on", accessor.GetName())
216223
return err
217224
}
225+
logger.Info("AddFinalizerIfNotPresent: finalizer added on ", accessor.GetName())
226+
} else {
227+
logger.Info("AddFinalizerIfNotPresent: finalizer already present on ", accessor.GetName())
218228
}
219229
return nil
220230
}
@@ -229,9 +239,19 @@ func (ch *ControllerHelper) RemoveFinalizer(instance crutils.Instance,
229239
return err
230240
}
231241

232-
accessor.SetFinalizers(util.Remove(accessor.GetFinalizers(), finalizerName))
233-
if err := ch.Update(context.TODO(), unwrappedInstance); err != nil {
234-
logger.Error(err, "failed to remove", "finalizer", finalizerName, "from", accessor.GetName())
242+
if !util.Contains(accessor.GetFinalizers(), finalizerName) {
243+
logger.Info("RemoveFinalizer: finalizer already removed from ", accessor.GetName())
244+
} else {
245+
accessor.SetFinalizers(util.Remove(accessor.GetFinalizers(), finalizerName))
246+
if err := ch.Update(context.TODO(), unwrappedInstance); err != nil {
247+
logger.Error(err, "failed to remove", "finalizer", finalizerName, "from", accessor.GetName())
248+
return err
249+
}
250+
logger.Info("RemoveFinalizer: finalizer removed from ", accessor.GetName())
251+
}
252+
253+
err = ch.updateControllerFinalizer(context.TODO(), constants.RemoveFinalizer, finalizerName)
254+
if err != nil {
235255
return err
236256
}
237257
return nil
@@ -413,3 +433,51 @@ func (ch *ControllerHelper) SetS3ProviderEP() {
413433
ch.CosEP = fmt.Sprintf(constants.WasabiEP, ch.S3ProviderRegion)
414434
}
415435
}
436+
437+
// Update finalizer to Controller Deployment under NS "ibm-object-csi-operator"
438+
// op = 1 Add finalizer op = 2 Remove finalizer
439+
func (ch *ControllerHelper) updateControllerFinalizer(ctx context.Context, op constants.FinalizerOps, finalizerName string) error {
440+
ch.Log.Info("updateControllerFinalizer(): Entry")
441+
defer ch.Log.Info("updateControllerFinalizer(): Exit")
442+
443+
ctrlDep := &appsv1.Deployment{}
444+
err := ch.Get(ctx, client.ObjectKey{Namespace: constants.CSIOperatorNamespace, Name: constants.DeploymentName}, ctrlDep)
445+
if err != nil {
446+
ch.Log.Error(err, "updateControllerFinalizer(): controller deployment not found. retrying...")
447+
return err
448+
}
449+
450+
if op == constants.AddFinalizer { // Add finalizer
451+
ch.Log.Info("updateControllerFinalizer(): add finalizer to controller deployment")
452+
chk := controllerutil.ContainsFinalizer(ctrlDep, finalizerName)
453+
if !chk {
454+
controllerutil.AddFinalizer(ctrlDep, finalizerName)
455+
err = ch.Update(ctx, ctrlDep)
456+
if err != nil {
457+
ch.Log.Error(err, "updateControllerFinalizer(): failed to add the finalizer")
458+
return err
459+
}
460+
ch.Log.Info("updateControllerFinalizer(): finalizer has been added in controller deployment")
461+
} else {
462+
ch.Log.Info("updateControllerFinalizer(): finalizer already present in controller deployment")
463+
}
464+
}
465+
466+
if op == constants.RemoveFinalizer { // Remove finalizer
467+
ch.Log.Info("updateControllerFinalizer(): remove finalizer from controller deployment")
468+
chk := controllerutil.ContainsFinalizer(ctrlDep, finalizerName)
469+
if chk {
470+
controllerutil.RemoveFinalizer(ctrlDep, finalizerName)
471+
err = ch.Update(ctx, ctrlDep)
472+
if err != nil {
473+
ch.Log.Error(err, "updateControllerFinalizer(): Failed to remove finalizer")
474+
return err
475+
}
476+
ch.Log.Info("updateControllerFinalizer(): finalizer has been removed from controller deployment")
477+
} else {
478+
ch.Log.Info("updateControllerFinalizer(): finalizer not present in controller deployment")
479+
}
480+
}
481+
482+
return nil
483+
}

0 commit comments

Comments
 (0)