Skip to content
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
13 changes: 7 additions & 6 deletions api/v1/kustomization_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,10 @@ const (
IfNotPresentValue = "IfNotPresent"
IgnoreValue = "Ignore"

DeletionPolicyMirrorPrune = "MirrorPrune"
DeletionPolicyDelete = "Delete"
DeletionPolicyOrphan = "Orphan"
DeletionPolicyMirrorPrune = "MirrorPrune"
DeletionPolicyDelete = "Delete"
DeletionPolicyWaitForTermination = "WaitForTermination"
DeletionPolicyOrphan = "Orphan"
)

// KustomizationSpec defines the configuration to calculate the desired state
Expand Down Expand Up @@ -101,9 +102,9 @@ type KustomizationSpec struct {

// DeletionPolicy can be used to control garbage collection when this
// Kustomization is deleted. Valid values are ('MirrorPrune', 'Delete',
// 'Orphan'). 'MirrorPrune' mirrors the Prune field (orphan if false,
// delete if true). Defaults to 'MirrorPrune'.
// +kubebuilder:validation:Enum=MirrorPrune;Delete;Orphan
// 'WaitForTermination', 'Orphan'). 'MirrorPrune' mirrors the Prune field
// (orphan if false, delete if true). Defaults to 'MirrorPrune'.
// +kubebuilder:validation:Enum=MirrorPrune;Delete;WaitForTermination;Orphan
// +optional
DeletionPolicy string `json:"deletionPolicy,omitempty"`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,12 @@ spec:
description: |-
DeletionPolicy can be used to control garbage collection when this
Kustomization is deleted. Valid values are ('MirrorPrune', 'Delete',
'Orphan'). 'MirrorPrune' mirrors the Prune field (orphan if false,
delete if true). Defaults to 'MirrorPrune'.
'WaitForTermination', 'Orphan'). 'MirrorPrune' mirrors the Prune field
(orphan if false, delete if true). Defaults to 'MirrorPrune'.
enum:
- MirrorPrune
- Delete
- WaitForTermination
- Orphan
type: string
dependsOn:
Expand Down
8 changes: 4 additions & 4 deletions docs/api/v1/kustomize.md
Original file line number Diff line number Diff line change
Expand Up @@ -217,8 +217,8 @@ string
<em>(Optional)</em>
<p>DeletionPolicy can be used to control garbage collection when this
Kustomization is deleted. Valid values are (&lsquo;MirrorPrune&rsquo;, &lsquo;Delete&rsquo;,
&lsquo;Orphan&rsquo;). &lsquo;MirrorPrune&rsquo; mirrors the Prune field (orphan if false,
delete if true). Defaults to &lsquo;MirrorPrune&rsquo;.</p>
&lsquo;WaitForTermination&rsquo;, &lsquo;Orphan&rsquo;). &lsquo;MirrorPrune&rsquo; mirrors the Prune field
(orphan if false, delete if true). Defaults to &lsquo;MirrorPrune&rsquo;.</p>
</td>
</tr>
<tr>
Expand Down Expand Up @@ -775,8 +775,8 @@ string
<em>(Optional)</em>
<p>DeletionPolicy can be used to control garbage collection when this
Kustomization is deleted. Valid values are (&lsquo;MirrorPrune&rsquo;, &lsquo;Delete&rsquo;,
&lsquo;Orphan&rsquo;). &lsquo;MirrorPrune&rsquo; mirrors the Prune field (orphan if false,
delete if true). Defaults to &lsquo;MirrorPrune&rsquo;.</p>
&lsquo;WaitForTermination&rsquo;, &lsquo;Orphan&rsquo;). &lsquo;MirrorPrune&rsquo; mirrors the Prune field
(orphan if false, delete if true). Defaults to &lsquo;MirrorPrune&rsquo;.</p>
</td>
</tr>
<tr>
Expand Down
8 changes: 8 additions & 0 deletions docs/spec/v1/kustomizations.md
Original file line number Diff line number Diff line change
Expand Up @@ -181,8 +181,16 @@ Valid values:
`true` and orphaned if `false`.
- `Delete` - Ensure the managed resources are deleted before the Kustomization
is deleted.
- `WaitForTermination` - Ensure the managed resources are deleted and wait for
termination before the Kustomization is deleted.
- `Orphan` - Leave the managed resources when the Kustomization is deleted.

The `WaitForTermination` deletion policy blocks and waits for the managed
resources to be removed from etcd by the Kubernetes garbage collector.
The wait time is determined by the `.spec.timeout` field. If a timeout occurs,
the controller will stop waiting for the deletion of the resources,
log an error and will allow the Kustomization to be deleted.

