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.  The MariaDBDatabase.secret
attribute becomes optional and deprecated.  Once all
consuming operators have moved to the new Database API,
MariaDBDatabase.secret can be removed entirely.

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 22, 2024
1 parent 69fbe67 commit 4d759dd
Show file tree
Hide file tree
Showing 14 changed files with 282 additions and 85 deletions.
5 changes: 1 addition & 4 deletions api/bases/mariadb.openstack.org_mariadbdatabases.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,8 @@ spec:
description: Name of the database in MariaDB
type: string
secret:
description: Name of secret which contains DatabasePassword
description: Name of secret which contains DatabasePassword (deprecated)
type: string
required:
- defaultCharacterSet
- defaultCollation
type: object
status:
description: MariaDBDatabaseStatus defines the observed state of MariaDBDatabase
Expand Down
110 changes: 106 additions & 4 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 @@ -162,6 +167,22 @@ func (d *Database) CreateOrPatchDBByName(
}
}

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,
Secret: d.secret,
},
}
}
// set the database hostname on the db instance
err := d.setDatabaseHostname(ctx, h, name)
if err != nil {
Expand All @@ -174,8 +195,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 +219,36 @@ 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,
)

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 +260,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 +277,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 +287,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 +333,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 +360,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
9 changes: 5 additions & 4 deletions api/v1beta1/mariadbdatabase_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,16 @@ const (

// MariaDBDatabaseSpec defines the desired state of MariaDBDatabase
type MariaDBDatabaseSpec struct {
// Name of secret which contains DatabasePassword
Secret string `json:"secret,omitempty"`
// Name of secret which contains DatabasePassword (deprecated)
Secret *string `json:"secret,omitempty"`
// Name of the database in MariaDB
Name string `json:"name,omitempty"`
// +kubebuilder:default=utf8
// Default character set for this database
DefaultCharacterSet string `json:"defaultCharacterSet"`
DefaultCharacterSet string `json:"defaultCharacterSet,omitempty"`
// +kubebuilder:default=utf8_general_ci
// Default collation for this database
DefaultCollation string `json:"defaultCollation"`
DefaultCollation string `json:"defaultCollation,omitempty"`
}

// MariaDBDatabaseStatus defines the observed state of MariaDBDatabase
Expand Down Expand Up @@ -88,6 +88,7 @@ const (
// Database -
type Database struct {
database *MariaDBDatabase
account *MariaDBAccount
databaseHostname string
databaseName string
databaseUser string
Expand Down
12 changes: 11 additions & 1 deletion api/v1beta1/zz_generated.deepcopy.go

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

5 changes: 1 addition & 4 deletions config/crd/bases/mariadb.openstack.org_mariadbdatabases.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,8 @@ spec:
description: Name of the database in MariaDB
type: string
secret:
description: Name of secret which contains DatabasePassword
description: Name of secret which contains DatabasePassword (deprecated)
type: string
required:
- defaultCharacterSet
- defaultCollation
type: object
status:
description: MariaDBDatabaseStatus defines the observed state of MariaDBDatabase
Expand Down
19 changes: 11 additions & 8 deletions controllers/mariadbaccount_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -411,16 +411,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
Loading

0 comments on commit 4d759dd

Please sign in to comment.