Skip to content

Commit 7baedcb

Browse files
committed
Remove stale remediated condition when in-sync
Remediation can roll back to a version that matches with the next good config. In such situation, release will be in-sync and no action will be performed. The status conditions will continue to show Remediated=True and Released=False. Check and remove stale Remediated condition and add a Released=True condition with message constructed from the latest release. Signed-off-by: Sunny <darkowlzz@protonmail.com>
1 parent ee8177e commit 7baedcb

File tree

2 files changed

+70
-9
lines changed

2 files changed

+70
-9
lines changed

internal/reconcile/atomic_release.go

+20
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,15 @@ func (r *AtomicRelease) actionForState(ctx context.Context, req *Request, state
315315
return NewUpgrade(r.configFactory, r.eventRecorder), nil
316316
}
317317

318+
// Since the release is in-sync, remove any remediated condition if
319+
// present and replace it with upgrade succeeded condition.
320+
if conditions.IsTrue(req.Object, v2.RemediatedCondition) {
321+
conditions.Delete(req.Object, v2.RemediatedCondition)
322+
cur := req.Object.Status.History.Latest()
323+
msg := fmt.Sprintf(fmtUpgradeSuccess, cur.FullReleaseName(), cur.VersionedChartName())
324+
conditions.MarkTrue(req.Object, v2.ReleasedCondition, v2.UpgradeSucceededReason, msg)
325+
}
326+
318327
return nil, nil
319328
case ReleaseStatusLocked:
320329
log.Info(msgWithReason("release locked", state.Reason))
@@ -378,6 +387,17 @@ func (r *AtomicRelease) actionForState(ctx context.Context, req *Request, state
378387
return nil, nil
379388
case ReleaseStatusUntested:
380389
log.Info(msgWithReason("release has not been tested", state.Reason))
390+
391+
// Since an untested release indicates that the release is already
392+
// in-sync, remove any remediated condition if present and replace it
393+
// with upgrade succeeded condition.
394+
if conditions.IsTrue(req.Object, v2.RemediatedCondition) {
395+
conditions.Delete(req.Object, v2.RemediatedCondition)
396+
cur := req.Object.Status.History.Latest()
397+
msg := fmt.Sprintf(fmtUpgradeSuccess, cur.FullReleaseName(), cur.VersionedChartName())
398+
conditions.MarkTrue(req.Object, v2.ReleasedCondition, v2.UpgradeSucceededReason, msg)
399+
}
400+
381401
return NewTest(r.configFactory, r.eventRecorder), nil
382402
case ReleaseStatusFailed:
383403
log.Info(msgWithReason("release is in a failed state", state.Reason))

internal/reconcile/atomic_release_test.go

+50-9
Original file line numberDiff line numberDiff line change
@@ -1015,15 +1015,16 @@ func TestAtomicRelease_Reconcile_Scenarios(t *testing.T) {
10151015

10161016
func TestAtomicRelease_actionForState(t *testing.T) {
10171017
tests := []struct {
1018-
name string
1019-
releases []*helmrelease.Release
1020-
annotations map[string]string
1021-
spec func(spec *v2.HelmReleaseSpec)
1022-
status func(releases []*helmrelease.Release) v2.HelmReleaseStatus
1023-
state ReleaseState
1024-
want ActionReconciler
1025-
wantEvent *corev1.Event
1026-
wantErr error
1018+
name string
1019+
releases []*helmrelease.Release
1020+
annotations map[string]string
1021+
spec func(spec *v2.HelmReleaseSpec)
1022+
status func(releases []*helmrelease.Release) v2.HelmReleaseStatus
1023+
state ReleaseState
1024+
want ActionReconciler
1025+
wantEvent *corev1.Event
1026+
wantErr error
1027+
assertConditions []metav1.Condition
10271028
}{
10281029
{
10291030
name: "in-sync release does not trigger any action",
@@ -1053,6 +1054,25 @@ func TestAtomicRelease_actionForState(t *testing.T) {
10531054
},
10541055
want: &Upgrade{},
10551056
},
1057+
{
1058+
name: "in-sync release with stale remediated condition",
1059+
status: func(releases []*helmrelease.Release) v2.HelmReleaseStatus {
1060+
return v2.HelmReleaseStatus{
1061+
History: v2.Snapshots{
1062+
{Version: 1},
1063+
},
1064+
Conditions: []metav1.Condition{
1065+
*conditions.FalseCondition(v2.ReleasedCondition, v2.UpgradeFailedReason, "upgrade failed"),
1066+
*conditions.TrueCondition(v2.RemediatedCondition, v2.RollbackSucceededReason, "rolled back"),
1067+
},
1068+
}
1069+
},
1070+
state: ReleaseState{Status: ReleaseStatusInSync},
1071+
want: nil,
1072+
assertConditions: []metav1.Condition{
1073+
*conditions.TrueCondition(v2.ReleasedCondition, v2.UpgradeSucceededReason, "upgrade succeeded"),
1074+
},
1075+
},
10561076
{
10571077
name: "locked release triggers unlock action",
10581078
state: ReleaseState{Status: ReleaseStatusLocked},
@@ -1245,6 +1265,25 @@ func TestAtomicRelease_actionForState(t *testing.T) {
12451265
state: ReleaseState{Status: ReleaseStatusUntested},
12461266
want: &Test{},
12471267
},
1268+
{
1269+
name: "untested release with stale remediated condition",
1270+
status: func(releases []*helmrelease.Release) v2.HelmReleaseStatus {
1271+
return v2.HelmReleaseStatus{
1272+
History: v2.Snapshots{
1273+
{Version: 1},
1274+
},
1275+
Conditions: []metav1.Condition{
1276+
*conditions.FalseCondition(v2.ReleasedCondition, v2.UpgradeFailedReason, "upgrade failed"),
1277+
*conditions.TrueCondition(v2.RemediatedCondition, v2.RollbackSucceededReason, "rolled back"),
1278+
},
1279+
}
1280+
},
1281+
state: ReleaseState{Status: ReleaseStatusUntested},
1282+
want: &Test{},
1283+
assertConditions: []metav1.Condition{
1284+
*conditions.TrueCondition(v2.ReleasedCondition, v2.UpgradeSucceededReason, "upgrade succeeded"),
1285+
},
1286+
},
12481287
{
12491288
name: "failed release without active remediation triggers upgrade",
12501289
state: ReleaseState{Status: ReleaseStatusFailed},
@@ -1513,6 +1552,8 @@ func TestAtomicRelease_actionForState(t *testing.T) {
15131552
} else {
15141553
g.Expect(recorder.GetEvents()).To(BeEmpty())
15151554
}
1555+
1556+
g.Expect(obj.Status.Conditions).To(conditions.MatchConditions(tt.assertConditions))
15161557
})
15171558
}
15181559
}

0 commit comments

Comments
 (0)