Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update cluster status #8455

Merged
merged 3 commits into from
Jul 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions pkg/api/v1alpha1/condition_consts.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,12 @@ const (

// AutoscalerConstraintNotMetReason reports the Cluster status is waiting for autoscaler constraint to be met.
AutoscalerConstraintNotMetReason = "AutoscalerConstraintNotMet"

// KubeadmControlPlaneNotReadyReason reports that the kubeadm control plane is not ready.
KubeadmControlPlaneNotReadyReason = "KubeadmControlPlaneNotReady"

// MachineDeploymentNotReadyReason reports that the machine deployment is not ready.
MachineDeploymentNotReadyReason = "MachineDeploymentNotReady"
)

const (
Expand Down
37 changes: 32 additions & 5 deletions pkg/controller/clusters/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ import (

// UpdateClusterStatusForControlPlane checks the current state of the Cluster's control plane and updates the
// Cluster status information.
// There is a posibility that UpdateClusterStatusForControlPlane does not update the
// controleplane status specially in case where it still waiting for cluster objects to be created.
// There is a possibility that UpdateClusterStatusForControlPlane does not update the
// controlplane status specially in case where it is still waiting for cluster objects to be created.
func UpdateClusterStatusForControlPlane(ctx context.Context, client client.Client, cluster *anywherev1.Cluster) error {
kcp, err := controller.GetKubeadmControlPlane(ctx, client, cluster)
if err != nil {
Expand Down Expand Up @@ -114,8 +114,8 @@ func updateControlPlaneReadyCondition(cluster *anywherev1.Cluster, kcp *controlp
totalReplicas := int(kcp.Status.Replicas)

// First, in the case of a rolling upgrade, we get the number of outdated nodes, and as long as there are some,
// we want to reflect in the message that the Cluster is in progres upgdating the old nodes with the
// the new machine spec.
// we want to reflect in the message that the Cluster is in progress updating the old nodes with the
// new machine spec.
updatedReplicas := int(kcp.Status.UpdatedReplicas)
totalOutdated := totalReplicas - updatedReplicas

Expand Down Expand Up @@ -156,6 +156,14 @@ func updateControlPlaneReadyCondition(cluster *anywherev1.Cluster, kcp *controlp
return
}

// We check for the Ready condition on the kubeadm control plane as a final validation. Usually, the kcp objects
// should be ready at this point but if that is not the case, we report it as an error.
kubeadmControlPlaneReadyCondition := conditions.Get(kcp, clusterv1.ReadyCondition)
if kubeadmControlPlaneReadyCondition != nil && kubeadmControlPlaneReadyCondition.Status == v1.ConditionFalse {
conditions.MarkFalse(cluster, anywherev1.ControlPlaneReadyCondition, anywherev1.KubeadmControlPlaneNotReadyReason, clusterv1.ConditionSeverityError, "Kubeadm control plane %s not ready yet", kcp.ObjectMeta.Name)
return
}

conditions.MarkTrue(cluster, anywherev1.ControlPlaneReadyCondition)
}

Expand Down Expand Up @@ -235,7 +243,7 @@ func updateWorkersReadyCondition(cluster *anywherev1.Cluster, machineDeployments
}

// There may be worker nodes that are not up to date yet in the case of a rolling upgrade,
// so reflect that on the conditon with an appropriate message.
// so reflect that on the condition with an appropriate message.
totalOutdated := totalReplicas - totalUpdatedReplicas
if totalOutdated > 0 {
upgradeReason := anywherev1.RollingUpgradeInProgress
Expand Down Expand Up @@ -281,6 +289,25 @@ func updateWorkersReadyCondition(cluster *anywherev1.Cluster, machineDeployments
}
}

// We check for the Ready condition on the machine deployments as a final validation. Usually, the md objects
// should be ready at this point but if that is not the case, we report it as an error.
for _, md := range machineDeployments {
mdConditions := md.GetConditions()
if mdConditions == nil {
continue
}
var machineDeploymentReadyCondition *clusterv1.Condition
for _, condition := range mdConditions {
if condition.Type == clusterv1.ReadyCondition {
machineDeploymentReadyCondition = &condition
}
}
if machineDeploymentReadyCondition != nil && machineDeploymentReadyCondition.Status == v1.ConditionFalse {
conditions.MarkFalse(cluster, anywherev1.WorkersReadyCondition, anywherev1.MachineDeploymentNotReadyReason, clusterv1.ConditionSeverityError, "Machine deployment %s not ready yet", md.ObjectMeta.Name)
return
}
}

conditions.MarkTrue(cluster, anywherev1.WorkersReadyCondition)
}

Expand Down
100 changes: 85 additions & 15 deletions pkg/controller/clusters/status_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,37 @@ func TestUpdateClusterStatusForControlPlane(t *testing.T) {
Status: "False",
},
},
{
name: "kcp not ready yet",
kcp: test.KubeadmControlPlane(func(kcp *controlplanev1.KubeadmControlPlane) {
kcp.Status.Replicas = 3
kcp.Status.ReadyReplicas = 3
kcp.Status.UpdatedReplicas = 3

kcp.Status.Conditions = []clusterv1.Condition{
{
Type: clusterv1.ReadyCondition,
Status: "False",
},
}
}),
controlPlaneCount: 3,
conditions: []anywherev1.Condition{
{
Type: anywherev1.ControlPlaneInitializedCondition,
Status: "True",
},
},
externalEtcdCount: 0,
externalEtcdCluster: nil,
wantCondition: &anywherev1.Condition{
Type: anywherev1.ControlPlaneReadyCondition,
Status: "False",
Reason: anywherev1.KubeadmControlPlaneNotReadyReason,
Severity: clusterv1.ConditionSeverityError,
Message: "Kubeadm control plane test-cluster not ready yet",
},
},
{
name: "control plane ready",
kcp: test.KubeadmControlPlane(func(kcp *controlplanev1.KubeadmControlPlane) {
Expand Down Expand Up @@ -1011,33 +1042,28 @@ func TestUpdateClusterStatusForWorkers(t *testing.T) {
},
},
{
name: "workers ready",
name: "workers not ready, md not ready yet",
workerNodeGroupConfigurations: []anywherev1.WorkerNodeGroupConfiguration{
{
Count: ptr.Int(1),
},
{
Count: ptr.Int(2),
},
},
machineDeployments: []clusterv1.MachineDeployment{
*test.MachineDeployment(func(md *clusterv1.MachineDeployment) {
md.ObjectMeta.Name = "md-0"
md.ObjectMeta.Labels = map[string]string{
clusterv1.ClusterNameLabel: clusterName,
}
md.Status.Replicas = 1
md.Status.ReadyReplicas = 1
md.Status.Replicas = 1
md.Status.UpdatedReplicas = 1
}),
*test.MachineDeployment(func(md *clusterv1.MachineDeployment) {
md.ObjectMeta.Name = "md-1"
md.ObjectMeta.Labels = map[string]string{
clusterv1.ClusterNameLabel: clusterName,

md.Status.Conditions = []clusterv1.Condition{
{
Type: clusterv1.ReadyCondition,
Status: "False",
},
}
md.Status.Replicas = 2
md.Status.ReadyReplicas = 2
md.Status.UpdatedReplicas = 2
}),
},
conditions: []anywherev1.Condition{
Expand All @@ -1047,8 +1073,11 @@ func TestUpdateClusterStatusForWorkers(t *testing.T) {
},
},
wantCondition: &anywherev1.Condition{
Type: anywherev1.WorkersReadyCondition,
Status: "True",
Type: anywherev1.WorkersReadyCondition,
Status: "False",
Reason: anywherev1.MachineDeploymentNotReadyReason,
Severity: clusterv1.ConditionSeverityError,
Message: "Machine deployment md-0 not ready yet",
},
},
{
Expand Down Expand Up @@ -1152,6 +1181,47 @@ func TestUpdateClusterStatusForWorkers(t *testing.T) {
Status: "True",
},
},
{
name: "workers ready",
workerNodeGroupConfigurations: []anywherev1.WorkerNodeGroupConfiguration{
{
Count: ptr.Int(1),
},
{
Count: ptr.Int(2),
},
},
machineDeployments: []clusterv1.MachineDeployment{
*test.MachineDeployment(func(md *clusterv1.MachineDeployment) {
md.ObjectMeta.Name = "md-0"
md.ObjectMeta.Labels = map[string]string{
clusterv1.ClusterNameLabel: clusterName,
}
md.Status.Replicas = 1
md.Status.ReadyReplicas = 1
md.Status.UpdatedReplicas = 1
}),
*test.MachineDeployment(func(md *clusterv1.MachineDeployment) {
md.ObjectMeta.Name = "md-1"
md.ObjectMeta.Labels = map[string]string{
clusterv1.ClusterNameLabel: clusterName,
}
md.Status.Replicas = 2
md.Status.ReadyReplicas = 2
md.Status.UpdatedReplicas = 2
}),
},
conditions: []anywherev1.Condition{
{
Type: anywherev1.ControlPlaneInitializedCondition,
Status: "True",
},
},
wantCondition: &anywherev1.Condition{
Type: anywherev1.WorkersReadyCondition,
Status: "True",
},
},
}

for _, tt := range tests {
Expand Down
Loading