Skip to content

DEVOPS-28123 include aurora rds read replica connection information in db claim secret #301

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
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: 3 additions & 2 deletions api/v1/databaseclaim_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ import (
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.

var (
DSNKey = "dsn.txt"
DSNURIKey = "uri_dsn.txt"
DSNKey = "dsn.txt"
DSNURIKey = "uri_dsn.txt"
ReplicaDSNURIKey = "ro_uri_dsn.txt"
)

type DatabaseType string
Expand Down
6 changes: 3 additions & 3 deletions pkg/databaseclaim/databaseclaim.go
Original file line number Diff line number Diff line change
Expand Up @@ -563,7 +563,7 @@ func (r *DatabaseClaimReconciler) executeDbClaimRequest(ctx context.Context, dbC
newDBConnInfo := dbClaim.Status.NewDB.ConnectionInfo.DeepCopy()
newDBConnInfo.Password = r.Input.TempSecret

if err := r.createOrUpdateSecret(ctx, dbClaim, newDBConnInfo); err != nil {
if err := r.createOrUpdateSecret(ctx, dbClaim, newDBConnInfo, basefun.GetCloud(r.Config.Viper)); err != nil {
return r.manageError(ctx, dbClaim, err)
}
}
Expand Down Expand Up @@ -645,7 +645,7 @@ func (r *DatabaseClaimReconciler) reconcileUseExistingDB(ctx context.Context, db
newDBConnInfo := dbClaim.Status.NewDB.ConnectionInfo.DeepCopy()
newDBConnInfo.Password = r.Input.TempSecret

if err := r.createOrUpdateSecret(ctx, dbClaim, newDBConnInfo); err != nil {
if err := r.createOrUpdateSecret(ctx, dbClaim, newDBConnInfo, basefun.GetCloud(r.Config.Viper)); err != nil {
return err
}
}
Expand Down Expand Up @@ -1405,7 +1405,7 @@ func (r *DatabaseClaimReconciler) rerouteTargetSecret(ctx context.Context, sourc
if err != nil {
return err
}
err = r.createOrUpdateSecret(ctx, dbClaim, targetAppConn)
err = r.createOrUpdateSecret(ctx, dbClaim, targetAppConn, basefun.GetCloud(r.Config.Viper))
if err != nil {
return err
}
Expand Down
36 changes: 21 additions & 15 deletions pkg/databaseclaim/secrets.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package databaseclaim
import (
"context"
"fmt"
"strings"

_ "github.com/lib/pq"
corev1 "k8s.io/api/core/v1"
Expand All @@ -17,21 +18,24 @@ import (
"k8s.io/apimachinery/pkg/api/errors"
)

func (r *DatabaseClaimReconciler) createOrUpdateSecret(ctx context.Context, dbClaim *v1.DatabaseClaim,
connInfo *v1.DatabaseClaimConnectionInfo) error {
func (r *DatabaseClaimReconciler) createOrUpdateSecret(ctx context.Context, dbClaim *v1.DatabaseClaim, connInfo *v1.DatabaseClaimConnectionInfo, cloud string) error {
logr := log.FromContext(ctx)
gs := &corev1.Secret{}
dbType := dbClaim.Spec.Type
secretName := dbClaim.Spec.SecretName
logr.Info("createOrUpdateSecret being executed. SecretName: " + secretName)
var dsn, dsnURI string
var dsn, dsnURI, replicaDsnURI string = "", "", ""

switch dbType {
case v1.Postgres:
fallthrough
case v1.AuroraPostgres:
dsn = dbclient.PostgresConnectionString(connInfo.Host, connInfo.Port, connInfo.Username, connInfo.Password, connInfo.DatabaseName, connInfo.SSLMode)
dsnURI = dbclient.PostgresURI(connInfo.Host, connInfo.Port, connInfo.Username, connInfo.Password, connInfo.DatabaseName, connInfo.SSLMode)

if cloud == "aws" {
replicaDsnURI = strings.Replace(dsnURI, ".cluster-", ".cluster-ro-", -1)
}
default:
return fmt.Errorf("unknown DB type")
}
Expand All @@ -42,16 +46,16 @@ func (r *DatabaseClaimReconciler) createOrUpdateSecret(ctx context.Context, dbCl
}, gs)

if err != nil && errors.IsNotFound(err) {
if err := r.createSecret(ctx, dbClaim, dsn, dsnURI, connInfo); err != nil {
if err := r.createSecret(ctx, dbClaim, dsn, dsnURI, replicaDsnURI, connInfo); err != nil {
return err
}
return nil
}

return r.updateSecret(ctx, dsn, dsnURI, connInfo, gs)
return r.updateSecret(ctx, dsn, dsnURI, replicaDsnURI, connInfo, gs)
}

func (r *DatabaseClaimReconciler) createSecret(ctx context.Context, dbClaim *v1.DatabaseClaim, dsn, dbURI string, connInfo *v1.DatabaseClaimConnectionInfo) error {
func (r *DatabaseClaimReconciler) createSecret(ctx context.Context, dbClaim *v1.DatabaseClaim, dsn, dbURI, replicaDbURI string, connInfo *v1.DatabaseClaimConnectionInfo) error {

logr := log.FromContext(ctx)
secretName := dbClaim.Spec.SecretName
Expand All @@ -73,27 +77,29 @@ func (r *DatabaseClaimReconciler) createSecret(ctx context.Context, dbClaim *v1.
},
},
Data: map[string][]byte{
v1.DSNKey: []byte(dsn),
v1.DSNURIKey: []byte(dbURI),
"hostname": []byte(connInfo.Host),
"port": []byte(connInfo.Port),
"database": []byte(connInfo.DatabaseName),
"username": []byte(connInfo.Username),
"password": []byte(connInfo.Password),
"sslmode": []byte(connInfo.SSLMode),
v1.DSNKey: []byte(dsn),
v1.DSNURIKey: []byte(dbURI),
v1.ReplicaDSNURIKey: []byte(replicaDbURI),
"hostname": []byte(connInfo.Host),
"port": []byte(connInfo.Port),
"database": []byte(connInfo.DatabaseName),
"username": []byte(connInfo.Username),
"password": []byte(connInfo.Password),
"sslmode": []byte(connInfo.SSLMode),
},
}
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 string, connInfo *v1.DatabaseClaimConnectionInfo, exSecret *corev1.Secret) error {
func (r *DatabaseClaimReconciler) updateSecret(ctx context.Context, dsn, dbURI, replicaDsnURI string, connInfo *v1.DatabaseClaimConnectionInfo, exSecret *corev1.Secret) error {

logr := log.FromContext(ctx)

exSecret.Data[v1.DSNKey] = []byte(dsn)
exSecret.Data[v1.DSNURIKey] = []byte(dbURI)
exSecret.Data[v1.ReplicaDSNURIKey] = []byte(replicaDsnURI)
exSecret.Data["hostname"] = []byte(connInfo.Host)
exSecret.Data["port"] = []byte(connInfo.Port)
exSecret.Data["database"] = []byte(connInfo.DatabaseName)
Expand Down
105 changes: 105 additions & 0 deletions pkg/databaseclaim/secrets_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package databaseclaim

import (
"context"
"testing"

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

v1 "github.com/infobloxopen/db-controller/api/v1"
role "github.com/infobloxopen/db-controller/pkg/roleclaim"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

func TestCreateSecret(t *testing.T) {

RegisterFailHandler(Fail)

mockClient := role.MockClient{}

dbClaimReconciler := DatabaseClaimReconciler{
Client: &mockClient,
}

ctx := context.Background()
claimConnInfo := v1.DatabaseClaimConnectionInfo{
Host: "host",
Port: "123",
DatabaseName: "dbName",
Username: "user",
Password: "pass",
SSLMode: "ssl",
}

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.createSecret(ctx, &dbClaim, "dsn", "dsnUri", "ro_dsnUri", &claimConnInfo)

secret := mockClient.CreatedObject.(*corev1.Secret)

Expect(secret.Data[v1.DSNKey]).To(Equal([]byte("dsn")))
Expect(secret.Data[v1.DSNURIKey]).To(Equal([]byte("dsnUri")))
Expect(secret.Data[v1.ReplicaDSNURIKey]).To(Equal([]byte("ro_dsnUri")))
Expect(secret.Data["hostname"]).To(Equal([]byte("host")))
Expect(secret.Data["port"]).To(Equal([]byte("123")))
Expect(secret.Data["database"]).To(Equal([]byte("dbName")))
Expect(secret.Data["username"]).To(Equal([]byte("user")))
Expect(secret.Data["password"]).To(Equal([]byte("pass")))
Expect(secret.Data["sslmode"]).To(Equal([]byte("ssl")))

if err != nil {
t.Errorf("Error updating secret: %s", err)
}
}

func TestUpdateSecret(t *testing.T) {

RegisterFailHandler(Fail)

mockClient := role.MockClient{}

dbClaimReconciler := DatabaseClaimReconciler{
Client: &mockClient,
}

ctx := context.Background()
claimConnInfo := v1.DatabaseClaimConnectionInfo{
Host: "host",
Port: "123",
DatabaseName: "dbName",
Username: "user",
Password: "pass",
SSLMode: "ssl",
}
secret := corev1.Secret{
Data: make(map[string][]byte),
}

err := dbClaimReconciler.updateSecret(ctx, "dsn", "dsnUri", "ro_dsnUri", &claimConnInfo, &secret)

Expect(secret.Data[v1.DSNKey]).To(Equal([]byte("dsn")))
Expect(secret.Data[v1.DSNURIKey]).To(Equal([]byte("dsnUri")))
Expect(secret.Data[v1.ReplicaDSNURIKey]).To(Equal([]byte("ro_dsnUri")))
Expect(secret.Data["hostname"]).To(Equal([]byte("host")))
Expect(secret.Data["port"]).To(Equal([]byte("123")))
Expect(secret.Data["database"]).To(Equal([]byte("dbName")))
Expect(secret.Data["username"]).To(Equal([]byte("user")))
Expect(secret.Data["password"]).To(Equal([]byte("pass")))
Expect(secret.Data["sslmode"]).To(Equal([]byte("ssl")))

if err != nil {
t.Errorf("Error updating secret: %s", err)
}
}
20 changes: 9 additions & 11 deletions pkg/roleclaim/mockclient_test.go → pkg/roleclaim/mockclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,24 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"
)

type mockClient struct {
type MockClient struct {
client.Client
// port is derived from the DSN
dsn string
dsn string
CreatedObject client.Object
}

var responseUpdate interface{}

func (m *mockClient) GetResponseUpdate() interface{} {
func (m *MockClient) GetResponseUpdate() interface{} {
return responseUpdate
}

func (m *mockClient) Update(ctx context.Context, obj client.Object, opts ...client.UpdateOption) error {
func (m *MockClient) Update(ctx context.Context, obj client.Object, opts ...client.UpdateOption) error {
return nil
}

func (m *mockClient) Get(ctx context.Context, key client.ObjectKey, obj client.Object, opts ...client.GetOption) error {
func (m *MockClient) Get(ctx context.Context, key client.ObjectKey, obj client.Object, opts ...client.GetOption) error {

parsedDSN, err := url.Parse(m.dsn)
if err != nil {
Expand Down Expand Up @@ -147,24 +148,21 @@ func (m *mockClient) Get(ctx context.Context, key client.ObjectKey, obj client.O
return errors.NewNotFound(schema.GroupResource{Group: "core", Resource: "secret"}, key.Name)
}

func (m *mockClient) Create(ctx context.Context, obj client.Object, opts ...client.CreateOption) error {
func (m *MockClient) Create(ctx context.Context, obj client.Object, opts ...client.CreateOption) error {
_ = ctx
if (obj.GetNamespace() == "testNamespace" || obj.GetNamespace() == "schema-user-test") &&
(obj.GetName() == "create-master-secret" || obj.GetName() == "sample-master-secret") {
sec, ok := obj.(*corev1.Secret)
m.CreatedObject = sec
if !ok {
return fmt.Errorf("can't assert type")
}
sec.Data = map[string][]byte{
"password": []byte("masterpassword"),
"username": []byte("mainUser"),
}
return nil
}
return fmt.Errorf("can't create object")
}

func (m *mockClient) Status() client.StatusWriter {
func (m *MockClient) Status() client.StatusWriter {
return &MockStatusWriter{}
}

Expand Down
12 changes: 6 additions & 6 deletions pkg/roleclaim/roleclaim_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func TestDBRoleClaimController_CreateSchemasAndRoles(t *testing.T) {
{
"Get UserSchema claim 1",
reconciler{
Client: &mockClient{dsn: dsn},
Client: &MockClient{dsn: dsn},
Config: &RoleConfig{
Viper: viperObj,
Class: "default",
Expand Down Expand Up @@ -90,7 +90,7 @@ func TestDBRoleClaimController_CreateSchemasAndRoles(t *testing.T) {
dbClient, err := basefun.GetClientForExistingDB(existingDBConnInfo, &controllerruntime.Log)
Expect(err).ShouldNot(HaveOccurred())

var responseUpdate = r.Client.(*mockClient).GetResponseUpdate()
var responseUpdate = r.Client.(*MockClient).GetResponseUpdate()
Expect(responseUpdate).Should(Not(BeNil()))
var schemaUserClaimStatus = responseUpdate.(*persistancev1.DbRoleClaim).Status
Expect(schemaUserClaimStatus).Should(Not(BeNil()))
Expand Down Expand Up @@ -166,7 +166,7 @@ func TestDBRoleClaimController_ExistingSchemaRoleAndUser(t *testing.T) {
wantErr bool
}{
reconciler{
Client: &mockClient{dsn: dsn},
Client: &MockClient{dsn: dsn},
Config: &RoleConfig{
Viper: viperObj,
Class: "default",
Expand Down Expand Up @@ -201,7 +201,7 @@ func TestDBRoleClaimController_ExistingSchemaRoleAndUser(t *testing.T) {

Expect(result.Requeue).Should(BeFalse())

var responseUpdate = r.Client.(*mockClient).GetResponseUpdate()
var responseUpdate = r.Client.(*MockClient).GetResponseUpdate()
Expect(responseUpdate).Should(Not(BeNil()))
var schemaUserClaimStatus = responseUpdate.(*persistancev1.DbRoleClaim).Status
Expect(schemaUserClaimStatus).Should(Not(BeNil()))
Expand Down Expand Up @@ -270,7 +270,7 @@ func TestDBRoleClaimController_RevokeRolesAndAssignNew(t *testing.T) {
wantErr bool
}{
reconciler{
Client: &mockClient{dsn: dsn},
Client: &MockClient{dsn: dsn},
Config: &RoleConfig{
Viper: viperObj,
Class: "default",
Expand Down Expand Up @@ -322,7 +322,7 @@ func TestDBRoleClaimController_RevokeRolesAndAssignNew(t *testing.T) {

Expect(result.Requeue).Should(BeFalse())

var responseUpdate = r.Client.(*mockClient).GetResponseUpdate()
var responseUpdate = r.Client.(*MockClient).GetResponseUpdate()
Expect(responseUpdate).Should(Not(BeNil()))
var schemaUserClaimStatus = responseUpdate.(*persistancev1.DbRoleClaim).Status
Expect(schemaUserClaimStatus).Should(Not(BeNil()))
Expand Down
Loading