For special cases when the managed resources are removed by other means (e.g.
the deletion of the namespace specified with
[`.spec.targetNamespace`](#target-namespace)), you can set the deletion policy
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ require (
github.com/fluxcd/pkg/http/fetch v0.16.0
github.com/fluxcd/pkg/kustomize v1.17.0
github.com/fluxcd/pkg/runtime v0.59.0
github.com/fluxcd/pkg/ssa v0.46.0
github.com/fluxcd/pkg/ssa v0.47.0
github.com/fluxcd/pkg/tar v0.12.0
github.com/fluxcd/pkg/testserver v0.11.0
github.com/fluxcd/source-controller/api v1.5.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -202,8 +202,8 @@ github.com/fluxcd/pkg/runtime v0.59.0 h1:3OrFkMJB39NcQ2vhhoxqls59sQVSn8U+thhyLbs
github.com/fluxcd/pkg/runtime v0.59.0/go.mod h1:MFbfyNyyoYRgPxpdwC9/dCOkzo7Yxhu/cQ9NKyhvqc0=
github.com/fluxcd/pkg/sourceignore v0.12.0 h1:jCIe6d50rQ3wdXPF0+PhhqN0XrTRIq3upMomPelI8Mw=
github.com/fluxcd/pkg/sourceignore v0.12.0/go.mod h1:dc0zvkuXM5OgL/b3IkrVuwvPjj1zJn4NBUMH45uJ4Y0=
github.com/fluxcd/pkg/ssa v0.46.0 h1:TGomtbA6zTfZrHF0TDn3mIGKH+bbX45zdWSkdYrwS8g=
github.com/fluxcd/pkg/ssa v0.46.0/go.mod h1:qCek0b8tKumh9iNZLmga1mjeXOlZPlZpc6xip/hLMJM=
github.com/fluxcd/pkg/ssa v0.47.0 h1:J6lt6g21HjpfF89xbwcMZ9s1ZgguvNsHrNyc0onjx8g=
github.com/fluxcd/pkg/ssa v0.47.0/go.mod h1:qCek0b8tKumh9iNZLmga1mjeXOlZPlZpc6xip/hLMJM=
github.com/fluxcd/pkg/tar v0.12.0 h1:og6F+ivnWNRbNJSq0ukCTVs7YrGIlzjxSVZU+E8NprM=
github.com/fluxcd/pkg/tar v0.12.0/go.mod h1:Ra5Cj++MD5iCy7bZGKJJX3GpOeMPv+ZDkPO9bBwpDeU=
github.com/fluxcd/pkg/testserver v0.11.0 h1:a/kxpFqv7XQxZjwVPP3voooRmSd/3ipLVolK0xUIxXQ=
Expand Down
46 changes: 40 additions & 6 deletions internal/controller/kustomization_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -1019,20 +1019,40 @@ func (r *KustomizationReconciler) prune(ctx context.Context,
return false, nil
}

// finalizerShouldDeleteResources determines if resources should be deleted
// based on the object's inventory and deletion policy.
// A suspended Kustomization or one without an inventory will not delete resources.
func finalizerShouldDeleteResources(obj *kustomizev1.Kustomization) bool {
if obj.GetDeletionPolicy() == kustomizev1.DeletionPolicyMirrorPrune {
if obj.Spec.Suspend {
return false
}

if obj.Status.Inventory == nil || len(obj.Status.Inventory.Entries) == 0 {
return false
}

switch obj.GetDeletionPolicy() {
case kustomizev1.DeletionPolicyMirrorPrune:
return obj.Spec.Prune
case kustomizev1.DeletionPolicyDelete:
return true
case kustomizev1.DeletionPolicyWaitForTermination:
return true
default:
return false
}
return obj.Spec.DeletionPolicy == kustomizev1.DeletionPolicyDelete
}

// finalize handles the finalization logic for a Kustomization resource during its deletion process.
// Managed resources are pruned based on the deletion policy and suspended state of the Kustomization.
// When the policy is set to WaitForTermination, the function blocks and waits for the resources
// to be terminated by the Kubernetes Garbage Collector for the specified timeout duration.
// If the service account used for impersonation is no longer available or if a timeout occurs
// while waiting for resources to be terminated, an error is logged and the finalizer is removed.
func (r *KustomizationReconciler) finalize(ctx context.Context,
obj *kustomizev1.Kustomization) (ctrl.Result, error) {
log := ctrl.LoggerFrom(ctx)
if finalizerShouldDeleteResources(obj) &&
!obj.Spec.Suspend &&
obj.Status.Inventory != nil &&
obj.Status.Inventory.Entries != nil {
if finalizerShouldDeleteResources(obj) {
objects, _ := inventory.List(obj.Status.Inventory)

var impersonatorOpts []runtimeClient.ImpersonatorOption
Expand Down Expand Up @@ -1085,7 +1105,21 @@ func (r *KustomizationReconciler) finalize(ctx context.Context,
}

if changeSet != nil && len(changeSet.Entries) > 0 {
// Emit event with the resources marked for deletion.
r.event(obj, obj.Status.LastAppliedRevision, obj.Status.LastAppliedOriginRevision, eventv1.EventSeverityInfo, changeSet.String(), nil)

// Wait for the resources marked for deletion to be terminated.
if obj.GetDeletionPolicy() == kustomizev1.DeletionPolicyWaitForTermination {
if err := resourceManager.WaitForSetTermination(changeSet, ssa.WaitOptions{
Interval: 2 * time.Second,
Timeout: obj.GetTimeout(),
}); err != nil {
// Emit an event and log the error if a timeout occurs.
msg := "failed to wait for resources termination"
log.Error(err, msg)
r.event(obj, obj.Status.LastAppliedRevision, obj.Status.LastAppliedOriginRevision, eventv1.EventSeverityError, msg, nil)
}
}
}
} else {
// when the account to impersonate is gone, log the stale objects and continue with the finalization
Expand Down
7 changes: 7 additions & 0 deletions internal/controller/kustomization_deletion_policy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ func TestKustomizationReconciler_DeletionPolicyDelete(t *testing.T) {
deletionPolicy: kustomizev1.DeletionPolicyDelete,
wantDelete: true,
},
{
name: "should delete and wait when deletionPolicy overrides pruning disabled",
prune: false,
deletionPolicy: kustomizev1.DeletionPolicyWaitForTermination,
wantDelete: true,
},
{
name: "should delete when deletionPolicy mirrors prune and pruning enabled",
prune: true,
Expand Down Expand Up @@ -131,6 +137,7 @@ data:
TargetNamespace: id,
Prune: tt.prune,
DeletionPolicy: tt.deletionPolicy,
Timeout: &metav1.Duration{Duration: 5 * time.Second},
},
}

Expand Down