Skip to content

Commit fad8432

Browse files
authored
refactor: DeletionPropagationPolicy helpers (#1639)
- Add helpers to the metadata package, remove from e2e - Add similar helpers to the ManagementMode enum
1 parent 4afc1ac commit fad8432

11 files changed

+131
-156
lines changed

e2e/nomostest/clean.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -644,11 +644,11 @@ func disableRepoSyncDeletionPropagation(nt *NT) error {
644644
return err
645645
}
646646
for _, rs := range rsList.Items {
647-
if IsDeletionPropagationEnabled(&rs) {
647+
if metadata.HasDeletionPropagationPolicy(&rs, metadata.DeletionPropagationPolicyForeground) {
648648
rsCopy := rs.DeepCopy()
649649
// Disable deletion-propagation and delete finalizers
650650
// This should unblock RepoSync & Namespace deletion.
651-
RemoveDeletionPropagationPolicy(rsCopy)
651+
metadata.RemoveDeletionPropagationPolicy(rsCopy)
652652
rsCopy.Finalizers = nil
653653
if err := nt.KubeClient.Update(rsCopy); err != nil {
654654
return err
@@ -669,11 +669,11 @@ func disableRootSyncDeletionPropagation(nt *NT) error {
669669
return err
670670
}
671671
for _, rs := range rsList.Items {
672-
if IsDeletionPropagationEnabled(&rs) {
672+
if metadata.HasDeletionPropagationPolicy(&rs, metadata.DeletionPropagationPolicyForeground) {
673673
rsCopy := rs.DeepCopy()
674674
// Disable deletion-propagation and delete finalizers
675675
// This should unblock RootSync & `config-management-system` Namespace deletion.
676-
RemoveDeletionPropagationPolicy(rsCopy)
676+
metadata.RemoveDeletionPropagationPolicy(rsCopy)
677677
rsCopy.Finalizers = nil
678678
if err := nt.KubeClient.Update(rsCopy); err != nil {
679679
return err

e2e/nomostest/config_sync.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -746,9 +746,9 @@ func SetRSyncTestDefaults(nt *NT, obj client.Object) {
746746
// Enable automatic deletion of managed objects by default.
747747
// This helps ensure that test artifacts are cleaned up.
748748
if nt.deletionPropagationPolicy == nil {
749-
RemoveDeletionPropagationPolicy(obj)
749+
metadata.RemoveDeletionPropagationPolicy(obj)
750750
} else {
751-
SetDeletionPropagationPolicy(obj, *nt.deletionPropagationPolicy)
751+
metadata.SetDeletionPropagationPolicy(obj, *nt.deletionPropagationPolicy)
752752
}
753753
}
754754

e2e/nomostest/deletion_propagation.go

Lines changed: 0 additions & 65 deletions
This file was deleted.

e2e/nomostest/reset.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ func ResetRootSyncs(nt *NT, rsList []v1beta1.RootSync) error {
157157

158158
if manager, found := rs.GetAnnotations()[string(metadata.ResourceManagerKey)]; found {
159159
nt.T.Logf("[RESET] RootSync %s managed by %q", rsNN, manager)
160-
if !IsDeletionPropagationEnabled(rs) {
160+
if !metadata.HasDeletionPropagationPolicy(rs, metadata.DeletionPropagationPolicyForeground) {
161161
// If you go this error, make sure your test cleanup ensures
162162
// that the managed RootSync has deletion propagation enabled.
163163
return fmt.Errorf("RootSync %s managed by %q does NOT have deletion propagation enabled: test reset incomplete", rsNN, manager)
@@ -166,7 +166,7 @@ func ResetRootSyncs(nt *NT, rsList []v1beta1.RootSync) error {
166166
}
167167

168168
// Enable deletion propagation, if not enabled
169-
if EnableDeletionPropagation(rs) {
169+
if metadata.SetDeletionPropagationPolicy(rs, metadata.DeletionPropagationPolicyForeground) {
170170
nt.T.Logf("[RESET] Enabling deletion propagation on RootSync %s", rsNN)
171171
// Use MergePatch instead of Update in case modified since list
172172
patch := fmt.Sprintf(`{"metadata": {"annotations": {"%s": "%s"}}}`,
@@ -232,7 +232,7 @@ func ResetRepoSyncs(nt *NT, rsList []v1beta1.RepoSync) error {
232232
// If managed, skip direct deletion
233233
if manager, found := rs.GetAnnotations()[string(metadata.ResourceManagerKey)]; found {
234234
nt.T.Logf("[RESET] RepoSync %s managed by %q", rsNN, manager)
235-
if !IsDeletionPropagationEnabled(rs) {
235+
if !metadata.HasDeletionPropagationPolicy(rs, metadata.DeletionPropagationPolicyForeground) {
236236
// If you go this error, make sure your test cleanup ensures
237237
// that the managed RepoSync has deletion propagation enabled.
238238
return fmt.Errorf("RepoSync %s managed by %q does NOT have deletion propagation enabled: test reset incomplete", rsNN, manager)
@@ -241,7 +241,7 @@ func ResetRepoSyncs(nt *NT, rsList []v1beta1.RepoSync) error {
241241
}
242242

243243
// Enable deletion propagation, if not enabled
244-
if EnableDeletionPropagation(rs) {
244+
if metadata.SetDeletionPropagationPolicy(rs, metadata.DeletionPropagationPolicyForeground) {
245245
nt.T.Logf("[RESET] Enabling deletion propagation on RepoSync %s", rsNN)
246246
// Use MergePatch instead of Update in case modified since list
247247
patch := fmt.Sprintf(`{"metadata": {"annotations": {"%s": "%s"}}}`,

e2e/testcases/reconciler_finalizer_test.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -95,15 +95,15 @@ func TestReconcilerFinalizer_Orphan(t *testing.T) {
9595
rootSync := &v1beta1.RootSync{}
9696
nt.Must(nt.KubeClient.Get(rootSyncID.Name, rootSyncID.Namespace, rootSync))
9797

98-
if nomostest.SetDeletionPropagationPolicy(rootSync, metadata.DeletionPropagationPolicyOrphan) {
98+
if metadata.SetDeletionPropagationPolicy(rootSync, metadata.DeletionPropagationPolicyOrphan) {
9999
nt.Must(nt.KubeClient.Update(rootSync))
100100
}
101101
nt.Must(nt.Watcher.WatchObject(kinds.RootSyncV1Beta1(), rootSync.GetName(), rootSync.GetNamespace(),
102102
testwatcher.WatchPredicates(
103103
testpredicates.StatusEquals(nt.Scheme, kstatus.CurrentStatus),
104104
testpredicates.HasFinalizer(metadata.ReconcilerFinalizer),
105105
testpredicates.HasAnnotation(metadata.DeletionPropagationPolicyAnnotationKey,
106-
string(metadata.DeletionPropagationPolicyOrphan)),
106+
metadata.DeletionPropagationPolicyOrphan.String()),
107107
)))
108108

109109
// Delete the RootSync
@@ -138,7 +138,7 @@ func TestReconcilerFinalizer_Orphan(t *testing.T) {
138138

139139
// Recreate the RootSync
140140
rootSync = nomostest.RootSyncObjectV1Beta1FromRootRepo(nt, rootSyncKey.Name)
141-
nomostest.RemoveDeletionPropagationPolicy(rootSync)
141+
metadata.RemoveDeletionPropagationPolicy(rootSync)
142142
nt.Must(nt.KubeClient.Create(rootSync))
143143
nt.Must(nt.WatchForAllSyncs())
144144

@@ -196,7 +196,7 @@ func TestReconcilerFinalizer_Foreground(t *testing.T) {
196196
if err != nil {
197197
nt.T.Fatal(err)
198198
}
199-
if nomostest.SetDeletionPropagationPolicy(rootSync, metadata.DeletionPropagationPolicyForeground) {
199+
if metadata.SetDeletionPropagationPolicy(rootSync, metadata.DeletionPropagationPolicyForeground) {
200200
err = nt.KubeClient.Update(rootSync)
201201
if err != nil {
202202
nt.T.Fatal(err)
@@ -306,7 +306,7 @@ func TestReconcilerFinalizer_MultiLevelForeground(t *testing.T) {
306306
if err != nil {
307307
nt.T.Fatal(err)
308308
}
309-
if nomostest.SetDeletionPropagationPolicy(rootSync, metadata.DeletionPropagationPolicyForeground) {
309+
if metadata.SetDeletionPropagationPolicy(rootSync, metadata.DeletionPropagationPolicyForeground) {
310310
err = nt.KubeClient.Update(rootSync)
311311
if err != nil {
312312
nt.T.Fatal(err)
@@ -320,7 +320,7 @@ func TestReconcilerFinalizer_MultiLevelForeground(t *testing.T) {
320320

321321
nt.T.Log("Enabling RepoSync deletion propagation")
322322
repoSync := rootSyncGitRepo.MustGet(nt.T, repoSyncPath)
323-
if nomostest.SetDeletionPropagationPolicy(repoSync, metadata.DeletionPropagationPolicyForeground) {
323+
if metadata.SetDeletionPropagationPolicy(repoSync, metadata.DeletionPropagationPolicyForeground) {
324324
nt.Must(rootSyncGitRepo.Add(repoSyncPath, repoSync))
325325
nt.Must(rootSyncGitRepo.CommitAndPush("Enabling RepoSync deletion propagation"))
326326
}
@@ -423,7 +423,7 @@ func TestReconcilerFinalizer_MultiLevelMixed(t *testing.T) {
423423
nt.T.Log("Enabling RootSync deletion propagation")
424424
rootSync := &v1beta1.RootSync{}
425425
nt.Must(nt.KubeClient.Get(rootSyncID.Name, rootSyncID.Namespace, rootSync))
426-
if nomostest.SetDeletionPropagationPolicy(rootSync, metadata.DeletionPropagationPolicyForeground) {
426+
if metadata.SetDeletionPropagationPolicy(rootSync, metadata.DeletionPropagationPolicyForeground) {
427427
nt.Must(nt.KubeClient.Update(rootSync))
428428
}
429429
nt.Must(nt.Watcher.WatchObject(kinds.RootSyncV1Beta1(), rootSync.GetName(), rootSync.GetNamespace(),
@@ -434,7 +434,7 @@ func TestReconcilerFinalizer_MultiLevelMixed(t *testing.T) {
434434

435435
nt.T.Log("Disabling RepoSync deletion propagation")
436436
repoSync := rootSyncGitRepo.MustGet(nt.T, repoSyncPath)
437-
if nomostest.RemoveDeletionPropagationPolicy(repoSync) {
437+
if metadata.RemoveDeletionPropagationPolicy(repoSync) {
438438
nt.Must(rootSyncGitRepo.Add(repoSyncPath, repoSync))
439439
nt.Must(rootSyncGitRepo.CommitAndPush("Disabling RepoSync deletion propagation"))
440440
nt.Must(nt.WatchForAllSyncs())
@@ -722,7 +722,7 @@ func deleteSyncWithOrphanPolicy(nt *nomostest.NT, obj client.Object) error {
722722
}
723723

724724
nt.T.Log("Removing deletion propagation annotation")
725-
if nomostest.RemoveDeletionPropagationPolicy(obj) {
725+
if metadata.RemoveDeletionPropagationPolicy(obj) {
726726
err = nt.KubeClient.Update(obj)
727727
if err != nil {
728728
return err

e2e/testcases/reconciler_manager_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1201,7 +1201,7 @@ func TestReconcilerManagerRootSyncCRDMissing(t *testing.T) {
12011201
// Enable RootSync deletion propagation, if not enabled
12021202
rootSync := &v1beta1.RootSync{}
12031203
nt.Must(nt.KubeClient.Get(rootSyncKey.Name, rootSyncKey.Namespace, rootSync))
1204-
if nomostest.EnableDeletionPropagation(rootSync) {
1204+
if metadata.SetDeletionPropagationPolicy(rootSync, metadata.DeletionPropagationPolicyForeground) {
12051205
nt.Must(nt.KubeClient.Update(rootSync))
12061206
nt.Must(nt.Watcher.WatchObject(kinds.RootSyncV1Beta1(), rootSync.Name, rootSync.Namespace,
12071207
testwatcher.WatchPredicates(
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
// Copyright 2025 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package metadata
16+
17+
import (
18+
"kpt.dev/configsync/pkg/api/configsync"
19+
"kpt.dev/configsync/pkg/core"
20+
"sigs.k8s.io/controller-runtime/pkg/client"
21+
)
22+
23+
// DeletionPropagationPolicy is the type used to identify value enums to use
24+
// with the deletion-propagation-policy annotation.
25+
type DeletionPropagationPolicy string
26+
27+
// String returns the string value of the DeletionPropagationPolicy.
28+
// Implements the Stringer interface.
29+
func (p DeletionPropagationPolicy) String() string {
30+
return string(p)
31+
}
32+
33+
const (
34+
// DeletionPropagationPolicyAnnotationKey is the annotation key set on
35+
// RootSync/RepoSync objects to indicate what do do with the managed
36+
// resources when the RootSync/RepoSync object is deleted.
37+
DeletionPropagationPolicyAnnotationKey = configsync.ConfigSyncPrefix + "deletion-propagation-policy"
38+
// DeletionPropagationPolicyForeground indicates that the managed resources
39+
// should all be deleted/pruned before the RootSync/RepoSync object is deleted.
40+
// This will block deletion of the RootSync/RepoSync using a finalizer.
41+
DeletionPropagationPolicyForeground DeletionPropagationPolicy = "Foreground"
42+
// DeletionPropagationPolicyOrphan indicates that the managed resources
43+
// should all be orphaned (unmanaged but not deleted) when the
44+
// RootSync/RepoSync object is deleted.
45+
// This is the default behavior if the annotation is not specified.
46+
DeletionPropagationPolicyOrphan DeletionPropagationPolicy = "Orphan"
47+
)
48+
49+
// HasDeletionPropagationPolicy returns true if deletion propagation annotation
50+
// is set to the specified policy. Returns false if not set.
51+
func HasDeletionPropagationPolicy(obj client.Object, policy DeletionPropagationPolicy) bool {
52+
return core.GetAnnotation(obj, DeletionPropagationPolicyAnnotationKey) == policy.String()
53+
}
54+
55+
// SetDeletionPropagationPolicy sets the value of the deletion propagation
56+
// annotation locally (does not apply). Returns true if the object was modified.
57+
func SetDeletionPropagationPolicy(obj client.Object, policy DeletionPropagationPolicy) bool {
58+
return core.SetAnnotation(obj, DeletionPropagationPolicyAnnotationKey, policy.String())
59+
}
60+
61+
// RemoveDeletionPropagationPolicy removes the deletion propagation annotation
62+
// locally (does not apply). Returns true if the object was modified.
63+
func RemoveDeletionPropagationPolicy(obj client.Object) bool {
64+
return core.RemoveAnnotations(obj, DeletionPropagationPolicyAnnotationKey)
65+
}
66+
67+
// WithDeletionPropagationPolicy returns a MetaMutator that sets the
68+
// DeletionPropagationPolicy annotation on an Object.
69+
func WithDeletionPropagationPolicy(mode DeletionPropagationPolicy) core.MetaMutator {
70+
return core.Annotation(DeletionPropagationPolicyAnnotationKey, mode.String())
71+
}
72+
73+
// WithoutDeletionPropagationPolicy returns a MetaMutator that removes the
74+
// DeletionPropagationPolicy annotation on an Object.
75+
func WithoutDeletionPropagationPolicy() core.MetaMutator {
76+
return core.WithoutAnnotation(DeletionPropagationPolicyAnnotationKey)
77+
}
78+
79+
// IsDeletionPropagationForeground returns true if the object has the annotation
80+
// `configsync.gke.io/deletion-propagation-policy: Foreground`.
81+
func IsDeletionPropagationForeground(obj client.Object) bool {
82+
return core.GetAnnotation(obj, DeletionPropagationPolicyAnnotationKey) == DeletionPropagationPolicyForeground.String()
83+
}
84+
85+
// IsDeletionPropagationOrphan returns true if the object has the annotation
86+
// `configsync.gke.io/deletion-propagation-policy: Orphan`.
87+
func IsDeletionPropagationOrphan(obj client.Object) bool {
88+
return core.GetAnnotation(obj, DeletionPropagationPolicyAnnotationKey) == DeletionPropagationPolicyOrphan.String()
89+
}
90+
91+
// IsDeletionPropagationUnspecified returns true if the object does NOT have an
92+
// annotation with the key `configsync.gke.io/deletion-propagation-policy`.
93+
func IsDeletionPropagationUnspecified(obj client.Object) bool {
94+
annotations := obj.GetAnnotations()
95+
if annotations == nil {
96+
return true
97+
}
98+
_, found := annotations[DeletionPropagationPolicyAnnotationKey]
99+
return !found
100+
}

pkg/metadata/annotations.go

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -111,11 +111,6 @@ const (
111111
// to indicate that the scope of a resource is unknown.
112112
UnknownScopeAnnotationValue = "true"
113113

114-
// DeletionPropagationPolicyAnnotationKey is the annotation key set on
115-
// RootSync/RepoSync objects to indicate what do do with the managed
116-
// resources when the RootSync/RepoSync object is deleted.
117-
DeletionPropagationPolicyAnnotationKey = configsync.ConfigSyncPrefix + "deletion-propagation-policy"
118-
119114
// RequiresRenderingAnnotationKey is the annotation key set on
120115
// RootSync/RepoSync objects to indicate whether the source of truth
121116
// requires last mile hydration. The reconciler writes the value of this
@@ -206,33 +201,6 @@ const KustomizeOrigin = "config.kubernetes.io/origin"
206201
// FleetWorkloadIdentityCredentials is the key for the credentials file of the Fleet Workload Identity.
207202
const FleetWorkloadIdentityCredentials = "config.kubernetes.io/fleet-workload-identity"
208203

209-
// DeletionPropagationPolicy is the type used to identify value enums to use
210-
// with the deletion-propagation-policy annotation.
211-
type DeletionPropagationPolicy string
212-
213-
// String returns the string value of the DeletionPropagationPolicy.
214-
// Implements the Stringer interface.
215-
func (p DeletionPropagationPolicy) String() string {
216-
return string(p)
217-
}
218-
219-
const (
220-
// DeletionPropagationPolicyForeground indicates that the managed resources
221-
// should all be deleted/pruned before the RootSync/RepoSync object is deleted.
222-
// This will block deletion of the RootSync/RepoSync using a finalizer.
223-
DeletionPropagationPolicyForeground = DeletionPropagationPolicy("Foreground")
224-
225-
// DeletionPropagationPolicyOrphan indicates that the managed resources
226-
// should all be orphanned (not deleted) when the RootSync/RepoSync object
227-
// is deleted.
228-
// This will NOT block deletion of the RootSync/RepoSync AND will not
229-
// remove or modify any config sync managed annotations.
230-
// This allows the RootSync/RepoSync to be deleted and re-created without
231-
// affecting the managed resources.
232-
// This is the default behavior if the annotation is not specified.
233-
DeletionPropagationPolicyOrphan = DeletionPropagationPolicy("Orphan")
234-
)
235-
236204
// StatusMode is the type used to identify value enums to use with the
237205
// `configsync.gke.io/status` annotation.
238206
type StatusMode string

0 commit comments

Comments
 (0)