Skip to content

Commit

Permalink
feat: support schemas
Browse files Browse the repository at this point in the history
  • Loading branch information
raffis committed Apr 16, 2024
1 parent 458c76f commit 5e45246
Show file tree
Hide file tree
Showing 10 changed files with 128 additions and 12 deletions.
6 changes: 5 additions & 1 deletion api/v1beta1/database_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const (
DatabaseReadyConditionType = "DatabaseReady"
UserReadyConditionType = "UserReady"
ExtensionReadyConditionType = "ExtensionReady"
SchemaReadyConditionType = "SchemaReady"
)

// Status reasons
Expand All @@ -28,8 +29,11 @@ const (
UserProvisioningSuccessfulReason = "UserProvisioningSuccessful"
CredentialsNotFoundReason = "CredentialsNotFound"
CreateDatabaseFailedReason = "CreateDatabaseFailed"
CreateExtensionFailedReason = "CreateExtensionFailed"
CreateExtensionsFailedReason = "CreateExtensionsFailed"
CreateSchemasFailedReason = "CreateSchemasFailed"
ProgressingReason = "ProgressingReason"
CreateExtensionsSuccessfulReason = "CreateExtensionsSuccessful"
CreateSchemasSuccessfulReason = "CreateSchemasSuccessful"
)

// DatabaseSpec defines the desired state of a *Database
Expand Down
25 changes: 25 additions & 0 deletions api/v1beta1/postgresqldatabase_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,26 @@ type Extension struct {
// Extensions is a collection of Extension types
type Extensions []Extension

// Schema is a resource representing database schema
type Schema struct {
Name string `json:"name"`
}

// Schemas is a collection of Schema types
type Schemas []Schema

// PostgreSQLDatabaseSpec defines the desired state of PostgreSQLDatabase
type PostgreSQLDatabaseSpec struct {
*DatabaseSpec `json:",inline"`

// Database extensions
// +optional
Extensions Extensions `json:"extensions,omitempty"`

// Database schemas
// +kubebuilder:default:={{name: public}}
// +optional
Schemas Schemas `json:"schemas,omitempty"`
}

// GetStatusConditions returns a pointer to the Status.Conditions slice
Expand Down Expand Up @@ -104,6 +117,18 @@ func ExtensionNotReadyCondition(in conditionalResource, reason, message string)
setResourceCondition(in, ExtensionReadyConditionType, metav1.ConditionFalse, reason, message)
}

func SchemaNotReadyCondition(in conditionalResource, reason, message string) {
setResourceCondition(in, SchemaReadyConditionType, metav1.ConditionFalse, reason, message)
}

func ExtensionReadyCondition(in conditionalResource, reason, message string) {
setResourceCondition(in, ExtensionReadyConditionType, metav1.ConditionTrue, reason, message)
}

func SchemaReadyCondition(in conditionalResource, reason, message string) {
setResourceCondition(in, SchemaReadyConditionType, metav1.ConditionTrue, reason, message)
}

