Skip to content

Commit

Permalink
Support reading DB credentials from secrets
Browse files Browse the repository at this point in the history
  • Loading branch information
amitlicht committed Jun 18, 2024
1 parent 0cb684b commit 7c7c2b3
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 16 deletions.
2 changes: 1 addition & 1 deletion src/operator/api/v1alpha3/postgresqlserverconfig_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ type DatabaseCredentials struct {
Password string `json:"password"`
// SecretRef is a reference to a k8s secret storing the credentials
//+optional
SecretRef DatabaseCredentialsSecretRef `json:"secretRef"`
SecretRef *DatabaseCredentialsSecretRef `json:"secretRef"`
}

// PostgreSQLServerConfigSpec defines the desired state of PostgreSQLServerConfig
Expand Down
14 changes: 9 additions & 5 deletions src/operator/api/v1alpha3/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,60 @@ func (r *DatabaseReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c
return ctrl.Result{}, nil
}

func (r *DatabaseReconciler) extractDBCredentials(ctx context.Context, namespace string, credentialsSpec otterizev1alpha3.DatabaseCredentials) (databaseconfigurator.DatabaseCredentials, error) {
creds := databaseconfigurator.DatabaseCredentials{}
if credentialsSpec.Username != "" {
creds.Username = credentialsSpec.Username
}
if credentialsSpec.Password != "" {
creds.Password = credentialsSpec.Password
}
if credentialsSpec.SecretRef != nil {
secret := corev1.Secret{}
name := credentialsSpec.SecretRef.Name
if credentialsSpec.SecretRef.Namespace != "" {
namespace = credentialsSpec.SecretRef.Namespace
}
err := r.client.Get(ctx, client.ObjectKey{Name: name, Namespace: namespace}, &secret)
if err != nil {
return creds, errors.Wrap(err)
}
if username, ok := secret.Data[credentialsSpec.SecretRef.UsernameKey]; ok {
creds.Username = string(username)
}
if password, ok := secret.Data[credentialsSpec.SecretRef.PasswordKey]; ok {
creds.Password = string(password)
}
}

if creds.Username == "" || creds.Password == "" {
// TODO: should validate this as part of admission webhook
return creds, errors.New("credentials missing either username or password")
}

return creds, nil
}

func (r *DatabaseReconciler) createPostgresDBConfigurator(ctx context.Context, pgServerConfig otterizev1alpha3.PostgreSQLServerConfig) (databaseconfigurator.DatabaseConfigurator, error) {
credentials, err := r.extractDBCredentials(ctx, pgServerConfig.Namespace, pgServerConfig.Spec.Credentials)
if err != nil {
return nil, errors.Wrap(err)
}

dbInfo := postgres.PostgresDatabaseInfo{
Credentials: credentials,
Address: pgServerConfig.Spec.Address,
}

dbConfigurator, err := postgres.NewPostgresConfigurator(ctx, dbInfo)
if err != nil {
return nil, errors.Wrap(err)
}
return dbConfigurator, nil
}

