// Copyright 2020-2026 Project Capsule Authors // SPDX-License-Identifier: Apache-2.0 package meta import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" ) const ( // ReadyCondition indicates the resource is ready and fully reconciled. ReadyCondition string = "Ready" CordonedCondition string = "Cordoned" TerminatingCondition string = "Terminating" NotReadyCondition string = "NotReady" AssignedCondition string = "Assigned" BoundCondition string = "Bound" ExhaustedCondition string = "Exhausted" // FailedReason indicates a condition or event observed a failure (Claim Rejected). SucceededReason string = "Succeeded" FailedReason string = "Failed" ActiveReason string = "Active" CordonedReason string = "Cordoned" TerminatingReason string = "Terminating" ReconcilingReason string = "Reconciling" PoolExhaustedReason string = "PoolExhausted" QueueExhaustedReason string = "QueueExhausted" NamespaceExhaustedReason string = "NamespaceExhausted" NoExhaustionsReason string = "NoExhaustions" InUseReason string = "InUse" UnusedReason string = "Unused" PendingUnmanagedContentReason string = "PendingUnmanagedContent" ) func IsStatusConditionTrue(conditions ConditionList, conditionType string) bool { cond := conditions.GetConditionByType(conditionType) if cond == nil { return false } return cond.Status == metav1.ConditionTrue } // +kubebuilder:object:generate=true type ConditionList []Condition // Adds a condition by type. func (c *ConditionList) GetConditionByType(conditionType string) *Condition { for i := range *c { if (*c)[i].Type == conditionType { return &(*c)[i] } } return nil } // Adds a condition by type. func (c *ConditionList) UpdateConditionByType(condition Condition) { for i, cond := range *c { if cond.Type == condition.Type { (*c)[i].UpdateCondition(condition) return } } *c = append(*c, condition) } func (c *ConditionList) UpdateConditionByTypeWithStatus(condition Condition) (updated bool) { for i, cond := range *c { if cond.Type == condition.Type { return (*c)[i].UpdateCondition(condition) } } *c = append(*c, condition) return true } // Removes a condition by type. func (c *ConditionList) RemoveConditionByType(condition string) { if c == nil { return } filtered := make(ConditionList, 0, len(*c)) for _, cond := range *c { if cond.Type != condition { filtered = append(filtered, cond) } } *c = filtered } // +kubebuilder:object:generate=true type Condition metav1.Condition func NewReadyCondition(obj client.Object) Condition { return Condition{ Type: ReadyCondition, Status: metav1.ConditionTrue, Reason: SucceededReason, Message: "reconciled", LastTransitionTime: metav1.Now(), } } func NewCordonedCondition(obj client.Object) Condition { return Condition{ Type: CordonedCondition, Status: metav1.ConditionFalse, Reason: ActiveReason, Message: "not cordoned", LastTransitionTime: metav1.Now(), } } func NewExhaustedCondition(obj client.Object) Condition { return Condition{ Type: ExhaustedCondition, ObservedGeneration: obj.GetGeneration(), LastTransitionTime: metav1.Now(), Reason: NoExhaustionsReason, Message: "no exhaustions", Status: metav1.ConditionFalse, } } func NewBoundCondition(obj client.Object) Condition { return Condition{ Type: BoundCondition, ObservedGeneration: obj.GetGeneration(), LastTransitionTime: metav1.Now(), Message: "bound by pool", } } func NewAssignedCondition(obj client.Object) Condition { return Condition{ Type: AssignedCondition, ObservedGeneration: obj.GetGeneration(), LastTransitionTime: metav1.Now(), Message: "assigned to pool", } } func NewReadyConditionReconcilingReason(obj client.Object) Condition { return Condition{ Type: ReadyCondition, Status: metav1.ConditionUnknown, Reason: ReconcilingReason, Message: "processing", LastTransitionTime: metav1.Now(), } } func NewTerminatingConditionReason(obj client.Object) Condition { return Condition{ Type: TerminatingCondition, Status: metav1.ConditionTrue, Reason: SucceededReason, Message: "cleaning up", LastTransitionTime: metav1.Now(), } } // Disregards fields like LastTransitionTime and Version, which are not relevant for the API. func (c *Condition) UpdateCondition(condition Condition) (updated bool) { if condition.Type == c.Type && condition.Status == c.Status && condition.Reason == c.Reason && condition.Message == c.Message && condition.ObservedGeneration == c.ObservedGeneration { return false } if condition.Status != c.Status { c.LastTransitionTime = metav1.Now() } c.Type = condition.Type c.Status = condition.Status c.Reason = condition.Reason c.Message = condition.Message c.ObservedGeneration = condition.ObservedGeneration c.LastTransitionTime = condition.LastTransitionTime return true }