Skip to content

Commit f94a5ed

Browse files
authored
Add finalizer for CSV cleanup (#3148)
Remove old CSV cleanup code Cleanup CRB/CR/MWC/VWC via finalizer. Signed-off-by: Todd Short <[email protected]>
1 parent 2bdaa66 commit f94a5ed

File tree

3 files changed

+127
-195
lines changed

3 files changed

+127
-195
lines changed

cmd/olm/manager.go

+7
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package main
33
import (
44
"context"
55

6+
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
67
appsv1 "k8s.io/api/apps/v1"
78
corev1 "k8s.io/api/core/v1"
89
rbacv1 "k8s.io/api/rbac/v1"
@@ -87,6 +88,12 @@ func Manager(ctx context.Context, debug bool) (ctrl.Manager, error) {
8788
&rbacv1.ClusterRoleBinding{}: {
8889
Label: labels.SelectorFromValidatedSet(map[string]string{install.OLMManagedLabelKey: install.OLMManagedLabelValue}),
8990
},
91+
&admissionregistrationv1.MutatingWebhookConfiguration{}: {
92+
Label: labels.SelectorFromValidatedSet(map[string]string{install.OLMManagedLabelKey: install.OLMManagedLabelValue}),
93+
},
94+
&admissionregistrationv1.ValidatingWebhookConfiguration{}: {
95+
Label: labels.SelectorFromValidatedSet(map[string]string{install.OLMManagedLabelKey: install.OLMManagedLabelValue}),
96+
},
9097
&operatorsv1alpha1.ClusterServiceVersion{}: {
9198
Label: copiedLabelDoesNotExist,
9299
},

pkg/controller/operators/olm/operator.go

+2-195
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import (
1111
"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/labeller"
1212
"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/olm/plugins"
1313
"github.com/sirupsen/logrus"
14-
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
1514
appsv1 "k8s.io/api/apps/v1"
1615
corev1 "k8s.io/api/core/v1"
1716
rbacv1 "k8s.io/api/rbac/v1"
@@ -50,7 +49,6 @@ import (
5049
csvutility "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/csv"
5150
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/event"
5251
index "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/index"
53-
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/kubestate"
5452
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/labeler"
5553
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient"
5654
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister"
@@ -86,7 +84,6 @@ type Operator struct {
8684
olmConfigQueue workqueue.RateLimitingInterface
8785
csvCopyQueueSet *queueinformer.ResourceQueueSet
8886
copiedCSVGCQueueSet *queueinformer.ResourceQueueSet
89-
objGCQueueSet *queueinformer.ResourceQueueSet
9087
nsQueueSet workqueue.RateLimitingInterface
9188
apiServiceQueue workqueue.RateLimitingInterface
9289
csvIndexers map[string]cache.Indexer
@@ -202,7 +199,6 @@ func newOperatorWithConfig(ctx context.Context, config *operatorConfig) (*Operat
202199
olmConfigQueue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "olmConfig"),
203200
csvCopyQueueSet: queueinformer.NewEmptyResourceQueueSet(),
204201
copiedCSVGCQueueSet: queueinformer.NewEmptyResourceQueueSet(),
205-
objGCQueueSet: queueinformer.NewEmptyResourceQueueSet(),
206202
apiServiceQueue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "apiservice"),
207203
resolver: config.strategyResolver,
208204
apiReconciler: config.apiReconciler,
@@ -480,21 +476,6 @@ func newOperatorWithConfig(ctx context.Context, config *operatorConfig) (*Operat
480476
if err := op.RegisterQueueInformer(serviceAccountQueueInformer); err != nil {
481477
return nil, err
482478
}
483-
484-
objGCQueue := workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), fmt.Sprintf("%s/obj-gc", namespace))
485-
op.objGCQueueSet.Set(namespace, objGCQueue)
486-
objGCQueueInformer, err := queueinformer.NewQueue(
487-
ctx,
488-
queueinformer.WithLogger(op.logger),
489-
queueinformer.WithQueue(objGCQueue),
490-
queueinformer.WithSyncer(queueinformer.LegacySyncHandler(op.syncGCObject).ToSyncer()),
491-
)
492-
if err != nil {
493-
return nil, err
494-
}
495-
if err := op.RegisterQueueInformer(objGCQueueInformer); err != nil {
496-
return nil, err
497-
}
498479
}
499480

500481
complete := map[schema.GroupVersionResource][]bool{}
@@ -568,22 +549,6 @@ func newOperatorWithConfig(ctx context.Context, config *operatorConfig) (*Operat
568549
return nil, err
569550
}
570551

571-
// add queue for all namespaces as well
572-
objGCQueue := workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), fmt.Sprintf("%s/obj-gc", ""))
573-
op.objGCQueueSet.Set("", objGCQueue)
574-
objGCQueueInformer, err := queueinformer.NewQueue(
575-
ctx,
576-
queueinformer.WithLogger(op.logger),
577-
queueinformer.WithQueue(objGCQueue),
578-
queueinformer.WithSyncer(queueinformer.LegacySyncHandler(op.syncGCObject).ToSyncer()),
579-
)
580-
if err != nil {
581-
return nil, err
582-
}
583-
if err := op.RegisterQueueInformer(objGCQueueInformer); err != nil {
584-
return nil, err
585-
}
586-
587552
// Register QueueInformer for olmConfig
588553
olmConfigInformer := externalversions.NewSharedInformerFactoryWithOptions(
589554
op.client,
@@ -948,98 +913,6 @@ func (a *Operator) EnsureCSVMetric() error {
948913
return nil
949914
}
950915

951-
func (a *Operator) syncGCObject(obj interface{}) (syncError error) {
952-
metaObj, ok := obj.(metav1.Object)
953-
if !ok {
954-
a.logger.Warn("object sync: casting to metav1.Object failed")
955-
return
956-
}
957-
logger := a.logger.WithFields(logrus.Fields{
958-
"name": metaObj.GetName(),
959-
"namespace": metaObj.GetNamespace(),
960-
"self": metaObj.GetSelfLink(),
961-
})
962-
963-
switch metaObj.(type) {
964-
case *rbacv1.ClusterRole:
965-
if name, ns, ok := ownerutil.GetOwnerByKindLabel(metaObj, v1alpha1.ClusterServiceVersionKind); ok {
966-
_, err := a.lister.OperatorsV1alpha1().ClusterServiceVersionLister().ClusterServiceVersions(ns).Get(name)
967-
if err == nil {
968-
logger.Debugf("CSV still present, must wait until it is deleted (owners=%v/%v)", ns, name)
969-
syncError = fmt.Errorf("cleanup must wait")
970-
return
971-
} else if !apierrors.IsNotFound(err) {
972-
syncError = err
973-
return
974-
}
975-
}
976-
977-
if err := a.opClient.DeleteClusterRole(metaObj.GetName(), &metav1.DeleteOptions{}); err != nil {
978-
logger.WithError(err).Warn("cannot delete cluster role")
979-
break
980-
}
981-
logger.Debugf("Deleted cluster role %v due to no owning CSV", metaObj.GetName())
982-
case *rbacv1.ClusterRoleBinding:
983-
if name, ns, ok := ownerutil.GetOwnerByKindLabel(metaObj, v1alpha1.ClusterServiceVersionKind); ok {
984-
_, err := a.lister.OperatorsV1alpha1().ClusterServiceVersionLister().ClusterServiceVersions(ns).Get(name)
985-
if err == nil {
986-
logger.Debugf("CSV still present, must wait until it is deleted (owners=%v)", name)
987-
syncError = fmt.Errorf("cleanup must wait")
988-
return
989-
} else if !apierrors.IsNotFound(err) {
990-
syncError = err
991-
return
992-
}
993-
}
994-
995-
if err := a.opClient.DeleteClusterRoleBinding(metaObj.GetName(), &metav1.DeleteOptions{}); err != nil {
996-
logger.WithError(err).Warn("cannot delete cluster role binding")
997-
break
998-
}
999-
logger.Debugf("Deleted cluster role binding %v due to no owning CSV", metaObj.GetName())
1000-
case *admissionregistrationv1.MutatingWebhookConfiguration:
1001-
if name, ns, ok := ownerutil.GetOwnerByKindLabel(metaObj, v1alpha1.ClusterServiceVersionKind); ok {
1002-
_, err := a.lister.OperatorsV1alpha1().ClusterServiceVersionLister().ClusterServiceVersions(ns).Get(name)
1003-
if err == nil {
1004-
logger.Debugf("CSV still present, must wait until it is deleted (owners=%v)", name)
1005-
syncError = fmt.Errorf("cleanup must wait")
1006-
return
1007-
} else if !apierrors.IsNotFound(err) {
1008-
logger.Infof("error CSV retrieval error")
1009-
syncError = err
1010-
return
1011-
}
1012-
}
1013-
1014-
if err := a.opClient.KubernetesInterface().AdmissionregistrationV1().MutatingWebhookConfigurations().Delete(context.TODO(), metaObj.GetName(), metav1.DeleteOptions{}); err != nil {
1015-
logger.WithError(err).Warn("cannot delete MutatingWebhookConfiguration")
1016-
break
1017-
}
1018-
logger.Debugf("Deleted MutatingWebhookConfiguration %v due to no owning CSV", metaObj.GetName())
1019-
case *admissionregistrationv1.ValidatingWebhookConfiguration:
1020-
if name, ns, ok := ownerutil.GetOwnerByKindLabel(metaObj, v1alpha1.ClusterServiceVersionKind); ok {
1021-
_, err := a.lister.OperatorsV1alpha1().ClusterServiceVersionLister().ClusterServiceVersions(ns).Get(name)
1022-
if err == nil {
1023-
logger.Debugf("CSV still present, must wait until it is deleted (owners=%v)", name)
1024-
syncError = fmt.Errorf("cleanup must wait")
1025-
return
1026-
} else if !apierrors.IsNotFound(err) {
1027-
logger.Infof("Error CSV retrieval error")
1028-
syncError = err
1029-
return
1030-
}
1031-
}
1032-
1033-
if err := a.opClient.KubernetesInterface().AdmissionregistrationV1().ValidatingWebhookConfigurations().Delete(context.TODO(), metaObj.GetName(), metav1.DeleteOptions{}); err != nil {
1034-
logger.WithError(err).Warn("cannot delete ValidatingWebhookConfiguration")
1035-
break
1036-
}
1037-
logger.Debugf("Deleted ValidatingWebhookConfiguration %v due to no owning CSV", metaObj.GetName())
1038-
}
1039-
1040-
return
1041-
}
1042-
1043916
func (a *Operator) syncObject(obj interface{}) (syncError error) {
1044917
// Assert as metav1.Object
1045918
metaObj, ok := obj.(metav1.Object)
@@ -1054,30 +927,8 @@ func (a *Operator) syncObject(obj interface{}) (syncError error) {
1054927
"self": metaObj.GetSelfLink(),
1055928
})
1056929

1057-
// Requeues objects that can't have ownerrefs (cluster -> namespace, cross-namespace)
1058-
if ownerutil.IsOwnedByKindLabel(metaObj, v1alpha1.ClusterServiceVersionKind) {
1059-
name, ns, ok := ownerutil.GetOwnerByKindLabel(metaObj, v1alpha1.ClusterServiceVersionKind)
1060-
if !ok {
1061-
logger.Error("unexpected owner label retrieval failure")
1062-
}
1063-
_, err := a.lister.OperatorsV1alpha1().ClusterServiceVersionLister().ClusterServiceVersions(ns).Get(name)
1064-
if !apierrors.IsNotFound(err) {
1065-
logger.Debug("requeueing owner csvs from owner label")
1066-
a.requeueOwnerCSVs(metaObj)
1067-
} else {
1068-
switch metaObj.(type) {
1069-
case *rbacv1.ClusterRole, *rbacv1.ClusterRoleBinding, *admissionregistrationv1.MutatingWebhookConfiguration, *admissionregistrationv1.ValidatingWebhookConfiguration:
1070-
resourceEvent := kubestate.NewResourceEvent(
1071-
kubestate.ResourceUpdated,
1072-
metaObj,
1073-
)
1074-
if syncError = a.objGCQueueSet.RequeueEvent("", resourceEvent); syncError != nil {
1075-
logger.WithError(syncError).Warnf("failed to requeue gc event: %v", resourceEvent)
1076-
}
1077-
return
1078-
}
1079-
}
1080-
}
930+
// Objects that can't have ownerrefs (cluster -> namespace, cross-namespace)
931+
// are handled by finalizer
1081932

1082933
// Requeue all owner CSVs
1083934
if ownerutil.IsOwnedByKind(metaObj, v1alpha1.ClusterServiceVersionKind) {
@@ -1332,50 +1183,6 @@ func (a *Operator) handleClusterServiceVersionDeletion(obj interface{}) {
13321183
}
13331184
}
13341185

1335-
ownerSelector := ownerutil.CSVOwnerSelector(clusterServiceVersion)
1336-
crbs, err := a.lister.RbacV1().ClusterRoleBindingLister().List(ownerSelector)
1337-
if err != nil {
1338-
logger.WithError(err).Warn("cannot list cluster role bindings")
1339-
}
1340-
for _, crb := range crbs {
1341-
if err := a.objGCQueueSet.RequeueEvent("", kubestate.NewResourceEvent(kubestate.ResourceUpdated, crb)); err != nil {
1342-
logger.WithError(err).Warnf("failed to requeue gc event: %v", crb)
1343-
}
1344-
}
1345-
1346-
crs, err := a.lister.RbacV1().ClusterRoleLister().List(ownerSelector)
1347-
if err != nil {
1348-
logger.WithError(err).Warn("cannot list cluster roles")
1349-
}
1350-
for _, cr := range crs {
1351-
if err := a.objGCQueueSet.RequeueEvent("", kubestate.NewResourceEvent(kubestate.ResourceUpdated, cr)); err != nil {
1352-
logger.WithError(err).Warnf("failed to requeue gc event: %v", cr)
1353-
}
1354-
}
1355-
1356-
webhookSelector := labels.SelectorFromSet(ownerutil.OwnerLabel(clusterServiceVersion, v1alpha1.ClusterServiceVersionKind)).String()
1357-
mWebhooks, err := a.opClient.KubernetesInterface().AdmissionregistrationV1().MutatingWebhookConfigurations().List(context.TODO(), metav1.ListOptions{LabelSelector: webhookSelector})
1358-
if err != nil {
1359-
logger.WithError(err).Warn("cannot list MutatingWebhookConfigurations")
1360-
}
1361-
for _, webhook := range mWebhooks.Items {
1362-
w := webhook
1363-
if err := a.objGCQueueSet.RequeueEvent("", kubestate.NewResourceEvent(kubestate.ResourceUpdated, &w)); err != nil {
1364-
logger.WithError(err).Warnf("failed to requeue gc event: %v", webhook)
1365-
}
1366-
}
1367-
1368-
vWebhooks, err := a.opClient.KubernetesInterface().AdmissionregistrationV1().ValidatingWebhookConfigurations().List(context.TODO(), metav1.ListOptions{LabelSelector: webhookSelector})
1369-
if err != nil {
1370-
logger.WithError(err).Warn("cannot list ValidatingWebhookConfigurations")
1371-
}
1372-
for _, webhook := range vWebhooks.Items {
1373-
w := webhook
1374-
if err := a.objGCQueueSet.RequeueEvent("", kubestate.NewResourceEvent(kubestate.ResourceUpdated, &w)); err != nil {
1375-
logger.WithError(err).Warnf("failed to requeue gc event: %v", webhook)
1376-
}
1377-
}
1378-
13791186
// Conversion webhooks are defined within a CRD.
13801187
// In an effort to prevent customer dataloss, OLM does not delete CRDs associated with a CSV when it is deleted.
13811188
// Deleting a CSV that introduced a conversion webhook removes the deployment that serviced the conversion webhook calls.

0 commit comments

Comments
 (0)