refactor: consolidate Instance phase handlers
This commit is contained in:
@@ -16,58 +16,115 @@ limitations under the License.
|
||||
|
||||
package controller
|
||||
|
||||
import databasev1alpha1 "git.ddupan.top/panxiao81/postgresql-tenant-operator/api/v1alpha1"
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
type instancePhaseResult struct {
|
||||
phase databasev1alpha1.PostgreSQLInstancePhase
|
||||
reconcilingMessage string
|
||||
}
|
||||
databasev1alpha1 "git.ddupan.top/panxiao81/postgresql-tenant-operator/api/v1alpha1"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
)
|
||||
|
||||
type instancePhaseHandler func(*databasev1alpha1.PostgreSQLInstance) instancePhaseResult
|
||||
type instancePhaseHandler func(context.Context, *databasev1alpha1.PostgreSQLInstance) (ctrl.Result, error)
|
||||
|
||||
type instanceStateMachine struct {
|
||||
handlers map[databasev1alpha1.PostgreSQLInstancePhase]instancePhaseHandler
|
||||
initializer PostgreSQLInstanceInitializer
|
||||
handlers map[databasev1alpha1.PostgreSQLInstancePhase]instancePhaseHandler
|
||||
}
|
||||
|
||||
func newInstanceStateMachine() instanceStateMachine {
|
||||
return instanceStateMachine{handlers: map[databasev1alpha1.PostgreSQLInstancePhase]instancePhaseHandler{
|
||||
databasev1alpha1.PostgreSQLInstancePhasePending: reconcileInstancePending,
|
||||
databasev1alpha1.PostgreSQLInstancePhaseValidating: keepInstancePhase,
|
||||
databasev1alpha1.PostgreSQLInstancePhaseInitializingRegistry: keepInstancePhase,
|
||||
databasev1alpha1.PostgreSQLInstancePhaseReady: keepInstancePhase,
|
||||
databasev1alpha1.PostgreSQLInstancePhaseDeleting: reconcileInstanceDeleting,
|
||||
}}
|
||||
func newInstanceStateMachine(initializer PostgreSQLInstanceInitializer) *instanceStateMachine {
|
||||
m := &instanceStateMachine{initializer: initializer}
|
||||
m.handlers = map[databasev1alpha1.PostgreSQLInstancePhase]instancePhaseHandler{
|
||||
databasev1alpha1.PostgreSQLInstancePhasePending: m.pending,
|
||||
databasev1alpha1.PostgreSQLInstancePhaseValidating: m.validate,
|
||||
databasev1alpha1.PostgreSQLInstancePhaseInitializingRegistry: m.initializeRegistry,
|
||||
databasev1alpha1.PostgreSQLInstancePhaseReady: m.ready,
|
||||
databasev1alpha1.PostgreSQLInstancePhaseDeleting: m.deleting,
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
func (m instanceStateMachine) reconcile(instance *databasev1alpha1.PostgreSQLInstance) instancePhaseResult {
|
||||
func (m *instanceStateMachine) reconcile(ctx context.Context, instance *databasev1alpha1.PostgreSQLInstance) (ctrl.Result, error) {
|
||||
phase := instance.Status.Phase
|
||||
if !instance.DeletionTimestamp.IsZero() {
|
||||
phase = databasev1alpha1.PostgreSQLInstancePhaseDeleting
|
||||
} else if phase == "" {
|
||||
phase = databasev1alpha1.PostgreSQLInstancePhasePending
|
||||
}
|
||||
|
||||
handler, found := m.handlers[phase]
|
||||
if !found {
|
||||
return instancePhaseResult{phase: phase}
|
||||
handler = m.pending
|
||||
}
|
||||
return handler(instance)
|
||||
result, err := handler(ctx, instance)
|
||||
if err != nil {
|
||||
instance.Status.ObservedGeneration = instance.Generation
|
||||
reason := databasev1alpha1.ReasonDependencyUnavailable
|
||||
var categorized interface{ ConditionReason() string }
|
||||
if errors.As(err, &categorized) {
|
||||
reason = categorized.ConditionReason()
|
||||
}
|
||||
setFailedCondition(&instance.Status.Conditions, instance.Generation, reason, "instance dependency validation failed")
|
||||
}
|
||||
return result, err
|
||||
}
|
||||
|
||||
func reconcileInstancePending(*databasev1alpha1.PostgreSQLInstance) instancePhaseResult {
|
||||
return instancePhaseResult{
|
||||
phase: databasev1alpha1.PostgreSQLInstancePhaseValidating,
|
||||
reconcilingMessage: "instance dependencies are being validated",
|
||||
}
|
||||
func (m *instanceStateMachine) pending(_ context.Context, instance *databasev1alpha1.PostgreSQLInstance) (ctrl.Result, error) {
|
||||
return advanceInstance(instance, databasev1alpha1.PostgreSQLInstancePhaseValidating,
|
||||
"instance dependencies are being validated"), nil
|
||||
}
|
||||
|
||||
func reconcileInstanceDeleting(*databasev1alpha1.PostgreSQLInstance) instancePhaseResult {
|
||||
return instancePhaseResult{
|
||||
phase: databasev1alpha1.PostgreSQLInstancePhaseDeleting,
|
||||
reconcilingMessage: "instance deletion is reconciling",
|
||||
func (m *instanceStateMachine) validate(ctx context.Context, instance *databasev1alpha1.PostgreSQLInstance) (ctrl.Result, error) {
|
||||
if m.initializer == nil {
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
version, err := m.initializer.Validate(ctx, instance)
|
||||
if err != nil {
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
instance.Status.PostgreSQLVersion = version
|
||||
return advanceInstance(instance, databasev1alpha1.PostgreSQLInstancePhaseInitializingRegistry,
|
||||
"PostgreSQL registry is being initialized"), nil
|
||||
}
|
||||
|
||||
func keepInstancePhase(instance *databasev1alpha1.PostgreSQLInstance) instancePhaseResult {
|
||||
return instancePhaseResult{phase: instance.Status.Phase}
|
||||
func (m *instanceStateMachine) initializeRegistry(ctx context.Context, instance *databasev1alpha1.PostgreSQLInstance) (ctrl.Result, error) {
|
||||
if m.initializer == nil {
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
version, err := m.initializer.InitializeRegistry(ctx, instance)
|
||||
if err != nil {
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
instance.Status.PostgreSQLVersion = version
|
||||
instance.Status.Phase = databasev1alpha1.PostgreSQLInstancePhaseReady
|
||||
instance.Status.ObservedGeneration = instance.Generation
|
||||
setReadyCondition(&instance.Status.Conditions, instance.Generation, "instance dependencies are ready")
|
||||
return ctrl.Result{RequeueAfter: time.Minute}, nil
|
||||
}
|
||||
|
||||
func (m *instanceStateMachine) ready(ctx context.Context, instance *databasev1alpha1.PostgreSQLInstance) (ctrl.Result, error) {
|
||||
if instance.Status.ObservedGeneration != instance.Generation {
|
||||
return m.pending(ctx, instance)
|
||||
}
|
||||
if m.initializer == nil {
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
version, err := m.initializer.Validate(ctx, instance)
|
||||
if err != nil {
|
||||
instance.Status.Phase = databasev1alpha1.PostgreSQLInstancePhaseValidating
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
instance.Status.PostgreSQLVersion = version
|
||||
return ctrl.Result{RequeueAfter: time.Minute}, nil
|
||||
}
|
||||
|
||||
func (m *instanceStateMachine) deleting(_ context.Context, instance *databasev1alpha1.PostgreSQLInstance) (ctrl.Result, error) {
|
||||
instance.Status.Phase = databasev1alpha1.PostgreSQLInstancePhaseDeleting
|
||||
setReconcilingCondition(&instance.Status.Conditions, instance.Generation, "instance deletion is reconciling")
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
func advanceInstance(instance *databasev1alpha1.PostgreSQLInstance, phase databasev1alpha1.PostgreSQLInstancePhase, message string) ctrl.Result {
|
||||
instance.Status.Phase = phase
|
||||
setReconcilingCondition(&instance.Status.Conditions, instance.Generation, message)
|
||||
return ctrl.Result{RequeueAfter: time.Millisecond}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user