Skip to content

Commit 4c1ea27

Browse files
authored
Merge pull request #943 from fluxcd/ssa-policies
Add `IfNotPresent` and `Ignore` SSA policies
2 parents 6c9c239 + 743cb79 commit 4c1ea27

5 files changed

Lines changed: 98 additions & 49 deletions

File tree

api/v1/kustomization_types.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@ const (
3030
MaxConditionMessageLength = 20000
3131
EnabledValue = "enabled"
3232
DisabledValue = "disabled"
33-
MergeValue = "merge"
33+
MergeValue = "Merge"
34+
IfNotPresentValue = "IfNotPresent"
35+
IgnoreValue = "Ignore"
3436
)
3537

3638
// KustomizationSpec defines the configuration to calculate the desired state

docs/spec/v1/kustomizations.md

Lines changed: 85 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1044,6 +1044,79 @@ cd apps/my-app
10441044
kustomize create --autodetect --recursive
10451045
```
10461046

1047+
### Controlling the apply behavior of resources
1048+
1049+
To change the apply behaviour for specific Kubernetes resources, you can annotate them with:
1050+
1051+
| Annotation | Default | Values | Role |
1052+
|-------------------------------------|------------|----------------------------------------------------------------|-----------------|
1053+
| `kustomize.toolkit.fluxcd.io/ssa` | `Override` | - `Override`<br/>- `Merge`<br/>- `IfNotPresent`<br/>- `Ignore` | Apply policy |
1054+
| `kustomize.toolkit.fluxcd.io/force` | `Disabled` | - `Enabled`<br/>- `Disabled` | Recreate policy |
1055+
| `kustomize.toolkit.fluxcd.io/prune` | `Enabled` | - `Enabled`<br/>- `Disabled` | Delete policy |
1056+
1057+
**Note:** These annotations should be set in the Kubernetes YAML manifests included
1058+
in the Flux Kustomization source (Git, OCI, Bucket).
1059+
1060+
#### `kustomize.toolkit.fluxcd.io/ssa`
1061+
1062+
##### Override
1063+
1064+
The `Override` policy instructs the controller to reconcile the Kubernetes resources
1065+
with the desired state (YAML manifests) defined in the Flux source (Git, OCI, Bucket).
1066+
1067+
If you use `kubectl` to edit a Kubernetes resource managed by Flux, all changes will be
1068+
reverted when the controller reconciles a Flux Kustomization containing that resource.
1069+
In order to preserve fields added with `kubectl`, you have to specify
1070+
a field manager named `flux-client-side-apply` e.g.:
1071+
1072+
```sh
1073+
kubectl apply --field-manager=flux-client-side-apply
1074+
```
1075+
1076+
##### Merge
1077+
1078+
The `Merge` policy instructs the controller to preserve the fields added by other tools to the
1079+
Kubernetes resources managed by Flux.
1080+
1081+
The fields defined in the manifests applied by the controller will always be overridden,
1082+
the `Merge` policy works only for adding new fields that don’t overlap with the desired
1083+
state.
1084+
1085+
For lists fields which are atomic (e.g. `.spec.tolerations` in PodSpec), Kubernetes
1086+
doesn't allow different managers for such fields, therefore any changes to these
1087+
fields will be reverted. For more context, please see the Kubernetes enhancement document:
1088+
[555-server-side-apply](https://github.com/kubernetes/enhancements/blob/master/keps/sig-api-machinery/555-server-side-apply/README.md#lists).
1089+
1090+
##### IfNotPresent
1091+
1092+
The `IfNotPresent` policy instructs the controller to only apply the Kubernetes resources
1093+
if they are not present on the cluster.
1094+
1095+
This policy can be used for Kubernetes Secrets and ValidatingWebhookConfigurations managed by cert-manager,
1096+
where Flux creates the resources with fields that are later on mutated by other controllers.
1097+
1098+
##### Ignore
1099+
1100+
The `Ignore` policy instructs the controller to skip applying Kubernetes resources
1101+
even if they are included in a Flux source (Git, OCI, Bucket).
1102+
1103+
#### `kustomize.toolkit.fluxcd.io/force`
1104+
1105+
When set to `Enabled`, this policy instructs the controller to recreate the Kubernetes resources
1106+
with changes to immutable fields.
1107+
1108+
This policy can be used for Kubernetes Jobs to rerun them when their container image changes.
1109+
1110+
**Note:** Using this policy for StatefulSets may result in potential data loss.
1111+
1112+
#### `kustomize.toolkit.fluxcd.io/prune`
1113+
1114+
When set to `Disabled`, this policy instructs the controller to skip the deletion of
1115+
the Kubernetes resources subject to [garbage collection](#prune).
1116+
1117+
This policy can be used to protect sensitive resources such as Namespaces, PVCs and PVs
1118+
from accidental deletion.
1119+
10471120
### Role-based access control
10481121

10491122
By default, a Kustomization apply runs under the cluster admin account and can
@@ -1502,48 +1575,6 @@ Using `flux`:
15021575
flux reconcile kustomization <kustomization-name>
15031576
```
15041577

