@@ -341,6 +341,84 @@ func (f ForceApplyObject) preprocess(parser Parser) (Operation, error) {
341341 return f , nil
342342}
343343
344+ // ExtractApply is a type of operation. It simulates extracting an object
345+ // the state based on the manager you have applied with, merging the
346+ // apply object with that extracted object and reapplying that.
347+ type ExtractApply struct {
348+ Manager string
349+ APIVersion fieldpath.APIVersion
350+ Object typed.YAMLObject
351+ }
352+
353+ var _ Operation = & ExtractApply {}
354+
355+ func (e ExtractApply ) run (state * State ) error {
356+ p , err := e .preprocess (state .Parser )
357+ if err != nil {
358+ return err
359+ }
360+ return p .run (state )
361+ }
362+
363+ func (e ExtractApply ) preprocess (parser Parser ) (Operation , error ) {
364+ forceApply := ForceApply {
365+ Manager : e .Manager ,
366+ APIVersion : e .APIVersion ,
367+ Object : e .Object ,
368+ }
369+ op , err := forceApply .preprocess (parser )
370+ if err != nil {
371+ return nil , err
372+ }
373+ object , ok := op .(ForceApplyObject )
374+ if ! ok {
375+ return nil , fmt .Errorf ("%v is not an ForceApplyObject" , op )
376+ }
377+ return ExtractApplyObject {
378+ Manager : object .Manager ,
379+ APIVersion : object .APIVersion ,
380+ Object : object .Object ,
381+ }, nil
382+ }
383+
384+ type ExtractApplyObject struct {
385+ Manager string
386+ APIVersion fieldpath.APIVersion
387+ Object * typed.TypedValue
388+ }
389+
390+ var _ Operation = & ExtractApplyObject {}
391+
392+ func (e ExtractApplyObject ) run (state * State ) error {
393+ var err error
394+ obj := e .Object
395+ // Get object from state
396+ if state .Live != nil {
397+ // Get set based on the manager you've applied with
398+ set := fieldpath .NewSet ()
399+ mgr := state .Managers [e .Manager ]
400+ if mgr != nil {
401+ // trying to extract the fieldSet directly will return everything
402+ // under the first path in the set, so we must filter out all
403+ // the non-leaf nodes from the fieldSet
404+ set = mgr .Set ().Leaves ()
405+ }
406+ // ExtractFields from the state object based on the set
407+ extracted := state .Live .ExtractItems (set )
408+ // Merge ApplyObject on top of the extracted object
409+ obj , err = extracted .Merge (e .Object )
410+ if err != nil {
411+ return err
412+ }
413+ }
414+ // Reapply that to the state
415+ return state .ApplyObject (obj , e .APIVersion , e .Manager , true )
416+ }
417+
418+ func (e ExtractApplyObject ) preprocess (parser Parser ) (Operation , error ) {
419+ return e , nil
420+ }
421+
344422// Update is a type of operation. It is a controller type of
345423// update. Errors are passed along.
346424type Update struct {
0 commit comments