Skip to content

Commit 48735f3

Browse files
author
Tomek Rękawek
committed
Support a new "Patches" field in the PostRenderer specification.
The new field allows to configure targeted JSON or strategic merge patches. Signed-off-by: Tomek Rękawek <rekawek@adobe.com>
1 parent a71ce4e commit 48735f3

7 files changed

+141
-21
lines changed

api/v2beta1/helmrelease_types.go

+5
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ const HelmReleaseFinalizer = "finalizers.fluxcd.io"
3535

3636
// Kustomize Helm PostRenderer specification.
3737
type Kustomize struct {
38+
// Strategic merge and JSON patches, defined as inline YAML objects,
39+
// capable of targeting objects based on kind, label and annotation selectors.
40+
// +optional
41+
Patches []kustomize.Patch `json:"patches,omitempty"`
42+
3843
// Strategic merge patches, defined as inline YAML objects.
3944
// +optional
4045
PatchesStrategicMerge []apiextensionsv1.JSON `json:"patchesStrategicMerge,omitempty"`

api/v2beta1/zz_generated.deepcopy.go

+5
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

+55
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,61 @@ spec:
299299
- name
300300
type: object
301301
type: array
302+
patches:
303+
description: Strategic merge and JSON patches, defined as
304+
inline YAML objects, capable of targeting objects based
305+
on kind, label and annotation selectors.
306+
items:
307+
description: Patch contains an inline StrategicMerge or
308+
JSON6902 patch, and the target the patch should be applied
309+
to.
310+
properties:
311+
patch:
312+
description: Patch contains an inline StrategicMerge
313+
patch or an inline JSON6902 patch with an array
314+
of operation objects.
315+
type: string
316+
target:
317+
description: Target points to the resources that the
318+
patch document should be applied to.
319+
properties:
320+
annotationSelector:
321+
description: AnnotationSelector is a string that
322+
follows the label selection expression https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api
323+
It matches with the resource annotations.
324+
type: string
325+
group:
326+
description: Group is the API group to select
327+
resources from. Together with Version and Kind
328+
it is capable of unambiguously identifying and/or
329+
selecting resources. https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md
330+
type: string
331+
kind:
332+
description: Kind of the API Group to select resources
333+
from. Together with Group and Version it is
334+
capable of unambiguously identifying and/or
335+
selecting resources. https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md
336+
type: string
337+
labelSelector:
338+
description: LabelSelector is a string that follows
339+
the label selection expression https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api
340+
It matches with the resource labels.
341+
type: string
342+
name:
343+
description: Name to match resources with.
344+
type: string
345+
namespace:
346+
description: Namespace to select resources from.
347+
type: string
348+
version:
349+
description: Version of the API Group to select
350+
resources from. Together with Group and Kind
351+
it is capable of unambiguously identifying and/or
352+
selecting resources. https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md
353+
type: string
354+
type: object
355+
type: object
356+
type: array
302357
patchesJson6902:
303358
description: JSON 6902 patches, defined as inline YAML objects.
304359
items:

docs/api/helmrelease.md

+15
Original file line numberDiff line numberDiff line change
@@ -1427,6 +1427,21 @@ the HelmRelease.</p>
14271427
<tbody>
14281428
<tr>
14291429
<td>
1430+
<code>patches</code><br>
1431+
<em>
1432+
<a href="https://godoc.org/github.com/fluxcd/pkg/apis/kustomize#Patch">
1433+
[]github.com/fluxcd/pkg/apis/kustomize.Patch
1434+
</a>
1435+
</em>
1436+
</td>
1437+
<td>
1438+
<em>(Optional)</em>
1439+
<p>Strategic merge and JSON patches, defined as inline YAML objects,
1440+
capable of targeting objects based on kind, label and annotation selectors.</p>
1441+
</td>
1442+
</tr>
1443+
<tr>
1444+
<td>
14301445
<code>patchesStrategicMerge</code><br>
14311446
<em>
14321447
<a href="https://pkg.go.dev/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1?tab=doc#JSON">

docs/spec/v2beta1/helmreleases.md

+1
Original file line numberDiff line numberDiff line change
@@ -1149,6 +1149,7 @@ HelmRelease resources has a built-in [Kustomize](https://kubectl.docs.kubernetes
11491149
compatible [Post Renderer](https://helm.sh/docs/topics/advanced/#post-rendering), which provides
11501150
the following Kustomize directives:
11511151

1152+
- [patches](https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/patches/)
11521153
- [patchesStrategicMerge](https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/patchesstrategicmerge/)
11531154
- [patchesJson6902](https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/patchesjson6902/)
11541155
- [images](https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/images/)

internal/runner/post_renderer_kustomize.go

+9-16
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ package runner
1919
import (
2020
"bytes"
2121
"encoding/json"
22-
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
2322
"sync"
2423

2524
"sigs.k8s.io/kustomize/api/filesys"
@@ -106,23 +105,17 @@ func (k *postRendererKustomize) Run(renderedManifests *bytes.Buffer) (modifiedMa
106105
return nil, err
107106
}
108107

108+
// Add patches.
109+
for _, m := range k.spec.Patches {
110+
cfg.Patches = append(cfg.Patches, kustypes.Patch{
111+
Patch: m.Patch,
112+
Target: adaptSelector(&m.Target),
113+
})
114+
}
115+
109116
// Add strategic merge patches.
110117
for _, m := range k.spec.PatchesStrategicMerge {
111-
patchWithTarget := struct {
112-
Patch apiextensionsv1.JSON `json:"patch"`
113-
Target kustomize.Selector `json:"target,omitempty"`
114-
}{}
115-
if err := json.Unmarshal(m.Raw, &patchWithTarget); err != nil {
116-
return nil, err
117-
}
118-
if len(patchWithTarget.Patch.Raw) == 0 {
119-
cfg.PatchesStrategicMerge = append(cfg.PatchesStrategicMerge, kustypes.PatchStrategicMerge(m.Raw))
120-
} else {
121-
cfg.Patches = append(cfg.Patches, kustypes.Patch{
122-
Patch: string(patchWithTarget.Patch.Raw),
123-
Target: adaptSelector(&patchWithTarget.Target),
124-
})
125-
}
118+
cfg.PatchesStrategicMerge = append(cfg.PatchesStrategicMerge, kustypes.PatchStrategicMerge(m.Raw))
126119
}
127120

128121
// Add JSON 6902 patches.

internal/runner/post_renderer_kustomize_test.go

+51-5
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ func Test_postRendererKustomize_Run(t *testing.T) {
6363
tests := []struct {
6464
name string
6565
renderedManifests string
66+
patches string
6667
patchesStrategicMerge string
6768
patchesJson6902 string
6869
images string
@@ -146,6 +147,42 @@ spec:
146147
`,
147148
expectManifests: `apiVersion: v1
148149
kind: Pod
150+
metadata:
151+
annotations:
152+
d: "42"
153+
e: "42"
154+
name: json6902
155+
`,
156+
},
157+
{
158+
name: "targeted json 6902",
159+
renderedManifests: json6902Mock,
160+
patches: `
161+
- target:
162+
version: v1
163+
kind: Pod
164+
name: json6902
165+
patch: |
166+
- op: test
167+
path: /metadata/annotations/c
168+
value: foo
169+
- op: remove
170+
path: /metadata/annotations/c
171+
- op: add
172+
path: /metadata/annotations/c
173+
value: [ "foo", "bar" ]
174+
- op: replace
175+
path: /metadata/annotations/c
176+
value: 42
177+
- op: move
178+
from: /metadata/annotations/c
179+
path: /metadata/annotations/d
180+
- op: copy
181+
from: /metadata/annotations/d
182+
path: /metadata/annotations/e
183+
`,
184+
expectManifests: `apiVersion: v1
185+
kind: Pod
149186
metadata:
150187
annotations:
151188
d: "42"
@@ -181,15 +218,15 @@ spec:
181218
`,
182219
},
183220
{
184-
name: "strategic merge with target test",
221+
name: "targeted strategic merge test",
185222
renderedManifests: strategicMergeMock,
186-
patchesStrategicMerge: `
223+
patches: `
187224
- target:
188225
group: apps
189226
version: v1
190227
kind: Deployment
191228
name: nginx
192-
patch:
229+
patch: |
193230
apiVersion: apps/v1
194231
kind: Deployment
195232
metadata:
@@ -216,7 +253,11 @@ spec:
216253
}
217254
for _, tt := range tests {
218255
t.Run(tt.name, func(t *testing.T) {
219-
spec, err := mockKustomize(tt.patchesStrategicMerge, tt.patchesJson6902, tt.images)
256+
spec, err := mockKustomize(tt.patches, tt.patchesStrategicMerge, tt.patchesJson6902, tt.images)
257+
if err != nil {
258+
t.Errorf("Run() mockKustomize returned %v", err)
259+
return
260+
}
220261
k := &postRendererKustomize{
221262
spec: spec,
222263
}
@@ -232,7 +273,11 @@ spec:
232273
}
233274
}
234275

235-
func mockKustomize(patchesStrategicMerge, patchesJson6902, images string) (*v2.Kustomize, error) {
276+
func mockKustomize(patches, patchesStrategicMerge, patchesJson6902, images string) (*v2.Kustomize, error) {
277+
var targeted []kustomize.Patch
278+
if err := yaml.Unmarshal([]byte(patches), &targeted); err != nil {
279+
return nil, err
280+
}
236281
b, err := yaml.YAMLToJSON([]byte(patchesStrategicMerge))
237282
if err != nil {
238283
return nil, err
@@ -250,6 +295,7 @@ func mockKustomize(patchesStrategicMerge, patchesJson6902, images string) (*v2.K
250295
return nil, err
251296
}
252297
return &v2.Kustomize{
298+
Patches: targeted,
253299
PatchesStrategicMerge: strategicMerge,
254300
PatchesJSON6902: json6902,
255301
Images: imgs,

0 commit comments

Comments
 (0)