@@ -20,6 +20,7 @@ import (
2020 "fmt"
2121
2222 v20250312sdk "go.mongodb.org/atlas-sdk/v20250312009/admin"
23+ apierrors "k8s.io/apimachinery/pkg/api/errors"
2324 controllerruntime "sigs.k8s.io/controller-runtime"
2425 builder "sigs.k8s.io/controller-runtime/pkg/builder"
2526 client "sigs.k8s.io/controller-runtime/pkg/client"
@@ -71,6 +72,26 @@ func (h *Handlerv20250312) getDependencies(ctx context.Context, flexcluster *ako
7172 return result , nil
7273}
7374
75+ // getMinimalGroupFromStatusOrSpec creates a minimal Group object with group ID from status (preferred) or spec (fallback).
76+ // Returns nil if no group ID is available. This allows deletion to proceed even if the Group CR is gone from Kubernetes.
77+ func (h * Handlerv20250312 ) getMinimalGroupFromStatusOrSpec (flexcluster * akov2generated.FlexCluster ) * akov2generated.Group {
78+ var groupID * string
79+ if flexcluster .Status .V20250312 != nil {
80+ groupID = flexcluster .Status .V20250312 .GroupId
81+ }
82+ if groupID == nil && flexcluster .Spec .V20250312 != nil {
83+ groupID = flexcluster .Spec .V20250312 .GroupId
84+ }
85+ if groupID == nil || * groupID == "" {
86+ return nil
87+ }
88+ return & akov2generated.Group {
89+ Status : akov2generated.GroupStatus {
90+ V20250312 : & akov2generated.GroupStatusV20250312 {Id : groupID },
91+ },
92+ }
93+ }
94+
7495// HandleInitial handles the initial state for version v20250312
7596func (h * Handlerv20250312 ) HandleInitial (ctx context.Context , flexcluster * akov2generated.FlexCluster ) (ctrlstate.Result , error ) {
7697 deps , err := h .getDependencies (ctx , flexcluster )
@@ -165,7 +186,18 @@ func (h *Handlerv20250312) HandleDeletionRequested(ctx context.Context, flexclus
165186
166187 deps , err := h .getDependencies (ctx , flexcluster )
167188 if err != nil {
168- return result .Error (state .StateDeletionRequested , fmt .Errorf ("failed to get dependencies: %w" , err ))
189+ // Race condition: Group CR may be deleted from K8s before FlexCluster finishes deletion.
190+ // If Group is not found but we have group ID in status, use it to proceed with deletion.
191+ var statusErr * apierrors.StatusError
192+ if errors .As (err , & statusErr ) && apierrors .IsNotFound (statusErr ) {
193+ if group := h .getMinimalGroupFromStatusOrSpec (flexcluster ); group != nil {
194+ deps = []client.Object {group }
195+ } else {
196+ return result .Error (state .StateDeletionRequested , fmt .Errorf ("failed to get dependencies: %w" , err ))
197+ }
198+ } else {
199+ return result .Error (state .StateDeletionRequested , fmt .Errorf ("failed to get dependencies: %w" , err ))
200+ }
169201 }
170202
171203 params := & v20250312sdk.DeleteFlexClusterApiParams {}
@@ -189,7 +221,18 @@ func (h *Handlerv20250312) HandleDeletionRequested(ctx context.Context, flexclus
189221func (h * Handlerv20250312 ) HandleDeleting (ctx context.Context , flexcluster * akov2generated.FlexCluster ) (ctrlstate.Result , error ) {
190222 deps , err := h .getDependencies (ctx , flexcluster )
191223 if err != nil {
192- return result .Error (state .StateDeleting , fmt .Errorf ("failed to get dependencies: %w" , err ))
224+ // Race condition: Group CR may be deleted from K8s before FlexCluster finishes deletion.
225+ // If Group is not found but we have group ID in status, use it to proceed with deletion.
226+ var statusErr * apierrors.StatusError
227+ if errors .As (err , & statusErr ) && apierrors .IsNotFound (statusErr ) {
228+ if group := h .getMinimalGroupFromStatusOrSpec (flexcluster ); group != nil {
229+ deps = []client.Object {group }
230+ } else {
231+ return result .Error (state .StateDeleting , fmt .Errorf ("failed to get dependencies: %w" , err ))
232+ }
233+ } else {
234+ return result .Error (state .StateDeleting , fmt .Errorf ("failed to get dependencies: %w" , err ))
235+ }
193236 }
194237
195238 params := & v20250312sdk.GetFlexClusterApiParams {}
0 commit comments