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 support for in-line generic patches to Flux Kustomization API #364

Merged
merged 2 commits into from
Jun 14, 2021
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
2 changes: 1 addition & 1 deletion api/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/fluxcd/kustomize-controller/api
go 1.16

require (
github.com/fluxcd/pkg/apis/kustomize v0.1.0
github.com/fluxcd/pkg/apis/kustomize v0.2.0
github.com/fluxcd/pkg/apis/meta v0.10.0
github.com/fluxcd/pkg/runtime v0.12.0
k8s.io/apiextensions-apiserver v0.21.1
Expand Down
4 changes: 2 additions & 2 deletions api/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,8 @@ github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMi
github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fluxcd/pkg/apis/kustomize v0.1.0 h1:sauL+KHmZ0zV2ZgpsLMyDzCQudBTtaFzSys+rXn9g9w=
github.com/fluxcd/pkg/apis/kustomize v0.1.0/go.mod h1:gEl+W5cVykCC3RfrCaqe+Pz+j4lKl2aeR4dxsom/zII=
github.com/fluxcd/pkg/apis/kustomize v0.2.0 h1:jhu2QHvs+j3Zo9rR6w8hkO3LSC6h3M37zY5ejufOmxY=
github.com/fluxcd/pkg/apis/kustomize v0.2.0/go.mod h1:gEl+W5cVykCC3RfrCaqe+Pz+j4lKl2aeR4dxsom/zII=
github.com/fluxcd/pkg/apis/meta v0.10.0 h1:N7wVGHC1cyPdT87hrDC7UwCwRwnZdQM46PBSLjG2rlE=
github.com/fluxcd/pkg/apis/meta v0.10.0/go.mod h1:CW9X9ijMTpNe7BwnokiUOrLl/h13miwVr/3abEQLbKE=
github.com/fluxcd/pkg/runtime v0.12.0 h1:BPZZ8bBkimpqGAPXqOf3LTaw+tcw6HgbWyCuzbbsJGs=
Expand Down
4 changes: 4 additions & 0 deletions api/v1beta1/kustomization_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"`
Expand Down
5 changes: 5 additions & 0 deletions api/v1beta1/zz_generated.deepcopy.go

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

35 changes: 35 additions & 0 deletions config/crd/bases/kustomize.toolkit.fluxcd.io_kustomizations.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
61 changes: 56 additions & 5 deletions controllers/kustomization_controller_patch_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,10 +144,62 @@ var _ = Describe("KustomizationReconciler", func() {
Expect(deployment.Spec.Template.Spec.Containers[0].Image).To(Equal("ghcr.io/stefanprodan/podinfo:5.2.0"))
})

It("patches as JSON", func() {
kustomization.Spec.Patches = []kustomize.Patch{
{
Patch: `
- op: add
path: /metadata/labels/patch
value: inline-json
`,
Target: kustomize.Selector{
LabelSelector: "app=podinfo",
},
},
}
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-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":{"xxxx":"yyyy"}}}`),
Raw: []byte(`{"kind":"Deployment","apiVersion":"apps/v1","metadata":{"name":"podinfo","labels":{"patch":"strategic-merge"}}}`),
},
}
Expect(k8sClient.Create(context.TODO(), kustomization)).To(Succeed())
Expand All @@ -160,15 +212,14 @@ 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("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{
Expand All @@ -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)))
})
})
Expand Down
7 changes: 7 additions & 0 deletions controllers/kustomization_generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -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))
}
Expand Down
28 changes: 28 additions & 0 deletions docs/api/kustomize.md
Original file line number Diff line number Diff line change
Expand Up @@ -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">
Expand Down Expand Up @@ -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">
Expand Down
43 changes: 36 additions & 7 deletions docs/spec/v1beta1/kustomization.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand All @@ -622,9 +623,37 @@ 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.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

items must contain a target but in the blow example there is no target specified

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the catch :)

In the original Kustomize resource, it's possible to apply a strategic merge patch (not JSON6902) without specifying the target.
I decided to force the target to be present in the Flux implementation for simplicity. Maybe that is something could be added in the future.

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
target:
labelSelector: "app=podinfo"
```

### 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:

Expand All @@ -649,7 +678,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:
Expand All @@ -675,7 +704,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:

Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ require (
github.com/cyphar/filepath-securejoin v0.2.2
github.com/drone/envsubst v1.0.3-0.20200804185402-58bc65f69603
github.com/fluxcd/kustomize-controller/api v0.12.2
github.com/fluxcd/pkg/apis/kustomize v0.1.0
github.com/fluxcd/pkg/apis/kustomize v0.2.0
github.com/fluxcd/pkg/apis/meta v0.10.0
github.com/fluxcd/pkg/runtime v0.12.0
github.com/fluxcd/pkg/testserver v0.1.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,8 @@ github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwo
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
github.com/fluxcd/pkg/apis/kustomize v0.1.0 h1:sauL+KHmZ0zV2ZgpsLMyDzCQudBTtaFzSys+rXn9g9w=
github.com/fluxcd/pkg/apis/kustomize v0.1.0/go.mod h1:gEl+W5cVykCC3RfrCaqe+Pz+j4lKl2aeR4dxsom/zII=
github.com/fluxcd/pkg/apis/kustomize v0.2.0 h1:jhu2QHvs+j3Zo9rR6w8hkO3LSC6h3M37zY5ejufOmxY=
github.com/fluxcd/pkg/apis/kustomize v0.2.0/go.mod h1:gEl+W5cVykCC3RfrCaqe+Pz+j4lKl2aeR4dxsom/zII=
github.com/fluxcd/pkg/apis/meta v0.10.0 h1:N7wVGHC1cyPdT87hrDC7UwCwRwnZdQM46PBSLjG2rlE=
github.com/fluxcd/pkg/apis/meta v0.10.0/go.mod h1:CW9X9ijMTpNe7BwnokiUOrLl/h13miwVr/3abEQLbKE=
github.com/fluxcd/pkg/runtime v0.12.0 h1:BPZZ8bBkimpqGAPXqOf3LTaw+tcw6HgbWyCuzbbsJGs=
Expand Down