Merge pull request #120542 from alvaroaleman/condition-change

Apimeta Set/RemoveStatusCondition: Indicate change
This commit is contained in:
Kubernetes Prow Robot 2023-10-03 20:20:21 +02:00 committed by GitHub
commit fe84992651
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 62 additions and 19 deletions

View File

@ -22,14 +22,15 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
) )
// SetStatusCondition sets the corresponding condition in conditions to newCondition. // SetStatusCondition sets the corresponding condition in conditions to newCondition and returns true
// if the conditions are changed by this call.
// conditions must be non-nil. // conditions must be non-nil.
// 1. if the condition of the specified type already exists (all fields of the existing condition are updated to // 1. if the condition of the specified type already exists (all fields of the existing condition are updated to
// newCondition, LastTransitionTime is set to now if the new status differs from the old status) // newCondition, LastTransitionTime is set to now if the new status differs from the old status)
// 2. if a condition of the specified type does not exist (LastTransitionTime is set to now() if unset, and newCondition is appended) // 2. if a condition of the specified type does not exist (LastTransitionTime is set to now() if unset, and newCondition is appended)
func SetStatusCondition(conditions *[]metav1.Condition, newCondition metav1.Condition) { func SetStatusCondition(conditions *[]metav1.Condition, newCondition metav1.Condition) (changed bool) {
if conditions == nil { if conditions == nil {
return return false
} }
existingCondition := FindStatusCondition(*conditions, newCondition.Type) existingCondition := FindStatusCondition(*conditions, newCondition.Type)
if existingCondition == nil { if existingCondition == nil {
@ -37,7 +38,7 @@ func SetStatusCondition(conditions *[]metav1.Condition, newCondition metav1.Cond
newCondition.LastTransitionTime = metav1.NewTime(time.Now()) newCondition.LastTransitionTime = metav1.NewTime(time.Now())
} }
*conditions = append(*conditions, newCondition) *conditions = append(*conditions, newCondition)
return return true
} }
if existingCondition.Status != newCondition.Status { if existingCondition.Status != newCondition.Status {
@ -47,18 +48,31 @@ func SetStatusCondition(conditions *[]metav1.Condition, newCondition metav1.Cond
} else { } else {
existingCondition.LastTransitionTime = metav1.NewTime(time.Now()) existingCondition.LastTransitionTime = metav1.NewTime(time.Now())
} }
changed = true
} }
existingCondition.Reason = newCondition.Reason if existingCondition.Reason != newCondition.Reason {
existingCondition.Message = newCondition.Message existingCondition.Reason = newCondition.Reason
existingCondition.ObservedGeneration = newCondition.ObservedGeneration changed = true
}
if existingCondition.Message != newCondition.Message {
existingCondition.Message = newCondition.Message
changed = true
}
if existingCondition.ObservedGeneration != newCondition.ObservedGeneration {
existingCondition.ObservedGeneration = newCondition.ObservedGeneration
changed = true
}
return changed
} }
// RemoveStatusCondition removes the corresponding conditionType from conditions. // RemoveStatusCondition removes the corresponding conditionType from conditions if present. Returns
// true if it was present and got removed.
// conditions must be non-nil. // conditions must be non-nil.
func RemoveStatusCondition(conditions *[]metav1.Condition, conditionType string) { func RemoveStatusCondition(conditions *[]metav1.Condition, conditionType string) (removed bool) {
if conditions == nil || len(*conditions) == 0 { if conditions == nil || len(*conditions) == 0 {
return return false
} }
newConditions := make([]metav1.Condition, 0, len(*conditions)-1) newConditions := make([]metav1.Condition, 0, len(*conditions)-1)
for _, condition := range *conditions { for _, condition := range *conditions {
@ -67,7 +81,10 @@ func RemoveStatusCondition(conditions *[]metav1.Condition, conditionType string)
} }
} }
removed = len(*conditions) != len(newConditions)
*conditions = newConditions *conditions = newConditions
return removed
} }
// FindStatusCondition finds the conditionType in conditions. // FindStatusCondition finds the conditionType in conditions.

View File

