Skip to content

Commit 2fc8a91

Browse files
committed
Cleanup legacy installPlan and Operator resource
The operator resource's have references to: -CSVs -Subscriptions -Installplans -CRDs So the cleanup for operators needs to run after applyCRDs where 'olm.managed' gets removed.
1 parent febbf25 commit 2fc8a91

2 files changed

Lines changed: 111 additions & 42 deletions

File tree

config/operator/rbac/role.yaml

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -107,13 +107,8 @@ rules:
107107
- operators.coreos.com
108108
resources:
109109
- clusterserviceversions
110-
verbs:
111-
- delete
112-
- get
113-
- list
114-
- apiGroups:
115-
- operators.coreos.com
116-
resources:
110+
- installplans
111+
- operators
117112
- subscriptions
118113
verbs:
119114
- delete

controllers/operator/openstack_controller.go

Lines changed: 109 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -59,21 +59,9 @@ type OpenStackReconciler struct {
5959
Kclient kubernetes.Interface
6060
}
6161

62-
var csvGVR = schema.GroupVersionResource{
63-
Group: "operators.coreos.com",
64-
Version: "v1alpha1",
65-
Resource: "clusterserviceversions",
66-
}
67-
68-
var subscriptionGVR = schema.GroupVersionResource{
69-
Group: "operators.coreos.com",
70-
Version: "v1alpha1",
71-
Resource: "subscriptions",
72-
}
73-
7462
// GetLog returns a logger object with a prefix of "controller.name" and aditional controller context fields
7563
func (r *OpenStackReconciler) GetLogger(ctx context.Context) logr.Logger {
76-
return log.FromContext(ctx).WithName("Controllers").WithName("OpenStackControlPlane")
64+
return log.FromContext(ctx).WithName("Controllers").WithName("OpenStackOperator")
7765
}
7866

