@@ -94,7 +94,9 @@ func New(options Options) (*ApplySet, error) {
94
94
parent := options .Parent
95
95
parentRef := & kubectlapply.ApplySetParentRef {Name : parent .Name (), Namespace : parent .Namespace (), RESTMapping : parent .RESTMapping ()}
96
96
kapplyset := kubectlapply .NewApplySet (parentRef , kubectlapply.ApplySetTooling {Name : options .Tooling }, options .RESTMapper )
97
- options .PatchOptions .FieldManager = kapplyset .FieldManager ()
97
+ if options .PatchOptions .FieldManager == "" {
98
+ options .PatchOptions .FieldManager = kapplyset .FieldManager ()
99
+ }
98
100
a := & ApplySet {
99
101
parentClient : options .ParentClient ,
100
102
client : options .Client ,
@@ -176,7 +178,7 @@ func (a *ApplySet) ApplyOnce(ctx context.Context) (*ApplyResults, error) {
176
178
}
177
179
}
178
180
if err := a .WithParent (ctx , kapplyset ); err != nil {
179
- return results , fmt .Errorf ("unable to update Parent %v " , err )
181
+ return results , fmt .Errorf ("unable to update Parent: %w " , err )
180
182
}
181
183
182
184
for i := range trackers .items {
@@ -198,11 +200,11 @@ func (a *ApplySet) ApplyOnce(ctx context.Context) (*ApplyResults, error) {
198
200
if restMapping == nil {
199
201
// Should be impossible
200
202
results .applyError (gvk , nn , fmt .Errorf ("rest mapping result not found for %v" , gvk ))
203
+ continue
201
204
}
202
205
203
206
if err := a .updateManifestLabel (obj , kapplyset .LabelsForMember ()); err != nil {
204
- klog .Errorf ("unable to update label for %v/%v %v: %v" , obj .GetName (), obj .GetNamespace (), gvk , err )
205
- continue
207
+ return results , fmt .Errorf ("unable to update label for %v/%v %v: %w" , obj .GetName (), obj .GetNamespace (), gvk , err )
206
208
}
207
209
208
210
gvr := restMapping .Resource
@@ -252,40 +254,23 @@ func (a *ApplySet) ApplyOnce(ctx context.Context) (*ApplyResults, error) {
252
254
// We want to be more cautions on pruning and only do it if all manifests are applied.
253
255
if a .prune && results .applyFailCount == 0 {
254
256
klog .V (4 ).Infof ("Prune is enabled" )
255
- err := func () error {
256
- pruneObjects , err := kapplyset .FindAllObjectsToPrune (ctx , a .client , visitedUids )
257
- if err != nil {
258
- return err
259
- }
260
- if err = a .deleteObjects (ctx , pruneObjects , results ); err != nil {
261
- return err
262
- }
263
- return nil
264
- }()
257
+ pruneObjects , err := kapplyset .FindAllObjectsToPrune (ctx , a .client , visitedUids )
265
258
if err != nil {
266
- klog .Errorf ("encounter error on pruning %v" , err )
267
- if e := a .updateParentLabelsAndAnnotations (ctx , kapplyset , "superset" ); e != nil {
268
- return results , e
269
- }
259
+ return results , err
260
+ }
261
+ if err = a .deleteObjects (ctx , pruneObjects , results ); err != nil {
262
+ return results , err
263
+ }
264
+ // "latest" mode updates the parent "applyset.kubernetes.io/contains-group-resources" annotations
265
+ // to only contain the current manifest GVRs.
266
+ if err := a .updateParentLabelsAndAnnotations (ctx , kapplyset , "latest" ); err != nil {
267
+ klog .Errorf ("update parent failed %v" , err )
270
268
}
271
- }
272
- if err := a .updateParentLabelsAndAnnotations (ctx , kapplyset , "latest" ); err != nil {
273
- klog .Errorf ("update parent failed %v" , err )
274
269
}
275
270
return results , nil
276
271
}
277
272
278
- func mergeMap (from , to map [string ]string ) map [string ]string {
279
- if to == nil {
280
- to = make (map [string ]string )
281
- }
282
- for k , v := range from {
283
- to [k ] = v
284
- }
285
- return to
286
- }
287
-
288
- // updateLabel adds the "applyset.kubernetes.io/part-of: Parent-ID" label to the manifest.
273
+ // updateManifestLabel adds the "applyset.kubernetes.io/part-of: Parent-ID" label to the manifest.
289
274
func (a * ApplySet ) updateManifestLabel (obj ApplyableObject , applysetLabels map [string ]string ) error {
290
275
u , ok := obj .(* unstructured.Unstructured )
291
276
if ! ok {
@@ -296,14 +281,14 @@ func (a *ApplySet) updateManifestLabel(obj ApplyableObject, applysetLabels map[s
296
281
if labels == nil {
297
282
labels = make (map [string ]string )
298
283
}
299
- newLabels := mergeMap (applysetLabels , labels )
300
- u .SetLabels (newLabels )
284
+ for k , v := range applysetLabels {
285
+ labels [k ] = v
286
+ }
287
+ u .SetLabels (labels )
301
288
return nil
302
289
}
303
290
304
291
// updateParentLabelsAndAnnotations updates the parent labels and annotations.
305
- // This method leverages the kubectlapply to build the parent labels and annotations, but avoid using the
306
- // `resource.NewHelper` and cmdutil to patch the parent.
307
292
func (a * ApplySet ) updateParentLabelsAndAnnotations (ctx context.Context , kapplyset * kubectlapply.ApplySet , mode kubectlapply.ApplySetUpdateMode ) error {
308
293
parent , err := meta .Accessor (a .parent .GetSubject ())
309
294
if err != nil {
@@ -315,26 +300,46 @@ func (a *ApplySet) updateParentLabelsAndAnnotations(ctx context.Context, kapplys
315
300
return err
316
301
}
317
302
partialParent := kapplyset .BuildParentPatch (mode )
318
- newAnnotations := mergeMap (partialParent .Annotations , parent .GetAnnotations ())
319
- parent .SetAnnotations (newAnnotations )
320
- newLabels := mergeMap (partialParent .Labels , parent .GetLabels ())
321
- parent .SetLabels (newLabels )
322
303
323
- return a .updateParent (ctx , original , parent )
304
+ // update annotation
305
+ annotations := parent .GetAnnotations ()
306
+ if annotations == nil {
307
+ annotations = make (map [string ]string )
308
+ }
309
+ for k , v := range partialParent .Annotations {
310
+ annotations [k ] = v
311
+ }
312
+ parent .SetAnnotations (annotations )
313
+
314
+ // update labels
315
+ labels := parent .GetLabels ()
316
+ if labels == nil {
317
+ labels = make (map [string ]string )
318
+ }
319
+ for k , v := range partialParent .Labels {
320
+ labels [k ] = v
321
+ }
322
+ parent .SetLabels (labels )
323
+
324
+ // update parent in the cluster.
325
+ if ! reflect .DeepEqual (original .GetLabels (), parent .GetLabels ()) || ! reflect .DeepEqual (original .GetAnnotations (), parent .GetAnnotations ()) {
326
+ if err := a .parentClient .Update (ctx , parent .(client.Object )); err != nil {
327
+ return fmt .Errorf ("error updating parent %w" , err )
328
+ }
329
+ }
330
+ return nil
324
331
}
325
332
326
333
func (a * ApplySet ) deleteObjects (ctx context.Context , pruneObjects []kubectlapply.PruneObject , results * ApplyResults ) error {
327
334
for i := range pruneObjects {
328
335
pruneObject := & pruneObjects [i ]
329
-
330
336
name := pruneObject .Name
331
337
namespace := pruneObject .Namespace
332
338
mapping := pruneObject .Mapping
333
339
gvk := pruneObject .Object .GetObjectKind ().GroupVersionKind ()
334
340
nn := types.NamespacedName {Namespace : namespace , Name : name }
335
341
336
342
if err := a .client .Resource (mapping .Resource ).Namespace (namespace ).Delete (ctx , name , a .deleteOptions ); err != nil {
337
- klog .Error ("unable to delete resource " )
338
343
results .pruneError (gvk , nn , fmt .Errorf ("error from delete: %w" , err ))
339
344
} else {
340
345
klog .Infof ("pruned resource %v" , pruneObject .String ())
@@ -344,16 +349,16 @@ func (a *ApplySet) deleteObjects(ctx context.Context, pruneObjects []kubectlappl
344
349
return nil
345
350
}
346
351
352
+ // WithParent guarantees the parent has the right applyset labels.
353
+ // It uses "superset" mode to determine the "applyset.kubernetes.io/contains-group-resources" which contains both
354
+ //
355
+ // previous manifests GVRs and the current manifests GVRs.
347
356
func (a * ApplySet ) WithParent (ctx context.Context , kapplyset * kubectlapply.ApplySet ) error {
348
357
parent := a .parent .GetSubject ()
349
358
object , err := meta .Accessor (parent )
350
359
if err != nil {
351
360
return err
352
361
}
353
- original , err := meta .Accessor (parent .DeepCopyObject ())
354
- if err != nil {
355
- return err
356
- }
357
362
//kubectlapply requires the tooling and id to exist.
358
363
{
359
364
annotations := object .GetAnnotations ()
@@ -378,15 +383,5 @@ func (a *ApplySet) WithParent(ctx context.Context, kapplyset *kubectlapply.Apply
378
383
return err
379
384
}
380
385
381
- return a .updateParent (ctx , original , object )
382
- }
383
-
384
- func (a * ApplySet ) updateParent (ctx context.Context , original , current metav1.Object ) error {
385
- if ! reflect .DeepEqual (original .GetLabels (), current .GetLabels ()) || ! reflect .DeepEqual (original .GetAnnotations (), current .GetAnnotations ()) {
386
- if err := a .parentClient .Update (ctx , current .(client.Object )); err != nil {
387
- return fmt .Errorf ("error updating parent %v" , err )
388
- }
389
- }
390
- klog .V (4 ).Infof ("parent labels and annotations are not changed, skip updating" )
391
- return nil
386
+ return a .updateParentLabelsAndAnnotations (ctx , kapplyset , "superset" )
392
387
}
0 commit comments