From e9d7a1cccd317d44394a91e7df85211aa9e4ccbc Mon Sep 17 00:00:00 2001 From: Brent Eagles Date: Fri, 22 Sep 2023 10:20:46 -0230 Subject: [PATCH] Conditions cleanup Patch introduces some octavia specific condition types and fixes some missing ready status updates in the umbrella controller. --- api/v1beta1/amphoracontroller_types.go | 9 +++ api/v1beta1/conditions.go | 72 ++++++++++++++++++++ controllers/octavia_controller.go | 93 +++++++++++++++++++++----- 3 files changed, 158 insertions(+), 16 deletions(-) create mode 100644 api/v1beta1/conditions.go diff --git a/api/v1beta1/amphoracontroller_types.go b/api/v1beta1/amphoracontroller_types.go index 187bdfcb..cedf1daa 100644 --- a/api/v1beta1/amphoracontroller_types.go +++ b/api/v1beta1/amphoracontroller_types.go @@ -23,6 +23,15 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) +const ( + // HealthManager is the role name for amphora controllers for the Octavia Health Manager services + HealthManager = "healthmanager" + // Housekeeping is the role name for amphora controllers for the Octavia Housekeeping services + Housekeeping = "housekeeping" + // Worker is the role name for amphora controllers for the Octavia Workerservices + Worker = "worker" +) + // OctaviaAmphoraControllerSpec defines common state for all Octavia Amphora Controllers type OctaviaAmphoraControllerSpec struct { // +kubebuilder:validation:Required diff --git a/api/v1beta1/conditions.go b/api/v1beta1/conditions.go new file mode 100644 index 00000000..07c7fa44 --- /dev/null +++ b/api/v1beta1/conditions.go @@ -0,0 +1,72 @@ +/* +Copyright 2023. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1beta1 + +import ( + condition "github.com/openstack-k8s-operators/lib-common/modules/common/condition" +) + +// Octavia Condition Types used by API Objects +const ( + // OctaviaAPIReadyCondition Status=True condition which indicates that the OctaviaAPI is configured and operational. + OctaviaAPIReadyCondition condition.Type = "OctaviaAPIReady" + + OctaviaHealthManagerReadyCondition condition.Type = "OctaviaHealthManagerReady" + + OctaviaHousekeepingReadyCondition condition.Type = "OctaviaHousekeepingReady" + + OctaviaWorkerReadyCondition condition.Type = "OctaviaWorkerReady" +) + +// Common Messages used by API objects +const ( + // + // OctaviaAPIReady condition messages + // + // OctaviaAPIReadyInitMessage + OctaviaAPIReadyInitMessage = "OctaviaAPI not started" + + // OctaviaAPIReadyErrorMessage + OctaviaAPIReadyErrorMessage = "OctaviaAPI error occured %s" + + // + // OctaviaHealthManagerReady condition messages + // + // OctaviaHealthManagerReadyInitMessage + OctaviaHealthManagerReadyInitMessage = "OctaviaHealthManager is not started" + + // OctaviaHealthManagerReadyErrorMessage + OctaviaHealthManagerReadyErrorMessage = "OctaviaHealthManager error occured %s" + + // + // OctaviaHousekeepingReady condition messages + // + // OctaviaHousekeepingReadyInitMessage + OctaviaHousekeepingReadyInitMessage = "OctaviaHousekeeping are not started" + + // OctaviaAmphoraControllerReadyErrorMessage + OctaviaHousekeepingReadyErrorMessage = "OctaviaHousekeeping error occured %s" + + // + // OctaviaWorkerReady condition messages + // + // OctaviaWorkerReadyInitMessage + OctaviaWorkerReadyInitMessage = "OctaviaWorker are not started" + + // OctaviaAmphoraControllerReadyErrorMessage + OctaviaWorkerReadyErrorMessage = "OctaviaWorker error occured %s" +) diff --git a/controllers/octavia_controller.go b/controllers/octavia_controller.go index 452c3bd7..a9403d7e 100644 --- a/controllers/octavia_controller.go +++ b/controllers/octavia_controller.go @@ -150,11 +150,16 @@ func (r *OctaviaReconciler) Reconcile(ctx context.Context, req ctrl.Request) (re cl := condition.CreateList( condition.UnknownCondition(condition.DBReadyCondition, condition.InitReason, condition.DBReadyInitMessage), condition.UnknownCondition(condition.DBSyncReadyCondition, condition.InitReason, condition.DBSyncReadyInitMessage), + condition.UnknownCondition(condition.RabbitMqTransportURLReadyCondition, condition.InitReason, condition.RabbitMqTransportURLReadyInitMessage), condition.UnknownCondition(condition.InputReadyCondition, condition.InitReason, condition.InputReadyInitMessage), condition.UnknownCondition(condition.ServiceConfigReadyCondition, condition.InitReason, condition.ServiceConfigReadyInitMessage), condition.UnknownCondition(condition.ServiceAccountReadyCondition, condition.InitReason, condition.ServiceAccountReadyInitMessage), condition.UnknownCondition(condition.RoleReadyCondition, condition.InitReason, condition.RoleReadyInitMessage), condition.UnknownCondition(condition.RoleBindingReadyCondition, condition.InitReason, condition.RoleBindingReadyInitMessage), + condition.UnknownCondition(octaviav1.OctaviaAPIReadyCondition, condition.InitReason, octaviav1.OctaviaAPIReadyInitMessage), + amphoraControllerInitCondition(octaviav1.HealthManager), + amphoraControllerInitCondition(octaviav1.Housekeeping), + amphoraControllerInitCondition(octaviav1.Worker), ) instance.Status.Conditions.Init(&cl) @@ -379,10 +384,10 @@ func (r *OctaviaReconciler) reconcileNormal(ctx context.Context, instance *octav transportURL, op, err := r.transportURLCreateOrUpdate(instance) if err != nil { instance.Status.Conditions.Set(condition.FalseCondition( - condition.InputReadyCondition, - condition.RequestedReason, - condition.SeverityInfo, - condition.InputReadyWaitingMessage)) + condition.RabbitMqTransportURLReadyCondition, + condition.ErrorReason, + condition.SeverityWarning, + condition.RabbitMqTransportURLReadyErrorMessage, err.Error())) return ctrl.Result{}, err } @@ -519,10 +524,10 @@ func (r *OctaviaReconciler) reconcileNormal(ctx context.Context, instance *octav octaviaAPI, op, err := r.apiDeploymentCreateOrUpdate(instance) if err != nil { instance.Status.Conditions.Set(condition.FalseCondition( - condition.ReadyCondition, + octaviav1.OctaviaAPIReadyCondition, condition.ErrorReason, condition.SeverityWarning, - "OctaviaAPI error occurred %s", + octaviav1.OctaviaAPIReadyErrorMessage, err.Error())) return ctrl.Result{}, err } @@ -534,18 +539,20 @@ func (r *OctaviaReconciler) reconcileNormal(ctx context.Context, instance *octav // TODO(beagles): We need to have a way to aggregate conditions from the other services into this // instance.Status.OctaviaAPIReadyCount = octaviaAPI.Status.ReadyCount - conditionStatus := octaviaAPI.Status.Conditions.Mirror(condition.ReadyCondition) + conditionStatus := octaviaAPI.Status.Conditions.Mirror(octaviav1.OctaviaAPIReadyCondition) if conditionStatus != nil { instance.Status.Conditions.Set(conditionStatus) + } else { + instance.Status.Conditions.MarkTrue(octaviav1.OctaviaAPIReadyCondition, condition.DeploymentReadyMessage) } - octaviaHousekeeping, op, err := r.amphoraControllerDeploymentCreateOrUpdate(instance, instance.Spec.OctaviaHousekeeping, "housekeeping") + octaviaHousekeeping, op, err := r.amphoraControllerDeploymentCreateOrUpdate(instance, instance.Spec.OctaviaHousekeeping, octaviav1.Housekeeping) if err != nil { instance.Status.Conditions.Set(condition.FalseCondition( - condition.ReadyCondition, + amphoraControllerReadyCondition(octaviav1.Housekeeping), condition.ErrorReason, condition.SeverityWarning, - "OctaviaHousekeeping error occurred %s", + amphoraControllerErrorMessage(octaviav1.Housekeeping), err.Error())) return ctrl.Result{}, err } @@ -555,14 +562,20 @@ func (r *OctaviaReconciler) reconcileNormal(ctx context.Context, instance *octav } instance.Status.OctaviaHousekeepingReadyCount = octaviaHousekeeping.Status.ReadyCount + conditionStatus = octaviaHousekeeping.Status.Conditions.Mirror(amphoraControllerReadyCondition(octaviav1.Housekeeping)) + if conditionStatus != nil { + instance.Status.Conditions.Set(conditionStatus) + } else { + instance.Status.Conditions.MarkTrue(amphoraControllerReadyCondition(octaviav1.Housekeeping), condition.DeploymentReadyMessage) + } - octaviaHealthManager, op, err := r.amphoraControllerDeploymentCreateOrUpdate(instance, instance.Spec.OctaviaHealthManager, "healthmanager") + octaviaHealthManager, op, err := r.amphoraControllerDeploymentCreateOrUpdate(instance, instance.Spec.OctaviaHealthManager, octaviav1.HealthManager) if err != nil { instance.Status.Conditions.Set(condition.FalseCondition( - condition.ReadyCondition, + amphoraControllerReadyCondition(octaviav1.HealthManager), condition.ErrorReason, condition.SeverityWarning, - "OctaviaHealthManager error occurred %s", + amphoraControllerErrorMessage(octaviav1.HealthManager), err.Error())) return ctrl.Result{}, err } @@ -572,14 +585,20 @@ func (r *OctaviaReconciler) reconcileNormal(ctx context.Context, instance *octav } instance.Status.OctaviaHealthManagerReadyCount = octaviaHealthManager.Status.ReadyCount + conditionStatus = octaviaHealthManager.Status.Conditions.Mirror(amphoraControllerReadyCondition(octaviav1.HealthManager)) + if conditionStatus != nil { + instance.Status.Conditions.Set(conditionStatus) + } else { + instance.Status.Conditions.MarkTrue(amphoraControllerReadyCondition(octaviav1.HealthManager), condition.DeploymentReadyMessage) + } - octaviaWorker, op, err := r.amphoraControllerDeploymentCreateOrUpdate(instance, instance.Spec.OctaviaWorker, "worker") + octaviaWorker, op, err := r.amphoraControllerDeploymentCreateOrUpdate(instance, instance.Spec.OctaviaWorker, octaviav1.Worker) if err != nil { instance.Status.Conditions.Set(condition.FalseCondition( - condition.ReadyCondition, + amphoraControllerReadyCondition(octaviav1.Worker), condition.ErrorReason, condition.SeverityWarning, - "OctaviaWorker error occurred %s", + amphoraControllerErrorMessage(octaviav1.Worker), err.Error())) return ctrl.Result{}, err } @@ -589,6 +608,12 @@ func (r *OctaviaReconciler) reconcileNormal(ctx context.Context, instance *octav } instance.Status.OctaviaWorkerReadyCount = octaviaWorker.Status.ReadyCount + conditionStatus = octaviaWorker.Status.Conditions.Mirror(amphoraControllerReadyCondition(octaviav1.Worker)) + if conditionStatus != nil { + instance.Status.Conditions.Set(conditionStatus) + } else { + instance.Status.Conditions.MarkTrue(amphoraControllerReadyCondition(octaviav1.Worker), condition.DeploymentReadyMessage) + } // create Deployment - end @@ -761,3 +786,39 @@ func (r *OctaviaReconciler) amphoraControllerDeploymentCreateOrUpdate( return deployment, op, err } + +func amphoraControllerReadyCondition(role string) condition.Type { + condMap := map[string]condition.Type{ + octaviav1.HealthManager: octaviav1.OctaviaHealthManagerReadyCondition, + octaviav1.Housekeeping: octaviav1.OctaviaHousekeepingReadyCondition, + octaviav1.Worker: octaviav1.OctaviaWorkerReadyCondition, + } + return condMap[role] +} + +func amphoraControllerInitCondition(role string) *condition.Condition { + condMap := map[string]*condition.Condition{ + octaviav1.HealthManager: condition.UnknownCondition( + amphoraControllerReadyCondition(role), + condition.InitReason, + octaviav1.OctaviaHealthManagerReadyInitMessage), + octaviav1.Housekeeping: condition.UnknownCondition( + amphoraControllerReadyCondition(role), + condition.InitReason, + octaviav1.OctaviaHousekeepingReadyInitMessage), + octaviav1.Worker: condition.UnknownCondition( + amphoraControllerReadyCondition(role), + condition.InitReason, + octaviav1.OctaviaWorkerReadyInitMessage), + } + return condMap[role] +} + +func amphoraControllerErrorMessage(role string) string { + condMap := map[string]string{ + octaviav1.HealthManager: octaviav1.OctaviaHealthManagerReadyErrorMessage, + octaviav1.Housekeeping: octaviav1.OctaviaHousekeepingReadyErrorMessage, + octaviav1.Worker: octaviav1.OctaviaWorkerReadyErrorMessage, + } + return condMap[role] +}