Skip to content

Commit 2e8dade

Browse files
authored
Merge pull request #1632 from qube-rt/add-build-metadata
Add `.spec.buildMetadata` optional field to Kustomization API
2 parents b4e2b52 + 2ab5e24 commit 2e8dade

8 files changed

Lines changed: 219 additions & 3 deletions

File tree

api/v1/kustomization_types.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,13 @@ type KustomizationSpec struct {
177177
// +optional
178178
Wait bool `json:"wait,omitempty"`
179179

180+
// BuildMetadata specifies which kustomize build metadata should be added
181+
// to the built resources. The allowed values are 'originAnnotations' to
182+
// annotate resources with their source origin, and 'transformerAnnotations'
183+
// to annotate resources with the transformers that produced them.
184+
// +optional
185+
BuildMetadata []BuildMetadataOption `json:"buildMetadata,omitempty"`
186+
180187
// Components specifies relative paths to kustomize Components.
181188
// +optional
182189
Components []string `json:"components,omitempty"`
@@ -194,6 +201,19 @@ type KustomizationSpec struct {
194201
HealthCheckExprs []kustomize.CustomHealthCheck `json:"healthCheckExprs,omitempty"`
195202
}
196203

204+
// BuildMetadataOption defines the supported buildMetadata options.
205+
// +kubebuilder:validation:Enum=originAnnotations;transformerAnnotations
206+
type BuildMetadataOption string
207+
208+
const (
209+
// BuildMetadataOriginAnnotations enables config.kubernetes.io/origin annotations
210+
// that track which file and path each resource was loaded from.
211+
BuildMetadataOriginAnnotations BuildMetadataOption = "originAnnotations"
212+
// BuildMetadataTransformerAnnotations enables internal.config.kubernetes.io annotations
213+
// that record which kustomize transformers modified each resource.
214+
BuildMetadataTransformerAnnotations BuildMetadataOption = "transformerAnnotations"
215+
)
216+
197217
// CommonMetadata defines the common labels and annotations.
198218
type CommonMetadata struct {
199219
// Annotations to be added to the object's metadata.

api/v1/zz_generated.deepcopy.go

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/crd/bases/kustomize.toolkit.fluxcd.io_kustomizations.yaml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,20 @@ spec:
5353
KustomizationSpec defines the configuration to calculate the desired state
5454
from a Source using Kustomize.
5555
properties:
56+
buildMetadata:
57+
description: |-
58+
BuildMetadata specifies which kustomize build metadata should be added
59+
to the built resources. The allowed values are 'originAnnotations' to
60+
annotate resources with their source origin, and 'transformerAnnotations'
61+
to annotate resources with the transformers that produced them.
62+
items:
63+
description: BuildMetadataOption defines the supported buildMetadata
64+
options.
65+
enum:
66+
- originAnnotations
67+
- transformerAnnotations
68+
type: string
69+
type: array
5670
commonMetadata:
5771
description: |-
5872
CommonMetadata specifies the common labels and annotations that are

docs/api/v1/kustomize.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,23 @@ resources. When enabled, the HealthChecks are ignored. Defaults to false.</p>
385385
</tr>
386386
<tr>
387387
<td>
388+
<code>buildMetadata</code><br>
389+
<em>
390+
<a href="#kustomize.toolkit.fluxcd.io/v1.BuildMetadataOption">
391+
[]BuildMetadataOption
392+
</a>
393+
</em>
394+
</td>
395+
<td>
396+
<em>(Optional)</em>
397+
<p>BuildMetadata specifies which kustomize build metadata should be added
398+
to the built resources. The allowed values are &lsquo;originAnnotations&rsquo; to
399+
annotate resources with their source origin, and &lsquo;transformerAnnotations&rsquo;
400+
to annotate resources with the transformers that produced them.</p>
401+
</td>
402+
</tr>
403+
<tr>
404+
<td>
388405
<code>components</code><br>
389406
<em>
390407
[]string
@@ -444,6 +461,13 @@ KustomizationStatus
444461
</table>
445462
</div>
446463
</div>
464+
<h3 id="kustomize.toolkit.fluxcd.io/v1.BuildMetadataOption">BuildMetadataOption
465+
(<code>string</code> alias)</h3>
466+
<p>
467+
(<em>Appears on:</em>
468+
<a href="#kustomize.toolkit.fluxcd.io/v1.KustomizationSpec">KustomizationSpec</a>)
469+
</p>
470+
<p>BuildMetadataOption defines the supported buildMetadata options.</p>
447471
<h3 id="kustomize.toolkit.fluxcd.io/v1.CommonMetadata">CommonMetadata
448472
</h3>
449473
<p>
@@ -1018,6 +1042,23 @@ resources. When enabled, the HealthChecks are ignored. Defaults to false.</p>
10181042
</tr>
10191043
<tr>
10201044
<td>
1045+
<code>buildMetadata</code><br>
1046+
<em>
1047+
<a href="#kustomize.toolkit.fluxcd.io/v1.BuildMetadataOption">
1048+
[]BuildMetadataOption
1049+
</a>
1050+
</em>
1051+
</td>
1052+
<td>
1053+
<em>(Optional)</em>
1054+
<p>BuildMetadata specifies which kustomize build metadata should be added
1055+
to the built resources. The allowed values are &lsquo;originAnnotations&rsquo; to
1056+
annotate resources with their source origin, and &lsquo;transformerAnnotations&rsquo;
1057+
to annotate resources with the transformers that produced them.</p>
1058+
</td>
1059+
</tr>
1060+
<tr>
1061+
<td>
10211062
<code>components</code><br>
10221063
<em>
10231064
[]string

docs/spec/v1/kustomizations.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -649,6 +649,41 @@ spec:
649649
digest: sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3
650650
```
651651

652+
### Build metadata
653+
654+
`.spec.buildMetadata` is an optional list used to specify which
655+
[Kustomize `buildMetadata`](https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/buildmetadata/)
656+
options should be added to the built resources. The allowed values are:
657+
658+
- `originAnnotations`: Adds `config.kubernetes.io/origin` annotations that
659+
track which file and path each resource was loaded from.
660+
- `transformerAnnotations`: Adds `internal.config.kubernetes.io` annotations
661+
that record which kustomize transformers modified each resource.
662+
663+
```yaml
664+
apiVersion: kustomize.toolkit.fluxcd.io/v1
665+
kind: Kustomization
666+
metadata:
667+
name: podinfo
668+
namespace: flux-system
669+
spec:
670+
# ...omitted for brevity
671+
buildMetadata:
672+
- originAnnotations
673+
```
674+
675+
When `originAnnotations` is enabled, each resource gets an annotation like:
676+
677+
```yaml
678+
metadata:
679+
annotations:
680+
config.kubernetes.io/origin: |
681+
path: apps/deployment.yaml
682+
```
683+
684+
This is useful for debugging, auditing, and tooling that needs to trace
685+
resources back to their source files.
686+
652687
### Components
653688

654689
`.spec.components` is an optional list used to specify

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ require (
2727
github.com/fluxcd/pkg/auth v0.40.0
2828
github.com/fluxcd/pkg/cache v0.13.0
2929
github.com/fluxcd/pkg/http/fetch v0.22.0
30-
github.com/fluxcd/pkg/kustomize v1.28.0
30+
github.com/fluxcd/pkg/kustomize v1.29.0
3131
github.com/fluxcd/pkg/runtime v0.103.0
3232
github.com/fluxcd/pkg/ssa v0.70.0
3333
github.com/fluxcd/pkg/tar v0.17.0

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -219,8 +219,8 @@ github.com/fluxcd/pkg/envsubst v1.5.0 h1:S07mo+MkGhptdHA4pRze5HPKlc8tHxKswNdcMZi
219219
github.com/fluxcd/pkg/envsubst v1.5.0/go.mod h1:c3a8DYI855sZUubHFYQbjfjop6Wu4/zg1cLyf7SnCes=
220220
github.com/fluxcd/pkg/http/fetch v0.22.0 h1:FT8CfstPE/e7+KRxNrx8ZJ1Uj5rkR5wXOtvQJurNQ0U=
221221
github.com/fluxcd/pkg/http/fetch v0.22.0/go.mod h1:X+8wF3peP79TyyDSgCJiavz+fAcYaf7CRXSeu7ccsPA=
222-
github.com/fluxcd/pkg/kustomize v1.28.0 h1:0RuFVczJRabbt8frHZ/ql8aqte6BOOKk274O09l6/hE=
223-
github.com/fluxcd/pkg/kustomize v1.28.0/go.mod h1:cW08mnngSP8MJYb6mDmMvxH8YjNATdiML0udb37dk+M=
222+
github.com/fluxcd/pkg/kustomize v1.29.0 h1:B/5hr9wX6INwaQAZ6BGKVNvZm++A6qjgorUfoaBAwPw=
223+
github.com/fluxcd/pkg/kustomize v1.29.0/go.mod h1:cW08mnngSP8MJYb6mDmMvxH8YjNATdiML0udb37dk+M=
224224
github.com/fluxcd/pkg/runtime v0.103.0 h1:J5y5GPhWdkyqIUBlaI1FP2N02TtZmsjbWhhZubuTSFk=
225225
github.com/fluxcd/pkg/runtime v0.103.0/go.mod h1:mbo2f3azo3yVQgm7XZGxQB6/2zvzQ5Wgtd8TjRRwwAw=
226226
github.com/fluxcd/pkg/sourceignore v0.17.0 h1:Z72nruRMhC15zIEpWoDrAcJcJ1El6QDnP/aRDfE4WOA=

internal/controller/kustomization_transformer_test.go

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -604,3 +604,104 @@ func checkSecret(list *corev1.SecretList, name string) bool {
604604

605605
return false
606606
}
607+
608+
func TestKustomizationReconciler_BuildMetadata(t *testing.T) {
609+
g := NewWithT(t)
610+
id := "bm-" + randStringRunes(5)
611+
revision := "v1.0.0"
612+
resultK := &kustomizev1.Kustomization{}
613+
614+
err := createNamespace(id)
615+
g.Expect(err).NotTo(HaveOccurred(), "failed to create test namespace")
616+
617+
err = createKubeConfigSecret(id)
618+
g.Expect(err).NotTo(HaveOccurred(), "failed to create kubeconfig secret")
619+
620+
manifests := func(name string) []testserver.File {
621+
return []testserver.File{
622+
{
623+
Name: "config.yaml",
624+
Body: fmt.Sprintf(`---
625+
apiVersion: v1
626+
kind: ConfigMap
627+
metadata:
628+
name: %[1]s
629+
data:
630+
key: val
631+
`, name),
632+
},
633+
}
634+
}
635+
636+
artifact, err := testServer.ArtifactFromFiles(manifests(id))
637+
g.Expect(err).NotTo(HaveOccurred())
638+
639+
repositoryName := types.NamespacedName{
640+
Name: fmt.Sprintf("bm-%s", randStringRunes(5)),
641+
Namespace: id,
642+
}
643+
644+
err = applyGitRepository(repositoryName, artifact, revision)
645+
g.Expect(err).NotTo(HaveOccurred())
646+
647+
kustomizationKey := types.NamespacedName{
648+
Name: fmt.Sprintf("bm-%s", randStringRunes(5)),
649+
Namespace: id,
650+
}
651+
kustomization := &kustomizev1.Kustomization{
652+
ObjectMeta: metav1.ObjectMeta{
653+
Name: kustomizationKey.Name,
654+
Namespace: kustomizationKey.Namespace,
655+
},
656+
Spec: kustomizev1.KustomizationSpec{
657+
Interval: metav1.Duration{Duration: 2 * time.Minute},
658+
Path: "./",
659+
KubeConfig: &meta.KubeConfigReference{
660+
SecretRef: &meta.SecretKeyReference{
661+
Name: "kubeconfig",
662+
},
663+
},
664+
SourceRef: kustomizev1.CrossNamespaceSourceReference{
665+
Name: repositoryName.Name,
666+
Namespace: repositoryName.Namespace,
667+
Kind: sourcev1.GitRepositoryKind,
668+
},
669+
Prune: true,
670+
BuildMetadata: []kustomizev1.BuildMetadataOption{
671+
kustomizev1.BuildMetadataOriginAnnotations,
672+
},
673+
TargetNamespace: id,
674+
},
675+
}
676+
677+
g.Expect(k8sClient.Create(context.Background(), kustomization)).To(Succeed())
678+
679+
t.Run("sets origin annotations", func(t *testing.T) {
680+
g := NewWithT(t)
681+
g.Eventually(func() bool {
682+
_ = k8sClient.Get(context.Background(), client.ObjectKeyFromObject(kustomization), resultK)
683+
return isReconcileSuccess(resultK)
684+
}, timeout, time.Second).Should(BeTrue())
685+
kstatusCheck.CheckErr(ctx, resultK)
686+
687+
var cm corev1.ConfigMap
688+
g.Expect(k8sClient.Get(context.Background(), client.ObjectKey{Name: id, Namespace: id}, &cm)).To(Succeed())
689+
g.Expect(cm.GetAnnotations()).To(HaveKey("config.kubernetes.io/origin"))
690+
})
691+
692+
t.Run("removes origin annotations", func(t *testing.T) {
693+
g := NewWithT(t)
694+
resultK.Spec.BuildMetadata = nil
695+
g.Expect(k8sClient.Update(context.Background(), resultK)).To(Succeed())
696+
697+
g.Eventually(func() bool {
698+
_ = k8sClient.Get(context.Background(), client.ObjectKeyFromObject(kustomization), resultK)
699+
return isReconcileSuccess(resultK)
700+
}, timeout, time.Second).Should(BeTrue())
701+
kstatusCheck.CheckErr(ctx, resultK)
702+
703+
var cm corev1.ConfigMap
704+
g.Expect(k8sClient.Get(context.Background(), client.ObjectKey{Name: id, Namespace: id}, &cm)).To(Succeed())
705+
g.Expect(cm.GetAnnotations()).ToNot(HaveKey("config.kubernetes.io/origin"))
706+
})
707+
}

0 commit comments

Comments
 (0)