@@ -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
7563func (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
7967var (
@@ -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-
444433func 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
454450func (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