diff --git a/api/v1/aerospikecluster_types.go b/api/v1/aerospikecluster_types.go index 13196062f..0ee8dcc94 100644 --- a/api/v1/aerospikecluster_types.go +++ b/api/v1/aerospikecluster_types.go @@ -669,6 +669,12 @@ type AerospikeClusterStatusSpec struct { //nolint:govet // for readability // In case of inconsistent state during dynamic config update, operator falls back to rolling restart. // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Enable Dynamic Config Update" EnableDynamicConfigUpdate *bool `json:"enableDynamicConfigUpdate,omitempty"` + + // IsClusterReadinessEnabled determines if the cluster is readiness enabled i.e. readiness probe is + // present in all pods. + // This field is used to determine if PodDisruptionBudget should be created for the Aerospike cluster or not. + // +optional + IsClusterReadinessEnabled bool `json:"isClusterReadinessEnabled"` // Define resources requests and limits for Aerospike Server Container. // Please contact aerospike for proper sizing exercise // Only Memory and Cpu resources can be given diff --git a/config/crd/bases/asdb.aerospike.com_aerospikeclusters.yaml b/config/crd/bases/asdb.aerospike.com_aerospikeclusters.yaml index 899c699e0..9be77f862 100644 --- a/config/crd/bases/asdb.aerospike.com_aerospikeclusters.yaml +++ b/config/crd/bases/asdb.aerospike.com_aerospikeclusters.yaml @@ -9618,6 +9618,12 @@ spec: image: description: Aerospike server image type: string + isClusterReadinessEnabled: + description: IsClusterReadinessEnabled determines if the cluster is + readiness enabled i.e. readiness probe is present in all pods. This + field is used to determine if PodDisruptionBudget should be created + for the Aerospike cluster or not. + type: boolean k8sNodeBlockList: description: K8sNodeBlockList is a list of Kubernetes nodes which are not used for Aerospike pods. diff --git a/controllers/poddistruptionbudget.go b/controllers/poddistruptionbudget.go index a130675a7..a97e89057 100644 --- a/controllers/poddistruptionbudget.go +++ b/controllers/poddistruptionbudget.go @@ -63,24 +63,16 @@ func (r *SingleClusterReconciler) deletePDB() error { } func (r *SingleClusterReconciler) createOrUpdatePDB() error { - podList, err := r.getClusterPodList() - if err != nil { - return err - } - - for podIdx := range podList.Items { - pod := &podList.Items[podIdx] - - for containerIdx := range pod.Spec.Containers { - if pod.Spec.Containers[containerIdx].Name != asdbv1.AerospikeServerContainerName { - continue - } + if !r.IsStatusEmpty() { + clusterReadinessEnabled, err := r.getClusterReadinessStatus() + if err != nil { + return fmt.Errorf("failed to get cluster readiness status: %v", err) + } - if pod.Spec.Containers[containerIdx].ReadinessProbe == nil { - r.Log.Info("Pod found without ReadinessProbe, skipping PodDisruptionBudget. Refer Aerospike "+ - "documentation for more details.", "name", pod.Name) - return nil - } + if !clusterReadinessEnabled { + r.Log.Info("Pod Readiness is not enabled throughout cluster. Skipping PodDisruptionBudget." + + " Refer Aerospike documentation for more details.") + return nil } } diff --git a/controllers/reconciler.go b/controllers/reconciler.go index d16e38875..fa7becdfe 100644 --- a/controllers/reconciler.go +++ b/controllers/reconciler.go @@ -417,6 +417,13 @@ func (r *SingleClusterReconciler) updateStatus() error { newAeroCluster.Status.AerospikeClusterStatusSpec = *specToStatus newAeroCluster.Status.Phase = asdbv1.AerospikeClusterCompleted + clusterReadinessEnable, err := r.getClusterReadinessStatus() + if err != nil { + return fmt.Errorf("failed to get cluster readiness status: %v", err) + } + + newAeroCluster.Status.IsClusterReadinessEnabled = clusterReadinessEnable + err = r.patchStatus(newAeroCluster) if err != nil { return fmt.Errorf("error updating status: %w", err) @@ -442,6 +449,29 @@ func (r *SingleClusterReconciler) setStatusPhase(phase asdbv1.AerospikeClusterPh return nil } +func (r *SingleClusterReconciler) getClusterReadinessStatus() (bool, error) { + podList, err := r.getClusterPodList() + if err != nil { + return false, err + } + + for podIdx := range podList.Items { + pod := &podList.Items[podIdx] + + for containerIdx := range pod.Spec.Containers { + if pod.Spec.Containers[containerIdx].Name != asdbv1.AerospikeServerContainerName { + continue + } + + if pod.Spec.Containers[containerIdx].ReadinessProbe == nil { + return false, nil + } + } + } + + return true, nil +} + func (r *SingleClusterReconciler) updateAccessControlStatus() error { if r.aeroCluster.Spec.AerospikeAccessControl == nil { return nil diff --git a/helm-charts/aerospike-kubernetes-operator/crds/customresourcedefinition_aerospikeclusters.asdb.aerospike.com.yaml b/helm-charts/aerospike-kubernetes-operator/crds/customresourcedefinition_aerospikeclusters.asdb.aerospike.com.yaml index 899c699e0..9be77f862 100644 --- a/helm-charts/aerospike-kubernetes-operator/crds/customresourcedefinition_aerospikeclusters.asdb.aerospike.com.yaml +++ b/helm-charts/aerospike-kubernetes-operator/crds/customresourcedefinition_aerospikeclusters.asdb.aerospike.com.yaml @@ -9618,6 +9618,12 @@ spec: image: description: Aerospike server image type: string + isClusterReadinessEnabled: + description: IsClusterReadinessEnabled determines if the cluster is + readiness enabled i.e. readiness probe is present in all pods. This + field is used to determine if PodDisruptionBudget should be created + for the Aerospike cluster or not. + type: boolean k8sNodeBlockList: description: K8sNodeBlockList is a list of Kubernetes nodes which are not used for Aerospike pods.