Skip to content

Commit 616ce88

Browse files
committed
add replace remediated with released helper
replaceRemediatedWithReleased() replaces remediated condition with released condition, retaining the transition time. This helps ensure that the last transition time of releases don't change when a release is marked from remediated to released. Signed-off-by: Sunny <darkowlzz@protonmail.com>
1 parent e627301 commit 616ce88

File tree

2 files changed

+123
-4
lines changed

2 files changed

+123
-4
lines changed

internal/reconcile/atomic_release.go

+19-4
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import (
3333
"github.com/fluxcd/pkg/runtime/logger"
3434
"github.com/fluxcd/pkg/runtime/patch"
3535
"github.com/fluxcd/pkg/ssa/jsondiff"
36+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3637

3738
v2 "github.com/fluxcd/helm-controller/api/v2beta2"
3839
"github.com/fluxcd/helm-controller/internal/action"
@@ -322,10 +323,9 @@ func (r *AtomicRelease) actionForState(ctx context.Context, req *Request, state
322323
// having the same chart version and values. As a result, we are already
323324
// in-sync without performing a release action.
324325
if conditions.IsTrue(req.Object, v2.RemediatedCondition) {
325-
conditions.Delete(req.Object, v2.RemediatedCondition)
326326
cur := req.Object.Status.History.Latest()
327327
msg := fmt.Sprintf(fmtUpgradeSuccess, cur.FullReleaseName(), cur.VersionedChartName())
328-
conditions.MarkTrue(req.Object, v2.ReleasedCondition, v2.UpgradeSucceededReason, msg)
328+
replaceRemediatedWithReleased(req.Object, metav1.ConditionTrue, v2.UpgradeSucceededReason, msg)
329329
}
330330

331331
return nil, nil
@@ -401,10 +401,9 @@ func (r *AtomicRelease) actionForState(ctx context.Context, req *Request, state
401401
// a result, we are already in-sync without performing a release action,
402402
// the existing release needs to undergo testing.
403403
if conditions.IsTrue(req.Object, v2.RemediatedCondition) {
404-
conditions.Delete(req.Object, v2.RemediatedCondition)
405404
cur := req.Object.Status.History.Latest()
406405
msg := fmt.Sprintf(fmtUpgradeSuccess, cur.FullReleaseName(), cur.VersionedChartName())
407-
conditions.MarkTrue(req.Object, v2.ReleasedCondition, v2.UpgradeSucceededReason, msg)
406+
replaceRemediatedWithReleased(req.Object, metav1.ConditionTrue, v2.UpgradeSucceededReason, msg)
408407
}
409408

410409
return NewTest(r.configFactory, r.eventRecorder), nil
@@ -520,3 +519,19 @@ func timeoutForAction(action ActionReconciler, obj *v2.HelmRelease) time.Duratio
520519
return obj.GetTimeout().Duration
521520
}
522521
}
522+
523+
// replaceRemediatedWithRelease replaces existing Remediated condition with
524+
// Released condition, if present, for the given values, retaining the
525+
// LastTransitionTime.
526+
func replaceRemediatedWithReleased(obj *v2.HelmRelease, status metav1.ConditionStatus, reason, msg string) {
527+
released := conditions.Get(obj, v2.RemediatedCondition)
528+
if released != nil {
529+
conditions.Delete(obj, v2.ReleasedCondition)
530+
released.Status = status
531+
released.Type = v2.ReleasedCondition
532+
released.Reason = reason
533+
released.Message = msg
534+
conditions.Set(obj, released)
535+
conditions.Delete(obj, v2.RemediatedCondition)
536+
}
537+
}

internal/reconcile/atomic_release_test.go

+104
Original file line numberDiff line numberDiff line change
@@ -1557,3 +1557,107 @@ func TestAtomicRelease_actionForState(t *testing.T) {
15571557
})
15581558
}
15591559
}
1560+
1561+
func Test_replaceRemediatedWithRelease(t *testing.T) {
1562+
g := NewWithT(t)
1563+
timestamp, err := time.Parse(time.UnixDate, "Wed Feb 25 11:06:39 GMT 2015")
1564+
g.Expect(err).ToNot(HaveOccurred())
1565+
1566+
tests := []struct {
1567+
name string
1568+
conditions []metav1.Condition
1569+
wantConditions []metav1.Condition
1570+
}{
1571+
{
1572+
name: "existing released and remediated conditions",
1573+
conditions: []metav1.Condition{
1574+
{
1575+
Type: v2.ReleasedCondition,
1576+
Status: metav1.ConditionFalse,
1577+
Reason: v2.UpgradeFailedReason,
1578+
Message: "upgrade failed",
1579+
ObservedGeneration: 1,
1580+
LastTransitionTime: metav1.NewTime(timestamp),
1581+
},
1582+
{
1583+
Type: v2.RemediatedCondition,
1584+
Status: metav1.ConditionTrue,
1585+
Reason: v2.RollbackSucceededReason,
1586+
Message: "rollback",
1587+
ObservedGeneration: 1,
1588+
LastTransitionTime: metav1.NewTime(timestamp),
1589+
},
1590+
},
1591+
wantConditions: []metav1.Condition{
1592+
{
1593+
Type: v2.ReleasedCondition,
1594+
Status: metav1.ConditionTrue,
1595+
Reason: v2.UpgradeSucceededReason,
1596+
Message: "foo",
1597+
ObservedGeneration: 1,
1598+
LastTransitionTime: metav1.NewTime(timestamp),
1599+
},
1600+
},
1601+
},
1602+
{
1603+
name: "no released condition",
1604+
conditions: []metav1.Condition{
1605+
{
1606+
Type: v2.RemediatedCondition,
1607+
Status: metav1.ConditionTrue,
1608+
Reason: v2.RollbackSucceededReason,
1609+
Message: "rollback",
1610+
ObservedGeneration: 1,
1611+
LastTransitionTime: metav1.NewTime(timestamp),
1612+
},
1613+
},
1614+
wantConditions: []metav1.Condition{
1615+
{
1616+
Type: v2.ReleasedCondition,
1617+
Status: metav1.ConditionTrue,
1618+
Reason: v2.UpgradeSucceededReason,
1619+
Message: "foo",
1620+
ObservedGeneration: 1,
1621+
LastTransitionTime: metav1.NewTime(timestamp),
1622+
},
1623+
},
1624+
},
1625+
{
1626+
name: "no remediated condition",
1627+
conditions: []metav1.Condition{
1628+
{
1629+
Type: v2.ReleasedCondition,
1630+
Status: metav1.ConditionFalse,
1631+
Reason: v2.UpgradeFailedReason,
1632+
Message: "upgrade failed",
1633+
ObservedGeneration: 1,
1634+
LastTransitionTime: metav1.NewTime(timestamp),
1635+
},
1636+
},
1637+
wantConditions: []metav1.Condition{
1638+
{
1639+
Type: v2.ReleasedCondition,
1640+
Status: metav1.ConditionFalse,
1641+
Reason: v2.UpgradeFailedReason,
1642+
Message: "upgrade failed",
1643+
ObservedGeneration: 1,
1644+
LastTransitionTime: metav1.NewTime(timestamp),
1645+
},
1646+
},
1647+
},
1648+
{
1649+
name: "no released and remediated conditions",
1650+
},
1651+
}
1652+
for _, tt := range tests {
1653+
t.Run(tt.name, func(t *testing.T) {
1654+
g := NewWithT(t)
1655+
1656+
obj := &v2.HelmRelease{}
1657+
obj.Generation = 1
1658+
obj.Status.Conditions = tt.conditions
1659+
replaceRemediatedWithReleased(obj, metav1.ConditionTrue, v2.UpgradeSucceededReason, "foo")
1660+
g.Expect(obj.Status.Conditions).To(Equal(tt.wantConditions))
1661+
})
1662+
}
1663+
}

0 commit comments

Comments
 (0)