remove GetModuleInstanceOutput

There is no codepath that can use this any longer, since we need to
evaluate the modules as whole objects.

This means we're going to have to live for now with invalid module
output references returning "object" errors rather that "module".
This commit is contained in:
James Bardin 2020-04-14 13:36:55 -04:00
parent ad069b7416
commit 42cee86ee2
3 changed files with 2 additions and 88 deletions

View File

@ -27,7 +27,6 @@ type Data interface {
GetResource(addrs.Resource, tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics)
GetLocalValue(addrs.LocalValue, tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics)
GetModule(addrs.ModuleCall, tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics)
GetModuleInstanceOutput(addrs.AbsModuleCallOutput, tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics)
GetPathAttr(addrs.PathAttr, tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics)
GetTerraformAttr(addrs.TerraformAttr, tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics)
GetInputVariable(addrs.InputVariable, tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics)

View File

@ -195,7 +195,6 @@ func (s *Scope) evalContext(refs []*addrs.Reference, selfAddr addrs.Referenceabl
dataResources := map[string]map[string]cty.Value{}
managedResources := map[string]map[string]cty.Value{}
wholeModules := map[string]cty.Value{}
moduleOutputs := map[string]map[addrs.InstanceKey]map[string]cty.Value{}
inputVariables := map[string]cty.Value{}
localValues := map[string]cty.Value{}
pathAttrs := map[string]cty.Value{}
@ -292,20 +291,6 @@ func (s *Scope) evalContext(refs []*addrs.Reference, selfAddr addrs.Referenceabl
diags = diags.Append(valDiags)
wholeModules[subj.Name] = val
case addrs.AbsModuleCallOutput:
val, valDiags := normalizeRefValue(s.Data.GetModuleInstanceOutput(subj, rng))
diags = diags.Append(valDiags)
callName := subj.Call.Call.Name
callKey := subj.Call.Key
if moduleOutputs[callName] == nil {
moduleOutputs[callName] = make(map[addrs.InstanceKey]map[string]cty.Value)
}
if moduleOutputs[callName][callKey] == nil {
moduleOutputs[callName][callKey] = make(map[string]cty.Value)
}
moduleOutputs[callName][callKey][subj.Name] = val
case addrs.InputVariable:
val, valDiags := normalizeRefValue(s.Data.GetInputVariable(subj, rng))
diags = diags.Append(valDiags)

View File

@ -471,8 +471,8 @@ func (d *evaluationStateData) GetModule(addr addrs.ModuleCall, rng tfdiags.Sourc
}
// we shouldn't have any holes, but insert real values just in case,
// while trimming off any extra values that may have there from old
// entries.
// while trimming off any extra values that we may have from guessing
// the length via the state instances.
last := 0
for i, v := range vals {
if v.IsNull() {
@ -510,76 +510,6 @@ func (d *evaluationStateData) GetModule(addr addrs.ModuleCall, rng tfdiags.Sourc
}
}
func (d *evaluationStateData) GetModuleInstanceOutput(addr addrs.AbsModuleCallOutput, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
var diags tfdiags.Diagnostics
// Output results live in the module that declares them, which is one of
// the child module instances of our current module path.
absAddr := addr.AbsOutputValue(d.ModulePath)
moduleAddr := absAddr.Module
// First we'll consult the configuration to see if an output of this
// name is declared at all.
moduleConfig := d.Evaluator.Config.DescendentForInstance(moduleAddr)
if moduleConfig == nil {
// this doesn't happen in normal circumstances due to our validation
// pass, but it can turn up in some unusual situations, like in the
// "terraform console" repl where arbitrary expressions can be
// evaluated.
diags = diags.Append(&hcl.Diagnostic{
Severity: hcl.DiagError,
Summary: `Reference to undeclared module`,
Detail: fmt.Sprintf(`The configuration contains no %s.`, moduleAddr),
Subject: rng.ToHCL().Ptr(),
})
return cty.DynamicVal, diags
}
config := moduleConfig.Module.Outputs[addr.Name]
if config == nil {
var suggestions []string
for k := range moduleConfig.Module.Outputs {
suggestions = append(suggestions, k)
}
suggestion := nameSuggestion(addr.Name, suggestions)
if suggestion != "" {
suggestion = fmt.Sprintf(" Did you mean %q?", suggestion)
}
diags = diags.Append(&hcl.Diagnostic{
Severity: hcl.DiagError,
Summary: `Reference to undeclared output value`,
Detail: fmt.Sprintf(`An output value with the name %q has not been declared in %s.%s`, addr.Name, moduleDisplayAddr(moduleAddr), suggestion),
Subject: rng.ToHCL().Ptr(),
})
return cty.DynamicVal, diags
}
// If a pending change is present in our current changeset then its value
// takes priority over what's in state. (It will usually be the same but
// will differ if the new value is unknown during planning.)
if changeSrc := d.Evaluator.Changes.GetOutputChange(absAddr); changeSrc != nil {
change, err := changeSrc.Decode()
if err != nil {
// This should happen only if someone has tampered with a plan
// file, so we won't bother with a pretty error for it.
diags = diags.Append(fmt.Errorf("planned change for %s could not be decoded: %s", absAddr, err))
return cty.DynamicVal, diags
}
// We care only about the "after" value, which is the value this output
// will take on after the plan is applied.
return change.After, diags
}
os := d.Evaluator.State.OutputValue(absAddr)
if os == nil {
// Not evaluated yet?
return cty.DynamicVal, diags
}
return os.Value, diags
}
func (d *evaluationStateData) GetPathAttr(addr addrs.PathAttr, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
var diags tfdiags.Diagnostics
switch addr.Name {