diff --git a/plans/changes.go b/plans/changes.go index d7e0dcdb8..1350181ff 100644 --- a/plans/changes.go +++ b/plans/changes.go @@ -81,6 +81,31 @@ func (c *Changes) OutputValue(addr addrs.AbsOutputValue) *OutputChangeSrc { return nil } +// OutputValues returns planned changes for all outputs for all module +// instances that reside in the parent path. Returns nil if no changes are +// planned. +func (c *Changes) OutputValues(parent addrs.ModuleInstance, module addrs.ModuleCall) []*OutputChangeSrc { + var res []*OutputChangeSrc + + for _, oc := range c.Outputs { + changeMod, changeCall := oc.Addr.Module.Call() + // this does not reside on our parent instance path + if !changeMod.Equal(parent) { + continue + } + + // this is not the module you're looking for + if changeCall.Name != module.Name { + continue + } + + res = append(res, oc) + + } + + return res +} + // SyncWrapper returns a wrapper object around the receiver that can be used // to make certain changes to the receiver in a concurrency-safe way, as long // as all callers share the same wrapper object. diff --git a/plans/changes_sync.go b/plans/changes_sync.go index 6b4ff98ff..56323e0e9 100644 --- a/plans/changes_sync.go +++ b/plans/changes_sync.go @@ -123,6 +123,23 @@ func (cs *ChangesSync) GetOutputChange(addr addrs.AbsOutputValue) *OutputChangeS return cs.changes.OutputValue(addr) } +// GetOutputChanges searches the set of output changes for any that reside in +// module instances beneath the given module. If no changes exist, nil +// is returned. +// +// The returned objects are a deep copy of the change recorded in the plan, so +// callers may mutate them although it's generally better (less confusing) to +// treat planned changes as immutable after they've been initially constructed. +func (cs *ChangesSync) GetOutputChanges(parent addrs.ModuleInstance, module addrs.ModuleCall) []*OutputChangeSrc { + if cs == nil { + panic("GetOutputChange on nil ChangesSync") + } + cs.lock.Lock() + defer cs.lock.Unlock() + + return cs.changes.OutputValues(parent, module) +} + // RemoveOutputChange searches the set of output value changes for one matching // the given address, and removes it from the set if it exists. func (cs *ChangesSync) RemoveOutputChange(addr addrs.AbsOutputValue) {