@@ -545,29 +545,25 @@ func (r *PatternReconciler) deleteSpokeApps(instance *api.Pattern, targetApp, ap
545545 if changed , _ := updateApplication (r .argoClient , targetApp , app , namespace ); changed {
546546 return fmt .Errorf ("updated application %q for spoke child deletion" , app .Name )
547547 }
548- // if app.Status.Sync.Status == argoapi.SyncStatusCodeOutOfSync {
549- // inProgress, err := syncApplicationWithPrune(r.argoClient, app)
550- // if err != nil {
551- // return err
552- // }
553- // if inProgress {
554- // return fmt.Errorf("sync with prune and force is already in progress for application %q", app.Name)
555- // }
556- // }
557548
558- // childApps, err := getChildApplications(r.argoClient, app)
559- // if err != nil {
560- // return err
561- // } else {
562- // for _, childApp := range childApps {
563- // if _, err := syncApplicationWithPrune(r.argoClient, &childApp); err != nil {
564- // return err
565- // }
566- // }
567- // }
549+ //FIXME
550+ if _ , err := syncApplication (r .argoClient , app , false ); err != nil {
551+ return err
552+ }
553+
554+ childApps , err := getChildApplications (r .argoClient , app )
555+ if err != nil {
556+ return err
557+ }
558+
559+ for _ , childApp := range childApps {
560+ if _ , err := syncApplication (r .argoClient , & childApp , false ); err != nil {
561+ return err
562+ }
563+ }
568564
569565 // Check if all child applications are gone from spoke
570- allGone , err := r .checkSpokeChildApplicationsGone ( instance )
566+ allGone , err := r .checkSpokeApplicationsGone ( false )
571567 if err != nil {
572568 return fmt .Errorf ("error checking child applications: %w" , err )
573569 }
@@ -613,16 +609,15 @@ func (r *PatternReconciler) deleteHubApps(targetApp, app *argoapi.Application, n
613609 return fmt .Errorf ("updated application %q for hub deletion" , app .Name )
614610 }
615611
616- inProgress , err := syncApplicationWithPrune (r .argoClient , app )
612+ _ , err = syncApplication (r .argoClient , app , true )
617613 if err != nil {
618614 return err
619615 }
620- if inProgress {
621- return fmt .Errorf ("sync with prune and force is already in progress for application %q" , app .Name )
622- }
616+ // if inProgress {
617+ // return fmt.Errorf("sync with prune and force is already in progress for application %q", app.Name)
618+ // }
623619
624- // return nil //fmt.Errorf("waiting for removal of that acm hub")
625- return fmt .Errorf ("waiting for application %q to be removed" , app .Name )
620+ return fmt .Errorf ("waiting %d hub child applications to be removed" , len (childApps ))
626621}
627622
628623func (r * PatternReconciler ) finalizeObject (instance * api.Pattern ) error {
@@ -666,6 +661,8 @@ func (r *PatternReconciler) finalizeObject(instance *api.Pattern) error {
666661 return err
667662 }
668663 }
664+
665+ return fmt .Errorf ("Initialized deletion phase, requeue now..." )
669666 }
670667
671668 // Phase 1: Delete child applications from spoke clusters
@@ -674,22 +671,45 @@ func (r *PatternReconciler) finalizeObject(instance *api.Pattern) error {
674671 return err
675672 }
676673
677- log .Printf ("All child applications are gone, transitioning to %s phase" , api .DeleteSpoke )
678674 if err := r .updateDeletionPhase (qualifiedInstance , api .DeleteSpoke ); err != nil {
679675 return err
680676 }
677+
678+ return fmt .Errorf ("All child applications are gone, transitioning to %s phase" , api .DeleteSpoke )
681679 }
682680
683681 // Phase 2: Delete app of apps from spoke
684682 if qualifiedInstance .Status .DeletionPhase == api .DeleteSpoke {
685683 if changed , _ := updateApplication (r .argoClient , targetApp , app , ns ); changed {
686684 return fmt .Errorf ("updated application %q for spoke app of apps deletion" , app .Name )
687685 }
688- // TODO: move the above to a fn, write some check to see if app of app is really gone from spoke
689- log .Printf ("App of apps are gone from spokes, transitioning to %s phase" , api .DeleteHubChildApps )
690- if err := r .updateDeletionPhase (qualifiedInstance , api .DeleteSpoke ); err != nil {
686+
687+ if _ , err := syncApplication (r .argoClient , app , false ); err != nil {
688+ return err
689+ }
690+
691+ childApps , err := getChildApplications (r .argoClient , app )
692+ if err != nil {
691693 return err
692694 }
695+
696+ // We need to prune policies from acm, to initiate app of apps removal from spoke
697+ for _ , childApp := range childApps {
698+ if _ , err := syncApplication (r .argoClient , & childApp , true ); err != nil {
699+ return err
700+ }
701+ }
702+
703+ // Check if app of apps are gone from spoke
704+ if _ , err = r .checkSpokeApplicationsGone (true ); err != nil {
705+ return fmt .Errorf ("error checking applications: %w" , err )
706+ }
707+
708+ if err := r .updateDeletionPhase (qualifiedInstance , api .DeleteHubChildApps ); err != nil {
709+ return err
710+ }
711+
712+ return fmt .Errorf ("App of apps are gone from spokes, transitioning to %s phase" , api .DeleteHubChildApps )
693713 }
694714
695715 // Phase 3: Delete applications from hub
@@ -698,10 +718,11 @@ func (r *PatternReconciler) finalizeObject(instance *api.Pattern) error {
698718 return err
699719 }
700720
701- log .Printf ("Apps are gone from hub, transitioning to %s phase" , api .DeleteHub )
702721 if err := r .updateDeletionPhase (qualifiedInstance , api .DeleteHub ); err != nil {
703722 return err
704723 }
724+
725+ return fmt .Errorf ("Apps are gone from hub, transitioning to %s phase" , api .DeleteHub )
705726 }
706727 // Phase 4: Delete app of apps from hub
707728 if qualifiedInstance .Status .DeletionPhase == api .DeleteHub {
@@ -868,10 +889,11 @@ func (r *PatternReconciler) updatePatternCRDetails(input *api.Pattern) (bool, er
868889 return false , nil
869890}
870891
871- // checkSpokeChildApplicationsGone checks if all child applications (excluding the app-of-apps) are gone from spoke clusters
892+ // checkSpokeApplicationsGone checks if all applications are gone from spoke clusters
893+ // passing appOfApps true will check the app of app instead of child apps
872894// The operator runs on the hub cluster and needs to check spoke clusters through ACM Search Service
873895// Returns true if all child applications are gone, false otherwise
874- func (r * PatternReconciler ) checkSpokeChildApplicationsGone ( p * api. Pattern ) (bool , error ) {
896+ func (r * PatternReconciler ) checkSpokeApplicationsGone ( appOfApps bool ) (bool , error ) {
875897
876898 // Running locally: use localhost with env var set to "https://localhost:4010/searchapi/graphql" and port-forward
877899 // User should run: kubectl port-forward -n open-cluster-management svc/search-search-api 4010:4010
@@ -896,6 +918,10 @@ func (r *PatternReconciler) checkSpokeChildApplicationsGone(p *api.Pattern) (boo
896918
897919 // Build GraphQL query to search for Applications
898920 // Filter out local-cluster apps and app of apps (based on namespace)
921+ ns := []string {fmt .Sprintf ("!%s" , getClusterWideArgoNamespace ())}
922+ if appOfApps {
923+ ns = []string {fmt .Sprintf ("%s" , getClusterWideArgoNamespace ())}
924+ }
899925 query := map [string ]any {
900926 "operationName" : "searchResult" ,
901927 "query" : "query searchResult($input: [SearchInput]) { searchResult: search(input: $input) { items related { kind items } } }" ,
@@ -917,7 +943,7 @@ func (r *PatternReconciler) checkSpokeChildApplicationsGone(p *api.Pattern) (boo
917943 },
918944 {
919945 "property" : "namespace" ,
920- "values" : [] string { fmt . Sprintf ( "!%s" , getClusterWideArgoNamespace ())} ,
946+ "values" : ns ,
921947 },
922948 },
923949 "relatedKinds" : []string {"Application" },
0 commit comments