Skip to content

Commit

Permalink
link MariaDBAccount to the Database api
Browse files Browse the repository at this point in the history
This replaces the MariaDBDatabase.secret attribute
with the use of MariaDBAccount instead.

also applies an interim fix to allow the encoding/collation to be
present in the Database API, otherwise the database pod would fail.

Amends MariaDBAccount to return from delete if the owning Galera
resource is already deleted.
  • Loading branch information
zzzeek committed Jan 11, 2024
1 parent 55df79e commit 7a4fceb
Show file tree
Hide file tree
Showing 9 changed files with 129 additions and 35 deletions.
3 changes: 0 additions & 3 deletions api/bases/mariadb.openstack.org_mariadbdatabases.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,6 @@ spec:
name:
description: Name of the database in MariaDB
type: string
secret:
description: Name of secret which contains DatabasePassword
type: string
required:
- defaultCharacterSet
- defaultCollation
Expand Down
115 changes: 110 additions & 5 deletions api/v1beta1/mariadbdatabase_funcs.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,11 @@ func (d *Database) GetDatabase() *MariaDBDatabase {
return d.database
}

// GetAccount - returns the account
func (d *Database) GetAccount() *MariaDBAccount {
return d.account
}

// CreateOrPatchDB - create or patch the service DB instance
// Deprecated. Use CreateOrPatchDBByName instead. If you want to use the
// default the DB service instance of the deployment then pass "openstack" as
Expand Down Expand Up @@ -157,11 +162,28 @@ func (d *Database) CreateOrPatchDBByName(
},
Spec: MariaDBDatabaseSpec{
// the DB name must not change, therefore specify it outside the mutuate function
Name: d.databaseName,
Name: d.databaseName,
DefaultCharacterSet: "utf8",
DefaultCollation: "utf8_general_ci",
},
}
}

