Skip to content

Commit e3bf74d

Browse files
Pieter Chitman99
Pieter C
authored andcommitted
fix: make compatbile for Azure Database for PostgreSQL (#21)
* feat: support for Azure managed Postgres database * feat: new config variable: POSTGRES_DEFAULT_DATABASE to use for connecting to the database * add login attribute to CRD * chore: manual replaced github.com entries to relative directory so git diff is smaller
1 parent 7122b0d commit e3bf74d

File tree

9 files changed

+84
-16
lines changed

9 files changed

+84
-16
lines changed

deploy/crds/db.movetokube.com_postgresusers_crd.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,16 @@ spec:
5151
type: string
5252
postgresGroup:
5353
type: string
54+
postgresLogin:
55+
type: string
5456
postgresRole:
5557
type: string
5658
succeeded:
5759
type: boolean
5860
required:
5961
- databaseName
6062
- postgresGroup
63+
- postgresLogin
6164
- postgresRole
6265
- succeeded
6366
type: object

pkg/apis/db/v1alpha1/postgresuser_types.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ type PostgresUserSpec struct {
2222
type PostgresUserStatus struct {
2323
Succeeded bool `json:"succeeded"`
2424
PostgresRole string `json:"postgresRole"`
25+
PostgresLogin string `json:"postgresLogin"`
2526
PostgresGroup string `json:"postgresGroup"`
2627
DatabaseName string `json:"databaseName"`
2728
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster

pkg/apis/db/v1alpha1/zz_generated.openapi.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,12 @@ func schema_pkg_apis_db_v1alpha1_PostgresUserStatus(ref common.ReferenceCallback
293293
Format: "",
294294
},
295295
},
296+
"postgresLogin": {
297+
SchemaProps: spec.SchemaProps{
298+
Type: []string{"string"},
299+
Format: "",
300+
},
301+
},
296302
"postgresGroup": {
297303
SchemaProps: spec.SchemaProps{
298304
Type: []string{"string"},
@@ -306,7 +312,7 @@ func schema_pkg_apis_db_v1alpha1_PostgresUserStatus(ref common.ReferenceCallback
306312
},
307313
},
308314
},
309-
Required: []string{"succeeded", "postgresRole", "postgresGroup", "databaseName"},
315+
Required: []string{"succeeded", "postgresRole", "postgresLogin", "postgresGroup", "databaseName"},
310316
},
311317
},
312318
}

