Skip to content

Commit 255cce7

Browse files
authored
CLOUDP-81188: fix deletion of Atlas Cluster (#65)
1 parent fe565af commit 255cce7

File tree

4 files changed

+41
-22
lines changed

4 files changed

+41
-22
lines changed

pkg/controller/atlas/api_error.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,7 @@ const (
77
// The error that Atlas API returns if the GET request is sent to read the project that either doesn't exist
88
// or the user doesn't have permissions for
99
NotInGroup = "NOT_IN_GROUP"
10+
11+
// Error indicates that the project is being removed while it still has clusters
12+
CannotCloseGroupActiveAtlasCluster = "CANNOT_CLOSE_GROUP_ACTIVE_ATLAS_CLUSTERS"
1013
)

pkg/controller/atlascluster/atlascluster_controller.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ func (r *AtlasClusterReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error
5858
}
5959
ctx := customresource.MarkReconciliationStarted(r.Client, cluster, log)
6060

61-
log.Infow("-> Starting AtlasCluster reconciliation", "spec", cluster.Spec)
61+
log.Infow("-> Starting AtlasCluster reconciliation", "spec", cluster.Spec, "generation", cluster.Generation, "status", cluster.Status)
6262
defer statushandler.Update(ctx, r.Client, cluster)
6363

6464
project := &mdbv1.AtlasProject{}
@@ -135,12 +135,12 @@ func (r *AtlasClusterReconciler) Delete(obj runtime.Object) error {
135135
return errors.New("cannot read Atlas connection")
136136
}
137137

138-
client, err := atlas.Client(connection, log)
138+
atlasClient, err := atlas.Client(connection, log)
139139
if err != nil {
140140
return fmt.Errorf("cannot build Atlas client: %w", err)
141141
}
142142

143-
_, err = client.Clusters.Delete(context.Background(), project.Status.ID, cluster.Name)
143+
_, err = atlasClient.Clusters.Delete(context.Background(), project.Status.ID, cluster.Spec.Name)
144144
if err != nil {
145145
return fmt.Errorf("cannot delete Atlas cluster: %w", err)
146146
}

pkg/util/testutil/customresources.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ func WaitFor(k8sClient client.Client, createdResource mdbv1.AtlasCustomResource,
2121
return false
2222
}
2323
// Atlas Operator hasn't started working yet
24+
fmt.Printf("Generation: %+v, observed Generation: %+v\n", createdResource.GetGeneration(), createdResource.GetStatus().GetObservedGeneration())
2425
if createdResource.GetGeneration() != createdResource.GetStatus().GetObservedGeneration() {
2526
return false
2627
}

test/int/cluster_test.go

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,20 @@ package int
22

33
import (
44
"context"
5+
"errors"
56
"fmt"
67
"net/http"
78
"time"
89

910
mdbv1 "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1"
1011
"github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1/status"
12+
"github.com/mongodb/mongodb-atlas-kubernetes/pkg/controller/atlas"
1113
"github.com/mongodb/mongodb-atlas-kubernetes/pkg/controller/workflow"
1214
"github.com/mongodb/mongodb-atlas-kubernetes/pkg/util/kube"
1315
"github.com/mongodb/mongodb-atlas-kubernetes/pkg/util/testutil"
1416
. "github.com/onsi/ginkgo"
1517
. "github.com/onsi/gomega"
18+
"go.mongodb.org/atlas/mongodbatlas"
1619
corev1 "k8s.io/api/core/v1"
1720
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1821
)
@@ -59,21 +62,24 @@ var _ = Describe("AtlasCluster", func() {
5962
AfterEach(func() {
6063
if createdProject != nil && createdProject.Status.ID != "" {
6164
if createdCluster != nil {
62-
By("Removing Atlas Cluster " + createdCluster.Spec.Name)
63-
_, _ = atlasClient.Clusters.Delete(context.Background(), createdProject.Status.ID, createdCluster.Spec.Name)
65+
By("Removing Atlas Cluster " + createdCluster.Name)
66+
Expect(k8sClient.Delete(context.Background(), createdCluster)).To(Succeed())
67+
68+
Eventually(checkAtlasClusterRemoved(createdProject.Status.ID, createdCluster.Name), 600, interval).Should(BeTrue())
6469
}
65-
// TODO need to wait for the cluster to get removed
66-
// By("Removing Atlas Project " + createdProject.Status.ID)
67-
// _, err := atlasClient.Projects.Delete(context.Background(), createdProject.Status.ID)
68-
// Expect(err).ToNot(HaveOccurred())
70+
By("Removing Atlas Project " + createdProject.Status.ID)
71+
// This is a bit strange but the delete request right after the cluster is removed may fail with "Still active cluster" error
72+
// UI shows the cluster being deleted though. Seems to be the issue only if removal is done using API,
73+
// if the cluster is terminated using UI - it stays in "Deleting" state
74+
Eventually(removeAtlasProject(createdProject.Status.ID), 600, interval).Should(BeTrue())
6975
}
7076

7177
By("Removing the namespace " + namespace.Name)
7278
err := k8sClient.Delete(context.Background(), &namespace)
7379
Expect(err).ToNot(HaveOccurred())
7480
})
7581

76-
Describe("Create/Update/Delete the cluster", func() {
82+
Describe("Create/Update the cluster", func() {
7783
It("Should Succeed", func() {
7884
expectedCluster := testAtlasCluster(namespace.Name, "test-cluster", createdProject.Name)
7985

@@ -137,16 +143,12 @@ var _ = Describe("AtlasCluster", func() {
137143
Expect(err).ToNot(HaveOccurred())
138144

139145
Expect(atlasCluster.Name).To(Equal(createdAtlasCluster.Name))
146+
print(createdCluster.Labels)
147+
print(createdAtlasCluster.Labels)
140148
Expect(atlasCluster.Labels).To(Equal(createdAtlasCluster.Labels))
141149
Expect(atlasCluster.ProviderSettings.InstanceSizeName).To(Equal(createdAtlasCluster.ProviderSettings.InstanceSizeName))
142150
Expect(atlasCluster.ProviderSettings.ProviderName).To(Equal(createdAtlasCluster.ProviderSettings.ProviderName))
143151
Expect(atlasCluster.ProviderSettings.RegionName).To(Equal(createdAtlasCluster.ProviderSettings.RegionName))
144-
145-
By("Deleting the cluster")
146-
err = k8sClient.Delete(context.Background(), createdCluster)
147-
Expect(err).ToNot(HaveOccurred())
148-
149-
Eventually(checkAtlasDeleteStarted(createdProject.Status.ID, createdCluster.Name), 1200, interval).Should(BeTrue())
150152
})
151153
})
152154
})
@@ -182,7 +184,7 @@ func testAtlasCluster(namespace, name, projectName string) *mdbv1.AtlasCluster {
182184
Namespace: namespace,
183185
},
184186
Spec: mdbv1.AtlasClusterSpec{
185-
Name: "test-cluster",
187+
Name: "test-atlas-cluster",
186188
Project: mdbv1.ResourceRef{Name: projectName},
187189
ProviderSettings: &mdbv1.ProviderSettingsSpec{
188190
InstanceSizeName: "M10",
@@ -192,18 +194,31 @@ func testAtlasCluster(namespace, name, projectName string) *mdbv1.AtlasCluster {
192194
},
193195
}
194196
}
195-
func checkAtlasDeleteStarted(projectID string, clusterName string) func() bool {
197+
198+
// checkAtlasClusterRemoved returns true if the Atlas Cluster is removed from Atlas. Note the behavior: the cluster
199+
// is removed from Atlas as soon as the DELETE API call has been made. This is different from the case when the
200+
// cluster is terminated from UI (in this case GET request succeeds while the cluster is being terminated)
201+
func checkAtlasClusterRemoved(projectID string, clusterName string) func() bool {
196202
return func() bool {
197-
c, r, err := atlasClient.Clusters.Get(context.Background(), projectID, clusterName)
203+
_, r, err := atlasClient.Clusters.Get(context.Background(), projectID, clusterName)
198204
if err != nil {
199-
// cluster already deleted - that's fine for us
200205
if r != nil && r.StatusCode == http.StatusNotFound {
201206
return true
202207
}
208+
}
209+
return false
210+
}
211+
}
203212

213+
func removeAtlasProject(projectID string) func() bool {
214+
return func() bool {
215+
_, err := atlasClient.Projects.Delete(context.Background(), projectID)
216+
if err != nil {
217+
var apiError *mongodbatlas.ErrorResponse
218+
Expect(errors.As(err, &apiError)).To(BeTrue())
219+
Expect(apiError.ErrorCode).To(Equal(atlas.CannotCloseGroupActiveAtlasCluster))
204220
return false
205221
}
206-
207-
return c.StateName == "DELETING" || c.StateName == "DELETED"
222+
return true
208223
}
209224
}

0 commit comments

Comments
 (0)