Skip to content

Commit 1b13cb4

Browse files
authored
feat: native ignore-mutation support in applier (#1883)
This change reimplements the ignore-mutation feature using the native support in the cli-utils applier. This removes the need for the workaround of caching the object in Config Sync and passing in the cached object to the applier. This fixes several race conditions and side effects associated with the caching solution.
1 parent d97f9e4 commit 1b13cb4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+624
-886
lines changed

e2e/testcases/ignore_mutation_test.go

Lines changed: 78 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,19 @@ import (
2424
"github.com/GoogleContainerTools/config-sync/e2e/nomostest/taskgroup"
2525
nomostesting "github.com/GoogleContainerTools/config-sync/e2e/nomostest/testing"
2626
"github.com/GoogleContainerTools/config-sync/e2e/nomostest/testpredicates"
27+
"github.com/GoogleContainerTools/config-sync/e2e/nomostest/testresourcegroup"
2728
"github.com/GoogleContainerTools/config-sync/e2e/nomostest/testwatcher"
2829
"github.com/GoogleContainerTools/config-sync/pkg/api/configsync"
30+
"github.com/GoogleContainerTools/config-sync/pkg/api/kpt.dev/v1alpha1"
2931
"github.com/GoogleContainerTools/config-sync/pkg/core"
3032
"github.com/GoogleContainerTools/config-sync/pkg/core/k8sobjects"
3133
"github.com/GoogleContainerTools/config-sync/pkg/kinds"
3234
"github.com/GoogleContainerTools/config-sync/pkg/metadata"
3335
"github.com/GoogleContainerTools/config-sync/pkg/reconcilermanager"
36+
"github.com/GoogleContainerTools/config-sync/pkg/resourcegroup"
3437
corev1 "k8s.io/api/core/v1"
3538
apierrors "k8s.io/apimachinery/pkg/api/errors"
39+
"k8s.io/apimachinery/pkg/types"
3640
kstatus "sigs.k8s.io/cli-utils/pkg/kstatus/status"
3741
)
3842

@@ -250,6 +254,10 @@ func TestMutationIgnoredObjectPruned(t *testing.T) {
250254
func TestAnnotationDrift(t *testing.T) {
251255
nt := nomostest.New(t, nomostesting.DriftControl, ntopts.SyncWithGitSource(nomostest.DefaultRootSyncID, ntopts.Unstructured))
252256
rootSyncGitRepo := nt.SyncSourceGitReadWriteRepository(nomostest.DefaultRootSyncID)
257+
rgNN := types.NamespacedName{
258+
Name: nomostest.DefaultRootSyncID.Name,
259+
Namespace: nomostest.DefaultRootSyncID.Namespace,
260+
}
253261

254262
nt.T.Log("Adding namespace to Git")
255263
namespace := k8sobjects.NamespaceObject("bookstore",
@@ -287,9 +295,77 @@ func TestAnnotationDrift(t *testing.T) {
287295
nsObj2 := k8sobjects.NamespaceObject("new-ns")
288296
nt.Must(rootSyncGitRepo.Add("acme/ns2.yaml", nsObj2))
289297
nt.Must(rootSyncGitRepo.CommitAndPush("add another namespace"))
290-
nt.Must(nt.WatchForAllSyncs())
291-
secondCommitHash := rootSyncGitRepo.MustHash(nt.T)
298+
nt.Must(nt.WatchForAllSyncs(nomostest.SkipAllResourceGroupChecks()))
299+
// Explicitly verify ResourceGroup status. The mutation-ignored object should
300+
// have "Skipped" actuation status
301+
shortCommit := resourcegroup.TruncateSourceHash(rootSyncGitRepo.MustHash(nt.T))
302+
expectedStatus := testresourcegroup.EmptyStatus()
303+
expectedStatus.ObservedGeneration = 6
304+
expectedStatus.ResourceStatuses = []v1alpha1.ResourceStatus{
305+
{
306+
ObjMetadata: v1alpha1.ObjMetadata{
307+
Name: "safety-config-management-system-root-sync",
308+
GroupKind: v1alpha1.GroupKind{
309+
Kind: "Namespace",
310+
},
311+
},
312+
Status: v1alpha1.Current,
313+
Strategy: v1alpha1.Apply,
314+
Actuation: v1alpha1.ActuationSucceeded,
315+
Reconcile: v1alpha1.ReconcileSucceeded,
316+
SourceHash: shortCommit,
317+
Conditions: nil,
318+
},
319+
{
320+
ObjMetadata: v1alpha1.ObjMetadata{
321+
Name: "new-ns",
322+
GroupKind: v1alpha1.GroupKind{
323+
Kind: "Namespace",
324+
},
325+
},
326+
Status: v1alpha1.Current,
327+
Strategy: v1alpha1.Apply,
328+
Actuation: v1alpha1.ActuationSucceeded,
329+
Reconcile: v1alpha1.ReconcileSucceeded,
330+
SourceHash: shortCommit,
331+
Conditions: nil,
332+
},
333+
{
334+
ObjMetadata: v1alpha1.ObjMetadata{
335+
Name: "safety-config-management-system-root-sync",
336+
GroupKind: v1alpha1.GroupKind{
337+
Kind: "ClusterRole",
338+
Group: "rbac.authorization.k8s.io",
339+
},
340+
},
341+
Status: v1alpha1.Current,
342+
Strategy: v1alpha1.Apply,
343+
Actuation: v1alpha1.ActuationSucceeded,
344+
Reconcile: v1alpha1.ReconcileSucceeded,
345+
SourceHash: shortCommit,
346+
Conditions: nil,
347+
},
348+
{
349+
ObjMetadata: v1alpha1.ObjMetadata{
350+
Name: "bookstore",
351+
GroupKind: v1alpha1.GroupKind{
352+
Kind: "Namespace",
353+
},
354+
},
355+
Status: v1alpha1.Current,
356+
Strategy: v1alpha1.Apply,
357+
Actuation: v1alpha1.ActuationSkipped, // ActuationSkipped for ignore-mutation object
358+
Reconcile: v1alpha1.ReconcileSucceeded,
359+
SourceHash: shortCommit,
360+
Conditions: nil,
361+
},
362+
}
363+
nt.Must(nt.Watcher.WatchObject(kinds.ResourceGroup(), rgNN.Name, rgNN.Namespace,
364+
testwatcher.WatchPredicates(
365+
testpredicates.ResourceGroupStatusEquals(expectedStatus),
366+
)))
292367

368+
secondCommitHash := rootSyncGitRepo.MustHash(nt.T)
293369
nt.Must(nt.Watcher.WatchObject(kinds.Namespace(), nsObj.Name, "",
294370
testwatcher.WatchPredicates(
295371
testpredicates.HasAnnotation(metadata.SyncTokenAnnotationKey, secondCommitHash),

go.mod

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ require (
5252
k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b
5353
k8s.io/kubectl v0.34.1
5454
k8s.io/kubernetes v1.34.1
55-
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397
56-
sigs.k8s.io/cli-utils v0.37.3-0.20250410211241-63a8e151c476
55+
k8s.io/utils v0.0.0-20250820121507-0af2bda4dd1d
56+
sigs.k8s.io/cli-utils v0.37.3-0.20251021150641-5895ad6c17dd
5757
sigs.k8s.io/controller-runtime v0.22.3
5858
sigs.k8s.io/controller-runtime/tools/setup-envtest v0.0.0-20231023142458-b9f29826ee83
5959
sigs.k8s.io/controller-tools v0.18.0
@@ -127,7 +127,7 @@ require (
127127
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
128128
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
129129
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
130-
github.com/onsi/gomega v1.38.0 // indirect
130+
github.com/onsi/gomega v1.38.2 // indirect
131131
github.com/opencontainers/go-digest v1.0.0 // indirect
132132
github.com/opencontainers/image-spec v1.1.1 // indirect
133133
github.com/otiai10/copy v1.14.0 // indirect

go.sum

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -321,10 +321,10 @@ github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
321321
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
322322
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
323323
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
324-
github.com/onsi/ginkgo/v2 v2.23.4 h1:ktYTpKJAVZnDT4VjxSbiBenUjmlL/5QkBEocaWXiQus=
325-
github.com/onsi/ginkgo/v2 v2.23.4/go.mod h1:Bt66ApGPBFzHyR+JO10Zbt0Gsp4uWxu5mIOTusL46e8=
326-
github.com/onsi/gomega v1.38.0 h1:c/WX+w8SLAinvuKKQFh77WEucCnPk4j2OTUr7lt7BeY=
327-
github.com/onsi/gomega v1.38.0/go.mod h1:OcXcwId0b9QsE7Y49u+BTrL4IdKOBOKnD6VQNTJEB6o=
324+
github.com/onsi/ginkgo/v2 v2.25.2 h1:hepmgwx1D+llZleKQDMEvy8vIlCxMGt7W5ZxDjIEhsw=
325+
github.com/onsi/ginkgo/v2 v2.25.2/go.mod h1:43uiyQC4Ed2tkOzLsEYm7hnrb7UJTWHYNsuy3bG/snE=
326+
github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A=
327+
github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k=
328328
github.com/open-policy-agent/cert-controller v0.14.0 h1:TPc19BOHOs4tARruTT5o4bzir7Ed6FF+j3EXP/nmZBs=
329329
github.com/open-policy-agent/cert-controller v0.14.0/go.mod h1:UhE/FU54DnKo+Rt0Yf3r+oKjgy6kqSH8Vsjo+5bGrSo=
330330
github.com/open-policy-agent/frameworks/constraint v0.0.0-20241101234656-e78c8abd754a h1:gQtOJ50XFyL2Xh3lDD9zP4KQ2PY4mZKQ9hDcWc81Sp8=
@@ -741,13 +741,13 @@ k8s.io/kubectl v0.34.1 h1:1qP1oqT5Xc93K+H8J7ecpBjaz511gan89KO9Vbsh/OI=
741741
k8s.io/kubectl v0.34.1/go.mod h1:JRYlhJpGPyk3dEmJ+BuBiOB9/dAvnrALJEiY/C5qa6A=
742742
k8s.io/kubernetes v1.34.1 h1:F3p8dtpv+i8zQoebZeK5zBqM1g9x1aIdnA5vthvcuUk=
743743
k8s.io/kubernetes v1.34.1/go.mod h1:iu+FhII+Oc/1gGWLJcer6wpyih441aNFHl7Pvm8yPto=
744-
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y=
745-
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
744+
k8s.io/utils v0.0.0-20250820121507-0af2bda4dd1d h1:wAhiDyZ4Tdtt7e46e9M5ZSAJ/MnPGPs+Ki1gHw4w1R0=
745+
k8s.io/utils v0.0.0-20250820121507-0af2bda4dd1d/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
746746
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
747747
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
748748
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
749-
sigs.k8s.io/cli-utils v0.37.3-0.20250410211241-63a8e151c476 h1:HjKF4Xfsh702Qx9J0Uu8QDywHA6aIKVoYFXIDTAEXZI=
750-
sigs.k8s.io/cli-utils v0.37.3-0.20250410211241-63a8e151c476/go.mod h1:bM9dkBKOU5vmCHVg5yr3Jf6ooy4S0giTbeaskiHkZfQ=
749+
sigs.k8s.io/cli-utils v0.37.3-0.20251021150641-5895ad6c17dd h1:QwwBjgDIYmNa4bf3AAbvsgkslFe0vF1Zgex1/ydtbDc=
750+
sigs.k8s.io/cli-utils v0.37.3-0.20251021150641-5895ad6c17dd/go.mod h1:u5LTcoijf7f18rMNL7PVNyJzoGEriT+tS57ZSVG3nc4=
751751
sigs.k8s.io/controller-runtime v0.22.3 h1:I7mfqz/a/WdmDCEnXmSPm8/b/yRTy6JsKKENTijTq8Y=
752752
sigs.k8s.io/controller-runtime v0.22.3/go.mod h1:+QX1XUpTXN4mLoblf4tqr5CQcyHPAki2HLXqQMY6vh8=
753753
sigs.k8s.io/controller-runtime/tools/setup-envtest v0.0.0-20231023142458-b9f29826ee83 h1:37G7lMdeXe0kogUnwCa1K+EIVYR5f4BqM0bqITyaDBI=

pkg/applier/applier.go

Lines changed: 49 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ func (s *supervisor) UpdateStatusMode(ctx context.Context) error {
207207
})
208208
}
209209

210-
func (s *supervisor) processApplyEvent(ctx context.Context, e event.ApplyEvent, syncStats *stats.ApplyEventStats, objectStatusMap ObjectStatusMap, unknownTypeResources map[core.ID]struct{}, resourceMap map[core.ID]client.Object, declaredResources *declared.Resources) status.Error {
210+
func (s *supervisor) processApplyEvent(ctx context.Context, e event.ApplyEvent, syncStats *stats.ApplyEventStats, objectStatusMap ObjectStatusMap, unknownTypeResources map[core.ID]struct{}, resourceMap map[core.ID]client.Object) status.Error {
211211
id := idFrom(e.Identifier)
212212
syncStats.Add(e.Status)
213213

@@ -231,15 +231,6 @@ func (s *supervisor) processApplyEvent(ctx context.Context, e event.ApplyEvent,
231231
case event.ApplyFailed:
232232
objectStatus.Actuation = actuation.ActuationFailed
233233
handleMetrics(ctx, "update", e.Error)
234-
// If apply failed for an ignore-mutation object, delete it from the ignore cache.
235-
// Normally the cached object should be updated by the remediator when it
236-
// receives a watch event - This is a fallback to force a live lookup the
237-
// next time the applier runs.
238-
iObj, found := declaredResources.GetIgnored(id)
239-
if found {
240-
klog.Infof("Deleting object '%v' from the ignore cache (apply failed)", core.GKNN(iObj))
241-
declaredResources.DeleteIgnored(id)
242-
}
243234
switch e.Error.(type) {
244235
case *applyerror.UnknownTypeError:
245236
unknownTypeResources[id] = struct{}{}
@@ -254,7 +245,7 @@ func (s *supervisor) processApplyEvent(ctx context.Context, e event.ApplyEvent,
254245
case event.ApplySkipped:
255246
objectStatus.Actuation = actuation.ActuationSkipped
256247
// Skip event always includes an error with the reason
257-
return s.handleApplySkippedEvent(e.Resource, id, e.Error)
248+
return s.handleApplySkippedEvent(ctx, e.Resource, id, e.Error)
258249

259250
default:
260251
return ErrorForResource(fmt.Errorf("unexpected prune event status: %v", e.Status), id)
@@ -297,7 +288,7 @@ func (s *supervisor) processWaitEvent(e event.WaitEvent, syncStats *stats.WaitEv
297288
}
298289

299290
// handleApplySkippedEvent translates from apply skipped event into resource error.
300-
func (s *supervisor) handleApplySkippedEvent(obj *unstructured.Unstructured, id core.ID, err error) status.Error {
291+
func (s *supervisor) handleApplySkippedEvent(ctx context.Context, obj *unstructured.Unstructured, id core.ID, err error) status.Error {
301292
var depErr *filter.DependencyPreventedActuationError
302293
if errors.As(err, &depErr) {
303294
return SkipErrorForResource(err, id, depErr.Strategy)
@@ -317,11 +308,52 @@ func (s *supervisor) handleApplySkippedEvent(obj *unstructured.Unstructured, id
317308
return KptManagementConflictError(obj)
318309
}
319310

311+
var annotationErr *filter.AnnotationPreventedUpdateError
312+
if errors.As(err, &annotationErr) {
313+
// For applies this is desired behavior, not unexpected. The following logic
314+
// re-applies just the CS metadata to ensure metadata does not drift.
315+
klog.Info("Got AnnotationPreventedUpdateError")
316+
if err := s.updateObjectMetadata(ctx, obj); err != nil {
317+
return SkipErrorForResource(
318+
fmt.Errorf("updating Config Sync metadata for ignore mutation object: %w", err),
319+
id, actuation.ActuationStrategyApply)
320+
}
321+
return nil
322+
}
323+
320324
return SkipErrorForResource(err, id, actuation.ActuationStrategyApply)
321325
}
322326

327+
func (s *supervisor) updateObjectMetadata(ctx context.Context, obj *unstructured.Unstructured) error {
328+
// Using PartialObjectMetadata optimizes the client calls (uses metadata client under the hood)
329+
metaObj := &metav1.PartialObjectMetadata{}
330+
metaObj.Name = obj.GetName()
331+
metaObj.Namespace = obj.GetNamespace()
332+
metaObj.SetGroupVersionKind(obj.GroupVersionKind())
333+
key := client.ObjectKey{
334+
Name: obj.GetName(),
335+
Namespace: obj.GetNamespace(),
336+
}
337+
if err := s.clientSet.Client.Get(ctx, key, metaObj); err != nil {
338+
return err
339+
}
340+
341+
existing := metaObj.DeepCopy()
342+
if metadata.UpdateConfigSyncMetadata(obj, metaObj) {
343+
if err := s.clientSet.Client.Patch(ctx, metaObj, client.MergeFrom(existing),
344+
client.FieldOwner(configsync.FieldManager)); err != nil {
345+
return err
346+
}
347+
klog.Infof("Patched drifted CS metadata on %s", key.String())
348+
return nil
349+
}
350+
klog.Infof("Skip patching CS metadata on %s", key.String())
351+
return nil
352+
353+
}
354+
323355
// processPruneEvent handles PruneEvents from the Applier
324-
func (s *supervisor) processPruneEvent(ctx context.Context, e event.PruneEvent, syncStats *stats.PruneEventStats, objectStatusMap ObjectStatusMap, declaredResources *declared.Resources) status.Error {
356+
func (s *supervisor) processPruneEvent(ctx context.Context, e event.PruneEvent, syncStats *stats.PruneEventStats, objectStatusMap ObjectStatusMap) status.Error {
325357
id := idFrom(e.Identifier)
326358
syncStats.Add(e.Status)
327359

@@ -340,13 +372,6 @@ func (s *supervisor) processPruneEvent(ctx context.Context, e event.PruneEvent,
340372
case event.PruneSuccessful:
341373
objectStatus.Actuation = actuation.ActuationSucceeded
342374
handleMetrics(ctx, "delete", e.Error)
343-
344-
iObj, found := declaredResources.GetIgnored(id)
345-
if found {
346-
klog.V(3).Infof("Deleting object '%v' from the ignore cache", core.GKNN(iObj))
347-
declaredResources.DeleteIgnored(id)
348-
}
349-
350375
return nil
351376

352377
case event.PruneFailed:
@@ -510,15 +535,6 @@ func (s *supervisor) applyInner(ctx context.Context, eventHandler func(Event), d
510535
objStatusMap := make(ObjectStatusMap)
511536
objs := declaredResources.DeclaredObjects()
512537

513-
if err := s.cacheIgnoreMutationObjects(ctx, declaredResources); err != nil {
514-
sendErrorEvent(err, eventHandler)
515-
return objStatusMap, syncStats
516-
}
517-
518-
if len(declaredResources.IgnoredObjects()) > 0 {
519-
klog.Infof("%v mutation-ignored objects: %v", len(declaredResources.IgnoredObjects()), core.GKNNs(declaredResources.IgnoredObjects()))
520-
}
521-
522538
// disabledObjs are objects for which the management are disabled
523539
// through annotation.
524540
enabledObjs, disabledObjs := partitionObjs(objs)
@@ -535,10 +551,8 @@ func (s *supervisor) applyInner(ctx context.Context, eventHandler func(Event), d
535551
}
536552
}
537553

538-
objsToApply := handleIgnoredObjects(enabledObjs, declaredResources)
539-
540-
klog.Infof("%v objects to be applied: %v", len(objsToApply), core.GKNNs(objsToApply))
541-
resources, err := toUnstructured(objsToApply)
554+
klog.Infof("%v objects to be applied: %v", len(enabledObjs), core.GKNNs(enabledObjs))
555+
resources, err := toUnstructured(enabledObjs)
542556
if err != nil {
543557
sendErrorEvent(err, eventHandler)
544558
return objStatusMap, syncStats
@@ -613,7 +627,7 @@ func (s *supervisor) applyInner(ctx context.Context, eventHandler func(Event), d
613627
} else {
614628
klog.V(1).Info(e.ApplyEvent)
615629
}
616-
if err := s.processApplyEvent(ctx, e.ApplyEvent, syncStats.ApplyEvent, objStatusMap, unknownTypeResources, resourceMap, declaredResources); err != nil {
630+
if err := s.processApplyEvent(ctx, e.ApplyEvent, syncStats.ApplyEvent, objStatusMap, unknownTypeResources, resourceMap); err != nil {
617631
sendErrorEvent(err, eventHandler)
618632
}
619633
case event.PruneType:
@@ -622,7 +636,7 @@ func (s *supervisor) applyInner(ctx context.Context, eventHandler func(Event), d
622636
} else {
623637
klog.V(1).Info(e.PruneEvent)
624638
}
625-
if err := s.processPruneEvent(ctx, e.PruneEvent, syncStats.PruneEvent, objStatusMap, declaredResources); err != nil {
639+
if err := s.processPruneEvent(ctx, e.PruneEvent, syncStats.PruneEvent, objStatusMap); err != nil {
626640
sendErrorEvent(err, eventHandler)
627641
}
628642
default:
@@ -836,37 +850,3 @@ func (s *supervisor) abandonObject(ctx context.Context, obj client.Object) error
836850
}
837851
return nil
838852
}
839-
840-
// cacheIgnoreMutationObjects gets the current cluster state of any declared objects with the ignore mutation annotation and puts it in the Resources ignore objects cache
841-
// Returns any errors that occur
842-
func (s *supervisor) cacheIgnoreMutationObjects(ctx context.Context, declaredResources *declared.Resources) error {
843-
var objsToUpdate []client.Object
844-
declaredObjs := declaredResources.DeclaredObjects()
845-
846-
for _, obj := range declaredObjs {
847-
if obj.GetAnnotations()[metadata.LifecycleMutationAnnotation] == metadata.IgnoreMutation {
848-
849-
if _, found := declaredResources.GetIgnored(core.IDOf(obj)); !found {
850-
// Fetch the cluster state of the object if not already in the cache
851-
uObj := &unstructured.Unstructured{}
852-
uObj.SetGroupVersionKind(obj.GetObjectKind().GroupVersionKind())
853-
err := s.clientSet.Client.Get(ctx, client.ObjectKeyFromObject(obj), uObj)
854-
855-
// Object doesn't exist on the cluster
856-
if apierrors.IsNotFound(err) {
857-
continue
858-
}
859-
860-
if err != nil {
861-
return err
862-
}
863-
864-
objsToUpdate = append(objsToUpdate, uObj)
865-
}
866-
}
867-
}
868-
869-
declaredResources.UpdateIgnored(objsToUpdate...)
870-
871-
return nil
872-
}

0 commit comments

Comments
 (0)