From 365800664da54026bd58d822796d0af7f9acc922 Mon Sep 17 00:00:00 2001 From: Drew Wells Date: Wed, 4 Dec 2024 16:12:23 -0600 Subject: [PATCH 1/6] update CI pipeline for gitflow branch names --- .github/workflows/build-main.yml | 4 +++- Jenkinsfile | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-main.yml b/.github/workflows/build-main.yml index e4f17f76..8fc7c0cb 100644 --- a/.github/workflows/build-main.yml +++ b/.github/workflows/build-main.yml @@ -2,7 +2,9 @@ name: Build and push :main image on: push: - branches: [ main ] + branches: + - main + - 'release/**' env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} diff --git a/Jenkinsfile b/Jenkinsfile index 00f7c188..a2e1934f 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -31,6 +31,7 @@ pipeline { anyOf { branch 'main' branch 'hotfix/*' + branch 'release/*' } expression { !isPrBuild() } } From cee2c75db00d5a839c01aa10ec30e8009ab377a2 Mon Sep 17 00:00:00 2001 From: Drew Wells Date: Thu, 5 Dec 2024 09:45:14 -0600 Subject: [PATCH 2/6] PTEUDO-2142 remove validation of DSNName (#370) Previously, customizing the dsnname would throw a validation error and prevent any processing of the databaseclaim. This allows the customization but ensures the normalized fields are always populated. --- .../databaseclaim_controller_test.go | 81 +++++++++++++++---- .../databasecontroller_migrate_test.go | 3 +- internal/dockerdb/mockdb.go | 15 +++- internal/dockerdb/testdb.go | 2 + pkg/databaseclaim/databaseclaim.go | 10 +-- pkg/databaseclaim/secrets.go | 14 +++- pkg/databaseclaim/secrets_test.go | 14 +++- 7 files changed, 109 insertions(+), 30 deletions(-) diff --git a/internal/controller/databaseclaim_controller_test.go b/internal/controller/databaseclaim_controller_test.go index 2074a4b3..beef40dc 100644 --- a/internal/controller/databaseclaim_controller_test.go +++ b/internal/controller/databaseclaim_controller_test.go @@ -33,6 +33,8 @@ import ( "sigs.k8s.io/controller-runtime/pkg/reconcile" persistancev1 "github.com/infobloxopen/db-controller/api/v1" + v1 "github.com/infobloxopen/db-controller/api/v1" + "github.com/infobloxopen/db-controller/internal/dockerdb" "github.com/infobloxopen/db-controller/pkg/hostparams" ) @@ -67,6 +69,25 @@ var _ = Describe("DatabaseClaim Controller", func() { password, ok := parsedDSN.User.Password() Expect(ok).To(BeTrue()) + secret := &corev1.Secret{} + err = k8sClient.Get(ctx, typeNamespacedSecretName, secret) + Expect(err).To(HaveOccurred()) + Expect(client.IgnoreNotFound(err)).To(Succeed()) + + By(fmt.Sprintf("creating master credentials: %s", secretName)) + secret = &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: secretName, + Namespace: "default", + }, + StringData: map[string]string{ + "password": password, + }, + Type: "Opaque", + } + Expect(k8sClient.Create(ctx, secret)).To(Succeed()) + + By("creating master databaseclaims") Expect(client.IgnoreNotFound(err)).To(Succeed()) resource := &persistancev1.DatabaseClaim{ TypeMeta: metav1.TypeMeta{ @@ -78,6 +99,8 @@ var _ = Describe("DatabaseClaim Controller", func() { Namespace: "default", }, Spec: persistancev1.DatabaseClaimSpec{ + // TODO: remove customization of DSNName + DSNName: "fixme.txt", Class: ptr.To(""), DatabaseName: "sample_app", SecretName: secretName, @@ -90,22 +113,14 @@ var _ = Describe("DatabaseClaim Controller", func() { } Expect(k8sClient.Create(ctx, resource)).To(Succeed()) - secret := &corev1.Secret{} - err = k8sClient.Get(ctx, typeNamespacedSecretName, secret) - Expect(err).To(HaveOccurred()) - Expect(client.IgnoreNotFound(err)).To(Succeed()) + By("Mocking master credentials") + hostParams, err := hostparams.New(controllerReconciler.Config.Viper, resource) + Expect(err).ToNot(HaveOccurred()) - secret = &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: secretName, - Namespace: "default", - }, - StringData: map[string]string{ - "password": password, - }, - Type: "Opaque", - } - Expect(k8sClient.Create(ctx, secret)).To(Succeed()) + credSecretName := fmt.Sprintf("%s-%s-%s", env, resourceName, hostParams.Hash()) + + cleanup := dockerdb.MockRDSCredentials(GinkgoT(), ctx, k8sClient, testDSN, credSecretName) + DeferCleanup(cleanup) }) @@ -146,6 +161,42 @@ var _ = Describe("DatabaseClaim Controller", func() { Expect(claim.Status.Error).To(Equal("")) }) + It("Should have DSN and URIDSN keys populated", func() { + By("Reconciling the created resource") + _, err := controllerReconciler.Reconcile(ctx, reconcile.Request{NamespacedName: typeNamespacedName}) + Expect(err).NotTo(HaveOccurred()) + + var claim persistancev1.DatabaseClaim + err = k8sClient.Get(ctx, typeNamespacedName, &claim) + Expect(err).NotTo(HaveOccurred()) + Expect(claim.Status.Error).To(Equal("")) + + By("Checking the user credentials secret") + + secret := &corev1.Secret{} + err = k8sClient.Get(ctx, typeNamespacedSecretName, secret) + Expect(err).NotTo(HaveOccurred()) + + for _, key := range []string{v1.DSNKey, v1.DSNURIKey, "fixme.txt", "uri_fixme.txt"} { + Expect(secret.Data[key]).NotTo(BeNil()) + } + oldKey := secret.Data[v1.DSNKey] + Expect(secret.Data[v1.DSNKey]).To(Equal(secret.Data["fixme.txt"])) + Expect(secret.Data[v1.DSNURIKey]).To(Equal(secret.Data["uri_fixme.txt"])) + // Slow down the test so creds are rotated, 60ns rotation time + By("Rotate passwords and verify credentials are updated") + _, err = controllerReconciler.Reconcile(ctx, reconcile.Request{NamespacedName: typeNamespacedName}) + Expect(err).NotTo(HaveOccurred()) + + err = k8sClient.Get(ctx, typeNamespacedSecretName, secret) + Expect(err).NotTo(HaveOccurred()) + + Expect(secret.Data[v1.DSNKey]).NotTo(Equal(oldKey)) + Expect(secret.Data[v1.DSNKey]).To(Equal(secret.Data["fixme.txt"])) + Expect(secret.Data[v1.DSNURIKey]).To(Equal(secret.Data["uri_fixme.txt"])) + + }) + It("Should succeed with no error status to reconcile CR with DBVersion", func() { By("Updating CR with a DB Version") diff --git a/internal/controller/databasecontroller_migrate_test.go b/internal/controller/databasecontroller_migrate_test.go index 148884e0..c310d947 100644 --- a/internal/controller/databasecontroller_migrate_test.go +++ b/internal/controller/databasecontroller_migrate_test.go @@ -36,6 +36,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/reconcile" persistancev1 "github.com/infobloxopen/db-controller/api/v1" + v1 "github.com/infobloxopen/db-controller/api/v1" "github.com/infobloxopen/db-controller/internal/dockerdb" "github.com/infobloxopen/db-controller/pkg/hostparams" "github.com/infobloxopen/db-controller/pkg/pgctl" @@ -152,7 +153,7 @@ var _ = Describe("claim migrate", func() { Namespace: "default", }, StringData: map[string]string{ - "uri_dsn.txt": testDSN, + v1.DSNURIKey: testDSN, }, Type: "Opaque", } diff --git a/internal/dockerdb/mockdb.go b/internal/dockerdb/mockdb.go index 6e2be8d2..d40eca52 100644 --- a/internal/dockerdb/mockdb.go +++ b/internal/dockerdb/mockdb.go @@ -4,7 +4,6 @@ import ( "context" "database/sql" "net/url" - "strings" . "github.com/onsi/ginkgo/v2" @@ -23,7 +22,16 @@ func MockRDS(t GinkgoTInterface, ctx context.Context, cli client.Client, secretN DockerTag: "15", }) - fakeDSN = strings.Replace(fakeDSN, "localhost", "127.0.0.1", 1) + cleanSecret := MockRDSCredentials(t, ctx, cli, fakeDSN, secretName) + + return dbCli, fakeDSN, func() { + cleanSecret() + clean() + } + +} + +func MockRDSCredentials(t GinkgoTInterface, ctx context.Context, cli client.Client, fakeDSN, secretName string) func() { u, err := url.Parse(fakeDSN) if err != nil { @@ -47,10 +55,9 @@ func MockRDS(t GinkgoTInterface, ctx context.Context, cli client.Client, secretN t.Fatalf("failed to create secret: %v", err) } - return dbCli, fakeDSN, func() { + return func() { if err := cli.Delete(ctx, secret); err != nil { t.Logf("failed to delete secret: %v", err) } - clean() } } diff --git a/internal/dockerdb/testdb.go b/internal/dockerdb/testdb.go index c2a1d9ea..b5ebc5b6 100644 --- a/internal/dockerdb/testdb.go +++ b/internal/dockerdb/testdb.go @@ -282,6 +282,8 @@ CREATE ROLE alloydbsuperuser WITH INHERIT LOGIN`) logger.Info(string(out)) os.Exit(1) } + + dsn = strings.Replace(dsn, "localhost", "127.0.0.1", 1) // TODO: change this to debug logging, just timing jenkins for now logger.Info("db_connected", "dsn", dsn, "duration", time.Since(now)) diff --git a/pkg/databaseclaim/databaseclaim.go b/pkg/databaseclaim/databaseclaim.go index 587f2118..cd4d2790 100644 --- a/pkg/databaseclaim/databaseclaim.go +++ b/pkg/databaseclaim/databaseclaim.go @@ -19,7 +19,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/reconcile" v1 "github.com/infobloxopen/db-controller/api/v1" "github.com/infobloxopen/db-controller/pkg/auth" @@ -146,12 +145,9 @@ func (r *DatabaseClaimReconciler) Reconcile(ctx context.Context, req ctrl.Reques } if err := validateDBClaim(&dbClaim); err != nil { - res, err := r.manageError(ctx, &dbClaim, err) - if dbClaim.Status.Error != "" { - metrics.ErrorStateClaims.Inc() - } - // TerminalError, do not requeue - return res, reconcile.TerminalError(err) + // Validation is weak until all apps are moved to new API + logr.Error(err, "dbclaim_failed_validation") + // FIXME: mark the claim status as error } if dbClaim.Spec.Class == nil { diff --git a/pkg/databaseclaim/secrets.go b/pkg/databaseclaim/secrets.go index 690150bf..c152b237 100644 --- a/pkg/databaseclaim/secrets.go +++ b/pkg/databaseclaim/secrets.go @@ -52,7 +52,7 @@ func (r *DatabaseClaimReconciler) createOrUpdateSecret(ctx context.Context, dbCl return nil } - return r.updateSecret(ctx, dsn, dsnURI, replicaDsnURI, connInfo, gs) + return r.updateSecret(ctx, dbClaim, dsn, dsnURI, replicaDsnURI, connInfo, gs) } func (r *DatabaseClaimReconciler) createSecret(ctx context.Context, dbClaim *v1.DatabaseClaim, dsn, dbURI, replicaDbURI string, connInfo *v1.DatabaseClaimConnectionInfo) error { @@ -88,12 +88,17 @@ func (r *DatabaseClaimReconciler) createSecret(ctx context.Context, dbClaim *v1. "sslmode": []byte(connInfo.SSLMode), }, } + if dbClaim.Spec.DSNName != "" && dbClaim.Spec.DSNName != v1.DSNKey { + secret.Data[dbClaim.Spec.DSNName] = []byte(dsn) + secret.Data["uri_"+dbClaim.Spec.DSNName] = []byte(dbURI) + } + logr.Info("creating connection info SECRET: "+secret.Name, "secret", secret.Name, "namespace", secret.Namespace) return r.Client.Create(ctx, secret) } -func (r *DatabaseClaimReconciler) updateSecret(ctx context.Context, dsn, dbURI, replicaDsnURI string, connInfo *v1.DatabaseClaimConnectionInfo, exSecret *corev1.Secret) error { +func (r *DatabaseClaimReconciler) updateSecret(ctx context.Context, dbClaim *v1.DatabaseClaim, dsn, dbURI, replicaDsnURI string, connInfo *v1.DatabaseClaimConnectionInfo, exSecret *corev1.Secret) error { logr := log.FromContext(ctx) @@ -108,6 +113,11 @@ func (r *DatabaseClaimReconciler) updateSecret(ctx context.Context, dsn, dbURI, exSecret.Data["sslmode"] = []byte(connInfo.SSLMode) logr.Info("updating connection info SECRET: "+exSecret.Name, "secret", exSecret.Name, "namespace", exSecret.Namespace) + if dbClaim.Spec.DSNName != "" && dbClaim.Spec.DSNName != v1.DSNKey { + exSecret.Data[dbClaim.Spec.DSNName] = []byte(dsn) + exSecret.Data["uri_"+dbClaim.Spec.DSNName] = []byte(dbURI) + } + return r.Client.Update(ctx, exSecret) } diff --git a/pkg/databaseclaim/secrets_test.go b/pkg/databaseclaim/secrets_test.go index 776b9c74..6a1226c9 100644 --- a/pkg/databaseclaim/secrets_test.go +++ b/pkg/databaseclaim/secrets_test.go @@ -87,7 +87,19 @@ func TestUpdateSecret(t *testing.T) { Data: make(map[string][]byte), } - err := dbClaimReconciler.updateSecret(ctx, "dsn", "dsnUri", "ro_dsnUri", &claimConnInfo, &secret) + dbClaim := v1.DatabaseClaim{ + TypeMeta: metav1.TypeMeta{}, + ObjectMeta: metav1.ObjectMeta{ + Name: "dbClaim", + Namespace: "testNamespace", + }, + Spec: v1.DatabaseClaimSpec{ + SecretName: "create-master-secret", + }, + Status: v1.DatabaseClaimStatus{}, + } + + err := dbClaimReconciler.updateSecret(ctx, &dbClaim, "dsn", "dsnUri", "ro_dsnUri", &claimConnInfo, &secret) Expect(secret.Data[v1.DSNKey]).To(Equal([]byte("dsn"))) Expect(secret.Data[v1.DSNURIKey]).To(Equal([]byte("dsnUri"))) From a9d87831445137fbb6e86c89f5fe3ac48cbab3d2 Mon Sep 17 00:00:00 2001 From: Drew Wells Date: Tue, 17 Dec 2024 12:58:05 -0600 Subject: [PATCH 3/6] update start-pgbouncer to exit after 60seconds (#379) --- dbproxy/scripts/start-pgbouncer.sh | 71 +++++++++++++++++++++++------- 1 file changed, 55 insertions(+), 16 deletions(-) diff --git a/dbproxy/scripts/start-pgbouncer.sh b/dbproxy/scripts/start-pgbouncer.sh index 227a03bb..39b7fc3b 100755 --- a/dbproxy/scripts/start-pgbouncer.sh +++ b/dbproxy/scripts/start-pgbouncer.sh @@ -5,26 +5,65 @@ set -e command -v pgbouncer set +e -until timeout 10 psql "$(cat /dbproxy/uri_dsn.txt)" -c 'SELECT 1'; do - echo "Waiting for PostgreSQL to be ready..." - sleep 1 -done -echo "PostgreSQL is ready!" +# Function to test PostgreSQL connection +test_postgres() { + local dsn="$1" + if psql "$dsn" -c 'SELECT 1' >/dev/null 2>&1; then + return 0 + fi + return 1 +} +# Function to run all connection tests with global timeout +run_connection_tests() { + local start_time=$(date +%s) + local timeout=60 + local ssl_ok=0 + local nonssl_ok=0 + + while [ $ssl_ok -eq 0 ] || [ $nonssl_ok -eq 0 ]; do + current_time=$(date +%s) + if [ $((current_time - start_time)) -ge $timeout ]; then + echo "Timed out waiting for PostgreSQL after ${timeout} seconds" + return 1 + fi + + if [ $ssl_ok -eq 0 ] && test_postgres "postgres://localhost:5432/?sslmode=require"; then + echo "SSL connection successful" + ssl_ok=1 + fi + + if [ $nonssl_ok -eq 0 ] && test_postgres "postgres://localhost:5432/?sslmode=disable"; then + echo "Non-SSL connection successful" + nonssl_ok=1 + fi + + if [ $ssl_ok -eq 0 ] || [ $nonssl_ok -eq 0 ]; then + echo "Waiting for PostgreSQL connections to be ready..." + sleep 2 + fi + done + return 0 +} + +# Initial PostgreSQL check +if ! test_postgres "$(cat /dbproxy/uri_dsn.txt)"; then + echo "Initial PostgreSQL connection failed" + exit 1 +fi +echo "Initial PostgreSQL connection successful!" + +# Generate certificates openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout dbproxy-server.key -out dbproxy-server.crt -subj "/C=US/CN=dbproxy-server/ST=CA/L=Santa Clara/O=Infoblox/OU=Blox in a Box" openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout dbproxy-client.key -out dbproxy-client.crt -subj "/C=US/CN=dbproxy-client/ST=CA/L=Santa Clara/O=Infoblox/OU=Blox in a Box" +# Start pgbouncer pgbouncer -d -v pgbouncer.ini -# Test that both SSL and non-SSL connections work -until timeout 10 psql postgres://localhost:5432/?sslmode=require -c 'SELECT 1'; do - echo "Waiting for PostgreSQL to be ready..." - sleep 1 -done - -until timeout 10 psql postgres://localhost:5432/?sslmode=disable -c 'SELECT 1'; do - echo "Waiting for PostgreSQL to be ready..." - sleep 1 -done +# Test both SSL and non-SSL connections concurrently +if ! run_connection_tests; then + echo "Connection tests failed" + exit 1 +fi -echo "PostgreSQL is ready!" +echo "All PostgreSQL connections are ready!" From 5d9094f476cb969e883b97e861f3d9587f7e0a66 Mon Sep 17 00:00:00 2001 From: Drew Wells Date: Wed, 18 Dec 2024 07:37:13 -0600 Subject: [PATCH 4/6] DEVOPS-30046 DEVOPS-30239 dsnexec conversion injects dbproxy (#381) A bug in the conversion webhook added dbproxy mutating labels when only dsnexec was requested. This would cause issues if the pod could not handle dbproxy listening on port 5432. --- internal/webhook/conversion.go | 59 ++++++++++++++++++----------- internal/webhook/conversion_test.go | 40 +++++++++---------- internal/webhook/defaulter.go | 2 +- scripts/check-sidecars.sh | 28 ++++++++++++++ scripts/psql-open.sh | 12 ++++-- 5 files changed, 95 insertions(+), 46 deletions(-) create mode 100755 scripts/check-sidecars.sh diff --git a/internal/webhook/conversion.go b/internal/webhook/conversion.go index dcfc795e..05c3283e 100644 --- a/internal/webhook/conversion.go +++ b/internal/webhook/conversion.go @@ -17,10 +17,13 @@ import ( ) var ( + // DSNExec annotations DeprecatedAnnotationDSNExecConfig = "infoblox.com/dsnexec-config-secret" DeprecatedAnnotationRemoteDBDSN = "infoblox.com/remote-db-dsn-secret" - DeprecatedAnnotationDBSecretPath = "infoblox.com/db-secret-path" - DeprecatedAnnotationMessages = "persistance.atlas.infoblox.com/deprecation-messages" + // DBProxy annotations + DeprecatedAnnotationDBSecretPath = "infoblox.com/db-secret-path" + + DeprecatedAnnotationMessages = "persistance.atlas.infoblox.com/deprecation-messages" ) // +kubebuilder:webhook:path=/convert-deprecated-pod,mutating=true,failurePolicy=fail,groups="",resources=pods,verbs=create;update,versions=v1,name=podconversion.persistance.atlas.infoblox.com,sideEffects=None,timeoutSeconds=10,admissionReviewVersions=v1 @@ -94,10 +97,18 @@ func (p *podConverter) Handle(ctx context.Context, req admission.Request) admiss } // Check if any of the deprecated annotations are present + // dsnexec dsnExecConfigSecret := pod.Annotations[DeprecatedAnnotationDSNExecConfig] remoteDBDSNSecret := pod.Annotations[DeprecatedAnnotationRemoteDBDSN] + // dbproxy dbSecretPath := pod.Annotations[DeprecatedAnnotationDBSecretPath] + if pod.Labels[LabelCheckExec] == "enabled" || pod.Labels[LabelCheckProxy] == "enabled" { + // This would log on every pod creation in the cluster + // log.V(1).Info("Skipped conversion, already converted", "uid", req.UID) + return admission.Allowed("Skipped conversion, already converted") + } + if dsnExecConfigSecret == "" && remoteDBDSNSecret == "" && dbSecretPath == "" { // This would log on every pod creation in the cluster // log.V(1).Info("Skipped conversion, no deprecated annotations found", "uid", req.UID) @@ -112,7 +123,7 @@ func (p *podConverter) Handle(ctx context.Context, req admission.Request) admiss if err != nil { return admission.Errored(http.StatusInternalServerError, err) } - log.Info("converted_pod") + log.Info("deprecated_pod_annotations_found") return admission.PatchResponseFromRaw(req.Object.Raw, bs) } @@ -139,7 +150,9 @@ func convertPod(ctx context.Context, reader client.Reader, class string, pod *co secretName = dbSecretPath } - log = log.WithValues("secret", secretName) + log = log.WithValues("secret", secretName).WithValues("annotations", pod.Annotations).WithValues("labels", pod.Labels) + + log.Info("converting_pod") // db-secret-path has a key in it, so remove the key parts := strings.Split(secretName, "/") @@ -147,33 +160,35 @@ func convertPod(ctx context.Context, reader client.Reader, class string, pod *co secretName = parts[0] } - labelConfigExec := pod.Labels[LabelConfigExec] - if labelConfigExec == "" && dsnExecConfigSecret != "" { - pod.Labels[LabelConfigExec] = pod.Annotations[DeprecatedAnnotationDSNExecConfig] - pod.Labels[LabelCheckExec] = "enabled" - deprecationMsgs = append(deprecationMsgs, fmt.Sprintf(`Label "%s" replaces annotation "%s"`, LabelConfigExec, DeprecatedAnnotationDSNExecConfig)) + var claimName string + var err error + if claimName, err = getClaimName(ctx, reader, pod.GetNamespace(), secretName); err != nil { + log.Error(err, "unable to find claim") + return err } - // Process claims label - if pod.Labels[LabelClaim] == "" { + // dsnexec + if dsnExecConfigSecret != "" && remoteDBDSNSecret != "" { + pod.Labels[LabelClaim] = claimName + pod.Labels[LabelClass] = class + pod.Labels[LabelConfigExec] = dsnExecConfigSecret + pod.Labels[LabelCheckExec] = "enabled" - if pod.Annotations[DeprecatedAnnotationRemoteDBDSN] != "" { - deprecationMsgs = append(deprecationMsgs, fmt.Sprintf(`Label "%s" replaces annotation "%s"`, LabelClaim, DeprecatedAnnotationRemoteDBDSN)) - } - if pod.Annotations[DeprecatedAnnotationDBSecretPath] != "" { - deprecationMsgs = append(deprecationMsgs, fmt.Sprintf(`Label "%s" replaces annotation "%s"`, LabelClaim, DeprecatedAnnotationDBSecretPath)) - } + deprecationMsgs = append(deprecationMsgs, fmt.Sprintf(`Use label "%s", annotation "%s" is deprecated`, LabelConfigExec, DeprecatedAnnotationDSNExecConfig)) - var claimName string - var err error - if claimName, err = getClaimName(ctx, reader, pod.GetNamespace(), secretName); err != nil { - log.Error(err, "unable to find claim") - return err + if pod.Annotations[DeprecatedAnnotationRemoteDBDSN] != "" { + deprecationMsgs = append(deprecationMsgs, fmt.Sprintf(`Use label "%s", annotation "%s" is deprecated`, LabelClaim, DeprecatedAnnotationRemoteDBDSN)) } + } + // dbproxy + if dbSecretPath != "" { pod.Labels[LabelClaim] = claimName pod.Labels[LabelClass] = class pod.Labels[LabelCheckProxy] = "enabled" + + deprecationMsgs = append(deprecationMsgs, fmt.Sprintf(`Label "%s" replaces annotation "%s"`, LabelClaim, DeprecatedAnnotationDBSecretPath)) + } // Remove deprecated annotations diff --git a/internal/webhook/conversion_test.go b/internal/webhook/conversion_test.go index c0007403..0abc393a 100644 --- a/internal/webhook/conversion_test.go +++ b/internal/webhook/conversion_test.go @@ -96,15 +96,16 @@ var _ = Describe("annotation conversions", func() { It("should convert deprecated pod", func() { - By("Check dbproxy pod is mutated") + By("Check deprecated dbproxy annotations are converted to labels") name := "deprecated-dbproxy" pod := makeConvertedPod(name, class, dbcSecretName, "") Expect(pod.Annotations).To(HaveKey(DeprecatedAnnotationMessages)) Expect(pod.Labels).To(HaveKeyWithValue(LabelClaim, dbcName)) Expect(pod.Labels).To(HaveKeyWithValue(LabelCheckProxy, "enabled")) Expect(pod.Labels).To(HaveKeyWithValue(LabelClass, class)) + Expect(pod.Labels).ToNot(HaveKey(LabelConfigExec)) - By("Check dsnexec pod is converted") + By("Check dsnexec annotations are converted to labels") name = "deprecated-dsnexec" pod = makeConvertedPod(name, class, dbcSecretName, configSecretName) Expect(pod.Annotations).To(HaveKey(DeprecatedAnnotationMessages)) @@ -112,14 +113,16 @@ var _ = Describe("annotation conversions", func() { Expect(pod.Labels).To(HaveKeyWithValue(LabelConfigExec, configSecretName)) Expect(pod.Labels).To(HaveKeyWithValue(LabelCheckExec, "enabled")) Expect(pod.Labels).To(HaveKeyWithValue(LabelClass, class)) + Expect(pod.Labels).ToNot(HaveKey(LabelCheckProxy)) - By("Check dbproxy dsnexec combo pod is converted") + By("Check dbproxy dsnexec combo annotations are converted to labels") name = "deprecated-both" pod = makeConvertedPod(name, class, dbcSecretName, configSecretName) Expect(pod.Annotations).To(HaveKey(DeprecatedAnnotationMessages)) Expect(pod.Labels).To(HaveKeyWithValue(LabelClaim, dbcName)) Expect(pod.Labels).To(HaveKeyWithValue(LabelConfigExec, configSecretName)) Expect(pod.Labels).To(HaveKeyWithValue(LabelCheckProxy, "enabled")) + Expect(pod.Labels).To(HaveKeyWithValue(LabelCheckExec, "enabled")) Expect(pod.Labels).To(HaveKeyWithValue(LabelClass, class)) }) @@ -173,31 +176,28 @@ func makeDeprecatedPod(name, secretName, configSecret string) *corev1.Pod { }, }, } + if pod.Annotations == nil { + pod.Annotations = map[string]string{} + } + if pod.Labels == nil { + pod.Labels = map[string]string{} + } Expect(secretName).NotTo(BeEmpty()) - switch name { case "deprecated-dbproxy": - pod.Annotations = map[string]string{ - DeprecatedAnnotationDBSecretPath: secretName + "/" + "dsn.txt", - } + pod.Annotations[DeprecatedAnnotationDBSecretPath] = secretName + "/" + "dsn.txt" + case "deprecated-both": - pod.Annotations = map[string]string{ - DeprecatedAnnotationDBSecretPath: secretName + "/" + "dsn.txt", - } + pod.Annotations[DeprecatedAnnotationDBSecretPath] = secretName + "/" + "dsn.txt" fallthrough case "deprecated-dsnexec": Expect(configSecret).NotTo(BeEmpty()) - pod.Annotations = map[string]string{ - DeprecatedAnnotationRemoteDBDSN: secretName, - DeprecatedAnnotationDSNExecConfig: configSecret, - } + + pod.Annotations[DeprecatedAnnotationRemoteDBDSN] = secretName + pod.Annotations[DeprecatedAnnotationDSNExecConfig] = configSecret case "deprecated-converted": - pod.Annotations = map[string]string{ - DeprecatedAnnotationDBSecretPath: secretName + "/" + "dsn.txt", - } - pod.Labels = map[string]string{ - LabelConfigExec: "default-db", - } + pod.Annotations[DeprecatedAnnotationDBSecretPath] = secretName + "/" + "dsn.txt" + pod.Labels[LabelConfigExec] = "default-db" case "deprecated-none": } diff --git a/internal/webhook/defaulter.go b/internal/webhook/defaulter.go index 34bb7b57..9ae70c81 100644 --- a/internal/webhook/defaulter.go +++ b/internal/webhook/defaulter.go @@ -91,12 +91,12 @@ func (p *podAnnotator) Default(ctx context.Context, obj runtime.Object) error { } log := logf.FromContext(ctx).WithName("defaulter").WithValues("pod", nn) - log.Info("processing") if pod.Labels == nil || len(pod.Labels[LabelClaim]) == 0 { log.Info("Skipping Pod") return nil } + log.Info("processing") claimName := pod.Labels[LabelClaim] diff --git a/scripts/check-sidecars.sh b/scripts/check-sidecars.sh new file mode 100755 index 00000000..30b0fe3c --- /dev/null +++ b/scripts/check-sidecars.sh @@ -0,0 +1,28 @@ +#!/bin/bash -x + + +# Optional namespace argument +namespace_filter=${1:-} + +# Determine the kubectl command based on whether a namespace filter is provided +if [[ -n "$namespace_filter" ]]; then + echo "Filtering by namespace: $namespace_filter" + kubectl_command="kubectl -n $namespace_filter get pods -l persistance.atlas.infoblox.com/dbproxy -o=jsonpath='{range .items[*]}{.metadata.namespace} {.metadata.name}{\"\\n\"}{end}'" +else + echo "Checking all namespaces" + kubectl_command="kubectl -A get pods -l persistance.atlas.infoblox.com/dbproxy -o=jsonpath='{range .items[*]}{.metadata.namespace} {.metadata.name}{\"\\n\"}{end}'" +fi + +# Get the pods +pods=$(eval "$kubectl_command") + +# Iterate over each pod and run the psql command +while read -r namespace pod; do + echo "Processing pod $pod in namespace $namespace" + + # Execute the SELECT 1 command and capture output + kubectl -n "$namespace" -c dbproxy exec "$pod" -- sh -c "psql \$(cat /dbproxy/uri_dsn.txt) -c 'SELECT 1'" + kubectl -n "$namespace" -c dbproxy exec "$pod" -- sh -c "cat /run/dbproxy/pgbouncer.ini" + kubectl -n "$namespace" -c dbproxy exec "$pod" -- sh -c "cat /run/dbproxy/userlist.txt" + +done <<< "$pods" diff --git a/scripts/psql-open.sh b/scripts/psql-open.sh index bbd41929..cb0cd7b4 100755 --- a/scripts/psql-open.sh +++ b/scripts/psql-open.sh @@ -19,8 +19,14 @@ open_psql() { secret_name=$(kubectl get databaseclaim "$claim_name" -n "$namespace" -o jsonpath='{.spec.secretName}') if [[ -z "$secret_name" ]]; then - echo "Error: Unable to find secret name for $claim_name in namespace $namespace" - return 1 + + secret_name=$(kubectl get dbroleclaim "$claim_name" -n "$namespace" -o jsonpath='{.spec.secretName}') + if [[ -z "$secret_name" ]]; then + echo "Error: Unable to find secret name for dbc: $claim_name in namespace $namespace" + echo "Error: Unable to find secret name for dbroleclaim: $claim_name in namespace $namespace" + return 1 + fi + fi # Get the DSN from the secret @@ -31,7 +37,7 @@ open_psql() { return 1 fi - printf "DatabaseClaim: %s/%s\n" "$namespace" "$claim_name" + printf "Claim: %s/%s\n" "$namespace" "$claim_name" # If a psql command is provided, execute it; otherwise, open a psql prompt if [[ -n "$psql_command" ]]; then kubectl exec deploy/db-controller -c manager -n db-controller -- psql "$dsn" -c "$psql_command" From cb8d04004c8497e2ca5b20a748fe56a002c1e4f2 Mon Sep 17 00:00:00 2001 From: bfabricio Date: Mon, 23 Dec 2024 13:17:16 -0300 Subject: [PATCH 5/6] fix db claim controller test after merge --- .../databaseclaim_controller_test.go | 232 ++++++++++-------- .../databasecontroller_migrate_test.go | 2 +- 2 files changed, 126 insertions(+), 108 deletions(-) diff --git a/internal/controller/databaseclaim_controller_test.go b/internal/controller/databaseclaim_controller_test.go index 9314600f..a14357b3 100644 --- a/internal/controller/databaseclaim_controller_test.go +++ b/internal/controller/databaseclaim_controller_test.go @@ -21,6 +21,7 @@ import ( "fmt" "net/url" + "github.com/infobloxopen/db-controller/internal/dockerdb" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -32,102 +33,77 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/reconcile" - persistancev1 "github.com/infobloxopen/db-controller/api/v1" v1 "github.com/infobloxopen/db-controller/api/v1" - "github.com/infobloxopen/db-controller/internal/dockerdb" "github.com/infobloxopen/db-controller/pkg/hostparams" ) var _ = Describe("DatabaseClaim Controller", func() { - // Define utility constants for object names and testing timeouts/durations and intervals. - Context("When updating DB Claim Status", func() { - - const resourceName = "test-dbclaim" - const secretName = "postgres-postgresql" - - ctx := context.Background() - typeNamespacedName := types.NamespacedName{ - Name: resourceName, - Namespace: "default", // TODO(user):Modify as needed - } - typeNamespacedSecretName := types.NamespacedName{ - Name: secretName, - Namespace: "default", // TODO(user):Modify as needed - } - claim := &persistancev1.DatabaseClaim{} - - BeforeEach(func() { - - By("ensuring the resource does not exist") - Expect(k8sClient.Get(ctx, typeNamespacedName, claim)).To(HaveOccurred()) - - By(fmt.Sprintf("Creating dbc: %s", resourceName)) + const ( + resourceName = "test-dbclaim" + secretName = "postgres-postgresql" + namespace = "default" + databaseName = "test-db" + databaseType = "postgres" + ) + var ( + ctx = context.Background() + typeNamespacedName = types.NamespacedName{Name: resourceName, Namespace: namespace} + typeNamespacedSecretName = types.NamespacedName{Name: secretName, Namespace: namespace} + claim = &v1.DatabaseClaim{} + ) + + createDatabaseClaim := func() { parsedDSN, err := url.Parse(testDSN) Expect(err).NotTo(HaveOccurred()) - password, ok := parsedDSN.User.Password() - Expect(ok).To(BeTrue()) - - secret := &corev1.Secret{} - err = k8sClient.Get(ctx, typeNamespacedSecretName, secret) - Expect(err).To(HaveOccurred()) - Expect(client.IgnoreNotFound(err)).To(Succeed()) - - By(fmt.Sprintf("creating master credentials: %s", secretName)) - secret = &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: secretName, - Namespace: "default", - }, - StringData: map[string]string{ - "password": password, - }, - Type: "Opaque", - } - Expect(k8sClient.Create(ctx, secret)).To(Succeed()) - - By("creating master databaseclaims") - Expect(client.IgnoreNotFound(err)).To(Succeed()) - resource := &persistancev1.DatabaseClaim{ + resource := &v1.DatabaseClaim{ TypeMeta: metav1.TypeMeta{ APIVersion: "persistance.atlas.infoblox.com/v1", Kind: "DatabaseClaim", }, ObjectMeta: metav1.ObjectMeta{ Name: resourceName, - Namespace: "default", + Namespace: namespace, }, - Spec: persistancev1.DatabaseClaimSpec{ - // TODO: remove customization of DSNName + Spec: v1.DatabaseClaimSpec{ DSNName: "fixme.txt", Class: ptr.To(""), - DatabaseName: "sample_app", + DatabaseName: databaseName, SecretName: secretName, Username: parsedDSN.User.Username(), EnableSuperUser: ptr.To(false), EnableReplicationRole: ptr.To(false), UseExistingSource: ptr.To(false), - Type: "postgres", + Type: databaseType, }, } Expect(k8sClient.Create(ctx, resource)).To(Succeed()) + } - By("Mocking master credentials") - hostParams, err := hostparams.New(controllerReconciler.Config.Viper, resource) - Expect(err).ToNot(HaveOccurred()) + BeforeEach(func() { + By("Verify environment") + viper := controllerReconciler.Config.Viper + Expect(viper.Get("env")).To(Equal(env)) - credSecretName := fmt.Sprintf("%s-%s-%s", env, resourceName, hostParams.Hash()) + By("Ensuring the resource does not exist") + Expect(k8sClient.Get(ctx, typeNamespacedName, claim)).To(HaveOccurred()) + + By(fmt.Sprintf("Creating DatabaseClaim: %s", resourceName)) + createDatabaseClaim() + By("Mocking master credentials") + Expect(k8sClient.Get(ctx, typeNamespacedName, claim)).To(Succeed()) + hostParams, err := hostparams.New(controllerReconciler.Config.Viper, claim) + Expect(err).NotTo(HaveOccurred()) + credSecretName := fmt.Sprintf("%s-%s-%s", env, resourceName, hostParams.Hash()) cleanup := dockerdb.MockRDSCredentials(GinkgoT(), ctx, k8sClient, testDSN, credSecretName) DeferCleanup(cleanup) - }) AfterEach(func() { - // TODO(user): Cleanup logic after each test, like removing the resource instance. By("Cleanup the specific resource instance DatabaseClaim") - resource := &persistancev1.DatabaseClaim{} + resource := &v1.DatabaseClaim{} err := k8sClient.Get(ctx, typeNamespacedName, resource) Expect(err).ToNot(HaveOccurred()) @@ -141,24 +117,43 @@ var _ = Describe("DatabaseClaim Controller", func() { Expect(err).To(HaveOccurred()) Expect(client.IgnoreNotFound(err)).To(Succeed()) + By("Cleanup DbClaim associated secret") secret := &corev1.Secret{} err = k8sClient.Get(ctx, typeNamespacedSecretName, secret) - Expect(err).NotTo(HaveOccurred()) - By("Cleanup the database secret") + // this secret is created without resource owner, so it does not get deleted after dbclain is deleted Expect(k8sClient.Delete(ctx, secret)).To(Succeed()) - }) It("Should succeed to reconcile DB Claim missing dbVersion", func() { - By("Verify environment") - viper := controllerReconciler.Config.Viper - Expect(viper.Get("env")).To(Equal(env)) + By("Verify that the DB Claim has not active DB yet and spec.DbVersion is empty") + resource := &v1.DatabaseClaim{} + Expect(k8sClient.Get(ctx, typeNamespacedName, resource)).To(Succeed()) + Expect(resource.Status.ActiveDB.DbCreatedAt).To(BeNil()) + Expect(resource.Spec.DBVersion).To(BeEmpty()) By("Reconciling the created resource") - _, err := controllerReconciler.Reconcile(ctx, reconcile.Request{NamespacedName: typeNamespacedName}) Expect(err).NotTo(HaveOccurred()) - Expect(claim.Status.Error).To(Equal("")) + + By("Verify that the DB Claim has active DB with default Version") + reconciledClaim := &v1.DatabaseClaim{} + Expect(k8sClient.Get(ctx, typeNamespacedName, reconciledClaim)).To(Succeed()) + Expect(reconciledClaim.Status.Error).To(Equal("")) + // default major version (spec version, no active DB) + + activeDb := reconciledClaim.Status.ActiveDB + Expect(activeDb.DBVersion).To(Equal("15")) + Expect(activeDb.DbState).To(Equal(v1.Ready)) + Expect(activeDb.SourceDataFrom).To(BeNil()) + + By("Validating timestamps in ActiveDB") + Expect(activeDb.DbCreatedAt).NotTo(BeNil()) + Expect(activeDb.ConnectionInfoUpdatedAt).NotTo(BeNil()) + Expect(activeDb.UserUpdatedAt).NotTo(BeNil()) + + By("Validating ConnectionInfo") + connectionInfo := activeDb.ConnectionInfo + Expect(connectionInfo).NotTo(BeNil()) }) It("Should have DSN and URIDSN keys populated", func() { @@ -166,13 +161,11 @@ var _ = Describe("DatabaseClaim Controller", func() { _, err := controllerReconciler.Reconcile(ctx, reconcile.Request{NamespacedName: typeNamespacedName}) Expect(err).NotTo(HaveOccurred()) - var claim persistancev1.DatabaseClaim - err = k8sClient.Get(ctx, typeNamespacedName, &claim) + err = k8sClient.Get(ctx, typeNamespacedName, claim) Expect(err).NotTo(HaveOccurred()) Expect(claim.Status.Error).To(Equal("")) By("Checking the user credentials secret") - secret := &corev1.Secret{} err = k8sClient.Get(ctx, typeNamespacedSecretName, secret) Expect(err).NotTo(HaveOccurred()) @@ -194,58 +187,70 @@ var _ = Describe("DatabaseClaim Controller", func() { Expect(secret.Data[v1.DSNKey]).NotTo(Equal(oldKey)) Expect(secret.Data[v1.DSNKey]).To(Equal(secret.Data["fixme.txt"])) Expect(secret.Data[v1.DSNURIKey]).To(Equal(secret.Data["uri_fixme.txt"])) - }) It("Should succeed with no error status to reconcile CR with DBVersion", func() { - By("Updating CR with a DB Version") - - resource := &persistancev1.DatabaseClaim{} - Expect(k8sClient.Get(ctx, typeNamespacedName, resource)).NotTo(HaveOccurred()) + By("Updating the DatabaseClaim resource with a DB Version 13.3") + resource := &v1.DatabaseClaim{} + Expect(k8sClient.Get(ctx, typeNamespacedName, resource)).To(Succeed()) + Expect(resource.Status.ActiveDB.DbCreatedAt).To(BeNil()) resource.Spec.DBVersion = "13.3" - Expect(k8sClient.Update(ctx, resource)).NotTo(HaveOccurred()) + Expect(k8sClient.Update(ctx, resource)).To(Succeed()) - Expect(k8sClient.Get(ctx, typeNamespacedName, resource)).NotTo(HaveOccurred()) - Expect(resource.Spec.DBVersion).To(Equal("13.3")) + By("Mocking RDS master credentials") + hostParams, err := hostparams.New(controllerReconciler.Config.Viper, resource) + Expect(err).ToNot(HaveOccurred()) - _, err := controllerReconciler.Reconcile(ctx, reconcile.Request{NamespacedName: typeNamespacedName}) - Expect(err).NotTo(HaveOccurred()) - Expect(resource.Status.Error).To(Equal("")) + // given db version changed, we need to mock master creds again as the hash changed + credSecretName := fmt.Sprintf("%s-%s-%s", env, resourceName, hostParams.Hash()) + cleanup := dockerdb.MockRDSCredentials(GinkgoT(), ctx, k8sClient, testDSN, credSecretName) + DeferCleanup(cleanup) - var instance crossplaneaws.DBInstance - viper := controllerReconciler.Config.Viper - hostParams, err := hostparams.New(viper, resource) + By("Reconciling the updated resource") + _, err = controllerReconciler.Reconcile(ctx, reconcile.Request{NamespacedName: typeNamespacedName}) Expect(err).ToNot(HaveOccurred()) + Expect(resource.Status.Error).To(BeEmpty()) - instanceName := fmt.Sprintf("%s-%s-%s", env, resourceName, hostParams.Hash()) - - By(fmt.Sprintf("Check dbinstance is created: %s", instanceName)) + By(fmt.Sprintf("Verifying that the DBInstance is created: %s", credSecretName)) + var instance crossplaneaws.DBInstance Eventually(func() error { - return k8sClient.Get(ctx, types.NamespacedName{Name: instanceName}, &instance) + return k8sClient.Get(ctx, types.NamespacedName{Name: credSecretName}, &instance) }).Should(Succeed()) - }) - - It("Should succeed with no error status to reconcile CR with DBVersion", func() { - By("Updating CR with a DB Version") - - resource := &persistancev1.DatabaseClaim{} - Expect(k8sClient.Get(ctx, typeNamespacedName, resource)).NotTo(HaveOccurred()) - resource.Spec.DBVersion = "13.3" - Expect(k8sClient.Update(ctx, resource)).NotTo(HaveOccurred()) - - Expect(k8sClient.Get(ctx, typeNamespacedName, resource)).NotTo(HaveOccurred()) - Expect(resource.Spec.DBVersion).To(Equal("13.3")) - - _, err := controllerReconciler.Reconcile(ctx, reconcile.Request{NamespacedName: typeNamespacedName}) - Expect(err).NotTo(HaveOccurred()) - Expect(resource.Status.Error).To(Equal("")) + By("Verifying that the DBInstance is updated") + var reconciledClaim v1.DatabaseClaim + Expect(k8sClient.Get(ctx, typeNamespacedName, &reconciledClaim)).NotTo(HaveOccurred()) + Expect(reconciledClaim.Status.Error).To(Equal("")) + + By("Validating the fields in ActiveDB") + activeDB := reconciledClaim.Status.ActiveDB + Expect(activeDB.Shape).To(Equal(hostParams.Shape)) + Expect(string(activeDB.Type)).To(Equal(hostParams.Type)) + Expect(activeDB.MinStorageGB).To(Equal(hostParams.MinStorageGB)) + Expect(activeDB.MaxStorageGB).To(Equal(hostParams.MaxStorageGB)) + + Expect(activeDB.DBVersion).To(Equal(resource.Spec.DBVersion)) + Expect(activeDB.Shape).To(Equal(*instance.Spec.ForProvider.DBInstanceClass)) + Expect(string(activeDB.Type)).To(Equal(*instance.Spec.ForProvider.Engine)) + Expect(int64(activeDB.MinStorageGB)).To(Equal(*instance.Spec.ForProvider.AllocatedStorage)) + + Expect(activeDB.DbState).To(Equal(v1.Ready)) + Expect(activeDB.SourceDataFrom).To(BeNil()) + + By("Validating timestamps in ActiveDB") + Expect(activeDB.DbCreatedAt).NotTo(BeNil()) + Expect(activeDB.ConnectionInfoUpdatedAt).NotTo(BeNil()) + Expect(activeDB.UserUpdatedAt).NotTo(BeNil()) + + By("Validating ConnectionInfo") + connectionInfo := activeDB.ConnectionInfo + Expect(connectionInfo).NotTo(BeNil()) }) It("Should propagate labels from DatabaseClaim to DBInstance", func() { By("Updating CR with labels") - resource := &persistancev1.DatabaseClaim{} + resource := &v1.DatabaseClaim{} Expect(k8sClient.Get(ctx, typeNamespacedName, resource)).NotTo(HaveOccurred()) resource.Labels = map[string]string{ @@ -272,5 +277,18 @@ var _ = Describe("DatabaseClaim Controller", func() { Expect(instance.ObjectMeta.Labels).To(Equal(resource.Labels)) }) + + It("Should fail to reconcile a newDB if secret is present", func() { + By(fmt.Sprintf("creating secret: %s", secretName)) + secret := &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: secretName, + Namespace: "default", + }, + } + Expect(k8sClient.Create(ctx, secret)).To(Succeed()) + _, err := controllerReconciler.Reconcile(ctx, reconcile.Request{NamespacedName: typeNamespacedName}) + Expect(err).To(HaveOccurred()) + }) }) }) diff --git a/internal/controller/databasecontroller_migrate_test.go b/internal/controller/databasecontroller_migrate_test.go index c310d947..0142f341 100644 --- a/internal/controller/databasecontroller_migrate_test.go +++ b/internal/controller/databasecontroller_migrate_test.go @@ -70,7 +70,7 @@ var _ = Describe("claim migrate", func() { // secret to store the dsn for claims const claimSecretName = "migrate-dbclaim-creds" // master creds to source db - const sourceSecretName = "postgres-source" + const sourceSecretName = "postgres-source-migrate" // master creds to target db // const targetSecretName = "postgres-target" From 7c4274455aefdcbcfaa144cab2725f71bc83e071 Mon Sep 17 00:00:00 2001 From: bfabricio Date: Mon, 23 Dec 2024 13:49:59 -0300 Subject: [PATCH 6/6] fix bug related to #377 after merge main --- pkg/databaseclaim/databaseclaim.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/databaseclaim/databaseclaim.go b/pkg/databaseclaim/databaseclaim.go index 835cc14b..c2fdd8d7 100644 --- a/pkg/databaseclaim/databaseclaim.go +++ b/pkg/databaseclaim/databaseclaim.go @@ -1128,7 +1128,7 @@ func (r *DatabaseClaimReconciler) createDatabaseAndExtensions(ctx context.Contex func (r *DatabaseClaimReconciler) manageUserAndExtensions(ctx context.Context, reqInfo *requestInfo, logger logr.Logger, dbClient dbclient.Clienter, dbClaim *v1.DatabaseClaim, operationalMode ModeEnum) error { - status := dbClaim.Status.NewDB + status := &dbClaim.Status.NewDB dbName := dbClaim.Spec.DatabaseName baseUsername := dbClaim.Spec.Username @@ -1169,7 +1169,7 @@ func (r *DatabaseClaimReconciler) manageUserAndExtensions(ctx context.Context, r if err := dbClient.UpdateUser(oldUsername+dbuser.SuffixA, dbu.GetUserA(), baseUsername, userPassword); err != nil { return err } - r.statusManager.UpdateUserStatus(&status, reqInfo, dbu.GetUserA(), userPassword) + r.statusManager.UpdateUserStatus(status, reqInfo, dbu.GetUserA(), userPassword) // updating user b userPassword, err = r.generatePassword() if err != nil { @@ -1200,7 +1200,7 @@ func (r *DatabaseClaimReconciler) manageUserAndExtensions(ctx context.Context, r return err } - r.statusManager.UpdateUserStatus(&status, reqInfo, nextUser, userPassword) + r.statusManager.UpdateUserStatus(status, reqInfo, nextUser, userPassword) } // baseUsername = myuser