package check_sts_deploy_status
import (
"errors"
"fmt"
appsv1 "k8s.io/api/apps/v1"
)
// IsDeploymentReady 检查 Deployment 是否到达终态
// 终态条件:
// 1. ObservedGeneration 等于 Generation(控制器已看到最新的 spec)
// 2. UpdatedReplicas 等于 spec.Replicas(所有副本已更新)
// 3. ReadyReplicas 等于 spec.Replicas(所有副本已就绪)
// 4. AvailableReplicas 等于 spec.Replicas(所有副本可用)
// 5. Available condition 为 True
// 6. Progressing condition 为 True 且 Reason 为 NewReplicaSetAvailable
// 返回值:
// - bool: 是否到达终态
// - error: 错误信息,当资源未到达终态时返回具体原因
func IsDeploymentReady(deploy *appsv1.Deployment) (bool, error) {
// 检查 Deployment 是否为 nil
if deploy == nil {
return false, errors.New("deployment is nil")
}
// 检查 ObservedGeneration 是否等于 Generation
if deploy.Status.ObservedGeneration < deploy.Generation {
return false, fmt.Errorf("observed generation %d < generation %d", deploy.Status.ObservedGeneration, deploy.Generation)
}
// 检查 spec.Replicas 是否为 nil
if deploy.Spec.Replicas == nil {
return false, errors.New("deployment spec.replicas is nil")
}
// 检查 UpdatedReplicas 是否等于 spec.Replicas
if deploy.Status.UpdatedReplicas != *deploy.Spec.Replicas {
return false, fmt.Errorf("updated replicas %d != spec.replicas %d", deploy.Status.UpdatedReplicas, *deploy.Spec.Replicas)
}
// 检查 ReadyReplicas 是否等于 spec.Replicas
if deploy.Status.ReadyReplicas != *deploy.Spec.Replicas {
return false, fmt.Errorf("ready replicas %d != spec.replicas %d", deploy.Status.ReadyReplicas, *deploy.Spec.Replicas)
}
// 检查 AvailableReplicas 是否等于 spec.Replicas
if deploy.Status.AvailableReplicas != *deploy.Spec.Replicas {
return false, fmt.Errorf("available replicas %d != spec.replicas %d", deploy.Status.AvailableReplicas, *deploy.Spec.Replicas)
}
// 检查 conditions
for _, cond := range deploy.Status.Conditions {
// 检查 Available condition 是否为 True
if cond.Type == appsv1.DeploymentAvailable && cond.Status != "True" {
return false, fmt.Errorf("deployment available condition is %s, not True", cond.Status)
}
// 检查 Progressing condition
if cond.Type == appsv1.DeploymentProgressing {
// 检查 Progressing condition 是否为 True
if cond.Status != "True" {
return false, fmt.Errorf("deployment progressing condition is %s, not True", cond.Status)
}
// 检查 Progressing reason 是否为 NewReplicaSetAvailable
if cond.Reason != "NewReplicaSetAvailable" {
return false, fmt.Errorf("deployment progressing reason is %s, not NewReplicaSetAvailable", cond.Reason)
}
}
}
// 所有条件都满足,到达终态
return true, nil
}
// IsStatefulSetReady 检查 StatefulSet 是否到达终态
// 终态条件:
// 1. ObservedGeneration 等于 Generation(控制器已看到最新的 spec)
// 2. UpdatedReplicas 等于 spec.Replicas(所有副本已更新)
// 3. ReadyReplicas 等于 spec.Replicas(所有副本已就绪)
// 4. AvailableReplicas 等于 spec.Replicas(所有副本可用)
// 5. CurrentRevision 等于 UpdateRevision(版本一致)
// 返回值:
// - bool: 是否到达终态
// - error: 错误信息,当资源未到达终态时返回具体原因
func IsStatefulSetReady(sts *appsv1.StatefulSet) (bool, error) {
// 检查 StatefulSet 是否为 nil
if sts == nil {
return false, errors.New("statefulset is nil")
}
// 检查 ObservedGeneration 是否等于 Generation
if sts.Status.ObservedGeneration < sts.Generation {
return false, fmt.Errorf("observed generation %d < generation %d", sts.Status.ObservedGeneration, sts.Generation)
}
// 检查 spec.Replicas 是否为 nil
if sts.Spec.Replicas == nil {
return false, errors.New("statefulset spec.replicas is nil")
}
// 检查 UpdatedReplicas 是否等于 spec.Replicas
if sts.Status.UpdatedReplicas != *sts.Spec.Replicas {
return false, fmt.Errorf("updated replicas %d != spec.replicas %d", sts.Status.UpdatedReplicas, *sts.Spec.Replicas)
}
// 检查 ReadyReplicas 是否等于 spec.Replicas
if sts.Status.ReadyReplicas != *sts.Spec.Replicas {
return false, fmt.Errorf("ready replicas %d != spec.replicas %d", sts.Status.ReadyReplicas, *sts.Spec.Replicas)
}
// 检查 AvailableReplicas 是否等于 spec.Replicas
if sts.Status.AvailableReplicas != *sts.Spec.Replicas {
return false, fmt.Errorf("available replicas %d != spec.replicas %d", sts.Status.AvailableReplicas, *sts.Spec.Replicas)
}
// 检查 CurrentRevision 是否等于 UpdateRevision
if sts.Status.CurrentRevision != sts.Status.UpdateRevision {
return false, fmt.Errorf("current revision %s != update revision %s", sts.Status.CurrentRevision, sts.Status.UpdateRevision)
}
// 所有条件都满足,到达终态
return true, nil
}