diff --git a/deploy/bundle.yaml b/deploy/bundle.yaml index 5b9ac149ac..55d4c6e9cd 100644 --- a/deploy/bundle.yaml +++ b/deploy/bundle.yaml @@ -26737,6 +26737,8 @@ spec: value: percona-server-mongodb-operator - name: RESYNC_PERIOD value: 5s + - name: RECONCILE_INTERVAL + value: 5s - name: DISABLE_TELEMETRY value: "false" - name: MAX_CONCURRENT_RECONCILES diff --git a/deploy/cw-bundle.yaml b/deploy/cw-bundle.yaml index cc126dccb1..dd8efc1575 100644 --- a/deploy/cw-bundle.yaml +++ b/deploy/cw-bundle.yaml @@ -26763,6 +26763,8 @@ spec: value: percona-server-mongodb-operator - name: RESYNC_PERIOD value: 5s + - name: RECONCILE_INTERVAL + value: 5s - name: DISABLE_TELEMETRY value: "false" - name: MAX_CONCURRENT_RECONCILES diff --git a/deploy/cw-operator.yaml b/deploy/cw-operator.yaml index 1a1c9ea41a..d75a4c03f1 100644 --- a/deploy/cw-operator.yaml +++ b/deploy/cw-operator.yaml @@ -54,6 +54,8 @@ spec: value: percona-server-mongodb-operator - name: RESYNC_PERIOD value: 5s + - name: RECONCILE_INTERVAL + value: 5s - name: DISABLE_TELEMETRY value: "false" - name: MAX_CONCURRENT_RECONCILES diff --git a/deploy/operator.yaml b/deploy/operator.yaml index 359515d48e..8fc39627e3 100644 --- a/deploy/operator.yaml +++ b/deploy/operator.yaml @@ -56,6 +56,8 @@ spec: value: percona-server-mongodb-operator - name: RESYNC_PERIOD value: 5s + - name: RECONCILE_INTERVAL + value: 5s - name: DISABLE_TELEMETRY value: "false" - name: MAX_CONCURRENT_RECONCILES diff --git a/pkg/controller/perconaservermongodb/psmdb_controller.go b/pkg/controller/perconaservermongodb/psmdb_controller.go index 5658c9ccf7..d25b9d378c 100644 --- a/pkg/controller/perconaservermongodb/psmdb_controller.go +++ b/pkg/controller/perconaservermongodb/psmdb_controller.go @@ -99,7 +99,7 @@ func newReconciler(mgr manager.Manager) (reconcile.Reconciler, error) { client: client, scheme: mgr.GetScheme(), serverVersion: sv, - reconcileIn: time.Second * 5, + reconcileIn: getReconcileInterval(), crons: NewCronRegistry(), lockers: newLockStore(), newPBM: backup.NewPBM, @@ -140,6 +140,32 @@ func getOperatorPodImage(ctx context.Context) (string, error) { return pod.Spec.Containers[0].Image, nil } +// getReconcileInterval returns the reconciliation interval from the RECONCILE_INTERVAL +// environment variable, or the default of 5 seconds if not set or invalid. +func getReconcileInterval() time.Duration { + defaultInterval := 5 * time.Second + + interval := os.Getenv("RECONCILE_INTERVAL") + if interval == "" { + return defaultInterval + } + + d, err := time.ParseDuration(interval) + if err != nil { + log := logf.Log.WithName("psmdb-controller") + log.Info("Invalid RECONCILE_INTERVAL value, using default (5s)", "value", interval, "error", err, "default", defaultInterval) + return defaultInterval + } + + if d < defaultInterval { + log := logf.Log.WithName("psmdb-controller") + log.Info("RECONCILE_INTERVAL must be at least 5s, using 5s", "value", interval, "default", defaultInterval) + return defaultInterval + } + + return d +} + // add adds a new Controller to mgr with r as the reconcile.Reconciler func add(mgr manager.Manager, r reconcile.Reconciler) error { return builder.ControllerManagedBy(mgr). diff --git a/pkg/controller/perconaservermongodb/psmdb_controller_test.go b/pkg/controller/perconaservermongodb/psmdb_controller_test.go index b8a3c541e7..6c8203cc1a 100644 --- a/pkg/controller/perconaservermongodb/psmdb_controller_test.go +++ b/pkg/controller/perconaservermongodb/psmdb_controller_test.go @@ -2,9 +2,14 @@ package perconaservermongodb import ( "context" + "os" + "testing" + "time" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" @@ -13,6 +18,67 @@ import ( psmdbv1 "github.com/percona/percona-server-mongodb-operator/pkg/apis/psmdb/v1" ) +func TestGetReconcileInterval(t *testing.T) { + tests := []struct { + name string + envValue string + setEnv bool + want time.Duration + }{ + { + name: "unset", + setEnv: false, + want: 5 * time.Second, + }, + { + name: "valid duration", + envValue: "30s", + setEnv: true, + want: 30 * time.Second, + }, + { + name: "invalid duration falls back to default", + envValue: "invalid", + setEnv: true, + want: 5 * time.Second, + }, + { + name: "zero duration falls back to default", + envValue: "0s", + setEnv: true, + want: 5 * time.Second, + }, + { + name: "negative duration falls back to default", + envValue: "-5s", + setEnv: true, + want: 5 * time.Second, + }, + { + name: "duration less than 5s falls back to default", + envValue: "1s", + setEnv: true, + want: 5 * time.Second, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + defer func() { + err := os.Unsetenv("RECONCILE_INTERVAL") + require.NoError(t, err) + }() + if tt.setEnv { + err := os.Setenv("RECONCILE_INTERVAL", tt.envValue) + require.NoError(t, err) + } + + got := getReconcileInterval() + assert.Equal(t, tt.want, got) + }) + } +} + var _ = Describe("PerconaServerMongoDB", Ordered, func() { ctx := context.Background() const ns = "psmdb"