7967
var (
@@ -125,8 +113,7 @@ func SetupEnv() {
125113
// +kubebuilder:rbac:groups=cert-manager.io,resources=issuers,verbs=get;list;watch;create;update;patch;delete;
126114
// +kubebuilder:rbac:groups=cert-manager.io,resources=certificates,verbs=get;list;watch;create;update;patch;delete;
127115
// +kubebuilder:rbac:groups="monitoring.coreos.com",resources=servicemonitors,verbs=list;get;watch;update;create
128-
// +kubebuilder:rbac:groups=operators.coreos.com,resources=clusterserviceversions,verbs=get;list;delete;
129-
// +kubebuilder:rbac:groups=operators.coreos.com,resources=subscriptions,verbs=get;list;delete;
116+
// +kubebuilder:rbac:groups=operators.coreos.com,resources=clusterserviceversions;subscriptions;installplans;operators,verbs=get;list;delete;
130117

131118
// Reconcile is part of the main kubernetes reconciliation loop which aims to
132119
// move the current state of the cluster closer to the desired state.
@@ -245,7 +232,7 @@ func (r *OpenStackReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
245232
return r.reconcileDelete(ctx, instance, openstackHelper)
246233
}
247234

248-
// TODO: cleanup obsolete resources here (remove old CSVs, etc)
235+
// cleanup obsolete resources here (remove old CSVs, etc)
249236
if err := r.cleanupObsoleteResources(ctx, instance); err != nil {
250237
return ctrl.Result{}, err
251238
}
@@ -260,6 +247,12 @@ func (r *OpenStackReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
260247
return ctrl.Result{}, err
261248
}
262249

250+
// now that CRDs have been updated (with old olm.managed references removed)
251+
// we can finally cleanup the old operators
252+
if err := r.postCleanupObsoleteResources(ctx, instance); err != nil {
253+
return ctrl.Result{}, err
254+
}
255+
263256
// Check if all deployments are running
264257
deploymentsRunning, err := r.countDeployments(ctx, instance)
265258
instance.Status.DeployedOperatorCount = &deploymentsRunning
@@ -437,11 +430,14 @@ func (r *OpenStackReconciler) renderAndApply(
437430
return nil
438431
}
439432

440-
var serviceOperatorNames = []string{"barbican", "cinder", "designate", "glance", "heat", "horizon", "infra",
441-
"ironic", "keystone", "manila", "mariadb", "neutron", "nova", "octavia", "openstack-baremetal", "ovn",
442-
"placement", "rabbitmq-cluster", "swift", "telemetry"}
443-
444433
func isServiceOperatorResource(name string) bool {
434+
//NOTE: test-operator was deployed as a independant package so it may or may not be installed
435+
//NOTE: depending on how watcher-operator is released for FR2 and then in FR3 it may need to be
436+
// added into this list in the future
437+
serviceOperatorNames := []string{"barbican", "cinder", "designate", "glance", "heat", "horizon", "infra",
438+
"ironic", "keystone", "manila", "mariadb", "neutron", "nova", "octavia", "openstack-baremetal", "ovn",
439+
"placement", "rabbitmq-cluster", "swift", "telemetry", "test"}
440+
445441
for _, item := range serviceOperatorNames {
446442
if strings.Index(name, item) == 0 {
447443
return true
@@ -450,48 +446,126 @@ func isServiceOperatorResource(name string) bool {
450446
return false
451447
}
452448

453-
// cleanupObsoleteResources - deletes CSVs for old service operator bundles
449+
// cleanupObsoleteResources - deletes CSVs and subscriptions
454450
func (r *OpenStackReconciler) cleanupObsoleteResources(ctx context.Context, instance *operatorv1beta1.OpenStack) error {
455451
Log := r.GetLogger(ctx)
456452

453+
csvGVR := schema.GroupVersionResource{
454+
Group: "operators.coreos.com",
455+
Version: "v1alpha1",
456+
Resource: "clusterserviceversions",
457+
}
458+
459+
subscriptionGVR := schema.GroupVersionResource{
460+
Group: "operators.coreos.com",
461+
Version: "v1alpha1",
462+
Resource: "subscriptions",
463+
}
464+
465+
installPlanGVR := schema.GroupVersionResource{
466+
Group: "operators.coreos.com",
467+
Version: "v1alpha1",
468+
Resource: "installplans",
469+
}
470+
471+
csvList := &uns.UnstructuredList{}
472+
csvList.SetGroupVersionKind(csvGVR.GroupVersion().WithKind("ClusterServiceVersion"))
473+
err := r.Client.List(ctx, csvList, &client.ListOptions{Namespace: instance.Namespace})
474+
if err != nil {
475+
return err
476+
}
477+
for _, csv := range csvList.Items {
478+
Log.Info("Found CSV", "name", csv.GetName())
479+
if isServiceOperatorResource(csv.GetName()) {
480+
err = r.Client.Delete(ctx, &csv)
481+
if err != nil {
482+
return err
483+
}
484+
Log.Info("CSV deleted successfully", "name", csv.GetName())
485+
}
486+
}
487+
457488
subscriptionList := &uns.UnstructuredList{}
458489
subscriptionList.SetGroupVersionKind(subscriptionGVR.GroupVersion().WithKind("Subscription"))
459-
err := r.Client.List(ctx, subscriptionList, &client.ListOptions{Namespace: instance.Namespace})
490+
err = r.Client.List(ctx, subscriptionList, &client.ListOptions{Namespace: instance.Namespace})
460491
if err != nil {
461-
Log.Error(err, "Unable to retrieve Subscriptions instances")
462492
return err
463493
}
464494
for _, subscription := range subscriptionList.Items {
465495
Log.Info("Found Subscription", "name", subscription.GetName())
466496
if isServiceOperatorResource(subscription.GetName()) {
467497
err = r.Client.Delete(ctx, &subscription)
468498
if err != nil {
469-
Log.Error(err, "Failed to delete existing Subscription")
470499
return err
471500
}
501+
Log.Info("Subscription deleted successfully", "name", subscription.GetName())
472502
}
473-
Log.Info("Subscription deleted successfully")
474503
}
475504

476-
csvList := &uns.UnstructuredList{}
477-
csvList.SetGroupVersionKind(csvGVR.GroupVersion().WithKind("ClusterServiceVersionList"))
505+
// lookup the installplan which has the clusterServiceVersionNames we removed above
506+
// there will be just a single installPlan that has all of them referenced
507+
installPlanList := &uns.UnstructuredList{}
508+
installPlanList.SetGroupVersionKind(installPlanGVR.GroupVersion().WithKind("InstallPlan"))
478509

479-
err = r.Client.List(ctx, csvList, &client.ListOptions{Namespace: instance.Namespace})
510+
err = r.Client.List(ctx, installPlanList, &client.ListOptions{Namespace: instance.Namespace})
480511
if err != nil {
481-
Log.Error(err, "Unable to retrieve CSV instances")
482512
return err
483513
}
484-
for _, csv := range csvList.Items {
485-
Log.Info("Found CSV", "name", csv.GetName())
486-
if isServiceOperatorResource(csv.GetName()) {
487-
err = r.Client.Delete(ctx, &csv)
514+
for _, installPlan := range installPlanList.Items {
515+
Log.Info("Found installPlan", "name", installPlan.GetName())
516+
// this should have a list containing the CSV names of all the old/legacy service operator CSVs
517+
csvNames, found, err := uns.NestedSlice(installPlan.Object, "spec", "clusterServiceVersionNames")
518+
if err != nil {
519+
return err
520+
}
521+
if found {
522+
// just checking for the first one should be sufficient
523+
if isServiceOperatorResource(csvNames[0].(string)) {
524+
err = r.Client.Delete(ctx, &installPlan)
525+
if err != nil {
526+
return err
527+
}
528+
Log.Info("Installplan deleted successfully", "name", installPlan.GetName())
529+
}
530+
}
531+
}
532+
533+
return nil
534+
535+
}
536+
537+
// postCleanupObsoleteResources - deletes CSVs for old service operator bundles
538+
func (r *OpenStackReconciler) postCleanupObsoleteResources(ctx context.Context, instance *operatorv1beta1.OpenStack) error {
539+
Log := r.GetLogger(ctx)
540+
541+
operatorGVR := schema.GroupVersionResource{
542+
Group: "operators.coreos.com",
543+
Version: "v1",
544+
Resource: "operators",
545+
}
546+
547+
// finally we can remove operator objects as all the refs have been cleaned up:
548+
// 1) CSVs
549+
// 2) Subscriptions
550+
// 3) CRD olm.managed references removed
551+
// 4) installPlan from old service operators removed
552+
operatorList := &uns.UnstructuredList{}
553+
operatorList.SetGroupVersionKind(operatorGVR.GroupVersion().WithKind("Operator"))
554+
err := r.Client.List(ctx, operatorList, &client.ListOptions{Namespace: instance.Namespace})
555+
if err != nil {
556+
return err
557+
}
558+
for _, operator := range operatorList.Items {
559+
Log.Info("Found Operator", "name", operator.GetName())
560+
if isServiceOperatorResource(operator.GetName()) {
561+
err = r.Client.Delete(ctx, &operator)
488562
if err != nil {
489-
Log.Error(err, "Failed to delete existing CSV")
490563
return err
491564
}
565+
Log.Info("Operator deleted successfully", "name", operator.GetName())
492566
}
493-
Log.Info("CSV deleted successfully")
494567
}
568+
495569
return nil
496570

497571
}

0 commit comments

Comments
 (0)