Skip to content

Commit 370baa4

Browse files
committed
Add support for drift detection ignore rules
Signed-off-by: Dipti Pai <diptipai89@outlook.com>
1 parent 8b08db6 commit 370baa4

9 files changed

Lines changed: 552 additions & 3 deletions

File tree

api/v1/kustomization_types.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,13 @@ type KustomizationSpec struct {
199199
// The expressions are evaluated only when Wait or HealthChecks are specified.
200200
// +optional
201201
HealthCheckExprs []kustomize.CustomHealthCheck `json:"healthCheckExprs,omitempty"`
202+
203+
// Ignore is a list of rules for specifying which changes to ignore
204+
// during drift detection. These rules are applied to the resources managed
205+
// by the Kustomization and are used to exclude specific JSON pointer paths
206+
// from the drift detection and apply process.
207+
// +optional
208+
Ignore []DriftIgnoreRule `json:"ignore,omitempty"`
202209
}
203210

204211
// BuildMetadataOption defines the supported buildMetadata options.
@@ -225,6 +232,22 @@ type CommonMetadata struct {
225232
Labels map[string]string `json:"labels,omitempty"`
226233
}
227234

235+
// DriftIgnoreRule defines a rule to selectively disregard specific changes during
236+
// the drift detection process.
237+
type DriftIgnoreRule struct {
238+
// Paths is a list of JSON Pointer (RFC 6901) paths to be excluded from
239+
// consideration in a Kubernetes object.
240+
// +required
241+
Paths []string `json:"paths"`
242+
243+
// Target is a selector for specifying Kubernetes objects to which this
244+
// rule applies.
245+
// If Target is not set, the Paths will be ignored for all Kubernetes
246+
// objects within the manifest of the Kustomization.
247+
// +optional
248+
Target *kustomize.Selector `json:"target,omitempty"`
249+
}
250+
228251
// Decryption defines how decryption is handled for Kubernetes manifests.
229252
type Decryption struct {
230253
// Provider is the name of the decryption engine.

api/v1/zz_generated.deepcopy.go

Lines changed: 32 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: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,73 @@ spec:
231231
- name
232232
type: object
233233
type: array
234+
ignore:
235+
description: |-
236+
Ignore is a list of rules for specifying which changes to ignore
237+
during drift detection. These rules are applied to the resources managed
238+
by the Kustomization and are used to exclude specific JSON pointer paths
239+
from the drift detection and apply process.
240+
items:
241+
description: |-
242+
DriftIgnoreRule defines a rule to selectively disregard specific changes during
243+
the drift detection process.
244+
properties:
245+
paths:
246+
description: |-
247+
Paths is a list of JSON Pointer (RFC 6901) paths to be excluded from
248+
consideration in a Kubernetes object.
249+
items:
250+
type: string
251+
type: array
252+
target:
253+
description: |-
254+
Target is a selector for specifying Kubernetes objects to which this
255+
rule applies.
256+
If Target is not set, the Paths will be ignored for all Kubernetes
257+
objects within the manifest of the Kustomization.
258+
properties:
259+
annotationSelector:
260+
description: |-
261+
AnnotationSelector is a string that follows the label selection expression
262+
https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api
263+
It matches with the resource annotations.
264+
type: string
265+
group:
266+
description: |-
267+
Group is the API group to select resources from.
268+
Together with Version and Kind it is capable of unambiguously identifying and/or selecting resources.
269+
https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md
270+
type: string
271+
kind:
272+
description: |-
273+
Kind of the API Group to select resources from.
274+
Together with Group and Version it is capable of unambiguously
275+
identifying and/or selecting resources.
276+
https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md
277+
type: string
278+
labelSelector:
279+
description: |-
280+
LabelSelector is a string that follows the label selection expression
281+
https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api
282+
It matches with the resource labels.
283+
type: string
284+
name:
285+
description: Name to match resources with.
286+
type: string
287+
namespace:
288+
description: Namespace to select resources from.
289+
type: string
290+
version:
291+
description: |-
292+
Version of the API Group to select resources from.
293+
Together with Group and Kind it is capable of unambiguously identifying and/or selecting resources.
294+
https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md
295+
type: string
296+
type: object
297+
required:
298+
- paths
299+
type: object
300+
type: array
234301
ignoreMissingComponents:
235302
description: |-
236303
IgnoreMissingComponents instructs the controller to ignore Components paths

docs/api/v1/kustomize.md

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,23 @@ health of custom resources using Common Expression Language (CEL).
442442
The expressions are evaluated only when Wait or HealthChecks are specified.</p>
443443
</td>
444444
</tr>
445+
<tr>
446+
<td>
447+
<code>ignore</code><br>
448+
<em>
449+
<a href="#kustomize.toolkit.fluxcd.io/v1.DriftIgnoreRule">
450+
[]DriftIgnoreRule
451+
</a>
452+
</em>
453+
</td>
454+
<td>
455+
<em>(Optional)</em>
456+
<p>Ignore is a list of rules for specifying which changes to ignore
457+
during drift detection. These rules are applied to the resources managed
458+
by the Kustomization and are used to exclude specific JSON pointer paths
459+
from the drift detection and apply process.</p>
460+
</td>
461+
</tr>
445462
</table>
446463
</td>
447464
</tr>
@@ -647,6 +664,57 @@ field.</p>
647664
</table>
648665
</div>
649666
</div>
667+
<h3 id="kustomize.toolkit.fluxcd.io/v1.DriftIgnoreRule">DriftIgnoreRule
668+
</h3>
669+
<p>
670+
(<em>Appears on:</em>
671+
<a href="#kustomize.toolkit.fluxcd.io/v1.KustomizationSpec">KustomizationSpec</a>)
672+
</p>
673+
<p>DriftIgnoreRule defines a rule to selectively disregard specific changes during
674+
the drift detection process.</p>
675+
<div class="md-typeset__scrollwrap">
676+
<div class="md-typeset__table">
677+
<table>
678+
<thead>
679+
<tr>
680+
<th>Field</th>
681+
<th>Description</th>
682+
</tr>
683+
</thead>
684+
<tbody>
685+
<tr>
686+
<td>
687+
<code>paths</code><br>
688+
<em>
689+
[]string
690+
</em>
691+
</td>
692+
<td>
693+
<p>Paths is a list of JSON Pointer (RFC 6901) paths to be excluded from
694+
consideration in a Kubernetes object.</p>
695+
</td>
696+
</tr>
697+
<tr>
698+
<td>
699+
<code>target</code><br>
700+
<em>
701+
<a href="https://godoc.org/github.com/fluxcd/pkg/apis/kustomize#Selector">
702+
github.com/fluxcd/pkg/apis/kustomize.Selector
703+
</a>
704+
</em>
705+
</td>
706+
<td>
707+
<em>(Optional)</em>
708+
<p>Target is a selector for specifying Kubernetes objects to which this
709+
rule applies.
710+
If Target is not set, the Paths will be ignored for all Kubernetes
711+
objects within the manifest of the Kustomization.</p>
712+
</td>
713+
</tr>
714+
</tbody>
715+
</table>
716+
</div>
717+
</div>
650718
<h3 id="kustomize.toolkit.fluxcd.io/v1.KustomizationSpec">KustomizationSpec
651719
</h3>
652720
<p>
@@ -1038,6 +1106,23 @@ health of custom resources using Common Expression Language (CEL).
10381106
The expressions are evaluated only when Wait or HealthChecks are specified.</p>
10391107
</td>
10401108
</tr>
1109+
<tr>
1110+
<td>
1111+
<code>ignore</code><br>
1112+
<em>
1113+
<a href="#kustomize.toolkit.fluxcd.io/v1.DriftIgnoreRule">
1114+
[]DriftIgnoreRule
1115+
</a>
1116+
</em>
1117+
</td>
1118+
<td>
1119+
<em>(Optional)</em>
1120+
<p>Ignore is a list of rules for specifying which changes to ignore
1121+
during drift detection. These rules are applied to the resources managed
1122+
by the Kustomization and are used to exclude specific JSON pointer paths
1123+
from the drift detection and apply process.</p>
1124+
</td>
1125+
</tr>
10411126
</tbody>
10421127
</table>
10431128
</div>

docs/spec/v1/kustomizations.md

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -893,6 +893,113 @@ kustomize.toolkit.fluxcd.io/force: enabled
893893
This way, only the targeted resources are force-replaced when immutable field
894894
changes are made. The annotation should be removed after the change is applied.
895895

896+
### Drift Ignore Rules
897+
898+
`.spec.ignore` is an optional list used to selectively ignore changes
899+
to specific fields during drift detection and correction. This allows external
900+
controllers or tools to manage certain fields on Kubernetes resources without
901+
having those changes reverted by the kustomize-controller during reconciliation.
902+
903+
Each item in the list must have the following fields:
904+
905+
- `paths` (required): A list of [JSON Pointer (RFC 6901)](https://datatracker.ietf.org/doc/html/rfc6901)
906+
paths to exclude from drift detection. These paths refer to specific fields
907+
within the Kubernetes object manifest.
908+
- `target` (optional): A selector to scope the rule to specific Kubernetes
909+
resources. If not set, the paths are ignored for all resources in the
910+
Kustomization.
911+
912+
**Warning:** Omitting the `target` selector causes the rule to match **all**
913+
objects managed by the Kustomization. Always scope rules to specific resources
914+
using `target` unless you intentionally want to ignore the specified paths
915+
across every resource.
916+
917+
The `target` selector supports the following fields:
918+
919+
| Field | Description |
920+
|----------------------|--------------------------------------|
921+
| `group` | API group (regex) |
922+
| `version` | API version (regex) |
923+
| `kind` | Resource kind (regex) |
924+
| `name` | Resource name (regex) |
925+
| `namespace` | Resource namespace (regex) |
926+
| `labelSelector` | Kubernetes label selector expression |
927+
| `annotationSelector` | Kubernetes annotation selector expression |
928+
929+
**Note:** The `group`, `version`, `kind`, `name`, and `namespace` fields
930+
support regex patterns. The `labelSelector` and `annotationSelector` fields
931+
use the standard Kubernetes
932+
[label selector](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors)
933+
syntax.
934+
935+
**Note:** For JSON Pointer paths that contain `/` in the key name (e.g.
936+
annotation keys), the `/` must be escaped as `~1` per
937+
[RFC 6901](https://datatracker.ietf.org/doc/html/rfc6901#section-3).
938+
For example, the annotation `external-dns.alpha.kubernetes.io/hostname`
939+
would be referenced as `/metadata/annotations/external-dns.alpha.kubernetes.io~1hostname`.
940+
941+
To ignore fields only on resources that match a target selector:
942+
943+
```yaml
944+
---
945+
apiVersion: kustomize.toolkit.fluxcd.io/v1
946+
kind: Kustomization
947+
metadata:
948+
name: app
949+
namespace: flux-system
950+
spec:
951+
# ...omitted for brevity
952+
ignore:
953+
- paths:
954+
- "/spec/replicas"
955+
target:
956+
kind: Deployment
957+
- paths:
958+
- "/metadata/annotations/external-dns.alpha.kubernetes.io~1hostname"
959+
target:
960+
kind: Service
961+
name: my-service
962+
- paths:
963+
- "/spec/template/spec/containers/0/resources"
964+
target:
965+
kind: Deployment
966+
name: my-app
967+
```
968+
969+
In the above example:
970+
971+
- The `/spec/replicas` field is ignored on all Deployments, allowing
972+
an HPA or other autoscaler to manage the replica count without
973+
interference from the kustomize-controller.
974+
- The `external-dns.alpha.kubernetes.io/hostname` annotation is ignored
975+
on a specific Service named `my-service`, allowing external-dns to
976+
manage this annotation.
977+
- The entire `/resources` subtree under container spec is ignored on
978+
a specific Deployment named `my-app`, allowing a VPA or other resource
979+
management tool to adjust container resources.
980+
981+
**Note:** Changes to ignored fields alone do not trigger a reconciliation.
982+
The controller excludes ignored paths when comparing the desired state against
983+
the live object, so modifications made by external controllers to those fields
984+
will not cause unnecessary applies or resource version bumps.
985+
986+
**Important:** Drift ignore rules work with the
987+
[server-side apply](https://kubernetes.io/docs/reference/using-api/server-side-apply/)
988+
field ownership model. When a reconciliation is triggered (e.g. by a source
989+
revision change or drift in non-ignored fields),
990+
the controller resolves each ignored path using one of two strategies based on
991+
field ownership:
992+
993+
- **Strip** — If the ignored field is owned by another Apply-type field manager
994+
(e.g. another controller using server-side apply), the field is removed from
995+
the apply payload. This relinquishes the controller's ownership and allows the
996+
other manager to retain full control of the field.
997+
- **Adopt** — If the controller is the sole Apply-type field manager for the
998+
field, the in-cluster value is copied into the apply payload. This preserves
999+
the current value without reverting changes made by Update-type operations
1000+
(e.g. `kubectl patch`, `kubectl edit`, or client-go Update calls) while
1001+
keeping the controller's field ownership intact.
1002+
8961003
### KubeConfig (Remote clusters)
8971004

8981005
With the `.spec.kubeConfig` field a Kustomization

go.mod

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ require (
2929
github.com/fluxcd/pkg/http/fetch v0.24.0
3030
github.com/fluxcd/pkg/kustomize v1.31.0
3131
github.com/fluxcd/pkg/runtime v0.107.0
32-
github.com/fluxcd/pkg/ssa v0.73.0
32+
github.com/fluxcd/pkg/ssa v0.74.0
3333
github.com/fluxcd/pkg/tar v1.1.0
3434
github.com/fluxcd/pkg/testserver v0.13.0
3535
github.com/fluxcd/source-controller/api v1.8.0
@@ -212,8 +212,13 @@ require (
212212
github.com/spf13/cobra v1.10.2 // indirect
213213
github.com/spiffe/go-spiffe/v2 v2.6.0 // indirect
214214
github.com/stoewer/go-strcase v1.3.0 // indirect
215+
github.com/tidwall/gjson v1.18.0 // indirect
216+
github.com/tidwall/match v1.1.1 // indirect
217+
github.com/tidwall/pretty v1.2.1 // indirect
218+
github.com/tidwall/sjson v1.2.5 // indirect
215219
github.com/tjfoc/gmsm v1.4.1 // indirect
216220
github.com/urfave/cli v1.22.17 // indirect
221+
github.com/wI2L/jsondiff v0.6.1 // indirect
217222
github.com/x448/float16 v0.8.4 // indirect
218223
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
219224
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect

0 commit comments

Comments
 (0)