func (r *DatabaseReconciler) applyPGDBInstanceIntents(ctx context.Context, config otterizev1alpha3.PostgreSQLServerConfig, clientIntents *otterizev1alpha3.ClientIntents, dbUsername string, dbInstanceIntents []otterizev1alpha3.Intent) error {
dbConfigurator, err := postgres.NewPostgresConfigurator(ctx, config.Spec)
dbConfigurator, err := r.createPostgresDBConfigurator(ctx, config)
if err != nil {
r.RecordWarningEventf(clientIntents, ReasonErrorConnectingToDatabase,
"Error connecting to PostgreSQL server. Error: %s", err.Error())
Expand All @@ -153,11 +205,29 @@ func (r *DatabaseReconciler) applyPGDBInstanceIntents(ctx context.Context, confi
return r.applyDBInstanceIntentsOnConfigurator(ctx, dbConfigurator, clientIntents, dbUsername, config.Name, dbInstanceIntents)
}

func (r *DatabaseReconciler) createMySQLDBConfigurator(ctx context.Context, mySqlServerConfig otterizev1alpha3.MySQLServerConfig) (databaseconfigurator.DatabaseConfigurator, error) {
credentials, err := r.extractDBCredentials(ctx, mySqlServerConfig.Namespace, mySqlServerConfig.Spec.Credentials)
if err != nil {
return nil, errors.Wrap(err)
}

dbInfo := mysql.MySQLDatabaseInfo{
Credentials: credentials,
Address: mySqlServerConfig.Spec.Address,
}

dbConfigurator, err := mysql.NewMySQLConfigurator(ctx, dbInfo)
if err != nil {
return nil, errors.Wrap(err)
}
return dbConfigurator, nil
}

func (r *DatabaseReconciler) applyMySQLDBInstanceIntents(ctx context.Context, config otterizev1alpha3.MySQLServerConfig, clientIntents *otterizev1alpha3.ClientIntents, dbUsername string, dbInstanceIntents []otterizev1alpha3.Intent) error {
dbConfigurator, err := mysql.NewMySQLConfigurator(ctx, config.Spec)
dbConfigurator, err := r.createMySQLDBConfigurator(ctx, config)
if err != nil {
r.RecordWarningEventf(clientIntents, ReasonErrorConnectingToDatabase,
"Error connecting to PostgreSQL server. Error: %s", err.Error())
"Error connecting to MySQL server. Error: %s", err.Error())
return errors.Wrap(err)
}

Expand Down
5 changes: 5 additions & 0 deletions src/shared/databaseconfigurator/dbconfigurator.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ const (
LatestAccessChangeAnnotation = "intents.otterize.com/database-access-update-time"
)

type DatabaseCredentials struct {
Username string
Password string
}

type DatabaseConfigurator interface {
CreateUser(ctx context.Context, username string, password string) error
ValidateUserExists(ctx context.Context, username string) (bool, error)
Expand Down
14 changes: 10 additions & 4 deletions src/shared/databaseconfigurator/mysql/mysql.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"fmt"
_ "github.com/go-sql-driver/mysql"
otterizev1alpha3 "github.com/otterize/intents-operator/src/operator/api/v1alpha3"
"github.com/otterize/intents-operator/src/shared/databaseconfigurator"
"github.com/otterize/intents-operator/src/shared/databaseconfigurator/sqlutils"
"github.com/otterize/intents-operator/src/shared/errors"
"github.com/samber/lo"
Expand Down Expand Up @@ -47,6 +48,11 @@ func privilegesToString(privs []PrivilegeType) []string {
})
}

type MySQLDatabaseInfo struct {
Address string
Credentials databaseconfigurator.DatabaseCredentials
}

type DBUserPrivilege struct {
Db string
Privileges []PrivilegeType
Expand All @@ -59,17 +65,17 @@ type TablePrivilege struct {
}

type MySQLConfigurator struct {
databaseInfo otterizev1alpha3.MySQLServerConfigSpec
databaseInfo MySQLDatabaseInfo
db *sql.DB
setDBMutex sync.Mutex
logger *logrus.Entry
}

func NewMySQLConfigurator(ctx context.Context, conf otterizev1alpha3.MySQLServerConfigSpec) (*MySQLConfigurator, error) {
func NewMySQLConfigurator(ctx context.Context, databaseInfo MySQLDatabaseInfo) (*MySQLConfigurator, error) {
m := &MySQLConfigurator{
databaseInfo: conf,
databaseInfo: databaseInfo,
setDBMutex: sync.Mutex{},
logger: logrus.WithField("database", conf.Address),
logger: logrus.WithField("database", databaseInfo.Address),
}

if err := m.setConnection(DefaultDatabase); err != nil {
Expand Down
12 changes: 9 additions & 3 deletions src/shared/databaseconfigurator/postgres/postgres.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"github.com/amit7itz/goset"
"github.com/jackc/pgx/v5"
otterizev1alpha3 "github.com/otterize/intents-operator/src/operator/api/v1alpha3"
"github.com/otterize/intents-operator/src/shared/databaseconfigurator"
"github.com/otterize/intents-operator/src/shared/databaseconfigurator/sqlutils"
"github.com/otterize/intents-operator/src/shared/errors"
"github.com/samber/lo"
Expand Down Expand Up @@ -42,15 +43,20 @@ func databaseConfigInputToSQLTableIdentifier(resource otterizev1alpha3.DatabaseR
return sqlutils.SQLTableIdentifier{TableSchema: "public", TableName: resource.Table}
}

type PostgresDatabaseInfo struct {
Address string
Credentials databaseconfigurator.DatabaseCredentials
}

type PostgresConfigurator struct {
conn *pgx.Conn
databaseInfo otterizev1alpha3.PostgreSQLServerConfigSpec
databaseInfo PostgresDatabaseInfo
setConnMutex sync.Mutex
}

func NewPostgresConfigurator(ctx context.Context, pgServerConfSpec otterizev1alpha3.PostgreSQLServerConfigSpec) (*PostgresConfigurator, error) {
func NewPostgresConfigurator(ctx context.Context, databaseInfo PostgresDatabaseInfo) (*PostgresConfigurator, error) {
p := &PostgresConfigurator{
databaseInfo: pgServerConfSpec,
databaseInfo: databaseInfo,
setConnMutex: sync.Mutex{},
}

Expand Down

0 comments on commit 7c7c2b3

Please sign in to comment.