Skip to content

Commit

Permalink
Merge branch 'main' into PTEUDO-2363
Browse files Browse the repository at this point in the history
  • Loading branch information
bfabricio committed Feb 27, 2025
2 parents b943fd1 + f241a7f commit fc52c08
Show file tree
Hide file tree
Showing 7 changed files with 225 additions and 88 deletions.
101 changes: 79 additions & 22 deletions internal/controller/databaseclaim_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,9 @@ package controller
import (
"context"
"fmt"
"net/url"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"net/url"

crossplaneaws "github.com/crossplane-contrib/provider-aws/apis/rds/v1alpha1"
corev1 "k8s.io/api/core/v1"
Expand Down Expand Up @@ -125,7 +124,7 @@ var _ = Describe("DatabaseClaim Controller", func() {
secret := &corev1.Secret{}
err = k8sClient.Get(ctx, typeNamespacedSecretName, 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())
k8sClient.Delete(ctx, secret)
})

It("Should succeed to reconcile DB Claim missing dbVersion", func() {
Expand All @@ -137,6 +136,17 @@ var _ = Describe("DatabaseClaim Controller", func() {

By("Reconciling the created resource")
_, err := controllerReconciler.Reconcile(ctx, reconcile.Request{NamespacedName: typeNamespacedName})
Expect(err).ToNot(HaveOccurred())

By("Mocking crossplane instance readiness")
hostParams, err := hostparams.New(controllerReconciler.Config.Viper, resource)
Expect(err).ToNot(HaveOccurred())
awsRes := &crossplaneaws.DBInstance{}
awsRes.SetName(env + "-" + resourceName + "-" + hostParams.Hash())
Expect(patchCrossplaneCRReadiness(ctx, k8sClient, awsRes)).NotTo(HaveOccurred())

By("Reconciling the created resource")
_, err = controllerReconciler.Reconcile(ctx, reconcile.Request{NamespacedName: typeNamespacedName})
Expect(err).NotTo(HaveOccurred())

By("Verify that the DB Claim has active DB with default Version")
Expand Down Expand Up @@ -169,6 +179,16 @@ var _ = Describe("DatabaseClaim Controller", func() {
Expect(err).NotTo(HaveOccurred())
Expect(claim.Status.Error).To(Equal(""))

By("Mocking crossplane instance readiness")
hostParams, err := hostparams.New(controllerReconciler.Config.Viper, claim)
Expect(err).ToNot(HaveOccurred())
awsRes := &crossplaneaws.DBInstance{}
awsRes.SetName(env + "-" + resourceName + "-" + hostParams.Hash())
Expect(patchCrossplaneCRReadiness(ctx, k8sClient, awsRes)).NotTo(HaveOccurred())

_, err = controllerReconciler.Reconcile(ctx, reconcile.Request{NamespacedName: typeNamespacedName})
Expect(err).NotTo(HaveOccurred())

By("Checking the user credentials secret")
secret := &corev1.Secret{}
err = k8sClient.Get(ctx, typeNamespacedSecretName, secret)
Expand Down Expand Up @@ -203,8 +223,17 @@ var _ = Describe("DatabaseClaim Controller", func() {
Expect(err).NotTo(HaveOccurred())
Expect(claim.Status.Error).To(Equal(""))

By("Checking the user credentials secret")
By("Mocking crossplane instance readiness")
hostParams, err := hostparams.New(controllerReconciler.Config.Viper, &claim)
Expect(err).ToNot(HaveOccurred())
awsRes := &crossplaneaws.DBInstance{}
awsRes.SetName(env + "-" + resourceName + "-" + hostParams.Hash())
Expect(patchCrossplaneCRReadiness(ctx, k8sClient, awsRes)).NotTo(HaveOccurred())

_, err = controllerReconciler.Reconcile(ctx, reconcile.Request{NamespacedName: typeNamespacedName})
Expect(err).NotTo(HaveOccurred())

By("Checking the user credentials secret")
secret := &corev1.Secret{}
err = k8sClient.Get(ctx, typeNamespacedSecretName, secret)
Expect(err).NotTo(HaveOccurred())
Expand Down Expand Up @@ -239,8 +268,17 @@ var _ = Describe("DatabaseClaim Controller", func() {
Expect(err).NotTo(HaveOccurred())
Expect(claim.Status.Error).To(Equal(""))

By("Checking the user credentials secret")
By("Mocking crossplane instance readiness")
hostParams, err := hostparams.New(controllerReconciler.Config.Viper, &claim)
Expect(err).ToNot(HaveOccurred())
awsRes := &crossplaneaws.DBInstance{}
awsRes.SetName(env + "-" + resourceName + "-" + hostParams.Hash())
Expect(patchCrossplaneCRReadiness(ctx, k8sClient, awsRes)).NotTo(HaveOccurred())

_, err = controllerReconciler.Reconcile(ctx, reconcile.Request{NamespacedName: typeNamespacedName})
Expect(err).NotTo(HaveOccurred())

By("Checking the user credentials secret")
secret := &corev1.Secret{}
err = k8sClient.Get(ctx, typeNamespacedSecretName, secret)
Expect(err).NotTo(HaveOccurred())
Expand Down Expand Up @@ -287,6 +325,13 @@ var _ = Describe("DatabaseClaim Controller", func() {
Expect(err).ToNot(HaveOccurred())
Expect(resource.Status.Error).To(BeEmpty())

By("Mocking crossplane instance readiness")
awsRes := &crossplaneaws.DBInstance{}
awsRes.SetName(env + "-" + resourceName + "-" + hostParams.Hash())
Expect(patchCrossplaneCRReadiness(ctx, k8sClient, awsRes)).NotTo(HaveOccurred())

_, err = controllerReconciler.Reconcile(ctx, reconcile.Request{NamespacedName: typeNamespacedName})

By(fmt.Sprintf("Verifying that the DBInstance is created: %s", credSecretName))
var instance crossplaneaws.DBInstance
Eventually(func() error {
Expand Down Expand Up @@ -339,9 +384,14 @@ var _ = Describe("DatabaseClaim Controller", func() {
_, err := controllerReconciler.Reconcile(ctx, reconcile.Request{NamespacedName: typeNamespacedName})
Expect(err).NotTo(HaveOccurred())

By("Mocking crossplane instance readiness")
hostParams, err := hostparams.New(controllerReconciler.Config.Viper, resource)
Expect(err).ToNot(HaveOccurred())
awsRes := &crossplaneaws.DBInstance{}
awsRes.SetName(env + "-" + resourceName + "-" + hostParams.Hash())
Expect(patchCrossplaneCRReadiness(ctx, k8sClient, awsRes)).NotTo(HaveOccurred())

var instance crossplaneaws.DBInstance
viper := controllerReconciler.Config.Viper
hostParams, err := hostparams.New(viper, resource)
Expect(err).ToNot(HaveOccurred())
instanceName := fmt.Sprintf("%s-%s-%s", env, resourceName, hostParams.Hash())

Expand All @@ -355,19 +405,6 @@ var _ = Describe("DatabaseClaim Controller", func() {

})

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())
})

It("Reconcile rotates the username", func() {
By("Updating CR with a DB Version")

Expand All @@ -378,9 +415,19 @@ var _ = Describe("DatabaseClaim Controller", func() {
Expect(k8sClient.Get(ctx, typeNamespacedName, resource)).NotTo(HaveOccurred())
Expect(resource.Spec.DBVersion).To(Equal(""))

By("Rotating to UserSuffixA")
By("Mocking crossplane instance readiness")
_, err := controllerReconciler.Reconcile(ctx, reconcile.Request{NamespacedName: typeNamespacedName})
Expect(err).NotTo(HaveOccurred())

hostParams, err := hostparams.New(controllerReconciler.Config.Viper, resource)
Expect(err).ToNot(HaveOccurred())
awsRes := &crossplaneaws.DBInstance{}
awsRes.SetName(env + "-" + resourceName + "-" + hostParams.Hash())
Expect(patchCrossplaneCRReadiness(ctx, k8sClient, awsRes)).NotTo(HaveOccurred())

By("Rotating to UserSuffixA")
_, err = controllerReconciler.Reconcile(ctx, reconcile.Request{NamespacedName: typeNamespacedName})
Expect(err).NotTo(HaveOccurred())
Expect(k8sClient.Get(ctx, typeNamespacedName, resource)).NotTo(HaveOccurred())
Expect(resource.Status.Error).To(Equal(""))
Expect(resource.Status.ActiveDB.ConnectionInfo.Username).To(Equal("postgres_a"))
Expand Down Expand Up @@ -408,9 +455,19 @@ var _ = Describe("DatabaseClaim Controller", func() {
Expect(k8sClient.Get(ctx, typeNamespacedName, resource)).NotTo(HaveOccurred())
Expect(resource.Spec.DBVersion).To(Equal(""))

By("Rotating to UserSuffixA")
By("Mocking crossplane instance readiness")
_, err := controllerReconciler.Reconcile(ctx, reconcile.Request{NamespacedName: typeNamespacedName})
Expect(err).NotTo(HaveOccurred())

hostParams, err := hostparams.New(controllerReconciler.Config.Viper, resource)
Expect(err).ToNot(HaveOccurred())
awsRes := &crossplaneaws.DBInstance{}
awsRes.SetName(env + "-" + resourceName + "-" + hostParams.Hash())
Expect(patchCrossplaneCRReadiness(ctx, k8sClient, awsRes)).NotTo(HaveOccurred())

By("Rotating to UserSuffixA")
_, err = controllerReconciler.Reconcile(ctx, reconcile.Request{NamespacedName: typeNamespacedName})
Expect(err).NotTo(HaveOccurred())
Expect(k8sClient.Get(ctx, typeNamespacedName, resource)).NotTo(HaveOccurred())
Expect(resource.Status.Error).To(Equal(""))
Expect(resource.Status.ActiveDB.ConnectionInfo.Username).To(Equal("postgres_a"))
Expand Down
18 changes: 17 additions & 1 deletion internal/controller/databasecontroller_migrate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package controller
import (
"context"
"fmt"
crossplaneaws "github.com/crossplane-contrib/provider-aws/apis/rds/v1alpha1"
"net/url"
"strings"
"time"
Expand Down Expand Up @@ -258,14 +259,21 @@ var _ = Describe("claim migrate", func() {
dbc.Spec.UseExistingSource = ptr.To(false)
Expect(k8sClient.Update(ctxLogger, &dbc)).NotTo(HaveOccurred())
res, err := controllerReconciler.Reconcile(ctxLogger, reconcile.Request{NamespacedName: typeNamespacedName})

hostParams, err = hostparams.New(controllerReconciler.Config.Viper, &dbc)
Expect(err).ToNot(HaveOccurred())
resAws := &crossplaneaws.DBInstance{}
resAws.SetName(env + "-" + resourceName + "-" + hostParams.Hash())
Expect(patchCrossplaneCRReadiness(ctxLogger, k8sClient, resAws)).NotTo(HaveOccurred())
res, err = controllerReconciler.Reconcile(ctxLogger, reconcile.Request{NamespacedName: typeNamespacedName})
Expect(err).To(BeNil())
Expect(dbc.Status.Error).To(Equal(""))
Expect(res.Requeue).To(BeTrue())
Expect(k8sClient.Get(ctxLogger, typeNamespacedName, &dbc)).NotTo(HaveOccurred())
By("Check source DSN looks roughly correct")
activeDB := dbc.Status.ActiveDB
Expect(activeDB.ConnectionInfo).NotTo(BeNil())
compareDSN := strings.Replace(testDSN, "//postgres:postgres", fmt.Sprintf("//%s_b:", migratedowner), 1)
compareDSN := strings.Replace(testDSN, "//postgres:postgres", fmt.Sprintf("//%s_a:", migratedowner), 1)
Expect(activeDB.ConnectionInfo.Uri()).To(Equal(compareDSN))

By("Check target DSN looks roughly correct")
Expand Down Expand Up @@ -346,6 +354,14 @@ var _ = Describe("claim migrate", func() {
dbc.Spec.UseExistingSource = ptr.To(false)
Expect(k8sClient.Update(ctxLogger, &dbc)).NotTo(HaveOccurred())

By("Reconciling once for transitioning the db instance to ready")
_, err = controllerReconciler.Reconcile(ctxLogger, reconcile.Request{NamespacedName: typeNamespacedName})
hostParams, err = hostparams.New(controllerReconciler.Config.Viper, &dbc)
Expect(err).ToNot(HaveOccurred())
resAws := &crossplaneaws.DBInstance{}
resAws.SetName(env + "-" + resourceName + "-" + hostParams.Hash())
Expect(patchCrossplaneCRReadiness(ctxLogger, k8sClient, resAws)).NotTo(HaveOccurred())

By("Reconciling again to trigger migration failure")
_, err = controllerReconciler.Reconcile(ctxLogger, reconcile.Request{NamespacedName: typeNamespacedName})
Expect(err).To(HaveOccurred())
Expand Down
28 changes: 28 additions & 0 deletions internal/controller/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,12 @@ limitations under the License.
package controller

import (
"context"
"database/sql"
"encoding/json"
"fmt"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"path/filepath"
"runtime"
"testing"
Expand Down Expand Up @@ -177,3 +181,27 @@ var _ = AfterSuite(func() {
err := testEnv.Stop()
Expect(err).NotTo(HaveOccurred())
})

func patchCrossplaneCRReadiness(ctx context.Context, k8sClient client.Client, resource client.Object) error {
now := metav1.Now()
patchData := map[string]interface{}{
"status": map[string]interface{}{
"conditions": []map[string]interface{}{
{
"type": "Ready",
"status": "True",
"reason": "Reconciled",
"message": "Resource is ready",
"lastTransitionTime": now.Format(time.RFC3339),
},
},
},
}

patchBytes, err := json.Marshal(patchData)
if err != nil {
return err
}

return k8sClient.Status().Patch(ctx, resource, client.RawPatch(types.MergePatchType, patchBytes))
}
13 changes: 7 additions & 6 deletions pkg/databaseclaim/databaseclaim.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ import (
"strings"
"time"

crossplaneaws "github.com/crossplane-contrib/provider-aws/apis/rds/v1alpha1"

Check failure on line 12 in pkg/databaseclaim/databaseclaim.go

View workflow job for this annotation

GitHub Actions / test

crossplaneaws redeclared in this block

Check failure on line 12 in pkg/databaseclaim/databaseclaim.go

View workflow job for this annotation

GitHub Actions / test

"github.com/crossplane-contrib/provider-aws/apis/rds/v1alpha1" imported as crossplaneaws and not used
xpv1 "github.com/crossplane/crossplane-runtime/apis/common/v1"
"github.com/go-logr/logr"
_ "github.com/lib/pq"
gopassword "github.com/sethvargo/go-password/password"
"github.com/spf13/viper"
crossplanegcp "github.com/upbound/provider-gcp/apis/alloydb/v1beta2"

Check failure on line 18 in pkg/databaseclaim/databaseclaim.go

View workflow job for this annotation

GitHub Actions / test

crossplanegcp redeclared in this block

Check failure on line 18 in pkg/databaseclaim/databaseclaim.go

View workflow job for this annotation

GitHub Actions / test

"github.com/upbound/provider-gcp/apis/alloydb/v1beta2" imported as crossplanegcp and not used
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/utils/ptr"
Expand Down Expand Up @@ -246,7 +248,7 @@ func (r *DatabaseClaimReconciler) createMetricsDeployment(ctx context.Context, d
cfg.DepYamlPath = r.Config.MetricsDepYamlPath
cfg.ConfigYamlPath = r.Config.MetricsConfigYamlPath
cfg.DatasourceSecretName = dbClaim.Spec.SecretName
cfg.DatasourceFileName = v1.DSNKey
cfg.DatasourceFileName = v1.DSNURIKey
return exporter.Apply(ctx, r.Client, cfg)
}

Expand Down Expand Up @@ -825,8 +827,6 @@ func (r *DatabaseClaimReconciler) reconcileMigrationInProgress(ctx context.Conte
ExportFilePath: basefun.GetPgTempFolder(r.Config.Viper),
}

logr.V(debugLevel).Info("pctl_dsn", "config", config)

s, err := pgctl.GetReplicatorState(migrationState, config)
if err != nil {
return r.statusManager.SetError(ctx, dbClaim, err)
Expand Down Expand Up @@ -1102,10 +1102,11 @@ func (r *DatabaseClaimReconciler) getPasswordRotationTime() time.Duration {

// FindStatusCondition finds the conditionType in conditions.
func (r *DatabaseClaimReconciler) isResourceReady(typ, name string, resourceStatus xpv1.ResourceStatus) (bool, error) {
if ok, err := isResourceReady(resourceStatus); err != nil {
return ok, fmt.Errorf("%s %s: %w", typ, name, err)
ok, err := isResourceReady(resourceStatus)
if err != nil {
return false, fmt.Errorf("%s %s: %w", typ, name, err)
}
return true, nil
return ok, nil
}

func isResourceReady(resourceStatus xpv1.ResourceStatus) (bool, error) {
Expand Down
Loading

0 comments on commit fc52c08

Please sign in to comment.