@@ -103,6 +103,8 @@ func (cic *ClusterClient) Merge(localInv Info, objs object.ObjMetadataSet, dryRu
103
103
if err != nil {
104
104
return pruneIds , err
105
105
}
106
+
107
+ // Inventory does not exist on the cluster.
106
108
if clusterInv == nil {
107
109
// Wrap inventory object and store the inventory in it.
108
110
var status []actuation.ObjectStatus
@@ -113,60 +115,41 @@ func (cic *ClusterClient) Merge(localInv Info, objs object.ObjMetadataSet, dryRu
113
115
if err := inv .Store (objs , status ); err != nil {
114
116
return nil , err
115
117
}
116
- invInfo , err := inv .GetObject ()
117
- if err != nil {
118
- return nil , err
119
- }
120
118
klog .V (4 ).Infof ("creating initial inventory object with %d objects" , len (objs ))
121
- createdObj , err := cic .createInventoryObj (invInfo , dryRun )
122
- if err != nil {
123
- return nil , err
124
- }
125
- // Status update requires the latest ResourceVersion
126
- invInfo .SetResourceVersion (createdObj .GetResourceVersion ())
127
- if err := cic .updateStatus (invInfo , dryRun ); err != nil {
128
- return nil , err
129
- }
130
- } else {
131
- // Update existing cluster inventory with merged union of objects
132
- clusterObjs , err := cic .GetClusterObjs (localInv )
133
- if err != nil {
134
- return pruneIds , err
135
- }
136
- pruneIds = clusterObjs .Diff (objs )
137
- unionObjs := clusterObjs .Union (objs )
138
- var status []actuation.ObjectStatus
139
- if cic .statusPolicy == StatusPolicyAll {
140
- status = getObjStatus (pruneIds , unionObjs )
141
- }
142
- klog .V (4 ).Infof ("num objects to prune: %d" , len (pruneIds ))
143
- klog .V (4 ).Infof ("num merged objects to store in inventory: %d" , len (unionObjs ))
144
- wrappedInv := cic .InventoryFactoryFunc (clusterInv )
145
- if err = wrappedInv .Store (unionObjs , status ); err != nil {
146
- return pruneIds , err
147
- }
148
- clusterInv , err = wrappedInv .GetObject ()
149
- if err != nil {
150
- return pruneIds , err
151
- }
119
+
152
120
if dryRun .ClientOrServerDryRun () {
153
- return pruneIds , nil
154
- }
155
- if ! objs .Equal (clusterObjs ) {
156
- klog .V (4 ).Infof ("update cluster inventory: %s/%s" , clusterInv .GetNamespace (), clusterInv .GetName ())
157
- appliedObj , err := cic .applyInventoryObj (clusterInv , dryRun )
158
- if err != nil {
159
- return pruneIds , err
160
- }
161
- // Status update requires the latest ResourceVersion
162
- clusterInv .SetResourceVersion (appliedObj .GetResourceVersion ())
163
- }
164
- if err := cic .updateStatus (clusterInv , dryRun ); err != nil {
165
- return pruneIds , err
121
+ klog .V (4 ).Infof ("dry-run create inventory object: not created" )
122
+ return nil , nil
166
123
}
124
+
125
+ err = inv .Apply (cic .dc , cic .mapper , cic .statusPolicy )
126
+ return nil , err
127
+ }
128
+
129
+ // Update existing cluster inventory with merged union of objects
130
+ clusterObjs , err := cic .GetClusterObjs (localInv )
131
+ if err != nil {
132
+ return pruneIds , err
133
+ }
134
+ pruneIds = clusterObjs .Diff (objs )
135
+ unionObjs := clusterObjs .Union (objs )
136
+ var status []actuation.ObjectStatus
137
+ if cic .statusPolicy == StatusPolicyAll {
138
+ status = getObjStatus (pruneIds , unionObjs )
139
+ }
140
+ klog .V (4 ).Infof ("num objects to prune: %d" , len (pruneIds ))
141
+ klog .V (4 ).Infof ("num merged objects to store in inventory: %d" , len (unionObjs ))
142
+ wrappedInv := cic .InventoryFactoryFunc (clusterInv )
143
+ if err = wrappedInv .Store (unionObjs , status ); err != nil {
144
+ return pruneIds , err
167
145
}
168
146
169
- return pruneIds , nil
147
+ if dryRun .ClientOrServerDryRun () {
148
+ klog .V (4 ).Infof ("dry-run create inventory object: not created" )
149
+ return pruneIds , nil
150
+ }
151
+ err = wrappedInv .Apply (cic .dc , cic .mapper , cic .statusPolicy )
152
+ return pruneIds , err
170
153
}
171
154
172
155
// Replace stores the passed objects in the cluster inventory object, or
@@ -178,49 +161,49 @@ func (cic *ClusterClient) Replace(localInv Info, objs object.ObjMetadataSet, sta
178
161
klog .V (4 ).Infoln ("dry-run replace inventory object: not applied" )
179
162
return nil
180
163
}
181
- clusterObjs , err := cic .GetClusterObjs (localInv )
182
- if err != nil {
183
- return fmt .Errorf ("failed to read inventory objects from cluster: %w" , err )
184
- }
185
164
clusterInv , err := cic .GetClusterInventoryInfo (localInv )
186
165
if err != nil {
187
166
return fmt .Errorf ("failed to read inventory from cluster: %w" , err )
188
167
}
189
- clusterInv , err = cic .replaceInventory (clusterInv , objs , status )
168
+
169
+ clusterObjs , err := cic .GetClusterObjs (localInv )
170
+ if err != nil {
171
+ return fmt .Errorf ("failed to read inventory objects from cluster: %w" , err )
172
+ }
173
+
174
+ clusterInv , wrappedInv , err := cic .replaceInventory (clusterInv , objs , status )
190
175
if err != nil {
191
176
return err
192
177
}
178
+
193
179
if ! objs .Equal (clusterObjs ) {
194
180
klog .V (4 ).Infof ("replace cluster inventory: %s/%s" , clusterInv .GetNamespace (), clusterInv .GetName ())
195
181
klog .V (4 ).Infof ("replace cluster inventory %d objects" , len (objs ))
196
- appliedObj , err := cic . applyInventoryObj ( clusterInv , dryRun )
197
- if err != nil {
182
+
183
+ if err := wrappedInv . ApplyWithPrune ( cic . dc , cic . mapper , cic . statusPolicy , objs ); err != nil {
198
184
return fmt .Errorf ("failed to write updated inventory to cluster: %w" , err )
199
185
}
200
- // Status update requires the latest ResourceVersion
201
- clusterInv .SetResourceVersion (appliedObj .GetResourceVersion ())
202
- }
203
- if err := cic .updateStatus (clusterInv , dryRun ); err != nil {
204
- return err
205
186
}
187
+
206
188
return nil
207
189
}
208
190
209
191
// replaceInventory stores the passed objects into the passed inventory object.
210
192
func (cic * ClusterClient ) replaceInventory (inv * unstructured.Unstructured , objs object.ObjMetadataSet ,
211
- status []actuation.ObjectStatus ) (* unstructured.Unstructured , error ) {
193
+ status []actuation.ObjectStatus ) (* unstructured.Unstructured , Storage , error ) {
212
194
if cic .statusPolicy == StatusPolicyNone {
213
195
status = nil
214
196
}
215
197
wrappedInv := cic .InventoryFactoryFunc (inv )
216
198
if err := wrappedInv .Store (objs , status ); err != nil {
217
- return nil , err
199
+ return nil , nil , err
218
200
}
219
201
clusterInv , err := wrappedInv .GetObject ()
220
202
if err != nil {
221
- return nil , err
203
+ return nil , nil , err
222
204
}
223
- return clusterInv , nil
205
+
206
+ return clusterInv , wrappedInv , nil
224
207
}
225
208
226
209
// DeleteInventoryObj deletes the inventory object from the cluster.
@@ -364,26 +347,6 @@ func (cic *ClusterClient) GetClusterInventoryObjs(inv Info) (object.Unstructured
364
347
return clusterInvObjects , err
365
348
}
366
349
367
- // applyInventoryObj applies the passed inventory object to the APIServer.
368
- func (cic * ClusterClient ) applyInventoryObj (obj * unstructured.Unstructured , dryRun common.DryRunStrategy ) (* unstructured.Unstructured , error ) {
369
- if dryRun .ClientOrServerDryRun () {
370
- klog .V (4 ).Infof ("dry-run apply inventory object: not applied" )
371
- return obj .DeepCopy (), nil
372
- }
373
- if obj == nil {
374
- return nil , fmt .Errorf ("attempting apply a nil inventory object" )
375
- }
376
-
377
- mapping , err := cic .getMapping (obj )
378
- if err != nil {
379
- return nil , err
380
- }
381
-
382
- klog .V (4 ).Infof ("replacing inventory object: %s/%s" , obj .GetNamespace (), obj .GetName ())
383
- return cic .dc .Resource (mapping .Resource ).Namespace (obj .GetNamespace ()).
384
- Update (context .TODO (), obj , metav1.UpdateOptions {})
385
- }
386
-
387
350
// createInventoryObj creates the passed inventory object on the APIServer.
388
351
func (cic * ClusterClient ) createInventoryObj (obj * unstructured.Unstructured , dryRun common.DryRunStrategy ) (* unstructured.Unstructured , error ) {
389
352
if dryRun .ClientOrServerDryRun () {
@@ -463,62 +426,6 @@ func (cic *ClusterClient) getMapping(obj *unstructured.Unstructured) (*meta.REST
463
426
return cic .mapper .RESTMapping (obj .GroupVersionKind ().GroupKind (), obj .GroupVersionKind ().Version )
464
427
}
465
428
466
- func (cic * ClusterClient ) updateStatus (obj * unstructured.Unstructured , dryRun common.DryRunStrategy ) error {
467
- if cic .statusPolicy != StatusPolicyAll {
468
- klog .V (4 ).Infof ("inventory status update skipped (StatusPolicy: %s)" , cic .statusPolicy )
469
- return nil
470
- }
471
- if dryRun .ClientOrServerDryRun () {
472
- klog .V (4 ).Infof ("dry-run update inventory status: not updated" )
473
- return nil
474
- }
475
- status , found , _ := unstructured .NestedMap (obj .UnstructuredContent (), "status" )
476
- if ! found {
477
- return nil
478
- }
479
- mapping , err := cic .mapper .RESTMapping (obj .GroupVersionKind ().GroupKind ())
480
- if err != nil {
481
- return nil
482
- }
483
- hasStatus , err := cic .hasSubResource (obj .GetAPIVersion (), mapping .Resource .Resource , "status" )
484
- if err != nil {
485
- return err
486
- }
487
- if ! hasStatus {
488
- klog .V (4 ).Infof ("skip updating inventory status" )
489
- return nil
490
- }
491
-
492
- klog .V (4 ).Infof ("update inventory status" )
493
- resource := cic .dc .Resource (mapping .Resource ).Namespace (obj .GetNamespace ())
494
- meta := metav1.TypeMeta {
495
- Kind : obj .GetKind (),
496
- APIVersion : obj .GetAPIVersion (),
497
- }
498
- if err = unstructured .SetNestedMap (obj .Object , status , "status" ); err != nil {
499
- return err
500
- }
501
- if _ , err = resource .UpdateStatus (context .TODO (), obj , metav1.UpdateOptions {TypeMeta : meta }); err != nil {
502
- return fmt .Errorf ("failed to write updated inventory status to cluster: %w" , err )
503
- }
504
- return nil
505
- }
506
-
507
- // hasSubResource checks if a resource has the given subresource using the discovery client.
508
- func (cic * ClusterClient ) hasSubResource (groupVersion , resource , subresource string ) (bool , error ) {
509
- resources , err := cic .discoveryClient .ServerResourcesForGroupVersion (groupVersion )
510
- if err != nil {
511
- return false , err
512
- }
513
-
514
- for _ , r := range resources .APIResources {
515
- if r .Name == fmt .Sprintf ("%s/%s" , resource , subresource ) {
516
- return true , nil
517
- }
518
- }
519
- return false , nil
520
- }
521
-
522
429
// getObjStatus returns the list of object status
523
430
// at the beginning of an apply process.
524
431
func getObjStatus (pruneIds , unionIds []object.ObjMetadata ) []actuation.ObjectStatus {
0 commit comments