Skip to content

Commit 02c6d31

Browse files
Merge pull request #795 from alecmerdler/OLM-974
Garbage Collection for OperatorGroup RBAC
2 parents 5a87338 + f66436c commit 02c6d31

File tree

4 files changed

+70
-8
lines changed

4 files changed

+70
-8
lines changed

pkg/controller/operators/olm/operator.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ func NewOperator(logger *logrus.Logger, crClient versioned.Interface, opClient o
299299
// Register queue and QueueInformer
300300
queueName := fmt.Sprintf("%s/operatorgroups", namespace)
301301
operatorGroupQueue := workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), queueName)
302-
operatorGroupQueueInformer := queueinformer.NewInformer(operatorGroupQueue, operatorGroupInformer.Informer(), op.syncOperatorGroups, nil, queueName, metrics.NewMetricsNil(), logger)
302+
operatorGroupQueueInformer := queueinformer.NewInformer(operatorGroupQueue, operatorGroupInformer.Informer(), op.syncOperatorGroups, &cache.ResourceEventHandlerFuncs{DeleteFunc: op.operatorGroupDeleted}, queueName, metrics.NewMetricsNil(), logger)
303303
op.RegisterQueueInformer(operatorGroupQueueInformer)
304304
op.ogQueueSet.Set(namespace, operatorGroupQueue)
305305
}