pkg/controller/postgres/postgres_controller.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
goerr "errors"
66
"fmt"
7+
78
"github.com/go-logr/logr"
89
dbv1alpha1 "github.com/movetokube/postgres-operator/pkg/apis/db/v1alpha1"
910
"github.com/movetokube/postgres-operator/pkg/postgres"
@@ -35,7 +36,8 @@ func newReconciler(mgr manager.Manager) reconcile.Reconciler {
3536
pgPass := utils.MustGetEnv("POSTGRES_PASS")
3637
pgUriArgs := utils.MustGetEnv("POSTGRES_URI_ARGS")
3738
pgCloudProvider := utils.GetEnv("POSTGRES_CLOUD_PROVIDER")
38-
pg, err := postgres.NewPG(pgHost, pgUser, pgPass, pgUriArgs, pgCloudProvider, log.WithName("postgres"))
39+
pgDefaultDatabase := utils.GetEnv("POSTGRES_DEFAULT_DATABASE")
40+
pg, err := postgres.NewPG(pgHost, pgUser, pgPass, pgUriArgs, pgDefaultDatabase, pgCloudProvider, log.WithName("postgres"))
3941
if err != nil {
4042
return nil
4143
}

pkg/controller/postgresuser/postgresuser_controller.go

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
goerr "errors"
66
"fmt"
7+
78
"github.com/go-logr/logr"
89
dbv1alpha1 "github.com/movetokube/postgres-operator/pkg/apis/db/v1alpha1"
910
"github.com/movetokube/postgres-operator/pkg/postgres"
@@ -44,7 +45,8 @@ func newReconciler(mgr manager.Manager) reconcile.Reconciler {
4445
pgPass := utils.MustGetEnv("POSTGRES_PASS")
4546
pgUriArgs := utils.MustGetEnv("POSTGRES_URI_ARGS")
4647
pgCloudProvider := utils.GetEnv("POSTGRES_CLOUD_PROVIDER")
47-
pg, err := postgres.NewPG(pgHost, pgUser, pgPass, pgUriArgs, pgCloudProvider, log.WithName("postgres"))
48+
pgDefaultDatabase := utils.GetEnv("POSTGRES_DEFAULT_DATABASE")
49+
pg, err := postgres.NewPG(pgHost, pgUser, pgPass, pgUriArgs, pgDefaultDatabase, pgCloudProvider, log.WithName("postgres"))
4850
if err != nil {
4951
return nil
5052
}
@@ -139,7 +141,7 @@ func (r *ReconcilePostgresUser) Reconcile(request reconcile.Request) (reconcile.
139141
}
140142

141143
// Creation logic
142-
var role string
144+
var role, login string
143145
password := utils.GetRandomString(15)
144146

145147
if instance.Status.PostgresRole == "" {
@@ -151,7 +153,7 @@ func (r *ReconcilePostgresUser) Reconcile(request reconcile.Request) (reconcile.
151153
// Create user role
152154
suffix := utils.GetRandomString(6)
153155
role = fmt.Sprintf("%s-%s", instance.Spec.Role, suffix)
154-
err = r.pg.CreateUserRole(role, password)
156+
login, err = r.pg.CreateUserRole(role, password)
155157
if err != nil {
156158
return r.requeue(instance, errors.NewInternalError(err))
157159
}
@@ -181,13 +183,15 @@ func (r *ReconcilePostgresUser) Reconcile(request reconcile.Request) (reconcile.
181183

182184
instance.Status.PostgresRole = role
183185
instance.Status.PostgresGroup = groupRole
186+
instance.Status.PostgresLogin = login
184187
instance.Status.DatabaseName = database.Spec.Database
185188
err = r.client.Status().Update(context.TODO(), instance)
186189
if err != nil {
187190
return r.requeue(instance, err)
188191
}
189192
} else {
190193
role = instance.Status.PostgresRole
194+
login = instance.Status.PostgresLogin
191195
}
192196

193197
err = r.addFinalizer(reqLogger, instance)
@@ -199,7 +203,7 @@ func (r *ReconcilePostgresUser) Reconcile(request reconcile.Request) (reconcile.
199203
return r.requeue(instance, err)
200204
}
201205

202-
secret := r.newSecretForCR(instance, role, password)
206+
secret := r.newSecretForCR(instance, role, password, login)
203207

204208
// Set PostgresUser instance as the owner and controller
205209
if err := controllerutil.SetControllerReference(instance, secret, r.scheme); err != nil {
@@ -248,7 +252,7 @@ func (r *ReconcilePostgresUser) addFinalizer(reqLogger logr.Logger, m *dbv1alpha
248252
return nil
249253
}
250254

251-
func (r *ReconcilePostgresUser) newSecretForCR(cr *dbv1alpha1.PostgresUser, role, password string) *corev1.Secret {
255+
func (r *ReconcilePostgresUser) newSecretForCR(cr *dbv1alpha1.PostgresUser, role, password, login string) *corev1.Secret {
252256
pgUserUrl := fmt.Sprintf("postgresql://%s:%s@%s/%s", role, password, r.pgHost, cr.Status.DatabaseName)
253257
labels := map[string]string{
254258
"app": cr.Name,
@@ -263,6 +267,7 @@ func (r *ReconcilePostgresUser) newSecretForCR(cr *dbv1alpha1.PostgresUser, role
263267
"POSTGRES_URL": []byte(pgUserUrl),
264268
"ROLE": []byte(role),
265269
"PASSWORD": []byte(password),
270+
"LOGIN": []byte(login),
266271
},
267272
}
268273
}

pkg/postgres/aws.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ type awspg struct {
1111
pg
1212
}
1313

14-
func newAWSPG(postgres *pg) (PG, error) {
14+
func newAWSPG(postgres *pg) PG {
1515
return &awspg{
1616
*postgres,
17-
}, nil
17+
}
1818
}
1919

2020
func (c *awspg) AlterDefaultLoginRole(role, setRole string) error {

pkg/postgres/azure.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package postgres
2+
3+
import (
4+
"fmt"
5+
"strings"
6+
)
7+
8+
type azurepg struct {
9+
serverName string
10+
pg
11+
}
12+
13+
func newAzurePG(postgres *pg) PG {
14+
splitUser := strings.Split(postgres.user, "@")
15+
serverName := ""
16+
if len(splitUser) > 1 {
17+
serverName = splitUser[1]
18+
}
19+
return &azurepg{
20+
serverName,
21+
*postgres,
22+
}
23+
}
24+
25+
func (azpg *azurepg) CreateUserRole(role, password string) (string, error) {
26+
returnedRole, err := azpg.pg.CreateUserRole(role, password)
27+
if err != nil {
28+
return "", err
29+
}
30+
return fmt.Sprintf("%s@%s", returnedRole, azpg.serverName), nil
31+
}
32+
33+
func (azpg *azurepg) GetRoleForLogin(login string) string {
34+
splitUser := strings.Split(azpg.user, "@")
35+
if len(splitUser) > 1 {
36+
return splitUser[0]
37+
}
38+
return login
39+
}
40+
41+
func (azpg *azurepg) CreateDB(dbname, role string) error {
42+
// Have to add the master role to the group role before we can transfer the database owner
43+
err := azpg.GrantRole(role, azpg.GetRoleForLogin(azpg.user))
44+
if err != nil {
45+
return err
46+
}
47+
48+
return azpg.pg.CreateDB(dbname, role)
49+
}

pkg/postgres/postgres.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ type PG interface {
1212
CreateDB(dbname, username string) error
1313
CreateSchema(db, role, schema string, logger logr.Logger) error
1414
CreateGroupRole(role string) error
15-
CreateUserRole(role, password string) error
15+
CreateUserRole(role, password string) (string, error)
1616
UpdatePassword(role, password string) error
1717
GrantRole(role, grantee string) error
1818
SetSchemaPrivileges(db, creator, role, schema, privs string, logger logr.Logger) error
@@ -32,9 +32,9 @@ type pg struct {
3232
args string
3333
}
3434

35-
func NewPG(host, user, password, uri_args, cloud_type string, logger logr.Logger) (PG, error) {
35+
func NewPG(host, user, password, uri_args, default_database, cloud_type string, logger logr.Logger) (PG, error) {
3636
postgres := &pg{
37-
db: GetConnection(user, password, host, "", uri_args, logger),
37+
db: GetConnection(user, password, host, default_database, uri_args, logger),
3838
log: logger,
3939
host: host,
4040
user: user,
@@ -44,7 +44,9 @@ func NewPG(host, user, password, uri_args, cloud_type string, logger logr.Logger
4444

4545
switch cloud_type {
4646
case "AWS":
47-
return newAWSPG(postgres)
47+
return newAWSPG(postgres), nil
48+
case "Azure":
49+
return newAzurePG(postgres), nil
4850
default:
4951
return postgres, nil
5052
}

pkg/postgres/role.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,12 @@ func (c *pg) CreateGroupRole(role string) error {
2828
return nil
2929
}
3030

31-
func (c *pg) CreateUserRole(role, password string) error {
31+
func (c *pg) CreateUserRole(role, password string) (string, error) {
3232
_, err := c.db.Exec(fmt.Sprintf(CREATE_USER_ROLE, role, password))
3333
if err != nil {
34-
return err
34+
return "", err
3535
}
36-
return nil
36+
return role, nil
3737
}
3838

3939
func (c *pg) GrantRole(role, grantee string) error {

0 commit comments

Comments
 (0)