Skip to content

Commit 5a1c513

Browse files
authored
Merge pull request #631 from raffis/feat-chart-metadata
feat: manage label and annotations for a helmchart
2 parents af59329 + a72a2fc commit 5a1c513

7 files changed

+190
-5
lines changed

api/v2beta1/helmrelease_types.go

+21
Original file line numberDiff line numberDiff line change
@@ -219,11 +219,32 @@ func (in HelmReleaseSpec) GetUninstall() Uninstall {
219219
// generate a v1beta2.HelmChart object in the same namespace as the referenced
220220
// v1beta2.Source.
221221
type HelmChartTemplate struct {
222+
// ObjectMeta holds the template for metadata like labels and annotations.
223+
// +optional
224+
ObjectMeta HelmChartTemplateObjectMeta `json:"metadata,omitempty"`
225+
222226
// Spec holds the template for the v1beta2.HelmChartSpec for this HelmRelease.
223227
// +required
224228
Spec HelmChartTemplateSpec `json:"spec"`
225229
}
226230

231+
// HelmChartTemplateObjectMeta defines the template for the ObjectMeta of a
232+
// v1beta2.HelmChart.
233+
type HelmChartTemplateObjectMeta struct {
234+
// Map of string keys and values that can be used to organize and categorize
235+
// (scope and select) objects.
236+
// More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/
237+
// +optional
238+
Labels map[string]string `json:"labels,omitempty"`
239+
240+
// Annotations is an unstructured key value map stored with a resource that may be
241+
// set by external tools to store and retrieve arbitrary metadata. They are not
242+
// queryable and should be preserved when modifying objects.
243+
// More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/
244+
// +optional
245+
Annotations map[string]string `json:"annotations,omitempty"`
246+
}
247+
227248
// HelmChartTemplateSpec defines the template from which the controller will
228249
// generate a v1beta2.HelmChartSpec object.
229250
type HelmChartTemplateSpec struct {

api/v2beta1/zz_generated.deepcopy.go

+30
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/crd/bases/helm.toolkit.fluxcd.io_helmreleases.yaml

+21
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,27 @@ spec:
5151
description: Chart defines the template of the v1beta2.HelmChart that
5252
should be created for this HelmRelease.
5353
properties:
54+
metadata:
55+
description: ObjectMeta holds the template for metadata like labels
56+
and annotations.
57+
properties:
58+
annotations:
59+
additionalProperties:
60+
type: string
61+
description: 'Annotations is an unstructured key value map
62+
stored with a resource that may be set by external tools
63+
to store and retrieve arbitrary metadata. They are not queryable
64+
and should be preserved when modifying objects. More info:
65+
https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/'
66+
type: object
67+
labels:
68+
additionalProperties:
69+
type: string
70+
description: 'Map of string keys and values that can be used
71+
to organize and categorize (scope and select) objects. More
72+
info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/'
73+
type: object
74+
type: object
5475
spec:
5576
description: Spec holds the template for the v1beta2.HelmChartSpec
5677
for this HelmRelease.

docs/api/helmrelease.md

+65
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,20 @@ v1beta2.Source.</p>
457457
<tbody>
458458
<tr>
459459
<td>
460+
<code>metadata</code><br>
461+
<em>
462+
<a href="#helm.toolkit.fluxcd.io/v2beta1.HelmChartTemplateObjectMeta">
463+
HelmChartTemplateObjectMeta
464+
</a>
465+
</em>
466+
</td>
467+
<td>
468+
<em>(Optional)</em>
469+
<p>ObjectMeta holds the template for metadata like labels and annotations.</p>
470+
</td>
471+
</tr>
472+
<tr>
473+
<td>
460474
<code>spec</code><br>
461475
<em>
462476
<a href="#helm.toolkit.fluxcd.io/v2beta1.HelmChartTemplateSpec">
@@ -591,6 +605,57 @@ Chart dependencies, which are not bundled in the umbrella chart artifact, are no
591605
</table>
592606
</div>
593607
</div>
608+
<h3 id="helm.toolkit.fluxcd.io/v2beta1.HelmChartTemplateObjectMeta">HelmChartTemplateObjectMeta
609+
</h3>
610+
<p>
611+
(<em>Appears on:</em>
612+
<a href="#helm.toolkit.fluxcd.io/v2beta1.HelmChartTemplate">HelmChartTemplate</a>)
613+
</p>
614+
<p>HelmChartTemplateObjectMeta defines the template for the ObjectMeta of a
615+
v1beta2.HelmChart.</p>
616+
<div class="md-typeset__scrollwrap">
617+
<div class="md-typeset__table">
618+
<table>
619+
<thead>
620+
<tr>
621+
<th>Field</th>
622+
<th>Description</th>
623+
</tr>
624+
</thead>
625+
<tbody>
626+
<tr>
627+
<td>
628+
<code>labels</code><br>
629+
<em>
630+
map[string]string
631+
</em>
632+
</td>
633+
<td>
634+
<em>(Optional)</em>
635+
<p>Map of string keys and values that can be used to organize and categorize
636+
(scope and select) objects.
637+
More info: <a href="https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/">https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/</a></p>
638+
</td>
639+
</tr>
640+
<tr>
641+
<td>
642+
<code>annotations</code><br>
643+
<em>
644+
map[string]string
645+
</em>
646+
</td>
647+
<td>
648+
<em>(Optional)</em>
649+
<p>Annotations is an unstructured key value map stored with a resource that may be
650+
set by external tools to store and retrieve arbitrary metadata. They are not
651+
queryable and should be preserved when modifying objects.
652+
More info: <a href="https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/">https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/</a></p>
653+
</td>
654+
</tr>
655+
</tbody>
656+
</table>
657+
</div>
658+
</div>
594659
<h3 id="helm.toolkit.fluxcd.io/v2beta1.HelmChartTemplateSpec">HelmChartTemplateSpec
595660
</h3>
596661
<p>

docs/spec/v2beta1/helmreleases.md

+27-3
Original file line numberDiff line numberDiff line change
@@ -134,11 +134,32 @@ type KubeConfig struct {
134134
// generate a v1beta1.HelmChart object in the same namespace as the referenced
135135
// v1beta1.Source.
136136
type HelmChartTemplate struct {
137+
// ObjectMeta holds the template for metadata like labels and annotations.
138+
// +optional
139+
ObjectMeta HelmChartTemplateObjectMeta `json:"metadata,omitempty"`
140+
137141
// Spec holds the template for the v1beta1.HelmChartSpec for this HelmRelease.
138142
// +required
139143
Spec HelmChartTemplateSpec `json:"spec"`
140144
}
141145

146+
// HelmChartTemplateObjectMeta defines the template for the ObjectMeta of a
147+
// v1beta2.HelmChart.
148+
type HelmChartTemplateObjectMeta struct {
149+
// Map of string keys and values that can be used to organize and categorize
150+
// (scope and select) objects.
151+
// More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/
152+
// +optional
153+
Labels map[string]string `json:"labels,omitempty"`
154+
155+
// Annotations is an unstructured key value map stored with a resource that may be
156+
// set by external tools to store and retrieve arbitrary metadata. They are not
157+
// queryable and should be preserved when modifying objects.
158+
// More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/
159+
// +optional
160+
Annotations map[string]string `json:"annotations,omitempty"`
161+
}
162+
142163
// HelmChartTemplateSpec defines the template from which the controller will
143164
// generate a v1beta1.HelmChartSpec object.
144165
type HelmChartTemplateSpec struct {
@@ -681,7 +702,7 @@ of the `HelmRelease`. These can be overridden respectively via `spec.targetNames
681702
682703
## Helm chart template
683704

684-
The `spec.chart.spec` values are used by the helm-controller as a template
705+
The `spec.chart` values are used by the helm-controller as a template
685706
to create a new `HelmChart` resource with the given spec.
686707

687708
The `spec.chart.spec.sourceRef` is a reference to an object managed by
@@ -699,8 +720,8 @@ The `HelmChart` is created in the same namespace as the `sourceRef`,
699720
with a name matching the `HelmRelease` `<metadata.namespace>-<metadata.name>`.
700721

701722
> **Note** that on multi-tenant clusters, platform admins can disable cross-namespace references
702-
> with the `--no-cross-namespace-refs=true` flag. When this flag is set, the helmrelease can only
703-
> refer to sources in the same namespace as the helmrelease object.
723+
> with the `--no-cross-namespace-refs=true` flag. When this flag is set, the HelmRelease can only
724+
> refer to sources in the same namespace as the HelmRelease object.
704725
705726
The `chart.spec.chart` can either contain:
706727

@@ -713,6 +734,9 @@ The `chart.spec.version` can be a fixed semver, or any semver range
713734
(i.e. `>=4.0.0 <5.0.0`). It is ignored for `HelmRelease` resources
714735
that reference a `GitRepository` or `Bucket` source.
715736

737+
Annotations and labels can be added by configuring the respective `.spec.chart.metadata`
738+
fields.
739+
716740
## Values overrides
717741

718742
The simplest way to define values overrides is inline via `spec.values`.

internal/controllers/helmrelease_controller_chart.go

+12-2
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import (
3434
_ "github.com/opencontainers/go-digest/blake3"
3535
"helm.sh/helm/v3/pkg/chart"
3636
"helm.sh/helm/v3/pkg/chart/loader"
37+
apiequality "k8s.io/apimachinery/pkg/api/equality"
3738
apierrors "k8s.io/apimachinery/pkg/api/errors"
3839
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3940
"k8s.io/apimachinery/pkg/types"
@@ -82,6 +83,9 @@ func (r *HelmReleaseReconciler) reconcileChart(ctx context.Context, hr *v2.HelmR
8283
case helmChartRequiresUpdate(hr, &helmChart):
8384
ctrl.LoggerFrom(ctx).Info("chart diverged from template", strings.ToLower(sourcev1.HelmChartKind), chartName.String())
8485
helmChart.Spec = hc.Spec
86+
helmChart.Labels = hc.Labels
87+
helmChart.Annotations = hc.Annotations
88+
8589
if err = r.Client.Update(ctx, &helmChart); err != nil {
8690
return nil, err
8791
}
@@ -196,8 +200,10 @@ func buildHelmChartFromTemplate(hr *v2.HelmRelease) *sourcev1.HelmChart {
196200
template := hr.Spec.Chart
197201
return &sourcev1.HelmChart{
198202
ObjectMeta: metav1.ObjectMeta{
199-
Name: hr.GetHelmChartName(),
200-
Namespace: hr.Spec.Chart.GetNamespace(hr.Namespace),
203+
Name: hr.GetHelmChartName(),
204+
Namespace: hr.Spec.Chart.GetNamespace(hr.Namespace),
205+
Labels: hr.Spec.Chart.ObjectMeta.Labels,
206+
Annotations: hr.Spec.Chart.ObjectMeta.Annotations,
201207
},
202208
Spec: sourcev1.HelmChartSpec{
203209
Chart: template.Spec.Chart,
@@ -239,6 +245,10 @@ func helmChartRequiresUpdate(hr *v2.HelmRelease, chart *sourcev1.HelmChart) bool
239245
return true
240246
case template.Spec.ValuesFile != chart.Spec.ValuesFile:
241247
return true
248+
case !apiequality.Semantic.DeepEqual(template.ObjectMeta.Annotations, chart.Annotations):
249+
return true
250+
case !apiequality.Semantic.DeepEqual(template.ObjectMeta.Labels, chart.Labels):
251+
return true
242252
case !reflect.DeepEqual(templateVerificationToSourceVerification(template.Spec.Verify), chart.Spec.Verify):
243253
return true
244254
default:

internal/controllers/helmrelease_controller_chart_test.go

+14
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,20 @@ func Test_helmChartRequiresUpdate(t *testing.T) {
514514
},
515515
want: true,
516516
},
517+
{
518+
name: "detects labels change",
519+
modify: func(hr *v2.HelmRelease, hc *sourcev1.HelmChart) {
520+
hr.Spec.Chart.ObjectMeta.Labels = map[string]string{"foo": "bar"}
521+
},
522+
want: true,
523+
},
524+
{
525+
name: "detects annotations change",
526+
modify: func(hr *v2.HelmRelease, hc *sourcev1.HelmChart) {
527+
hr.Spec.Chart.ObjectMeta.Annotations = map[string]string{"foo": "bar"}
528+
},
529+
want: true,
530+
},
517531
}
518532
for _, tt := range tests {
519533
t.Run(tt.name, func(t *testing.T) {

0 commit comments

Comments
 (0)