pkg/controller/operators/olm/operator_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3935,6 +3935,10 @@ func TestSyncOperatorGroups(t *testing.T) {
39353935
withAnnotations(operatorCSVFinal.DeepCopy(), map[string]string{v1.OperatorGroupTargetsAnnotationKey: "", v1.OperatorGroupAnnotationKey: "operator-group-1", v1.OperatorGroupNamespaceAnnotationKey: operatorNamespace}),
39363936
annotatedGlobalDeployment,
39373937
&v1.OperatorGroup{
3938+
TypeMeta: metav1.TypeMeta{
3939+
Kind: v1.OperatorGroupKind,
3940+
APIVersion: strings.Join([]string{v1.GroupName, v1.GroupVersion}, "/"),
3941+
},
39383942
ObjectMeta: metav1.ObjectMeta{
39393943
Name: "operator-group-1",
39403944
Namespace: operatorNamespace,

pkg/controller/operators/olm/operatorgroup.go

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,31 @@ func (a *Operator) syncOperatorGroups(obj interface{}) error {
117117
return nil
118118
}
119119

120+
func (a *Operator) operatorGroupDeleted(obj interface{}) {
121+
op, ok := obj.(*v1.OperatorGroup)
122+
if !ok {
123+
a.Log.Debugf("casting OperatorGroup failed, wrong type: %#v\n", obj)
124+
return
125+
}
126+
127+
logger := a.Log.WithFields(logrus.Fields{
128+
"operatorGroup": op.GetName(),
129+
"namespace": op.GetNamespace(),
130+
})
131+
132+
clusterRoles, err := a.lister.RbacV1().ClusterRoleLister().List(labels.SelectorFromSet(ownerutil.OwnerLabel(op, "OperatorGroup")))
133+
if err != nil {
134+
logger.WithError(err).Error("failed to list ClusterRoles for garbage collection")
135+
return
136+
}
137+
for _, clusterRole := range clusterRoles {
138+
err = a.OpClient.KubernetesInterface().RbacV1().ClusterRoles().Delete(clusterRole.GetName(), &metav1.DeleteOptions{})
139+
if err != nil {
140+
logger.WithError(err).Error("failed to delete ClusterRole during garbage collection")
141+
}
142+
}
143+
}
144+
120145
func (a *Operator) annotateCSVs(group *v1.OperatorGroup, targetNamespaces []string, logger *logrus.Entry) error {
121146
updateErrs := []error{}
122147
targetNamespaceSet := resolver.NewNamespaceSet(targetNamespaces)
@@ -222,6 +247,10 @@ func (a *Operator) ensureProvidedAPIClusterRole(operatorGroup *v1.OperatorGroup,
222247
},
223248
Rules: []rbacv1.PolicyRule{{Verbs: verbs, APIGroups: []string{group}, Resources: []string{resource}, ResourceNames: resourceNames}},
224249
}
250+
err := ownerutil.AddOwnerLabels(clusterRole, operatorGroup)
251+
if err != nil {
252+
return err
253+
}
225254
existingCR, err := a.OpClient.KubernetesInterface().RbacV1().ClusterRoles().Create(clusterRole)
226255
if k8serrors.IsAlreadyExists(err) {
227256
if existingCR != nil && reflect.DeepEqual(existingCR.Labels, clusterRole.Labels) && reflect.DeepEqual(existingCR.Rules, clusterRole.Rules) {
@@ -754,7 +783,11 @@ func (a *Operator) ensureOpGroupClusterRole(op *v1.OperatorGroup, suffix string)
754783
},
755784
},
756785
}
757-
_, err := a.OpClient.KubernetesInterface().RbacV1().ClusterRoles().Create(clusterRole)
786+
err := ownerutil.AddOwnerLabels(clusterRole, op)
787+
if err != nil {
788+
return err
789+
}
790+
_, err = a.OpClient.KubernetesInterface().RbacV1().ClusterRoles().Create(clusterRole)
758791
if k8serrors.IsAlreadyExists(err) {
759792
return nil
760793
} else if err != nil {

test/e2e/operator_groups_e2e_test.go

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import (
2121

2222
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/ownerutil"
2323

24-
"github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1"
24+
v1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1"
2525
"github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1"
2626
"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/install"
2727
"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry"
@@ -139,11 +139,6 @@ func TestOperatorGroup(t *testing.T) {
139139
}
140140
_, err = crc.OperatorsV1().OperatorGroups(opGroupNamespace).Create(&operatorGroup)
141141
require.NoError(t, err)
142-
defer func() {
143-
err = crc.OperatorsV1().OperatorGroups(opGroupNamespace).Delete(operatorGroup.Name, &metav1.DeleteOptions{})
144-
require.NoError(t, err)
145-
}()
146-
147142
expectedOperatorGroupStatus := v1.OperatorGroupStatus{
148143
Namespaces: []string{opGroupNamespace, createdOtherNamespace.GetName()},
149144
}
@@ -407,6 +402,36 @@ func TestOperatorGroup(t *testing.T) {
407402
return err
408403
})
409404
require.NoError(t, err)
405+
406+
err = crc.OperatorsV1().OperatorGroups(opGroupNamespace).Delete(operatorGroup.Name, &metav1.DeleteOptions{})
407+
require.NoError(t, err)
408+
t.Log("Waiting for OperatorGroup RBAC to be garbage collected")
409+
err = wait.Poll(pollInterval, pollDuration, func() (bool, error) {
410+
_, err := c.KubernetesInterface().RbacV1().ClusterRoles().Get(operatorGroup.Name+"-admin", metav1.GetOptions{})
411+
if err == nil {
412+
return false, nil
413+
}
414+
return true, err
415+
})
416+
require.True(t, errors.IsNotFound(err))
417+
418+
err = wait.Poll(pollInterval, pollDuration, func() (bool, error) {
419+
_, err := c.KubernetesInterface().RbacV1().ClusterRoles().Get(operatorGroup.Name+"-edit", metav1.GetOptions{})
420+
if err == nil {
421+
return false, nil
422+
}
423+
return true, err
424+
})
425+
require.True(t, errors.IsNotFound(err))
426+
427+
err = wait.Poll(pollInterval, pollDuration, func() (bool, error) {
428+
_, err := c.KubernetesInterface().RbacV1().ClusterRoles().Get(operatorGroup.Name+"-view", metav1.GetOptions{})
429+
if err == nil {
430+
return false, nil
431+
}
432+
return true, err
433+
})
434+
require.True(t, errors.IsNotFound(err))
410435
}
411436

412437
func createProjectAdmin(t *testing.T, c operatorclient.ClientInterface, namespace string) (string, cleanupFunc) {

0 commit comments

Comments
 (0)