Skip to content

Commit

Permalink
add conditions for mariadbdatabase
Browse files Browse the repository at this point in the history
by adding conditions, we allow the mariadbaccount to start its
work before the mariadbdatabase is fully completed.

this also brings MariaDBDatabase into the same condition style
as other controllers in play.
  • Loading branch information
zzzeek committed Jan 16, 2024
1 parent 6fb96fd commit 69fbe67
Show file tree
Hide file tree
Showing 8 changed files with 215 additions and 6 deletions.
43 changes: 43 additions & 0 deletions api/bases/mariadb.openstack.org_mariadbdatabases.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,49 @@ spec:
properties:
completed:
type: boolean
conditions:
description: Deployment Conditions
items:
description: Condition defines an observation of a API resource
operational state.
properties:
lastTransitionTime:
description: Last time the condition transitioned from one status
to another. This should be when the underlying condition changed.
If that is not known, then using the time when the API field
changed is acceptable.
format: date-time
type: string
message:
description: A human readable message indicating details about
the transition.
type: string
reason:
description: The reason for the condition's last transition
in CamelCase.
type: string
severity:
description: Severity provides a classification of Reason code,
so the current situation is immediately understandable and
could act accordingly. It is meant for situations where Status=False
and it should be indicated if it is just informational, warning
(next reconciliation might fix it) or an error (e.g. DB create
issue and no actions to automatically resolve the issue can/should
be done). For conditions where Status=Unknown or Status=True
the Severity should be SeverityNone.
type: string
status:
description: Status of the condition, one of True, False, Unknown.
type: string
type:
description: Type of condition in CamelCase.
type: string
required:
- lastTransitionTime
- status
- type
type: object
type: array
hash:
additionalProperties:
type: string
Expand Down
2 changes: 2 additions & 0 deletions api/v1beta1/conditions.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ const (

MariaDBServerReadyMessage = "MariaDB / Galera server ready"

MariaDBServerNotBootstrappedMessage = "MariaDB / Galera server not bootstrapped"

MariaDBAccountReadyInitMessage = "MariaDBAccount create / drop not started"

MariaDBAccountReadyMessage = "MariaDBAccount creation complete"
Expand Down
4 changes: 4 additions & 0 deletions api/v1beta1/mariadbdatabase_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package v1beta1

import (
condition "github.com/openstack-k8s-operators/lib-common/modules/common/condition"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

Expand Down Expand Up @@ -44,6 +45,9 @@ type MariaDBDatabaseSpec struct {

// MariaDBDatabaseStatus defines the observed state of MariaDBDatabase
type MariaDBDatabaseStatus struct {
// Deployment Conditions
Conditions condition.Conditions `json:"conditions,omitempty" optional:"true"`

Completed bool `json:"completed,omitempty"`
// Map of hashes to track e.g. job status
Hash map[string]string `json:"hash,omitempty"`
Expand Down
7 changes: 7 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.

43 changes: 43 additions & 0 deletions config/crd/bases/mariadb.openstack.org_mariadbdatabases.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,49 @@ spec:
properties:
completed:
type: boolean
conditions:
description: Deployment Conditions
items:
description: Condition defines an observation of a API resource
operational state.
properties:
lastTransitionTime:
description: Last time the condition transitioned from one status
to another. This should be when the underlying condition changed.
If that is not known, then using the time when the API field
changed is acceptable.
format: date-time
type: string
message:
description: A human readable message indicating details about
the transition.
type: string
reason:
description: The reason for the condition's last transition
in CamelCase.
type: string
severity:
description: Severity provides a classification of Reason code,
so the current situation is immediately understandable and
could act accordingly. It is meant for situations where Status=False
and it should be indicated if it is just informational, warning
(next reconciliation might fix it) or an error (e.g. DB create
issue and no actions to automatically resolve the issue can/should
be done). For conditions where Status=Unknown or Status=True
the Severity should be SeverityNone.
type: string
status:
description: Status of the condition, one of True, False, Unknown.
type: string
type:
description: Type of condition in CamelCase.
type: string
required:
- lastTransitionTime
- status
- type
type: object
type: array
hash:
additionalProperties:
type: string
Expand Down
16 changes: 12 additions & 4 deletions controllers/mariadbaccount_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,8 @@ func (r *MariaDBAccountReconciler) reconcileCreate(
instance.Name, instance.ObjectMeta.Labels["mariaDBDatabaseName"]))

return ctrl.Result{RequeueAfter: time.Duration(10) * time.Second}, nil
} else if err == nil && !mariadbDatabase.Status.Completed {
// found but not in completed status.
} else if err == nil && !mariadbDatabase.Status.Conditions.IsTrue(databasev1beta1.MariaDBDatabaseReadyCondition) {
// found but database not ready

// for the create case, need to wait for the MariaDBDatabase to exists before we can continue;
// requeue
Expand Down Expand Up @@ -356,8 +356,8 @@ func (r *MariaDBAccountReconciler) reconcileDelete(
controllerutil.RemoveFinalizer(instance, helper.GetFinalizer())

return ctrl.Result{}, nil
} else if err == nil && !mariadbDatabase.Status.Completed {
// found but not in completed status.
} else if err == nil && !mariadbDatabase.Status.Conditions.IsTrue(databasev1beta1.MariaDBDatabaseReadyCondition) {
// found but database is not ready

// for the delete case, the database doesn't exist. so
// that means we don't, either. remove finalizer from
Expand Down Expand Up @@ -427,6 +427,14 @@ func (r *MariaDBAccountReconciler) reconcileDelete(

if !dbGalera.Status.Bootstrapped {
log.Info("DB bootstrap not complete. Requeue...")

instance.Status.Conditions.MarkFalse(
databasev1beta1.MariaDBServerReadyCondition,
databasev1beta1.ReasonDBWaitingInitialized,
condition.SeverityInfo,
databasev1beta1.MariaDBServerNotBootstrappedMessage,
)

return ctrl.Result{RequeueAfter: time.Second * 10}, nil
}

Expand Down
56 changes: 54 additions & 2 deletions controllers/mariadbdatabase_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"

condition "github.com/openstack-k8s-operators/lib-common/modules/common/condition"
helper "github.com/openstack-k8s-operators/lib-common/modules/common/helper"
job "github.com/openstack-k8s-operators/lib-common/modules/common/job"
databasev1beta1 "github.com/openstack-k8s-operators/mariadb-operator/api/v1beta1"
Expand Down Expand Up @@ -73,13 +74,49 @@ func (r *MariaDBDatabaseReconciler) Reconcile(ctx context.Context, req ctrl.Requ

// Always patch the instance status when exiting this function so we can persist any changes.
defer func() {
if instance.Status.Conditions.AllSubConditionIsTrue() {
// update the Ready condition based on the sub conditions

instance.Status.Conditions.MarkTrue(
condition.ReadyCondition, condition.ReadyMessage)
} else {
// something is not ready so reset the Ready condition
instance.Status.Conditions.MarkUnknown(
condition.ReadyCondition, condition.InitReason, condition.ReadyInitMessage)
// and recalculate it based on the state of the rest of the conditions
instance.Status.Conditions.Set(
instance.Status.Conditions.Mirror(condition.ReadyCondition))
}

if instance.Status.Conditions.IsTrue(condition.ReadyCondition) {
// database creation finished... okay to set to completed
instance.Status.Completed = true
}

err := helper.PatchInstance(ctx, instance)

if err != nil {
_err = err
return
}

}()

if instance.Status.Conditions == nil {
instance.Status.Conditions = condition.Conditions{}

// initialize conditions used later as Status=Unknown
cl := condition.CreateList(
condition.UnknownCondition(databasev1beta1.MariaDBServerReadyCondition, condition.InitReason, databasev1beta1.MariaDBServerReadyInitMessage),
condition.UnknownCondition(databasev1beta1.MariaDBDatabaseReadyCondition, condition.InitReason, databasev1beta1.MariaDBDatabaseReadyInitMessage),
)

instance.Status.Conditions.Init(&cl)

// Register overall status immediately to have an early feedback e.g. in the cli
return ctrl.Result{}, nil
}

// Fetch the Galera instance from which we'll pull the credentials
dbGalera, err := r.getDatabaseObject(ctx, instance)

Expand Down Expand Up @@ -133,6 +170,14 @@ func (r *MariaDBDatabaseReconciler) Reconcile(ctx context.Context, req ctrl.Requ

if !dbGalera.Status.Bootstrapped {
log.Info("DB bootstrap not complete. Requeue...")

instance.Status.Conditions.MarkFalse(
databasev1beta1.MariaDBServerReadyCondition,
databasev1beta1.ReasonDBWaitingInitialized,
condition.SeverityInfo,
databasev1beta1.MariaDBServerNotBootstrappedMessage,
)

return ctrl.Result{RequeueAfter: time.Second * 10}, nil
}

Expand All @@ -141,6 +186,11 @@ func (r *MariaDBDatabaseReconciler) Reconcile(ctx context.Context, req ctrl.Requ
dbContainerImage = dbGalera.Spec.ContainerImage
serviceAccount = dbGalera.RbacResourceName()

instance.Status.Conditions.MarkTrue(
databasev1beta1.MariaDBServerReadyCondition,
databasev1beta1.MariaDBServerReadyMessage,
)

// Define a new Job object (hostname, password, containerImage)
jobDef, err := mariadb.DbDatabaseJob(instance, dbName, dbSecret, dbContainerImage, serviceAccount)
if err != nil {
Expand Down Expand Up @@ -173,8 +223,10 @@ func (r *MariaDBDatabaseReconciler) Reconcile(ctx context.Context, req ctrl.Requ
log.Info("Job hash added", "Job", jobDef.Name, "Hash", instance.Status.Hash[databasev1beta1.DbCreateHash])
}

// database creation finished... okay to set to completed
instance.Status.Completed = true
instance.Status.Conditions.MarkTrue(
databasev1beta1.MariaDBDatabaseReadyCondition,
databasev1beta1.MariaDBDatabaseReadyMessage,
)

return ctrl.Result{}, nil
}
Expand Down
50 changes: 50 additions & 0 deletions tests/kuttl/tests/database_create/02-assert.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,53 @@ metadata:
name: kuttldb-latin1-db-create
status:
succeeded: 1
---
apiVersion: mariadb.openstack.org/v1beta1
kind: MariaDBDatabase
metadata:
name: kuttldb-utf8
labels:
dbName: openstack
spec:
secret: osp-secret
name: kuttldb_utf8
status:
conditions:
- message: Setup complete
reason: Ready
status: "True"
type: Ready
- message: MariaDBDatabase ready
reason: Ready
status: "True"
type: MariaDBDatabaseReady
- message: MariaDB / Galera server ready
reason: Ready
status: "True"
type: MariaDBServerReady
completed: true
---
apiVersion: mariadb.openstack.org/v1beta1
kind: MariaDBDatabase
metadata:
name: kuttldb-latin1
labels:
dbName: openstack
spec:
secret: osp-secret
name: kuttldb_latin1
status:
conditions:
- message: Setup complete
reason: Ready
status: "True"
type: Ready
- message: MariaDBDatabase ready
reason: Ready
status: "True"
type: MariaDBDatabaseReady
- message: MariaDB / Galera server ready
reason: Ready
status: "True"
type: MariaDBServerReady
completed: true

0 comments on commit 69fbe67

Please sign in to comment.