Skip to content

Commit ae52bb4

Browse files
committed
CLOUDP-327089: Add status field support (squash of last 6 commits)
1 parent 0617759 commit ae52bb4

File tree

5 files changed

+94
-12
lines changed

5 files changed

+94
-12
lines changed

api/v1/search/mongodbsearch_types.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ type MongoDBSearchStatus struct {
102102
// +k8s:openapi-gen=true
103103
// +kubebuilder:subresource:status
104104
// +kubebuilder:printcolumn:name="Phase",type="string",JSONPath=".status.phase",description="Current state of the MongoDB deployment."
105+
// +kubebuilder:printcolumn:name="Version",type="string",JSONPath=".status.version",description="MongoDB Search version reconciled by the operator."
105106
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description="The time since the MongoDB resource was created."
106107
// +kubebuilder:resource:path=mongodbsearch,scope=Namespaced,shortName=mdbs
107108
type MongoDBSearch struct {
@@ -142,6 +143,9 @@ func (s *MongoDBSearch) UpdateStatus(phase status.Phase, statusOptions ...status
142143
if option, exists := status.GetOption(statusOptions, status.WarningsOption{}); exists {
143144
s.Status.Warnings = append(s.Status.Warnings, option.(status.WarningsOption).Warnings...)
144145
}
146+
if option, exists := status.GetOption(statusOptions, MongoDBSearchVersionOption{}); exists {
147+
s.Status.Version = option.(MongoDBSearchVersionOption).Version
148+
}
145149
}
146150

147151
func (s *MongoDBSearch) NamespacedName() types.NamespacedName {

api/v1/search/status_options.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package search
2+
3+
import "github.com/mongodb/mongodb-kubernetes/api/v1/status"
4+
5+
type MongoDBSearchVersionOption struct {
6+
Version string
7+
}
8+
9+
var _ status.Option = MongoDBSearchVersionOption{}
10+
11+
func NewMongoDBSearchVersionOption(version string) MongoDBSearchVersionOption {
12+
return MongoDBSearchVersionOption{Version: version}
13+
}
14+
15+
func (o MongoDBSearchVersionOption) Value() interface{} {
16+
return o.Version
17+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
title: Surface reconciled MongoDBSearch version
3+
kind: fix
4+
date: 2025-10-24
5+
---
6+
7+
* MongoDBSearch now records the reconciled mongot version in status and exposes it via a dedicated kubectl print column.

controllers/operator/mongodbsearch_controller_test.go

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,12 @@ func TestMongoDBSearchReconcile_Success(t *testing.T) {
172172
search.Spec.LogLevel = "WARN"
173173

174174
mdbc := newMongoDBCommunity("mdb", mock.TestNamespace)
175-
reconciler, c := newSearchReconciler(mdbc, search)
175+
operatorConfig := searchcontroller.OperatorSearchConfig{
176+
SearchRepo: "testrepo",
177+
SearchName: "mongot",
178+
SearchVersion: "1.48.0",
179+
}
180+
reconciler, c := newSearchReconcilerWithOperatorConfig(mdbc, operatorConfig, search)
176181

177182
res, err := reconciler.Reconcile(
178183
ctx,
@@ -182,6 +187,11 @@ func TestMongoDBSearchReconcile_Success(t *testing.T) {
182187
assert.NoError(t, err)
183188
assert.Equal(t, expected, res)
184189

190+
// BEFORE readiness: version should still be empty (controller sets Version only after StatefulSet ready)
191+
searchPending := &searchv1.MongoDBSearch{}
192+
assert.NoError(t, c.Get(ctx, types.NamespacedName{Name: search.Name, Namespace: search.Namespace}, searchPending))
193+
assert.Empty(t, searchPending.Status.Version, "Status.Version must be empty before StatefulSet is marked ready")
194+
185195
svc := &corev1.Service{}
186196
err = c.Get(ctx, search.SearchServiceNamespacedName(), svc)
187197
assert.NoError(t, err)
@@ -194,9 +204,18 @@ func TestMongoDBSearchReconcile_Success(t *testing.T) {
194204
assert.NoError(t, err)
195205
assert.Equal(t, string(configYaml), cm.Data[searchcontroller.MongotConfigFilename])
196206

197-
sts := &appsv1.StatefulSet{}
198-
err = c.Get(ctx, search.StatefulSetNamespacedName(), sts)
207+
markStatefulSetReady(ctx, t, c, search.StatefulSetNamespacedName())
208+
209+
res, err = reconciler.Reconcile(
210+
ctx,
211+
reconcile.Request{NamespacedName: types.NamespacedName{Name: search.Name, Namespace: search.Namespace}},
212+
)
199213
assert.NoError(t, err)
214+
assert.Equal(t, expected, res)
215+
216+
updatedSearch := &searchv1.MongoDBSearch{}
217+
assert.NoError(t, c.Get(ctx, types.NamespacedName{Name: search.Name, Namespace: search.Namespace}, updatedSearch))
218+
assert.Equal(t, operatorConfig.SearchVersion, updatedSearch.Status.Version)
200219
}
201220

202221
func checkSearchReconcileFailed(
@@ -296,3 +315,18 @@ func TestMongoDBSearchReconcile_InvalidSearchImageVersion(t *testing.T) {
296315
})
297316
}
298317
}
318+
319+
func markStatefulSetReady(ctx context.Context, t *testing.T, c client.Client, name types.NamespacedName) {
320+
t.Helper()
321+
322+
sts := &appsv1.StatefulSet{}
323+
assert.NoError(t, c.Get(ctx, name, sts))
324+
325+
sts.Status.UpdatedReplicas = 1
326+
sts.Status.ReadyReplicas = 1
327+
sts.Status.CurrentReplicas = 1
328+
sts.Status.Replicas = 1
329+
sts.Status.ObservedGeneration = sts.Generation
330+
331+
assert.NoError(t, c.Status().Update(ctx, sts))
332+
}

controllers/searchcontroller/mongodbsearch_reconcile_helper.go

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,9 @@ func (r *MongoDBSearchReconcileHelper) reconcile(ctx context.Context, log *zap.S
8989
return workflow.Failed(err)
9090
}
9191

92-
if err := r.ValidateSearchImageVersion(); err != nil {
92+
version := r.getMongotVersion()
93+
94+
if err := r.ValidateSearchImageVersion(version); err != nil {
9395
return workflow.Failed(err)
9496
}
9597

@@ -137,7 +139,7 @@ func (r *MongoDBSearchReconcileHelper) reconcile(ctx context.Context, log *zap.S
137139
return statefulSetStatus
138140
}
139141

140-
return workflow.OK()
142+
return workflow.OK().WithAdditionalOptions(searchv1.NewMongoDBSearchVersionOption(version))
141143
}
142144

143145
func (r *MongoDBSearchReconcileHelper) ensureSourceKeyfile(ctx context.Context, log *zap.SugaredLogger) (statefulset.Modification, error) {
@@ -435,24 +437,23 @@ func (r *MongoDBSearchReconcileHelper) ValidateSingleMongoDBSearchForSearchSourc
435437
return nil
436438
}
437439

438-
func (r *MongoDBSearchReconcileHelper) ValidateSearchImageVersion() error {
439-
version := r.getMongotImage()
440-
440+
func (r *MongoDBSearchReconcileHelper) ValidateSearchImageVersion(version string) error {
441441
if strings.Contains(version, unsupportedSearchVersion) {
442442
return xerrors.Errorf(unsupportedSearchVersionErrorFmt, unsupportedSearchVersion)
443443
}
444444

445445
return nil
446446
}
447447

448-
func (r *MongoDBSearchReconcileHelper) getMongotImage() string {
448+
func (r *MongoDBSearchReconcileHelper) getMongotVersion() string {
449449
version := strings.TrimSpace(r.mdbSearch.Spec.Version)
450450
if version != "" {
451451
return version
452452
}
453453

454-
if r.operatorSearchConfig.SearchVersion != "" {
455-
return r.operatorSearchConfig.SearchVersion
454+
version = strings.TrimSpace(r.operatorSearchConfig.SearchVersion)
455+
if version != "" {
456+
return version
456457
}
457458

458459
if r.mdbSearch.Spec.StatefulSetConfiguration == nil {
@@ -461,13 +462,32 @@ func (r *MongoDBSearchReconcileHelper) getMongotImage() string {
461462

462463
for _, container := range r.mdbSearch.Spec.StatefulSetConfiguration.SpecWrapper.Spec.Template.Spec.Containers {
463464
if container.Name == MongotContainerName {
464-
return container.Image
465+
return extractImageTag(container.Image)
465466
}
466467
}
467468

468469
return ""
469470
}
470471

472+
func extractImageTag(image string) string {
473+
image = strings.TrimSpace(image)
474+
if image == "" {
475+
return ""
476+
}
477+
478+
if at := strings.Index(image, "@"); at != -1 {
479+
image = image[:at]
480+
}
481+
482+
lastSlash := strings.LastIndex(image, "/")
483+
lastColon := strings.LastIndex(image, ":")
484+
if lastColon > lastSlash {
485+
return image[lastColon+1:]
486+
}
487+
488+
return ""
489+
}
490+
471491
func SearchCoordinatorRole() mdbv1.MongoDBRole {
472492
// direct translation of https://github.com/10gen/mongo/blob/6f8d95a513eea8f91ea9f5d895dd8a288dfcf725/src/mongo/db/auth/builtin_roles.yml#L652
473493
return mdbv1.MongoDBRole{

0 commit comments

Comments
 (0)