77
88 v1 "github.com/operator-framework/api/pkg/operators/v1"
99 "github.com/operator-framework/api/pkg/operators/v1alpha1"
10- "github.com/operator-framework/operator-registry/pkg/lib/bundle"
1110 "github.com/spf13/pflag"
1211 apierrors "k8s.io/apimachinery/pkg/api/errors"
1312 "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
@@ -66,22 +65,13 @@ func (u *OperatorUninstall) Run(ctx context.Context) error {
6665 return fmt .Errorf ("operator package %q not found" , u .Package )
6766 }
6867
69- // Since the install plan is owned by the subscription, we need to
70- // read all of the resource references from the install plan before
71- // deleting the subscription.
72- var crds , csvs , others []controllerutil.Object
73- if sub .Status .InstallPlanRef != nil {
74- ipKey := types.NamespacedName {
75- Namespace : sub .Status .InstallPlanRef .Namespace ,
76- Name : sub .Status .InstallPlanRef .Name ,
77- }
78- var err error
79- crds , csvs , others , err = u .getInstallPlanResources (ctx , ipKey )
80- if err != nil {
81- return fmt .Errorf ("get install plan resources: %v" , err )
82- }
68+ csv , err := u .getInstalledCSV (ctx , sub )
69+ if err != nil {
70+ return fmt .Errorf ("get installed CSV %q: %v" , sub .Status .InstalledCSV , err )
8371 }
8472
73+ crds := getCRDs (csv )
74+
8575 // Delete the subscription first, so that no further installs or upgrades
8676 // of the operator occur while we're cleaning up.
8777 if err := u .deleteObjects (ctx , sub ); err != nil {
@@ -96,9 +86,10 @@ func (u *OperatorUninstall) Run(ctx context.Context) error {
9686 }
9787 }
9888
99- // Delete CSVs and all other objects created by the install plan.
100- objects := append (csvs , others ... )
101- if err := u .deleteObjects (ctx , objects ... ); err != nil {
89+ // OLM puts an ownerref on every namespaced resource to the CSV,
90+ // and an owner label on every cluster scoped resource. When CSV is deleted
91+ // kube and olm gc will remove all the referenced resources.
92+ if err := u .deleteObjects (ctx , csv ); err != nil {
10293 return err
10394 }
10495
@@ -140,43 +131,41 @@ func (u *OperatorUninstall) deleteObjects(ctx context.Context, objs ...controlle
140131 return waitForDeletion (ctx , u .config .Client , objs ... )
141132}
142133
143- func (u * OperatorUninstall ) getInstallPlanResources (ctx context.Context , installPlanKey types. NamespacedName ) (crds , csvs , others []controllerutil. Object , err error ) {
144- installPlan := & v1alpha1. InstallPlan {}
145- if err := u . config . Client . Get ( ctx , installPlanKey , installPlan ); err != nil {
146- return nil , nil , nil , fmt . Errorf ( "get install plan: %v" , err )
134+ func (u * OperatorUninstall ) getInstalledCSV (ctx context.Context , subscription * v1alpha1. Subscription ) (* v1alpha1. ClusterServiceVersion , error ) {
135+ key := types. NamespacedName {
136+ Name : subscription . Status . InstalledCSV ,
137+ Namespace : subscription . GetNamespace (),
147138 }
148139
149- for _ , step := range installPlan .Status .Plan {
150- obj := & unstructured.Unstructured {}
140+ installedCSV := & v1alpha1.ClusterServiceVersion {}
141+ if err := u .config .Client .Get (ctx , key , installedCSV ); err != nil {
142+ return nil , err
143+ }
151144
152- obj .SetGroupVersionKind (schema.GroupVersionKind {
153- Group : step .Resource .Group ,
154- Version : step .Resource .Version ,
155- Kind : step .Resource .Kind ,
156- })
157- obj .SetName (step .Resource .Name )
145+ installedCSV .SetGroupVersionKind (schema.GroupVersionKind {
146+ Kind : csvKind ,
147+ Version : installedCSV .GroupVersionKind ().Version ,
148+ Group : installedCSV .GroupVersionKind ().Group ,
149+ })
150+ return installedCSV , nil
151+ }
158152
159- // TODO: Use RESTMapper interface to identify if the object is namespaced or not.
160- // Reference: https://github.com/kubernetes-sigs/controller-runtime/blob/master/pkg/client/namespaced_client.go
161- if supported , namespaced := bundle .IsSupported (step .Resource .Kind ); supported && bool (namespaced ) {
162- obj .SetNamespace (installPlanKey .Namespace )
163- }
153+ func getCRDs (csv * v1alpha1.ClusterServiceVersion ) (crds []controllerutil.Object ) {
154+ for _ , resource := range csv .Status .RequirementStatus {
155+ if resource .Kind == crdKind {
156+ obj := & unstructured.Unstructured {}
157+ obj .SetGroupVersionKind (schema.GroupVersionKind {
158+ Group : resource .Group ,
159+ Version : resource .Version ,
160+ Kind : resource .Kind ,
161+ })
162+ obj .SetName (resource .Name )
163+ obj .SetNamespace (csv .GetNamespace ())
164164
165- switch step .Resource .Kind {
166- case crdKind :
167165 crds = append (crds , obj )
168- case csvKind :
169- csvs = append (csvs , obj )
170- default :
171- // Skip non-CRD/non-CSV resources in the install plan that were not created by the install plan.
172- // This means we avoid deleting things like the default service account.
173- if step .Status != v1alpha1 .StepStatusCreated {
174- continue
175- }
176- others = append (others , obj )
177166 }
178167 }
179- return crds , csvs , others , nil
168+ return
180169}
181170
182171func contains (haystack []string , needle string ) bool {
0 commit comments