Skip to content

Commit 0e8bf5f

Browse files
authored
Merge pull request #1367 from yozel/yozel/add-drifted-condition
Add `Drifted` condition to HelmRelease
2 parents 390b7de + 99a3e37 commit 0e8bf5f

File tree

4 files changed

+52
-6
lines changed

4 files changed

+52
-6
lines changed

api/v2/condition_types.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ const (
2929
// (uninstall/rollback) due to a failure of the last release attempt against the
3030
// latest desired state.
3131
RemediatedCondition string = "Remediated"
32+
33+
// DriftedCondition represents the status of the Helm release drift detection,
34+
// indicating that the deployed release has drifted from the desired state.
35+
DriftedCondition string = "Drifted"
3236
)
3337

3438
const (
@@ -79,4 +83,12 @@ const (
7983
// DependencyNotReadyReason represents the fact that
8084
// one of the dependencies is not ready.
8185
DependencyNotReadyReason string = "DependencyNotReady"
86+
87+
// DriftDetectedReason represents the fact that drift has been detected in the
88+
// Helm release compared to the expected state.
89+
DriftDetectedReason string = "DriftDetected"
90+
91+
// NoDriftDetectedReason represents the fact that no drift has been detected in
92+
// the Helm release compared to the expected state.
93+
NoDriftDetectedReason string = "NoDriftDetected"
8294
)

docs/spec/v2/helmreleases.md

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2020,8 +2020,9 @@ A HelmRelease enters various states during its lifecycle, reflected as
20202020
[Kubernetes Conditions](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties).
20212021
It can be [reconciling](#reconciling-helmrelease) when it is being processed by
20222022
the controller, it can be [ready](#ready-helmrelease) when the Helm release is
2023-
installed and up-to-date, or it can [fail](#failed-helmrelease) during
2024-
reconciliation.
2023+
installed and up-to-date, it can [fail](#failed-helmrelease) during
2024+
reconciliation, or it can be [drifted](#drifted-helmrelease) if the
2025+
drift detection mode is set to enabled/warn and there is a drift.
20252026

20262027
The HelmRelease API is compatible with the [kstatus specification](https://github.com/kubernetes-sigs/cli-utils/tree/master/pkg/kstatus),
20272028
and reports `Reconciling` and `Stalled` conditions where applicable to provide
@@ -2106,6 +2107,29 @@ HelmRelease's `.status.conditions`:
21062107
The `TestSuccess` Condition will retain a status value of `"True"` until the
21072108
next Helm install or upgrade occurs, or the Helm tests are disabled.
21082109

2110+
#### Drifted HelmRelease
2111+
2112+
The helm-controller marks the HelmRelease as _drifted_ when it has the following
2113+
characteristics:
2114+
2115+
- The HelmRelease have drift detection mode set to enabled or warn.
2116+
- There is a drift detected against the cluster state.
2117+
2118+
When the HelmRelease is "drifted", the controller sets a Condition with the
2119+
following attributes in the HelmRelease's `.status.conditions`:
2120+
2121+
- `type: Drifted`
2122+
- `status: "True"`
2123+
- `reason: DriftDetected`
2124+
2125+
When the HelmRelease have drift detection mode set to enabled or warn there
2126+
and there is no drift, the controller sets a Condition with the following
2127+
attributes in the HelmRelease's `.status.conditions`:
2128+
2129+
- `type: Drifted`
2130+
- `status: "False"`
2131+
- `reason: NoDriftDetected`
2132+
21092133
#### Failed HelmRelease
21102134

21112135
The helm-controller may get stuck trying to determine state or produce a Helm

internal/reconcile/atomic_release.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,10 @@ func (r *AtomicRelease) actionForState(ctx context.Context, req *Request, state
381381
}
382382
}
383383

384+
if req.Object.GetDriftDetection().MustDetectChanges() {
385+
conditions.MarkFalse(req.Object, v2.DriftedCondition, v2.NoDriftDetectedReason, "No drift detected against the cluster state")
386+
}
387+
384388
return nil, nil
385389
case ReleaseStatusLocked:
386390
log.Info(msgWithReason("release locked", state.Reason))
@@ -436,10 +440,10 @@ func (r *AtomicRelease) actionForState(ctx context.Context, req *Request, state
436440
}
437441
}
438442

439-
r.eventRecorder.Eventf(req.Object, corev1.EventTypeWarning, "DriftDetected",
440-
"Cluster state of release %s has drifted from the desired state:\n%s",
441-
req.Object.Status.History.Latest().FullReleaseName(), diff.SummarizeDiffSet(state.Diff),
442-
)
443+
msg := fmt.Sprintf("Cluster state of release %s has drifted from the desired state:\n%s",
444+
req.Object.Status.History.Latest().FullReleaseName(), diff.SummarizeDiffSet(state.Diff))
445+
r.eventRecorder.Eventf(req.Object, corev1.EventTypeWarning, v2.DriftDetectedReason, msg)
446+
conditions.MarkTrue(req.Object, v2.DriftedCondition, v2.DriftDetectedReason, "%s", msg)
443447

444448
if req.Object.GetDriftDetection().GetMode() == v2.DriftDetectionEnabled {
445449
return NewCorrectClusterDrift(r.configFactory, r.eventRecorder, state.Diff, kube.ManagedFieldsManager), nil

internal/reconcile/atomic_release_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1656,6 +1656,9 @@ func TestAtomicRelease_actionForState(t *testing.T) {
16561656
"Deployment/something/mock removed",
16571657
),
16581658
},
1659+
assertConditions: []metav1.Condition{
1660+
*conditions.TrueCondition(v2.DriftedCondition, v2.DriftDetectedReason, "Cluster state of release mock-ns/mock-release.v1 has drifted from the desired state:\nDeployment/something/mock removed"),
1661+
},
16591662
},
16601663
{
16611664
name: "drifted release only triggers event if mode is warn",
@@ -1725,6 +1728,9 @@ func TestAtomicRelease_actionForState(t *testing.T) {
17251728
"Deployment/something/mock changed (0 additions, 1 changes, 0 removals)",
17261729
),
17271730
},
1731+
assertConditions: []metav1.Condition{
1732+
*conditions.TrueCondition(v2.DriftedCondition, v2.DriftDetectedReason, "Cluster state of release mock-ns/mock-release.v1 has drifted from the desired state:\nDeployment/something/mock changed (0 additions, 1 changes, 0 removals)"),
1733+
},
17281734
},
17291735
{
17301736
name: "out-of-sync release triggers upgrade",

0 commit comments

Comments
 (0)