Implement generic patches in Kustomization
Allow patching multiple resources instead of a single existing one as StrategicMerge & JSON6902 are forced to target existing named resources. Signed-off-by: Guillaume Le Biller <glebiller@Traveldoo.com>
This commit is contained in:
parent
30dd0c33b0
commit
b797eac907
|
@ -83,6 +83,10 @@ type KustomizationSpec struct {
|
|||
// +optional
|
||||
HealthChecks []meta.NamespacedObjectKindReference `json:"healthChecks,omitempty"`
|
||||
|
||||
// Patches (also called overlays), defined as inline YAML objects.
|
||||
// +optional
|
||||
Patches []kustomize.Patch `json:"patches,omitempty"`
|
||||
|
||||
// Strategic merge patches, defined as inline YAML objects.
|
||||
// +optional
|
||||
PatchesStrategicMerge []apiextensionsv1.JSON `json:"patchesStrategicMerge,omitempty"`
|
||||
|
|
|
@ -173,6 +173,11 @@ func (in *KustomizationSpec) DeepCopyInto(out *KustomizationSpec) {
|
|||
*out = make([]meta.NamespacedObjectKindReference, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Patches != nil {
|
||||
in, out := &in.Patches, &out.Patches
|
||||
*out = make([]kustomize.Patch, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.PatchesStrategicMerge != nil {
|
||||
in, out := &in.PatchesStrategicMerge, &out.PatchesStrategicMerge
|
||||
*out = make([]apiextensionsv1.JSON, len(*in))
|
||||
|
|
|
@ -142,6 +142,41 @@ spec:
|
|||
- name
|
||||
type: object
|
||||
type: object
|
||||
patches:
|
||||
description: Patches (also called overlays), defined as inline YAML objects.
|
||||
items:
|
||||
description: Patch contains either a StrategicMerge or a JSON6902 patch, either a file or inline, and the target the patch should be applied to.
|
||||
properties:
|
||||
patch:
|
||||
description: Patch contains the JSON6902 patch document with an array of operation objects.
|
||||
type: string
|
||||
target:
|
||||
description: Target points to the resources that the patch document should be applied to.
|
||||
properties:
|
||||
annotationSelector:
|
||||
description: AnnotationSelector is a string that follows the label selection expression https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api It matches with the resource annotations.
|
||||
type: string
|
||||
group:
|
||||
description: Group is the API group to select resources from. Together with Version and Kind it is capable of unambiguously identifying and/or selecting resources. https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md
|
||||
type: string
|
||||
kind:
|
||||
description: Kind of the API Group to select resources from. Together with Group and Version it is capable of unambiguously identifying and/or selecting resources. https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md
|
||||
type: string
|
||||
labelSelector:
|
||||
description: LabelSelector is a string that follows the label selection expression https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api It matches with the resource labels.
|
||||
type: string
|
||||
name:
|
||||
description: Name to match resources with.
|
||||
type: string
|
||||
namespace:
|
||||
description: Namespace to select resources from.
|
||||
type: string
|
||||
version:
|
||||
description: Version of the API Group to select resources from. Together with Group and Kind it is capable of unambiguously identifying and/or selecting resources. https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
type: array
|
||||
patchesJson6902:
|
||||
description: JSON 6902 patches, defined as inline YAML objects.
|
||||
items:
|
||||
|
|
|
@ -144,10 +144,17 @@ var _ = Describe("KustomizationReconciler", func() {
|
|||
Expect(deployment.Spec.Template.Spec.Containers[0].Image).To(Equal("ghcr.io/stefanprodan/podinfo:5.2.0"))
|
||||
})
|
||||
|
||||
It("strategic merge patches", func() {
|
||||
kustomization.Spec.PatchesStrategicMerge = []apiextensionsv1.JSON{
|
||||
It("patches as JSON", func() {
|
||||
kustomization.Spec.Patches = []kustomize.Patch{
|
||||
{
|
||||
Raw: []byte(`{"kind":"Deployment","apiVersion":"apps/v1","metadata":{"name":"podinfo","labels":{"xxxx":"yyyy"}}}`),
|
||||
Patch: `
|
||||
- op: add
|
||||
path: /metadata/labels/patch
|
||||
value: inline-json
|
||||
`,
|
||||
Target: kustomize.Selector{
|
||||
LabelSelector: "app=podinfo",
|
||||
},
|
||||
},
|
||||
}
|
||||
Expect(k8sClient.Create(context.TODO(), kustomization)).To(Succeed())
|
||||
|
@ -160,15 +167,59 @@ var _ = Describe("KustomizationReconciler", func() {
|
|||
|
||||
var deployment appsv1.Deployment
|
||||
Expect(k8sClient.Get(context.TODO(), client.ObjectKey{Name: "podinfo", Namespace: namespace.Name}, &deployment)).To(Succeed())
|
||||
Expect(deployment.ObjectMeta.Labels["xxxx"]).To(Equal("yyyy"))
|
||||
Expect(deployment.ObjectMeta.Labels["patch"]).To(Equal("inline-json"))
|
||||
})
|
||||
|
||||
It("patches as YAML", func() {
|
||||
kustomization.Spec.Patches = []kustomize.Patch{
|
||||
{
|
||||
Patch: `
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: podinfo
|
||||
labels:
|
||||
patch: inline-yaml
|
||||
`,
|
||||
},
|
||||
}
|
||||
Expect(k8sClient.Create(context.TODO(), kustomization)).To(Succeed())
|
||||
|
||||
Eventually(func() bool {
|
||||
var obj kustomizev1.Kustomization
|
||||
_ = k8sClient.Get(context.Background(), ObjectKey(kustomization), &obj)
|
||||
return obj.Status.LastAppliedRevision == "main/"+artifactChecksum
|
||||
}, timeout, time.Second).Should(BeTrue())
|
||||
|
||||
var deployment appsv1.Deployment
|
||||
Expect(k8sClient.Get(context.TODO(), client.ObjectKey{Name: "podinfo", Namespace: namespace.Name}, &deployment)).To(Succeed())
|
||||
Expect(deployment.ObjectMeta.Labels["patch"]).To(Equal("inline-yaml"))
|
||||
})
|
||||
|
||||
It("strategic merge patches", func() {
|
||||
kustomization.Spec.PatchesStrategicMerge = []apiextensionsv1.JSON{
|
||||
{
|
||||
Raw: []byte(`{"kind":"Deployment","apiVersion":"apps/v1","metadata":{"name":"podinfo","labels":{"patch":"strategic-merge"}}}`),
|
||||
},
|
||||
}
|
||||
Expect(k8sClient.Create(context.TODO(), kustomization)).To(Succeed())
|
||||
|
||||
Eventually(func() bool {
|
||||
var obj kustomizev1.Kustomization
|
||||
_ = k8sClient.Get(context.Background(), ObjectKey(kustomization), &obj)
|
||||
return obj.Status.LastAppliedRevision == "main/"+artifactChecksum
|
||||
}, timeout, time.Second).Should(BeTrue())
|
||||
|
||||
var deployment appsv1.Deployment
|
||||
Expect(k8sClient.Get(context.TODO(), client.ObjectKey{Name: "podinfo", Namespace: namespace.Name}, &deployment)).To(Succeed())
|
||||
Expect(deployment.ObjectMeta.Labels["patch"]).To(Equal("strategic-merge"))
|
||||
})
|
||||
|
||||
It("JSON6902 patches", func() {
|
||||
kustomization.Spec.PatchesJSON6902 = []kustomize.JSON6902Patch{
|
||||
{
|
||||
|
||||
Patch: []kustomize.JSON6902{
|
||||
{Op: "add", Path: "/metadata/labels/yyyy", Value: &apiextensionsv1.JSON{Raw: []byte(`"xxxx"`)}},
|
||||
{Op: "add", Path: "/metadata/labels/patch", Value: &apiextensionsv1.JSON{Raw: []byte(`"json6902"`)}},
|
||||
{Op: "replace", Path: "/spec/replicas", Value: &apiextensionsv1.JSON{Raw: []byte("2")}},
|
||||
},
|
||||
Target: kustomize.Selector{
|
||||
|
@ -189,7 +240,7 @@ var _ = Describe("KustomizationReconciler", func() {
|
|||
|
||||
var deployment appsv1.Deployment
|
||||
Expect(k8sClient.Get(context.TODO(), client.ObjectKey{Name: "podinfo", Namespace: namespace.Name}, &deployment)).To(Succeed())
|
||||
Expect(deployment.ObjectMeta.Labels["yyyy"]).To(Equal("xxxx"))
|
||||
Expect(deployment.ObjectMeta.Labels["patch"]).To(Equal("json6902"))
|
||||
Expect(*deployment.Spec.Replicas).To(Equal(int32(2)))
|
||||
})
|
||||
})
|
||||
|
|
|
@ -104,6 +104,13 @@ func (kg *KustomizeGenerator) WriteFile(ctx context.Context, dirPath string) (st
|
|||
kus.Namespace = kg.kustomization.Spec.TargetNamespace
|
||||
}
|
||||
|
||||
for _, m := range kg.kustomization.Spec.Patches {
|
||||
kus.Patches = append(kus.Patches, kustypes.Patch{
|
||||
Patch: m.Patch,
|
||||
Target: adaptSelector(&m.Target),
|
||||
})
|
||||
}
|
||||
|
||||
for _, m := range kg.kustomization.Spec.PatchesStrategicMerge {
|
||||
kus.PatchesStrategicMerge = append(kus.PatchesStrategicMerge, kustypes.PatchStrategicMerge(m.Raw))
|
||||
}
|
||||
|
|
|
@ -198,6 +198,20 @@ bool
|
|||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>patches</code><br>
|
||||
<em>
|
||||
<a href="https://godoc.org/github.com/fluxcd/pkg/apis/kustomize#Patch">
|
||||
[]github.com/fluxcd/pkg/apis/kustomize.Patch
|
||||
</a>
|
||||
</em>
|
||||
</td>
|
||||
<td>
|
||||
<em>(Optional)</em>
|
||||
<p>Patches (also called overlays), defined as inline YAML objects.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>patchesStrategicMerge</code><br>
|
||||
<em>
|
||||
<a href="https://pkg.go.dev/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1?tab=doc#JSON">
|
||||
|
@ -657,6 +671,20 @@ bool
|
|||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>patches</code><br>
|
||||
<em>
|
||||
<a href="https://godoc.org/github.com/fluxcd/pkg/apis/kustomize#Patch">
|
||||
[]github.com/fluxcd/pkg/apis/kustomize.Patch
|
||||
</a>
|
||||
</em>
|
||||
</td>
|
||||
<td>
|
||||
<em>(Optional)</em>
|
||||
<p>Patches (also called overlays), defined as inline YAML objects.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>patchesStrategicMerge</code><br>
|
||||
<em>
|
||||
<a href="https://pkg.go.dev/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1?tab=doc#JSON">
|
||||
|
|
|
@ -598,14 +598,15 @@ The Kustomization has a set of fields to extend and/or override the Kustomize
|
|||
patches and namespace on all the Kubernetes objects reconciled by the resource,
|
||||
offering support for the following Kustomize directives:
|
||||
|
||||
- [namespace](https://kubectl.docs.kubernetes.io/references/kustomize/namespace/)
|
||||
- [namespace](https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/namespace/)
|
||||
- [patches](https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/patches/)
|
||||
- [patchesStrategicMerge](https://kubectl.docs.kubernetes.io/references/kustomize/patchesstrategicmerge/)
|
||||
- [patchesJson6902](https://kubectl.docs.kubernetes.io/references/kustomize/patchesjson6902/)
|
||||
- [images](https://kubectl.docs.kubernetes.io/references/kustomize/images/)
|
||||
- [patchesJson6902](https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/patchesjson6902/)
|
||||
- [images](https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/images/)
|
||||
|
||||
### Target namespace
|
||||
|
||||
To configure the [Kustomize `namespace`](https://kubectl.docs.kubernetes.io/references/kustomize/namespace/)
|
||||
To configure the [Kustomize `namespace`](https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/namespace/)
|
||||
and overwrite the namespace of all the Kubernetes objects reconciled by the `Kustomization`,
|
||||
`spec.targetNamespace` can be defined:
|
||||
|
||||
|
@ -622,9 +623,35 @@ spec:
|
|||
|
||||
The `targetNamespace` is expected to exist.
|
||||
|
||||
### Patches
|
||||
|
||||
To add [Kustomize `patches` entries](https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/patches/)
|
||||
to the configuration, and patch resources using either a [strategic merge](https://kubectl.docs.kubernetes.io/references/kustomize/glossary#patchstrategicmerge)
|
||||
patch or a [JSON](https://kubectl.docs.kubernetes.io/references/kustomize/glossary#patchjson6902) patch,
|
||||
`spec.patches` items must contain a `target` selector and a `patch` document.
|
||||
The patch can target a single resource or multiple resources
|
||||
|
||||
```yaml
|
||||
apiVersion: kustomize.toolkit.fluxcd.io/v1beta1
|
||||
kind: Kustomization
|
||||
metadata:
|
||||
name: podinfo
|
||||
namespace: flux-system
|
||||
spec:
|
||||
# ...omitted for brevity
|
||||
patches:
|
||||
- patch: |-
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: not-used
|
||||
labels:
|
||||
app.kubernetes.io/part-of: test-app
|
||||
```
|
||||
|
||||
### Strategic Merge patches
|
||||
|
||||
To add [Kustomize `patchesStrategicMerge` entries](https://kubectl.docs.kubernetes.io/references/kustomize/patchesstrategicmerge/)
|
||||
To add [Kustomize `patchesStrategicMerge` entries](https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/patchesstrategicmerge/)
|
||||
to the configuration, `spec.patchesStrategicMerge` can be defined with a list
|
||||
of strategic merge patches in YAML format:
|
||||
|
||||
|
@ -649,7 +676,7 @@ spec:
|
|||
|
||||
### JSON 6902 patches
|
||||
|
||||
To add [Kustomize `patchesJson6902` entries](https://kubectl.docs.kubernetes.io/references/kustomize/patchesjson6902/)
|
||||
To add [Kustomize `patchesJson6902` entries](https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/patchesjson6902/)
|
||||
to the configuration, and patch resources using the [JSON 6902 standard](https://tools.ietf.org/html/rfc6902),
|
||||
`spec.patchesJson6902`, the items must contain a `target` selector and JSON 6902
|
||||
`patch` document:
|
||||
|
@ -675,7 +702,7 @@ spec:
|
|||
|
||||
### Images
|
||||
|
||||
To add [Kustomize `images` entries](https://kubectl.docs.kubernetes.io/references/kustomize/images/)
|
||||
To add [Kustomize `images` entries](https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/images/)
|
||||
to the configuration, and overwrite the name, tag or digest of container images
|
||||
without creating patches, `spec.images` can be defined:
|
||||
|
||||
|
|
Loading…
Reference in New Issue