Skip to content

Commit b51b081

Browse files
CLOUDP-221979: Fix: Remove all search index status entries where ID is empty (#1565)
Cleanup indexes with empty IDs when all indexes are ready
1 parent 2306425 commit b51b081

File tree

3 files changed

+119
-0
lines changed

3 files changed

+119
-0
lines changed

pkg/api/v1/status/atlasdeployment.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,18 @@ func AtlasDeploymentMongoURIUpdatedOption(mongoURIUpdated string) AtlasDeploymen
171171
}
172172
}
173173

174+
func AtlasDeploymentRemoveStatusesWithEmptyIDs() AtlasDeploymentStatusOption {
175+
return func(s *AtlasDeploymentStatus) {
176+
var result []DeploymentSearchIndexStatus
177+
for i := range s.SearchIndexes {
178+
if s.SearchIndexes[i].ID != "" {
179+
result = append(result, s.SearchIndexes[i])
180+
}
181+
}
182+
s.SearchIndexes = result
183+
}
184+
}
185+
174186
// AtlasDeploymentSetSearchIndexStatus set the status for one SearchIndex
175187
func AtlasDeploymentSetSearchIndexStatus(indexStatus DeploymentSearchIndexStatus) AtlasDeploymentStatusOption {
176188
return func(s *AtlasDeploymentStatus) {

pkg/controller/atlasdeployment/searchindexes.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,5 +151,6 @@ func (sr *searchIndexesReconciler) empty() workflow.Result {
151151

152152
func (sr *searchIndexesReconciler) idle() workflow.Result {
153153
sr.ctx.SetConditionTrue(status.SearchIndexesReadyType)
154+
sr.ctx.EnsureStatusOption(status.AtlasDeploymentRemoveStatusesWithEmptyIDs())
154155
return workflow.OK()
155156
}

pkg/controller/atlasdeployment/searchindexes_test.go

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import (
66
"net/http"
77
"testing"
88

9+
internal "github.com/mongodb/mongodb-atlas-kubernetes/v2/internal/searchindex"
10+
911
"github.com/stretchr/testify/mock"
1012
"go.mongodb.org/atlas-sdk/v20231115008/admin"
1113
"go.mongodb.org/atlas-sdk/v20231115008/mockadmin"
@@ -128,6 +130,110 @@ func Test_SearchIndexesReconcile(t *testing.T) {
128130
assert.False(t, result.IsOk())
129131
})
130132

133+
t.Run("Should cleanup indexes with empty IDs when IDLE", func(t *testing.T) {
134+
searchIndexConfig := &akov2.AtlasSearchIndexConfig{
135+
TypeMeta: metav1.TypeMeta{},
136+
ObjectMeta: metav1.ObjectMeta{
137+
Name: "testConfig",
138+
Namespace: "testNamespace",
139+
},
140+
Spec: akov2.AtlasSearchIndexConfigSpec{
141+
Analyzer: pointer.MakePtr("testAnalyzer"),
142+
},
143+
Status: status.AtlasSearchIndexConfigStatus{},
144+
}
145+
IDForStatus := "123"
146+
deployment := &akov2.AtlasDeployment{
147+
TypeMeta: metav1.TypeMeta{},
148+
ObjectMeta: metav1.ObjectMeta{},
149+
Spec: akov2.AtlasDeploymentSpec{
150+
DeploymentSpec: &akov2.AdvancedDeploymentSpec{
151+
Name: "testDeployment",
152+
SearchIndexes: []akov2.SearchIndex{
153+
{
154+
Name: "Index1",
155+
Type: IndexTypeSearch,
156+
Search: &akov2.Search{
157+
Synonyms: &([]akov2.Synonym{
158+
{
159+
Name: "testSynonym",
160+
Analyzer: "testAnalyzer",
161+
Source: akov2.Source{
162+
Collection: "testCollection",
163+
},
164+
},
165+
}),
166+
Mappings: nil,
167+
SearchConfigurationRef: common.ResourceRefNamespaced{
168+
Name: searchIndexConfig.Name,
169+
Namespace: searchIndexConfig.Namespace,
170+
},
171+
},
172+
},
173+
},
174+
},
175+
},
176+
Status: status.AtlasDeploymentStatus{
177+
SearchIndexes: []status.DeploymentSearchIndexStatus{
178+
{
179+
Name: "Index1",
180+
ID: IDForStatus,
181+
Status: "",
182+
Message: "",
183+
},
184+
{
185+
Name: "Index2",
186+
ID: "",
187+
Status: "",
188+
Message: "",
189+
},
190+
},
191+
},
192+
}
193+
194+
sch := runtime.NewScheme()
195+
assert.Nil(t, akov2.AddToScheme(sch))
196+
assert.Nil(t, corev1.AddToScheme(sch))
197+
198+
atlasIdxToReturn, err := internal.NewSearchIndexFromAKO(&deployment.Spec.DeploymentSpec.SearchIndexes[0],
199+
&searchIndexConfig.Spec).ToAtlas()
200+
assert.NoError(t, err)
201+
mockSearchAPI := mockadmin.NewAtlasSearchApi(t)
202+
mockSearchAPI.EXPECT().
203+
GetAtlasSearchIndex(context.Background(), mock.Anything, mock.Anything, mock.Anything).
204+
Return(admin.GetAtlasSearchIndexApiRequest{ApiService: mockSearchAPI})
205+
mockSearchAPI.EXPECT().
206+
GetAtlasSearchIndexExecute(admin.GetAtlasSearchIndexApiRequest{ApiService: mockSearchAPI}).
207+
Return(
208+
atlasIdxToReturn,
209+
&http.Response{StatusCode: http.StatusCreated}, nil,
210+
)
211+
212+
k8sClient := fake.NewClientBuilder().
213+
WithScheme(sch).
214+
WithObjects(deployment, searchIndexConfig).
215+
Build()
216+
217+
reconciler := searchIndexesReconciler{
218+
ctx: &workflow.Context{
219+
Log: zap.S(),
220+
OrgID: "testOrgID",
221+
Client: nil,
222+
SdkClient: &admin.APIClient{AtlasSearchApi: mockSearchAPI},
223+
Context: context.Background(),
224+
},
225+
deployment: deployment,
226+
k8sClient: k8sClient,
227+
projectID: "testProjectID",
228+
}
229+
230+
result := reconciler.Reconcile()
231+
assert.True(t, result.IsOk())
232+
deployment.UpdateStatus(reconciler.ctx.Conditions(), reconciler.ctx.StatusOptions()...)
233+
assert.Len(t, deployment.Status.SearchIndexes, 1)
234+
assert.True(t, deployment.Status.SearchIndexes[0].ID == IDForStatus)
235+
})
236+
131237
t.Run("Should proceed with the index Type Search: CREATE INDEX", func(t *testing.T) {
132238
mockSearchAPI := mockadmin.NewAtlasSearchApi(t)
133239
mockSearchAPI.EXPECT().

0 commit comments

Comments
 (0)