account := d.account
if account == nil {
account = &MariaDBAccount{
ObjectMeta: metav1.ObjectMeta{
Name: d.databaseUser,
Namespace: d.namespace,
Labels: map[string]string{
"mariaDBDatabaseName": d.name,
},
},
Spec: MariaDBAccountSpec{
UserName: d.databaseUser,
},
}
}
// set the database hostname on the db instance
err := d.setDatabaseHostname(ctx, h, name)
if err != nil {
Expand All @@ -174,8 +196,6 @@ func (d *Database) CreateOrPatchDBByName(
d.labels,
)

db.Spec.Secret = d.secret

err := controllerutil.SetControllerReference(h.GetBeforeObject(), db, h.GetScheme())
if err != nil {
return err
Expand All @@ -200,6 +220,38 @@ func (d *Database) CreateOrPatchDBByName(
return ctrl.Result{RequeueAfter: time.Second * 5}, nil
}

op_acc, err_acc := controllerutil.CreateOrPatch(ctx, h.GetClient(), account, func() error {
account.Labels = util.MergeStringMaps(
account.GetLabels(),
d.labels,
)

account.Spec.Secret = d.secret

err := controllerutil.SetControllerReference(h.GetBeforeObject(), account, h.GetScheme())
if err != nil {
return err
}

// If the service object doesn't have our finalizer, add it.
controllerutil.AddFinalizer(account, h.GetFinalizer())

return nil
})

if err_acc != nil && !k8s_errors.IsNotFound(err_acc) {
return ctrl.Result{}, util.WrapErrorForObject(
fmt.Sprintf("Error create or update account object %s", account.Name),
account,
err_acc,
)
}

if op_acc != controllerutil.OperationResultNone {
util.LogForObject(h, fmt.Sprintf("Account object %s created or patched", account.Name), account)
return ctrl.Result{RequeueAfter: time.Second * 5}, nil
}

err = d.getDBWithName(
ctx,
h,
Expand All @@ -211,7 +263,9 @@ func (d *Database) CreateOrPatchDBByName(
return ctrl.Result{}, nil
}

// WaitForDBCreatedWithTimeout - wait until the MariaDBDatabase is initialized and reports Status.Completed == true
// WaitForDBCreatedWithTimeout - wait until the MariaDBDatabase and MariaDBAccounts are
// initialized and reports Status.Conditions.IsTrue(MariaDBDatabaseReadyCondition)
// and Status.Conditions.IsTrue(MariaDBAccountReadyCondition)
func (d *Database) WaitForDBCreatedWithTimeout(
ctx context.Context,
h *helper.Helper,
Expand All @@ -226,7 +280,7 @@ func (d *Database) WaitForDBCreatedWithTimeout(
return ctrl.Result{}, err
}

if !d.database.Status.Completed || k8s_errors.IsNotFound(err) {
if !d.database.Status.Conditions.IsTrue(MariaDBDatabaseReadyCondition) {
util.LogForObject(
h,
fmt.Sprintf("Waiting for service DB %s to be created", d.database.Name),
Expand All @@ -236,6 +290,26 @@ func (d *Database) WaitForDBCreatedWithTimeout(
return ctrl.Result{RequeueAfter: requeueAfter}, nil
}

if !d.account.Status.Conditions.IsTrue(MariaDBAccountReadyCondition) {
util.LogForObject(
h,
fmt.Sprintf("Waiting for service account %s to be created", d.account.Name),
d.account,
)

return ctrl.Result{RequeueAfter: requeueAfter}, nil
}

if k8s_errors.IsNotFound(err) {
util.LogForObject(
h,
fmt.Sprintf("DB or account objects not yet found %s", d.database.Name),
d.database,
)

return ctrl.Result{RequeueAfter: requeueAfter}, nil
}

return ctrl.Result{}, nil
}

Expand All @@ -262,13 +336,15 @@ func (d *Database) getDBWithName(
if namespace == "" {
namespace = h.GetBeforeObject().GetNamespace()
}

err := h.GetClient().Get(
ctx,
types.NamespacedName{
Name: name,
Namespace: namespace,
},
db)

if err != nil {
if k8s_errors.IsNotFound(err) {
return util.WrapErrorForObject(
Expand All @@ -287,6 +363,35 @@ func (d *Database) getDBWithName(

d.database = db

account := &MariaDBAccount{}
username := d.databaseUser

err = h.GetClient().Get(
ctx,
types.NamespacedName{
Name: username,
Namespace: namespace,
},
account)

if err != nil {
if k8s_errors.IsNotFound(err) {
return util.WrapErrorForObject(
fmt.Sprintf("Failed to get %s account %s ", username, namespace),
h.GetBeforeObject(),
err,
)
}

return util.WrapErrorForObject(
fmt.Sprintf("account error %s %s ", username, namespace),
h.GetBeforeObject(),
err,
)
}

d.account = account

return nil
}

Expand Down
3 changes: 1 addition & 2 deletions api/v1beta1/mariadbdatabase_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@ const (

// MariaDBDatabaseSpec defines the desired state of MariaDBDatabase
type MariaDBDatabaseSpec struct {
// Name of secret which contains DatabasePassword
Secret string `json:"secret,omitempty"`
// Name of the database in MariaDB
Name string `json:"name,omitempty"`
// +kubebuilder:default=utf8
Expand Down Expand Up @@ -88,6 +86,7 @@ const (
// Database -
type Database struct {
database *MariaDBDatabase
account *MariaDBAccount
databaseHostname string
databaseName string
databaseUser string
Expand Down
5 changes: 5 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.

3 changes: 0 additions & 3 deletions config/crd/bases/mariadb.openstack.org_mariadbdatabases.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,6 @@ spec:
name:
description: Name of the database in MariaDB
type: string
secret:
description: Name of secret which contains DatabasePassword
type: string
required:
- defaultCharacterSet
- defaultCollation
Expand Down
19 changes: 11 additions & 8 deletions controllers/mariadbaccount_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -429,16 +429,19 @@ func (r *MariaDBAccountReconciler) reconcileDelete(

// remove local finalizer
controllerutil.RemoveFinalizer(instance, helper.GetFinalizer())
}

instance.Status.Conditions.Set(condition.FalseCondition(
databasev1beta1.MariaDBServerReadyCondition,
condition.ErrorReason,
condition.SeverityError,
"Error retrieving MariaDB/Galera instance %s",
err))
// galera DB does not exist, so return
return ctrl.Result{}, nil
} else {
instance.Status.Conditions.Set(condition.FalseCondition(
databasev1beta1.MariaDBServerReadyCondition,
condition.ErrorReason,
condition.SeverityError,
"Error retrieving MariaDB/Galera instance %s",
err))

return ctrl.Result{}, err
return ctrl.Result{}, err
}
}

var dbInstance, dbAdminSecret, dbContainerImage, serviceAccountName string
Expand Down
11 changes: 0 additions & 11 deletions pkg/mariadb/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,17 +66,6 @@ func DbDatabaseJob(database *databasev1beta1.MariaDBDatabase, databaseHostName s
},
},
},
{
Name: "DatabasePassword",
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
LocalObjectReference: corev1.LocalObjectReference{
Name: database.Spec.Secret,
},
Key: "DatabasePassword",
},
},
},
},
},
},
Expand Down
3 changes: 1 addition & 2 deletions templates/database.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#!/bin/bash
export DatabasePassword=${DatabasePassword:?"Please specify a DatabasePassword variable."}

mysql -h {{.DatabaseHostname}} -u {{.DatabaseAdminUsername}} -P 3306 -e "CREATE DATABASE IF NOT EXISTS {{.DatabaseName}}; ALTER DATABASE {{.DatabaseName}} CHARACTER SET '{{.DefaultCharacterSet}}' COLLATE '{{.DefaultCollation}}'; GRANT ALL PRIVILEGES ON {{.DatabaseName}}.* TO '{{.DatabaseName}}'@'localhost' IDENTIFIED BY '$DatabasePassword';GRANT ALL PRIVILEGES ON {{.DatabaseName}}.* TO '{{.DatabaseName}}'@'%' IDENTIFIED BY '$DatabasePassword';"
mysql -h {{.DatabaseHostname}} -u {{.DatabaseAdminUsername}} -P 3306 -e "CREATE DATABASE IF NOT EXISTS {{.DatabaseName}}; ALTER DATABASE {{.DatabaseName}} CHARACTER SET '{{.DefaultCharacterSet}}' COLLATE '{{.DefaultCollation}}';"
2 changes: 1 addition & 1 deletion templates/delete_database.sh
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
#!/bin/bash

mysql -h {{.DatabaseHostname}} -u {{.DatabaseAdminUsername}} -P 3306 -e "DROP DATABASE IF EXISTS {{.DatabaseName}}; DROP USER IF EXISTS '{{.DatabaseName}}'@'localhost'; DROP USER IF EXISTS '{{.DatabaseName}}'@'%';"
mysql -h {{.DatabaseHostname}} -u {{.DatabaseAdminUsername}} -P 3306 -e "DROP DATABASE IF EXISTS {{.DatabaseName}};"

0 comments on commit 7a4fceb

Please sign in to comment.