Skip to content

Commit a904879

Browse files
committed
Expose ExtractItems as the opposite of RemoveItems
This exposes a new method on TypedValue called ExtractItems. Whereas RemoveItems takes a fieldpath.Set and returns the typed value with the provided set items removed from it, ExtractItems returns ONLY those items provided by the fieldpath.Set, effectively extracting them from the original TypedValue.
1 parent f541d63 commit a904879

File tree

5 files changed

+1260
-14
lines changed

5 files changed

+1260
-14
lines changed

internal/fixture/state.go

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,83 @@ 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+
365+
tv, err := parser.Type(string(e.APIVersion)).FromYAML(FixTabsOrDie(e.Object))
366+
if err != nil {
367+
return nil, err
368+
}
369+
return ExtractApplyObject{
370+
Manager: e.Manager,
371+
APIVersion: e.APIVersion,
372+
Object: tv,
373+
}, nil
374+
}
375+
376+
type ExtractApplyObject struct {
377+
Manager string
378+
APIVersion fieldpath.APIVersion
379+
Object *typed.TypedValue
380+
}
381+
382+
var _ Operation = &ExtractApplyObject{}
383+
384+
func (e ExtractApplyObject) run(state *State) error {
385+
if state.Live == nil {
386+
return state.ApplyObject(e.Object, e.APIVersion, e.Manager, true)
387+
}
388+
// Get object from state and convert it to current APIVersion
389+
current, err := state.Updater.Converter.Convert(state.Live, e.APIVersion)
390+
if err != nil {
391+
return err
392+
}
393+
// Get set based on the manager you've applied with
394+
set := fieldpath.NewSet()
395+
mgr := state.Managers[e.Manager]
396+
if mgr != nil {
397+
// we cannot extract a set that is for a different version
398+
if mgr.APIVersion() != e.APIVersion {
399+
return fmt.Errorf("existing managed fieldpath set APIVersion (%s) differs from desired (%s), unable to extract", mgr.APIVersion(), e.APIVersion)
400+
}
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 := current.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+
// Reapply that to the state
414+
return state.ApplyObject(obj, e.APIVersion, e.Manager, true)
415+
}
416+
417+
func (e ExtractApplyObject) preprocess(parser Parser) (Operation, error) {
418+
return e, nil
419+
}
420+
344421
// Update is a type of operation. It is a controller type of
345422
// update. Errors are passed along.
346423
type Update struct {

0 commit comments

Comments
 (0)