1505-
### Customizing reconciliation
1506-
1507-
You can configure the controller to ignore in-cluster resources by labelling or
1508-
annotating them with:
1509-
1510-
```yaml
1511-
kustomize.toolkit.fluxcd.io/reconcile: disabled
1512-
```
1513-
1514-
**Note:** When the `kustomize.toolkit.fluxcd.io/reconcile` annotation is set to
1515-
`disabled`, the controller will no longer apply changes from the source, nor
1516-
will it prune the resource. To resume reconciliation, set the annotation to
1517-
`enabled` in the source or remove it from the in-cluster object.
1518-
1519-
If you use `kubectl` to edit an object managed by Flux, all changes will be
1520-
reverted when the controller reconciles a Flux Kustomization containing that
1521-
object. In order to preserve fields added with `kubectl`, you have to specify
1522-
a field manager named `flux-client-side-apply` e.g.:
1523-
1524-
```sh
1525-
kubectl apply --field-manager=flux-client-side-apply
1526-
```
1527-
1528-
Another option is to annotate or label objects with:
1529-
1530-
```yaml
1531-
kustomize.toolkit.fluxcd.io/ssa: merge
1532-
```
1533-
1534-
**Note:** The fields defined in manifests will always be overridden, the above
1535-
procedure works only for adding new fields that don’t overlap with the desired
1536-
state.
1537-
1538-
For lists fields which are atomic (e.g. `.spec.tolerations` in PodSpec), Kubernetes
1539-
doesn't allow different managers for such fields, therefore any changes to these
1540-
fields will be undone, even if you specify a manager. For more context, please
1541-
see the Kubernetes enhancement document:
1542-
[555-server-side-apply](https://github.com/kubernetes/enhancements/blob/master/keps/sig-api-machinery/555-server-side-apply/README.md#lists).
1543-
1544-
To learn how to handle patching failures due to immutable field changes, refer
1545-
to [`.spec.force`](#force).
1546-
15471578
### Waiting for `Ready`
15481579

15491580
When a change is applied, it is possible to wait for the Kustomization to reach
@@ -1558,6 +1589,18 @@ kubectl wait kustomization/<kustomization-name> --for=condition=ready --timeout=
15581589
When you find yourself in a situation where you temporarily want to pause the
15591590
reconciliation of a Kustomization, you can suspend it using [`.spec.suspend`](#suspend).
15601591

1592+
To pause the reconciliation of a specific Kubernetes resource managed by a Flux Kustomization,
1593+
you can annotate or label the resource in-cluster with:
1594+
1595+
```yaml
1596+
kustomize.toolkit.fluxcd.io/reconcile: disabled
1597+
```
1598+
1599+
**Note:** When the `kustomize.toolkit.fluxcd.io/reconcile` annotation is set to
1600+
`disabled`, the controller will no longer apply changes, nor
1601+
will it prune the resource. To resume reconciliation, set the annotation to
1602+
`enabled` in the source or remove it from the in-cluster object.
1603+
15611604
#### Suspend a Kustomization
15621605

15631606
In your YAML declaration:

go.mod

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ require (
3131
github.com/fluxcd/pkg/http/fetch v0.5.2
3232
github.com/fluxcd/pkg/kustomize v1.3.4
3333
github.com/fluxcd/pkg/runtime v0.41.0
34-
github.com/fluxcd/pkg/ssa v0.29.0
34+
github.com/fluxcd/pkg/ssa v0.30.0
3535
github.com/fluxcd/pkg/tar v0.2.0
3636
github.com/fluxcd/pkg/testserver v0.4.0
3737
github.com/fluxcd/source-controller/api v1.0.0
@@ -226,5 +226,5 @@ require (
226226
k8s.io/kubectl v0.27.1 // indirect
227227
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
228228
sigs.k8s.io/kustomize/kyaml v0.14.2 // indirect
229-
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
229+
sigs.k8s.io/structured-merge-diff/v4 v4.3.0 // indirect
230230
)

go.sum

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -196,8 +196,8 @@ github.com/fluxcd/pkg/runtime v0.41.0 h1:hjWUwVRCKDuGEUhovWrygt/6PRry4p278yKuJNg
196196
github.com/fluxcd/pkg/runtime v0.41.0/go.mod h1:1GN+nxoQ7LmSsLJwjH8JW8pA27tBSO+KLH43HpywCDM=
197197
github.com/fluxcd/pkg/sourceignore v0.3.4 h1:0cfS2Pj7xp2qpaerMjYqOBr82LC+/mGHl6v6pRbi5hs=
198198
github.com/fluxcd/pkg/sourceignore v0.3.4/go.mod h1:ejLx+/uIrPUgqVzMTR5JiWuUnzs+zTkoEf9gS92LqaE=
199-
github.com/fluxcd/pkg/ssa v0.29.0 h1:s2M6507YlYRLsPuXuGhXez/EqA5LFLhI13TZe31sm10=
200-
github.com/fluxcd/pkg/ssa v0.29.0/go.mod h1:wvmBGQC47669GqhOvi0Ec0HTMziqMSNkPIsyIPBtGTQ=
199+
github.com/fluxcd/pkg/ssa v0.30.0 h1:SYf8EBXevbTNwdHoKqRuU00YdnmqqUuR5xcciRrIi0E=
200+
github.com/fluxcd/pkg/ssa v0.30.0/go.mod h1:eUcni/amc2fM9rJ3ZR3oPeAW/ZYk3mOGO1TW9RFmAuI=
201201
github.com/fluxcd/pkg/tar v0.2.0 h1:HEUHgONQYsJGeZZ4x6h5nQU9Aox1I4T3bOp1faWTqf8=
202202
github.com/fluxcd/pkg/tar v0.2.0/go.mod h1:w0/TOC7kwBJhnSJn7TCABkc/I7ib1f2Yz6vOsbLBnhw=
203203
github.com/fluxcd/pkg/testserver v0.4.0 h1:pDZ3gistqYhwlf3sAjn1Q8NzN4Qe6I1BEmHMHi46lMg=
@@ -737,7 +737,7 @@ sigs.k8s.io/kustomize/api v0.13.4 h1:E38Hfx0G9R9v7vRgKshviPotJQETG0S2gD3JdHLCAsI
737737
sigs.k8s.io/kustomize/api v0.13.4/go.mod h1:Bkaavz5RKK6ZzP0zgPrB7QbpbBJKiHuD3BB0KujY7Ls=
738738
sigs.k8s.io/kustomize/kyaml v0.14.2 h1:9WSwztbzwGszG1bZTziQUmVMrJccnyrLb5ZMKpJGvXw=
739739
sigs.k8s.io/kustomize/kyaml v0.14.2/go.mod h1:AN1/IpawKilWD7V+YvQwRGUvuUOOWpjsHu6uHwonSF4=
740-
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE=
741-
sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E=
740+
sigs.k8s.io/structured-merge-diff/v4 v4.3.0 h1:UZbZAZfX0wV2zr7YZorDz6GXROfDFj6LvqCRm4VUVKk=
741+
sigs.k8s.io/structured-merge-diff/v4 v4.3.0/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08=
742742
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
743743
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=

internal/controller/kustomization_controller.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -658,6 +658,10 @@ func (r *KustomizationReconciler) apply(ctx context.Context,
658658
applyOpts.Force = obj.Spec.Force
659659
applyOpts.ExclusionSelector = map[string]string{
660660
fmt.Sprintf("%s/reconcile", kustomizev1.GroupVersion.Group): kustomizev1.DisabledValue,
661+
fmt.Sprintf("%s/ssa", kustomizev1.GroupVersion.Group): kustomizev1.IgnoreValue,
662+
}
663+
applyOpts.IfNotPresentSelector = map[string]string{
664+
fmt.Sprintf("%s/ssa", kustomizev1.GroupVersion.Group): kustomizev1.IfNotPresentValue,
661665
}
662666
applyOpts.ForceSelector = map[string]string{
663667
fmt.Sprintf("%s/force", kustomizev1.GroupVersion.Group): kustomizev1.EnabledValue,

0 commit comments

Comments
 (0)