Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add the chart app version to status and events metadata #968

Merged
merged 3 commits into from
May 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions api/v2/snapshot_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,9 @@ type Snapshot struct {
// storage.
// +required
ChartVersion string `json:"chartVersion"`
// AppVersion is the chart app version of the release object in storage.
// +optional
AppVersion string `json:"appVersion,omitempty"`
// ConfigDigest is the checksum of the config (better known as
// "values") of the release object in storage.
// It has the format of `<algo>:<checksum>`.
Expand Down
3 changes: 2 additions & 1 deletion api/v2beta1/helmrelease_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"github.com/fluxcd/pkg/apis/kustomize"
"github.com/fluxcd/pkg/apis/meta"

v2 "github.com/fluxcd/helm-controller/api/v2"
"github.com/fluxcd/helm-controller/api/v2beta2"
)

Expand Down Expand Up @@ -931,7 +932,7 @@ type HelmReleaseStatus struct {
// Note: this field is provisional to the v2beta2 API, and not actively used
// by v2beta1 HelmReleases.
// +optional
History v2beta2.Snapshots `json:"history,omitempty"`
History v2.Snapshots `json:"history,omitempty"`

// LastAttemptedGeneration is the last generation the controller attempted
// to reconcile.
Expand Down
5 changes: 3 additions & 2 deletions api/v2beta1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion api/v2beta2/helmrelease_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import (

"github.com/fluxcd/pkg/apis/kustomize"
"github.com/fluxcd/pkg/apis/meta"

v2 "github.com/fluxcd/helm-controller/api/v2"
)

const (
Expand Down Expand Up @@ -976,7 +978,7 @@ type HelmReleaseStatus struct {
// History holds the history of Helm releases performed for this HelmRelease
// up to the last successfully completed release.
// +optional
History Snapshots `json:"history,omitempty"`
History v2.Snapshots `json:"history,omitempty"`

// LastAttemptedReleaseAction is the last release action performed for this
// HelmRelease. It is used to determine the active remediation strategy.
Expand Down
5 changes: 3 additions & 2 deletions api/v2beta2/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions config/crd/bases/helm.toolkit.fluxcd.io_helmreleases.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1002,6 +1002,10 @@ spec:
Provisional: when the calculation method of the Digest field is changed,
this field will be used to distinguish between the old and new methods.
type: string
appVersion:
description: AppVersion is the chart app version of the release
object in storage.
type: string
chartName:
description: ChartName is the chart name of the release object
in storage.
Expand Down Expand Up @@ -2220,6 +2224,10 @@ spec:
Provisional: when the calculation method of the Digest field is changed,
this field will be used to distinguish between the old and new methods.
type: string
appVersion:
description: AppVersion is the chart app version of the release
object in storage.
type: string
chartName:
description: ChartName is the chart name of the release object
in storage.
Expand Down Expand Up @@ -3505,6 +3513,10 @@ spec:
Provisional: when the calculation method of the Digest field is changed,
this field will be used to distinguish between the old and new methods.
type: string
appVersion:
description: AppVersion is the chart app version of the release
object in storage.
type: string
chartName:
description: ChartName is the chart name of the release object
in storage.
Expand Down
12 changes: 12 additions & 0 deletions docs/api/v2/helm.md
Original file line number Diff line number Diff line change
Expand Up @@ -2277,6 +2277,18 @@ storage.</p>
</tr>
<tr>
<td>
<code>appVersion</code><br>
<em>
string
</em>
</td>
<td>
<em>(Optional)</em>
<p>AppVersion is the chart app version of the release object in storage.</p>
</td>
</tr>
<tr>
<td>
<code>configDigest</code><br>
<em>
string
Expand Down
106 changes: 70 additions & 36 deletions docs/spec/v2/helmreleases.md
Original file line number Diff line number Diff line change
Expand Up @@ -1385,7 +1385,7 @@ LAST SEEN TYPE REASON OBJECT MESSAGE
88s Normal HelmChartInSync HelmRelease/podinfo HelmChart/podinfo/podinfo-podinfo with SourceRef 'HelmRepository/podinfo/podinfo' is in-sync
83s Normal InstallSucceeded HelmRelease/podinfo Helm install succeeded for release podinfo/podinfo.v1 with chart podinfo@6.5.3
78s Warning TestFailed HelmRelease/podinfo Helm test failed for release podinfo/podinfo.v1 with chart podinfo@6.5.3: 1 error occurred:
* pod podinfo-fault-test-a0tew failed
* pod podinfo-fault-test-a0tew failed
```

Besides being reported in Events, the controller may also log reconciliation
Expand All @@ -1394,6 +1394,44 @@ HelmRelease, e.g. `flux logs --level=error --kind=HelmRelease --name=<release-na

## HelmRelease Status

### Events

The controller emits Kubernetes Events to report the result of each Helm action
performed for a HelmRelease. These events can be used to monitor the progress
of the HelmRelease and can be forwarded to external systems using
[notification-controller alerts](https://fluxcd.io/flux/monitoring/alerts/).

The controller annotates the events with the Helm chart version, app version,
and with the chart OCI digest if available.

#### Event example

```yaml
apiVersion: v1
kind: Event
metadata:
annotations:
helm.toolkit.fluxcd.io/app-version: 6.6.1
helm.toolkit.fluxcd.io/revision: 6.6.1+0cc9a8446c95
helm.toolkit.fluxcd.io/oci-digest: sha256:0cc9a8446c95009ef382f5eade883a67c257f77d50f84e78ecef2aac9428d1e5
creationTimestamp: "2024-05-07T05:02:34Z"
name: podinfo.17cd1c4e15d474bb
namespace: default
firstTimestamp: "2024-05-07T05:02:34Z"
involvedObject:
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
name: podinfo
namespace: default
lastTimestamp: "2024-05-07T05:02:34Z"
message: 'Helm test succeeded for release podinfo/podinfo.v2 with chart podinfo@6.6.1+0cc9a8446c95:
3 test hooks completed successfully'
reason: TestSucceeded
source:
component: helm-controller
type: Normal
```

### History

The HelmRelease shows the history of Helm releases it has performed up to the
Expand All @@ -1414,52 +1452,40 @@ metadata:
name: <release-name>
status:
history:
- chartName: podinfo
chartVersion: 6.5.3
configDigest: sha256:803f06d4673b07668ff270301ca54ca5829da3133c1219f47bd9f52a60b22f9f
digest: sha256:3036cf7c06fd35b8ccb15c426fed9ce8a059a0a4befab1a47170b6e962c4d784
firstDeployed: '2023-12-06T20:38:47Z'
lastDeployed: '2023-12-06T20:52:06Z'
- appVersion: 6.6.1
chartName: podinfo
chartVersion: 6.6.1+0cc9a8446c95
configDigest: sha256:e15c415d62760896bd8bec192a44c5716dc224db9e0fc609b9ac14718f8f9e56
digest: sha256:e59349a6d8cf01d625de9fe73efd94b5e2a8cc8453d1b893ec367cfa2105bae9
firstDeployed: "2024-05-07T04:54:21Z"
lastDeployed: "2024-05-07T04:54:55Z"
name: podinfo
namespace: podinfo
ociDigest: sha256:0cc9a8446c95009ef382f5eade883a67c257f77d50f84e78ecef2aac9428d1e5
status: deployed
testHooks:
podinfo-grpc-test-qulpw:
lastCompleted: '2023-12-06T20:52:09Z'
lastStarted: '2023-12-06T20:52:07Z'
phase: Succeeded
podinfo-jwt-test-xe0ch:
lastCompleted: '2023-12-06T20:52:12Z'
lastStarted: '2023-12-06T20:52:09Z'
phase: Succeeded
podinfo-service-test-eh6x2:
lastCompleted: '2023-12-06T20:52:14Z'
lastStarted: '2023-12-06T20:52:12Z'
podinfo-grpc-test-goyey:
lastCompleted: "2024-05-07T04:55:11Z"
lastStarted: "2024-05-07T04:55:09Z"
phase: Succeeded
version: 3
- chartName: podinfo
chartVersion: 6.5.3
version: 2
- appVersion: 6.6.0
chartName: podinfo
chartVersion: 6.6.0+cdd538a0167e
configDigest: sha256:e15c415d62760896bd8bec192a44c5716dc224db9e0fc609b9ac14718f8f9e56
digest: sha256:858b157a63889b25379e287e24a9b38beb09a8ae21f31ae2cf7ad53d70744375
firstDeployed: '2023-12-06T20:38:47Z'
lastDeployed: '2023-12-06T20:39:02Z'
digest: sha256:9be0d34ced6b890a72026749bc0f1f9e3c1a89673e17921bbcc0f27774f31c3a
firstDeployed: "2024-05-07T04:54:21Z"
lastDeployed: "2024-05-07T04:54:21Z"
name: podinfo
namespace: podinfo
ociDigest: sha256:cdd538a0167e4b51152b71a477e51eb6737553510ce8797dbcc537e1342311bb
status: superseded
testHooks:
podinfo-grpc-test-aiuee:
lastCompleted: '2023-12-06T20:39:04Z'
lastStarted: '2023-12-06T20:39:02Z'
phase: Succeeded
podinfo-jwt-test-dme3b:
lastCompleted: '2023-12-06T20:39:07Z'
lastStarted: '2023-12-06T20:39:04Z'
phase: Succeeded
podinfo-service-test-fgvte:
lastCompleted: '2023-12-06T20:39:09Z'
lastStarted: '2023-12-06T20:39:07Z'
podinfo-grpc-test-q0ucx:
lastCompleted: "2024-05-07T04:54:25Z"
lastStarted: "2024-05-07T04:54:23Z"
phase: Succeeded
version: 2
version: 1
```

### Conditions
Expand Down Expand Up @@ -1658,6 +1684,14 @@ to perform a Helm install or upgrade with in the
The revision is used by the controller to determine if it should reset the
[failure counters](#failure-counters) due to a change in the chart version.

### Last Attempted Revision Digest

The helm-controller reports the OCI artifact digest of the Helm chart it last attempted
to perform a Helm install or upgrade with in the
`.status.lastAttemptedRevisionDigest` field.

This field is present in status only when `.spec.chartRef.type` is set to `OCIRepository`.

### Last Attempted Release Action

The helm-controller reports the last Helm release action it attempted to
Expand Down
6 changes: 4 additions & 2 deletions internal/reconcile/correct_cluster_drift.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,10 +104,12 @@ func (r *CorrectClusterDrift) report(obj *v2.HelmRelease, changeSet *ssa.ChangeS
sb.WriteString(changeSet.String())
}

r.eventRecorder.AnnotatedEventf(obj, eventMeta(cur.ChartVersion, cur.ConfigDigest, addOCIDigest(cur.OCIDigest)), corev1.EventTypeWarning,
r.eventRecorder.AnnotatedEventf(obj, eventMeta(cur.ChartVersion, cur.ConfigDigest,
addAppVersion(cur.AppVersion), addOCIDigest(cur.OCIDigest)), corev1.EventTypeWarning,
"DriftCorrectionFailed", sb.String())
case changeSet != nil && len(changeSet.Entries) > 0:
r.eventRecorder.AnnotatedEventf(obj, eventMeta(cur.ChartVersion, cur.ConfigDigest, addOCIDigest(cur.OCIDigest)), corev1.EventTypeNormal,
r.eventRecorder.AnnotatedEventf(obj, eventMeta(cur.ChartVersion, cur.ConfigDigest,
addAppVersion(cur.AppVersion), addOCIDigest(cur.OCIDigest)), corev1.EventTypeNormal,
"DriftCorrected", "Cluster state of release %s has been corrected:\n%s",
obj.Status.History.Latest().FullReleaseName(), changeSet.String())
}
Expand Down
4 changes: 2 additions & 2 deletions internal/reconcile/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ func (r *Install) failure(req *Request, buffer *action.LogBuffer, err error) {
r.eventRecorder.AnnotatedEventf(
req.Object,
eventMeta(req.Chart.Metadata.Version, chartutil.DigestValues(digest.Canonical, req.Values).String(),
addOCIDigest(req.Object.Status.LastAttemptedRevisionDigest)),
addAppVersion(req.Chart.AppVersion()), addOCIDigest(req.Object.Status.LastAttemptedRevisionDigest)),
corev1.EventTypeWarning,
v2.InstallFailedReason,
eventMessageWithLog(msg, buffer),
Expand All @@ -182,7 +182,7 @@ func (r *Install) success(req *Request) {
// Record event.
r.eventRecorder.AnnotatedEventf(
req.Object,
eventMeta(cur.ChartVersion, cur.ConfigDigest, addOCIDigest(cur.OCIDigest)),
eventMeta(cur.ChartVersion, cur.ConfigDigest, addAppVersion(cur.AppVersion), addOCIDigest(cur.OCIDigest)),
corev1.EventTypeNormal,
v2.InstallSucceededReason,
msg,
Expand Down
2 changes: 2 additions & 0 deletions internal/reconcile/install_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,7 @@ func TestInstall_failure(t *testing.T) {
Annotations: map[string]string{
eventMetaGroupKey(metaOCIDigestKey): obj.Status.LastAttemptedRevisionDigest,
eventMetaGroupKey(eventv1.MetaRevisionKey): chrt.Metadata.Version,
eventMetaGroupKey(metaAppVersionKey): chrt.Metadata.AppVersion,
eventMetaGroupKey(eventv1.MetaTokenKey): chartutil.DigestValues(digest.Canonical, req.Values).String(),
},
},
Expand Down Expand Up @@ -413,6 +414,7 @@ func TestInstall_success(t *testing.T) {
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
eventMetaGroupKey(eventv1.MetaRevisionKey): obj.Status.History.Latest().ChartVersion,
eventMetaGroupKey(metaAppVersionKey): obj.Status.History.Latest().AppVersion,
eventMetaGroupKey(eventv1.MetaTokenKey): obj.Status.History.Latest().ConfigDigest,
},
},
Expand Down
20 changes: 18 additions & 2 deletions internal/reconcile/release.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,8 +200,13 @@ func eventMessageWithLog(msg string, log *action.LogBuffer) string {
// addMeta is a function that adds metadata to an event map.
type addMeta func(map[string]string)

// metaOCIDigestKey is the key for the OCI digest metadata.
const metaOCIDigestKey = "oci-digest"
const (
// metaOCIDigestKey is the key for the chart OCI artifact digest.
metaOCIDigestKey = "oci-digest"

// metaAppVersionKey is the key for the app version found in chart metadata.
metaAppVersionKey = "app-version"
)

// eventMeta returns the event (annotation) metadata based on the given
// parameters.
Expand Down Expand Up @@ -235,6 +240,17 @@ func addOCIDigest(digest string) addMeta {
}
}

func addAppVersion(appVersion string) addMeta {
return func(m map[string]string) {
if appVersion != "" {
if m == nil {
m = make(map[string]string)
}
m[eventMetaGroupKey(metaAppVersionKey)] = appVersion
}
}
}

// eventMetaGroupKey returns the event (annotation) metadata key prefixed with
// the group.
func eventMetaGroupKey(key string) string {
Expand Down
6 changes: 4 additions & 2 deletions internal/reconcile/rollback_remediation.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,8 @@ func (r *RollbackRemediation) failure(req *Request, prev *v2.Snapshot, buffer *a
// Condition summary.
r.eventRecorder.AnnotatedEventf(
req.Object,
eventMeta(prev.ChartVersion, chartutil.DigestValues(digest.Canonical, req.Values).String(), addOCIDigest(prev.OCIDigest)),
eventMeta(prev.ChartVersion, chartutil.DigestValues(digest.Canonical, req.Values).String(),
addAppVersion(prev.AppVersion), addOCIDigest(prev.OCIDigest)),
corev1.EventTypeWarning,
v2.RollbackFailedReason,
eventMessageWithLog(msg, buffer),
Expand All @@ -162,7 +163,8 @@ func (r *RollbackRemediation) success(req *Request, prev *v2.Snapshot) {
// Record event.
r.eventRecorder.AnnotatedEventf(
req.Object,
eventMeta(prev.ChartVersion, chartutil.DigestValues(digest.Canonical, req.Values).String(), addOCIDigest(prev.OCIDigest)),
eventMeta(prev.ChartVersion, chartutil.DigestValues(digest.Canonical, req.Values).String(),
addAppVersion(prev.AppVersion), addOCIDigest(prev.OCIDigest)),
corev1.EventTypeNormal,
v2.RollbackSucceededReason,
msg,
Expand Down
Loading