@ -29,10 +29,11 @@ func TestSetStatusCondition(t *testing.T) {
oneHourAfter := time.Now().Add(1 * time.Hour) oneHourAfter := time.Now().Add(1 * time.Hour)
tests := []struct { tests := []struct {
name string name string
conditions []metav1.Condition conditions []metav1.Condition
toAdd metav1.Condition toAdd metav1.Condition
expected []metav1.Condition expectChanged bool
expected []metav1.Condition
}{ }{
{ {
name: "should-add", name: "should-add",
@ -40,7 +41,8 @@ func TestSetStatusCondition(t *testing.T) {
{Type: "first"}, {Type: "first"},
{Type: "third"}, {Type: "third"},
}, },
toAdd: metav1.Condition{Type: "second", Status: metav1.ConditionTrue, LastTransitionTime: metav1.Time{Time: oneHourBefore}, Reason: "reason", Message: "message"}, toAdd: metav1.Condition{Type: "second", Status: metav1.ConditionTrue, LastTransitionTime: metav1.Time{Time: oneHourBefore}, Reason: "reason", Message: "message"},
expectChanged: true,
expected: []metav1.Condition{ expected: []metav1.Condition{
{Type: "first"}, {Type: "first"},
{Type: "third"}, {Type: "third"},
@ -54,7 +56,8 @@ func TestSetStatusCondition(t *testing.T) {
{Type: "second", Status: metav1.ConditionFalse}, {Type: "second", Status: metav1.ConditionFalse},
{Type: "third"}, {Type: "third"},
}, },
toAdd: metav1.Condition{Type: "second", Status: metav1.ConditionTrue, LastTransitionTime: metav1.Time{Time: oneHourBefore}, Reason: "reason", Message: "message"}, toAdd: metav1.Condition{Type: "second", Status: metav1.ConditionTrue, LastTransitionTime: metav1.Time{Time: oneHourBefore}, Reason: "reason", Message: "message"},
expectChanged: true,
expected: []metav1.Condition{ expected: []metav1.Condition{
{Type: "first"}, {Type: "first"},
{Type: "second", Status: metav1.ConditionTrue, LastTransitionTime: metav1.Time{Time: oneHourBefore}, Reason: "reason", Message: "message"}, {Type: "second", Status: metav1.ConditionTrue, LastTransitionTime: metav1.Time{Time: oneHourBefore}, Reason: "reason", Message: "message"},
@ -68,18 +71,36 @@ func TestSetStatusCondition(t *testing.T) {
{Type: "second", Status: metav1.ConditionTrue, LastTransitionTime: metav1.Time{Time: oneHourBefore}}, {Type: "second", Status: metav1.ConditionTrue, LastTransitionTime: metav1.Time{Time: oneHourBefore}},
{Type: "third"}, {Type: "third"},
}, },
toAdd: metav1.Condition{Type: "second", Status: metav1.ConditionTrue, LastTransitionTime: metav1.Time{Time: oneHourAfter}, Reason: "reason", Message: "message", ObservedGeneration: 3}, toAdd: metav1.Condition{Type: "second", Status: metav1.ConditionTrue, LastTransitionTime: metav1.Time{Time: oneHourAfter}, Reason: "reason", Message: "message", ObservedGeneration: 3},
expectChanged: true,
expected: []metav1.Condition{ expected: []metav1.Condition{
{Type: "first"}, {Type: "first"},
{Type: "second", Status: metav1.ConditionTrue, LastTransitionTime: metav1.Time{Time: oneHourBefore}, Reason: "reason", Message: "message", ObservedGeneration: 3}, {Type: "second", Status: metav1.ConditionTrue, LastTransitionTime: metav1.Time{Time: oneHourBefore}, Reason: "reason", Message: "message", ObservedGeneration: 3},
{Type: "third"}, {Type: "third"},
}, },
}, },
{
name: "nothing changes",
conditions: []metav1.Condition{{
Type: "type",
Status: metav1.ConditionTrue,
LastTransitionTime: metav1.Time{Time: oneHourBefore},
}},
toAdd: metav1.Condition{Type: "type", Status: metav1.ConditionTrue, LastTransitionTime: metav1.Time{Time: oneHourBefore}},
expected: []metav1.Condition{{
Type: "type",
Status: metav1.ConditionTrue,
LastTransitionTime: metav1.Time{Time: oneHourBefore},
}},
},
} }
for _, test := range tests { for _, test := range tests {
t.Run(test.name, func(t *testing.T) { t.Run(test.name, func(t *testing.T) {
SetStatusCondition(&test.conditions, test.toAdd) changed := SetStatusCondition(&test.conditions, test.toAdd)
if test.expectChanged != changed {
t.Errorf("expectChanged=%t != changed=%t", test.expectChanged, changed)
}
if !reflect.DeepEqual(test.conditions, test.expected) { if !reflect.DeepEqual(test.conditions, test.expected) {
t.Error(test.conditions) t.Error(test.conditions)
} }
@ -92,6 +113,7 @@ func TestRemoveStatusCondition(t *testing.T) {
name string name string
conditions []metav1.Condition conditions []metav1.Condition
conditionType string conditionType string
expectRemoval bool
expected []metav1.Condition expected []metav1.Condition
}{ }{
{ {
@ -102,6 +124,7 @@ func TestRemoveStatusCondition(t *testing.T) {
{Type: "third"}, {Type: "third"},
}, },
conditionType: "second", conditionType: "second",
expectRemoval: true,
expected: []metav1.Condition{ expected: []metav1.Condition{
{Type: "first"}, {Type: "first"},
{Type: "third"}, {Type: "third"},
@ -131,7 +154,10 @@ func TestRemoveStatusCondition(t *testing.T) {
for _, test := range tests { for _, test := range tests {
t.Run(test.name, func(t *testing.T) { t.Run(test.name, func(t *testing.T) {
RemoveStatusCondition(&test.conditions, test.conditionType) removed := RemoveStatusCondition(&test.conditions, test.conditionType)
if test.expectRemoval != removed {
t.Errorf("expectRemoval=%t != removal=%t", test.expectRemoval, removed)
}
if !reflect.DeepEqual(test.conditions, test.expected) { if !reflect.DeepEqual(test.conditions, test.expected) {
t.Error(test.conditions) t.Error(test.conditions)
} }