@@ -18,10 +18,14 @@ package common
1818
1919import (
2020 "context"
21+ "strings"
22+ "time"
2123
2224 olmv1alpha1 "github.com/operator-framework/api/pkg/operators/v1alpha1"
2325 "k8s.io/apimachinery/pkg/api/errors"
26+ "k8s.io/apimachinery/pkg/runtime"
2427 "k8s.io/apimachinery/pkg/types"
28+ "k8s.io/apimachinery/pkg/util/wait"
2529 "k8s.io/klog"
2630 "sigs.k8s.io/controller-runtime/pkg/client"
2731
@@ -166,6 +170,70 @@ func FetchClusterServiceVersion(c client.Client, sub *olmv1alpha1.Subscription)
166170 return csv , nil
167171}
168172
173+ // FetchClusterServiceVersionForDelete fetch the ClusterServiceVersion from the subscription for delete
174+ func FetchClusterServiceVersionForDelete (c client.Client , sub * olmv1alpha1.Subscription ) (* olmv1alpha1.ClusterServiceVersion , error ) {
175+ csvName := ""
176+ csvNamespace := sub .Namespace
177+
178+ if sub .Status .InstallPlanRef != nil {
179+ ip , err := FetchInstallPlan (c , sub .Status .InstallPlanRef .Name , sub .Status .InstallPlanRef .Namespace )
180+ if err != nil {
181+ return nil , err
182+ }
183+ for _ , step := range ip .Status .Plan {
184+ if step .Resource .Kind == "ClusterServiceVersion" && strings .HasPrefix (step .Resource .Name , sub .Name ) {
185+ csvName = step .Resource .Name
186+ }
187+ }
188+ } else {
189+ klog .Warningf ("The Installplan for Subscription %s is not ready. Will check it again" , sub .Name )
190+ return nil , nil
191+ }
192+
193+ if csvName == "" {
194+ return nil , nil
195+ }
196+
197+ csv := & olmv1alpha1.ClusterServiceVersion {}
198+ csvKey := types.NamespacedName {
199+ Name : csvName ,
200+ Namespace : csvNamespace ,
201+ }
202+ if err := getObjectWithRetry (c , csvKey , csv ); err != nil {
203+ return nil , err
204+ }
205+ return csv , nil
206+ }
207+
208+ func FetchInstallPlan (c client.Client , name , namespace string ) (* olmv1alpha1.InstallPlan , error ) {
209+ installPlan := & olmv1alpha1.InstallPlan {}
210+ installPlanKey := types.NamespacedName {
211+ Namespace : namespace ,
212+ Name : name ,
213+ }
214+ if err := getObjectWithRetry (c , installPlanKey , installPlan ); err != nil {
215+ return nil , err
216+ }
217+ return installPlan , nil
218+ }
219+
220+ // Get object with retry
221+ func getObjectWithRetry (c client.Client , key types.NamespacedName , obj runtime.Object ) error {
222+ if err := wait .PollImmediate (time .Second * 5 , time .Second * 15 , func () (bool , error ) {
223+ if err := c .Get (context .TODO (), key , obj ); err != nil {
224+ if errors .IsNotFound (err ) {
225+ return false , nil
226+ }
227+ klog .Errorf ("failed to get %s with %s: %v" , obj .GetObjectKind (), key .String (), err )
228+ return false , err
229+ }
230+ return true , nil
231+ }); err != nil {
232+ return err
233+ }
234+ return nil
235+ }
236+
169237// GetOperatorNamespace returns the operator namespace based on the install mode
170238func GetOperatorNamespace (installMode , namespace string ) string {
171239 if installMode == apiv1alpha1 .InstallModeCluster {
0 commit comments