@@ -61,33 +61,15 @@ func (u *OperatorUninstall) Run(ctx context.Context) error {
6161		}
6262	}
6363	if  sub  ==  nil  {
64- 		return  fmt .Errorf ("operator package %q not found" , u .Package )
65- 	}
66- 
67- 	var  subObj , csvObj  client.Object 
68- 	var  crds  []client.Object 
69- 	if  sub  !=  nil  {
70- 		subObj  =  sub 
71- 		// CSV name may either be the installed or current name in a subscription's status, 
72- 		// depending on installation state. 
73- 		csvKey  :=  types.NamespacedName {
74- 			Name :      sub .Status .InstalledCSV ,
75- 			Namespace : u .config .Namespace ,
76- 		}
77- 		if  csvKey .Name  ==  ""  {
78- 			csvKey .Name  =  sub .Status .CurrentCSV 
79- 		}
64+ 		return  & ErrPackageNotFound {u .Package }
65+ 	}
8066
81- 		// This value can be empty which will cause errors. 
82- 		if  csvKey .Name  !=  ""  {
83- 			csv  :=  & v1alpha1.ClusterServiceVersion {}
84- 			if  err  :=  u .config .Client .Get (ctx , csvKey , csv ); err  !=  nil  &&  ! apierrors .IsNotFound (err ) {
85- 				return  fmt .Errorf ("error getting installed CSV %q: %v" , csvKey .Name , err )
86- 			} else  if  err  ==  nil  {
87- 				crds  =  getCRDs (csv )
88- 			}
89- 			csvObj  =  csv 
67+ 	csv , csvName , err  :=  u .getSubscriptionCSV (ctx , sub )
68+ 	if  err  !=  nil  &&  ! apierrors .IsNotFound (err ) {
69+ 		if  csvName  ==  ""  {
70+ 			return  fmt .Errorf ("get subscription CSV: %v" , err )
9071		}
72+ 		return  fmt .Errorf ("get subscription CSV %q: %v" , csvName , err )
9173	}
9274
9375	// Deletion order: 
@@ -98,23 +80,26 @@ func (u *OperatorUninstall) Run(ctx context.Context) error {
9880	//    and an owner label on every cluster scoped resource so they get gc'd on deletion. 
9981
10082	// Subscriptions can be deleted asynchronously. 
101- 	if  err  :=  u .deleteObjects (ctx , subObj ); err  !=  nil  {
83+ 	if  err  :=  u .deleteObjects (ctx , sub ); err  !=  nil  {
10284		return  err 
10385	}
10486
105- 	if  u . DeleteCRDs  {
87+ 	if  csv   !=   nil  {
10688		// Ensure CustomResourceDefinitions are deleted next, so that the operator 
10789		// has a chance to handle CRs that have finalizers. 
108- 		if  err  :=  u .deleteObjects (ctx , crds ... ); err  !=  nil  {
109- 			return  err 
90+ 		if  u .DeleteCRDs  {
91+ 			crds  :=  getCRDs (csv )
92+ 			if  err  :=  u .deleteObjects (ctx , crds ... ); err  !=  nil  {
93+ 				return  err 
94+ 			}
11095		}
111- 	}
11296
113- 	// OLM puts an ownerref on every namespaced resource to the CSV, 
114- 	// and an owner label on every cluster scoped resource. When CSV is deleted 
115- 	// kube and olm gc will remove all the referenced resources. 
116- 	if  err  :=  u .deleteObjects (ctx , csvObj ); err  !=  nil  {
117- 		return  err 
97+ 		// OLM puts an ownerref on every namespaced resource to the CSV, 
98+ 		// and an owner label on every cluster scoped resource. When CSV is deleted 
99+ 		// kube and olm gc will remove all the referenced resources. 
100+ 		if  err  :=  u .deleteObjects (ctx , csv ); err  !=  nil  {
101+ 			return  err 
102+ 		}
118103	}
119104
120105	if  u .DeleteOperatorGroups  {
@@ -138,12 +123,6 @@ func (u *OperatorUninstall) Run(ctx context.Context) error {
138123			}
139124		}
140125	}
141- 
142- 	// If no objects were cleaned up, it means the package was not found 
143- 	if  subObj  ==  nil  &&  csvObj  ==  nil  &&  len (crds ) ==  0  {
144- 		return  & ErrPackageNotFound {u .Package }
145- 	}
146- 
147126	return  nil 
148127}
149128
@@ -160,6 +139,37 @@ func (u *OperatorUninstall) deleteObjects(ctx context.Context, objs ...client.Ob
160139	return  waitForDeletion (ctx , u .config .Client , objs ... )
161140}
162141
142+ // getSubscriptionCSV looks up the installed CSV name from the provided subscription and fetches it. 
143+ func  (u  * OperatorUninstall ) getSubscriptionCSV (ctx  context.Context , subscription  * v1alpha1.Subscription ) (* v1alpha1.ClusterServiceVersion , string , error ) {
144+ 	name  :=  csvNameFromSubscription (subscription )
145+ 
146+ 	// If we could not find a name in the subscription, that likely 
147+ 	// means there is no CSV associated with it yet. This should 
148+ 	// not be treated as an error, so return a nil CSV with a nil error. 
149+ 	if  name  ==  ""  {
150+ 		return  nil , "" , nil 
151+ 	}
152+ 
153+ 	key  :=  types.NamespacedName {
154+ 		Name :      name ,
155+ 		Namespace : subscription .GetNamespace (),
156+ 	}
157+ 
158+ 	csv  :=  & v1alpha1.ClusterServiceVersion {}
159+ 	if  err  :=  u .config .Client .Get (ctx , key , csv ); err  !=  nil  {
160+ 		return  nil , name , err 
161+ 	}
162+ 	csv .SetGroupVersionKind (v1alpha1 .SchemeGroupVersion .WithKind (csvKind ))
163+ 	return  csv , name , nil 
164+ }
165+ 
166+ func  csvNameFromSubscription (subscription  * v1alpha1.Subscription ) string  {
167+ 	if  subscription .Status .InstalledCSV  !=  ""  {
168+ 		return  subscription .Status .InstalledCSV 
169+ 	}
170+ 	return  subscription .Status .CurrentCSV 
171+ }
172+ 
163173// getCRDs returns the list of CRDs required by a CSV. 
164174func  getCRDs (csv  * v1alpha1.ClusterServiceVersion ) (crds  []client.Object ) {
165175	for  _ , resource  :=  range  csv .Status .RequirementStatus  {
0 commit comments