Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions controllers/operator/mongodbmultireplicaset_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,11 @@ func (r *ReconcileMongoDbMultiReplicaSet) Reconcile(ctx context.Context, request
return reconcileResult, err
}

if val, ok := mrs.Annotations[util.DisableReconciliation]; ok && val == util.DisableReconciliationValue {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will be something our users will be using during migration, but as part of this PR I"m not going to document the annotation/add a release note. It will be included in the migration guide once we release a version which is ready for migration. Until then - let's leave it undocumented.

log.Info("Reconciliation disabled")
return r.updateStatus(ctx, &mrs, workflow.Disabled(), log)
}

if !architectures.IsRunningStaticArchitecture(mrs.Annotations) {
agents.UpgradeAllIfNeeded(ctx, agents.ClientSecret{Client: r.client, SecretClient: r.SecretClient}, r.omConnectionFactory, GetWatchedNamespace(), true)
}
Expand Down
70 changes: 70 additions & 0 deletions controllers/operator/mongodbmultireplicaset_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"context"
"encoding/json"
"fmt"
"maps"
"sort"
"testing"

Expand Down Expand Up @@ -1425,6 +1426,75 @@ func TestValidationsRunOnReconcile(t *testing.T) {
assert.Equal(t, fmt.Sprintf("Multiple clusters with the same name (%s) are not allowed", duplicateName), mrs.Status.Message)
}

func TestReconcileDisableReconciliationAnnotation(t *testing.T) {
tests := []struct {
name string
annotations map[string]string
expectedPhase status.Phase
expectedReconcileResult reconcile.Result
}{
{
name: "reconciliation disabled when annotation is true",
annotations: map[string]string{util.DisableReconciliation: util.DisableReconciliationValue},
expectedPhase: status.PhaseDisabled,
expectedReconcileResult: reconcile.Result{Requeue: false, RequeueAfter: 0},
},
{
name: "reconciliation proceeds when annotation is false",
annotations: map[string]string{util.DisableReconciliation: "false"},
expectedPhase: status.PhaseRunning,
expectedReconcileResult: reconcile.Result{RequeueAfter: util.TWENTY_FOUR_HOURS},
},
{
name: "reconciliation proceeds when annotation is empty string",
annotations: map[string]string{util.DisableReconciliation: ""},
expectedPhase: status.PhaseRunning,
expectedReconcileResult: reconcile.Result{RequeueAfter: util.TWENTY_FOUR_HOURS},
},
{
name: "reconciliation proceeds when annotation is arbitrary value",
annotations: map[string]string{util.DisableReconciliation: "some-other-value"},
expectedPhase: status.PhaseRunning,
expectedReconcileResult: reconcile.Result{RequeueAfter: util.TWENTY_FOUR_HOURS},
},
{
name: "reconciliation proceeds when annotation is absent",
expectedPhase: status.PhaseRunning,
expectedReconcileResult: reconcile.Result{RequeueAfter: util.TWENTY_FOUR_HOURS},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ctx := context.Background()
mrs := mdbmulti.DefaultMultiReplicaSetBuilder().SetClusterSpecList(clusters).Build()

// Set up test annotations
if mrs.Annotations == nil {
mrs.Annotations = map[string]string{}
}
maps.Copy(mrs.Annotations, tt.annotations)

reconciler, client, _, _ := defaultMultiReplicaSetReconciler(ctx, nil, "", "", mrs)

// Update the resource with the annotation
err := client.Update(ctx, mrs)
assert.NoError(t, err)

// Reconcile should return without error and with expected result
result, err := reconciler.Reconcile(ctx, requestFromObject(mrs))
assert.NoError(t, err)
assert.Equal(t, tt.expectedReconcileResult, result)

// Fetch the updated resource to check the status
err = client.Get(ctx, kube.ObjectKey(mrs.Namespace, mrs.Name), mrs)
assert.NoError(t, err)

assert.Equal(t, tt.expectedPhase, mrs.Status.Phase)
})
}
}

func assertClusterpresent(t *testing.T, m map[string]int, specs mdb.ClusterSpecList, arr []int) {
tmp := make([]int, 0)
for _, s := range specs {
Expand Down
3 changes: 3 additions & 0 deletions pkg/util/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,9 @@ const (
LastAchievedSpec = "mongodb.com/v1.lastSuccessfulConfiguration"
LastAchievedRsMemberIds = "mongodb.com/v1.lastAchievedRsMemberIds"

DisableReconciliation = "mongodb.com/v1.disableReconciliation"
DisableReconciliationValue = "true"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Had to define a constant because linter was not happy.


// SecretVolumeName is the name of the volume resource.
SecretVolumeName = "secret-certs"

Expand Down