func (d *PostgreSQLDatabase) SetDefaults() error {
if d.Spec.DatabaseName == "" {
d.Spec.DatabaseName = d.GetName()
Expand Down
39 changes: 39 additions & 0 deletions api/v1beta1/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 @@ -83,6 +83,19 @@ spec:
required:
- name
type: object
schemas:
default:
- name: public
description: Database schemas
items:
description: Schema is a resource representing database schema
properties:
name:
type: string
required:
- name
type: object
type: array
required:
- rootSecret
type: object
Expand Down
5 changes: 5 additions & 0 deletions common/database/postgresql.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,11 @@ func (s *PostgreSQLRepository) DropUser(ctx context.Context, user PostgresqlUser
return nil
}

func (s *PostgreSQLRepository) CreateSchema(ctx context.Context, db, name string) error {
_, err := s.conn.Exec(ctx, fmt.Sprintf("CREATE SCHEMA IF NOT EXISTS %s;", (pgx.Identifier{name}).Sanitize()))
return err
}

func (s *PostgreSQLRepository) EnableExtension(ctx context.Context, db, name string) error {
if extensionExists, err := s.doesExtensionExist(ctx, db, name); err != nil {
return err
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,19 @@ spec:
required:
- name
type: object
schemas:
default:
- name: public
description: Database schemas
items:
description: Schema is a resource representing database schema
properties:
name:
type: string
required:
- name
type: object
type: array
required:
- rootSecret
type: object
Expand Down
8 changes: 4 additions & 4 deletions controllers/mongodbuser_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ func (r *MongoDBUserReconciler) reconcile(ctx context.Context, user infrav1beta1

err := r.Client.Get(ctx, databaseName, &db)
if err != nil {
err = fmt.Errorf("Referencing database was not found: %w", err)
err = fmt.Errorf("referencing database was not found: %w", err)
infrav1beta1.UserNotReadyCondition(&user, infrav1beta1.DatabaseNotFoundReason, err.Error())
return user, err
}
Expand Down Expand Up @@ -236,7 +236,7 @@ func (r *MongoDBUserReconciler) reconcileGenericUser(ctx context.Context, user i

err = dbHandler.SetupUser(ctx, db.GetDatabaseName(), usr, pw, extractMongoDBUserRoles(user.GetRoles()))
if err != nil {
err = fmt.Errorf("Failed to provision user account: %w", err)
err = fmt.Errorf("failed to provision user account: %w", err)
infrav1beta1.UserNotReadyCondition(&user, infrav1beta1.ConnectionFailedReason, err.Error())
return user, err
}
Expand Down Expand Up @@ -278,7 +278,7 @@ func (r *MongoDBUserReconciler) reconcileAtlasUser(ctx context.Context, user inf

err = dbHandler.SetupUser(ctx, db.GetDatabaseName(), usr, pw, extractMongoDBUserRoles(user.GetRoles()))
if err != nil {
err = fmt.Errorf("Failed to provison user account: %w", err)
err = fmt.Errorf("failed to provison user account: %w", err)
infrav1beta1.UserNotReadyCondition(&user, infrav1beta1.ConnectionFailedReason, err.Error())
return user, err
}
Expand All @@ -291,7 +291,7 @@ func (r *MongoDBUserReconciler) reconcileAtlasUser(ctx context.Context, user inf
func (r *MongoDBUserReconciler) finalizeUser(ctx context.Context, user infrav1beta1.MongoDBUser, db infrav1beta1.MongoDBDatabase, userDropper userDropper) (infrav1beta1.MongoDBUser, error) {
err := userDropper.DropUser(ctx, db.GetDatabaseName(), user.Status.Username)
if err != nil {
err = fmt.Errorf("Failed to remove user account: %w", err)
err = fmt.Errorf("failed to remove user account: %w", err)
infrav1beta1.UserNotReadyCondition(&user, infrav1beta1.ConnectionFailedReason, err.Error())
return user, err
}
Expand Down
18 changes: 15 additions & 3 deletions controllers/postgresqldatabase_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ func (r *PostgreSQLDatabaseReconciler) reconcile(ctx context.Context, db infrav1

err = rootDBHandler.CreateDatabaseIfNotExists(ctx, db.GetDatabaseName())
if err != nil {
err = fmt.Errorf("Failed to provision database: %w", err)
err = fmt.Errorf("failed to provision database: %w", err)
infrav1beta1.DatabaseNotReadyCondition(&db, infrav1beta1.CreateDatabaseFailedReason, err.Error())
return db, err
}
Expand All @@ -184,12 +184,24 @@ func (r *PostgreSQLDatabaseReconciler) reconcile(ctx context.Context, db infrav1

for _, ext := range db.Spec.Extensions {
if err := dbHandler.EnableExtension(ctx, db.GetDatabaseName(), ext.Name); err != nil {
err = fmt.Errorf("Failed to create extension %s in database: %w", ext.Name, err)
infrav1beta1.ExtensionNotReadyCondition(&db, infrav1beta1.CreateExtensionFailedReason, err.Error())
err = fmt.Errorf("failed to create extension %s in database: %w", ext.Name, err)
infrav1beta1.ExtensionNotReadyCondition(&db, infrav1beta1.CreateExtensionsFailedReason, err.Error())
return db, err
}
}

infrav1beta1.ExtensionReadyCondition(&db, infrav1beta1.CreateExtensionsSuccessfulReason, "")

for _, schema := range db.Spec.Schemas {
if err := dbHandler.CreateSchema(ctx, db.GetDatabaseName(), schema.Name); err != nil {
err = fmt.Errorf("failed to create schemas %s in database: %w", schema.Name, err)
infrav1beta1.SchemaNotReadyCondition(&db, infrav1beta1.CreateSchemasFailedReason, err.Error())
return db, err
}
}

infrav1beta1.SchemaReadyCondition(&db, infrav1beta1.CreateSchemasSuccessfulReason, "")

return db, nil
}

Expand Down
8 changes: 4 additions & 4 deletions controllers/postgresqluser_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ func (r *PostgreSQLUserReconciler) reconcile(ctx context.Context, user infrav1be

err := r.Client.Get(ctx, databaseName, &db)
if err != nil {
err = fmt.Errorf("Referencing database was not found: %w", err)
err = fmt.Errorf("referencing database was not found: %w", err)
infrav1beta1.UserNotReadyCondition(&user, infrav1beta1.DatabaseNotFoundReason, err.Error())
return user, err
}
Expand Down Expand Up @@ -260,7 +260,7 @@ func (r *PostgreSQLUserReconciler) reconcile(ctx context.Context, user infrav1be

err = dbHandler.SetupUser(ctx, userSpec)
if err != nil {
err = fmt.Errorf("Failed to provison user account: %w", err)
err = fmt.Errorf("failed to provison user account: %w", err)
infrav1beta1.UserNotReadyCondition(&user, infrav1beta1.ConnectionFailedReason, err.Error())
return user, err
}
Expand Down Expand Up @@ -295,15 +295,15 @@ func (r *PostgreSQLUserReconciler) finalizeUser(ctx context.Context, user infrav
//Instead privileges are revoked and the password gets randomized
err := dbHandler.SetupUser(ctx, userSpec)
if err != nil {
err = fmt.Errorf("Failed to update user account: %w", err)
err = fmt.Errorf("failed to update user account: %w", err)
infrav1beta1.UserNotReadyCondition(&user, infrav1beta1.ConnectionFailedReason, err.Error())
return user, err
}

err = dbHandler.RevokeAllPrivileges(ctx, userSpec)

if err != nil {
err = fmt.Errorf("Failed to revoke privileges from user account: %w", err)
err = fmt.Errorf("failed to revoke privileges from user account: %w", err)
infrav1beta1.UserNotReadyCondition(&user, infrav1beta1.ConnectionFailedReason, err.Error())
return user, err
}
Expand Down
5 changes: 5 additions & 0 deletions renovate.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@
{
"semanticCommitScope": "deps-dev",
"matchManagers": ["github-actions"]
},
{
"description": "Automerge non-major updates",
"matchUpdateTypes": ["minor", "patch"],
"automerge": true
}
],
"postUpdateOptions": [
Expand Down

0 comments on commit 5e45246

Please sign in to comment.