Skip to content

Commit 9efac33

Browse files
committed
WIP: refactor application sync, error handling
We only sync now with prune if its a must
1 parent 134b063 commit 9efac33

2 files changed

Lines changed: 64 additions & 38 deletions

File tree

internal/controller/argo.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1063,16 +1063,16 @@ func updateHelmParameter(goal api.PatternParameter, actual []argoapi.HelmParamet
10631063
return false
10641064
}
10651065

1066-
// syncApplicationWithPrune syncs the application with prune and force options if such a sync is not already in progress.
1066+
// syncApplication syncs the application with prune and force options if such a sync is not already in progress.
10671067
// Returns true if a sync with prune and force is already in progress, false otherwise
1068-
func syncApplicationWithPrune(client argoclient.Interface, app *argoapi.Application) (bool, error) {
1069-
if app.Operation != nil && app.Operation.Sync != nil && app.Operation.Sync.Prune && slices.Contains(app.Operation.Sync.SyncOptions, "Force=true") {
1068+
func syncApplication(client argoclient.Interface, app *argoapi.Application, withPrune bool) (bool, error) {
1069+
if app.Operation != nil && app.Operation.Sync != nil && app.Operation.Sync.Prune == withPrune && slices.Contains(app.Operation.Sync.SyncOptions, "Force=true") {
10701070
return true, nil
10711071
}
10721072

10731073
app.Operation = &argoapi.Operation{
10741074
Sync: &argoapi.SyncOperation{
1075-
Prune: true,
1075+
Prune: withPrune,
10761076
SyncOptions: []string{"Force=true"},
10771077
},
10781078
}

internal/controller/pattern_controller.go

Lines changed: 60 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -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

628623
func (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

Comments
 (0)