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:
parent
ad069b7416
commit
42cee86ee2
|
@ -27,7 +27,6 @@ type Data interface {
|
||||||
GetResource(addrs.Resource, tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics)
|
GetResource(addrs.Resource, tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics)
|
||||||
GetLocalValue(addrs.LocalValue, tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics)
|
GetLocalValue(addrs.LocalValue, tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics)
|
||||||
GetModule(addrs.ModuleCall, 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)
|
GetPathAttr(addrs.PathAttr, tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics)
|
||||||
GetTerraformAttr(addrs.TerraformAttr, tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics)
|
GetTerraformAttr(addrs.TerraformAttr, tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics)
|
||||||
GetInputVariable(addrs.InputVariable, tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics)
|
GetInputVariable(addrs.InputVariable, tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics)
|
||||||
|
|
15
lang/eval.go
15
lang/eval.go
|
@ -195,7 +195,6 @@ func (s *Scope) evalContext(refs []*addrs.Reference, selfAddr addrs.Referenceabl
|
||||||
dataResources := map[string]map[string]cty.Value{}
|
dataResources := map[string]map[string]cty.Value{}
|
||||||
managedResources := map[string]map[string]cty.Value{}
|
managedResources := map[string]map[string]cty.Value{}
|
||||||
wholeModules := map[string]cty.Value{}
|
wholeModules := map[string]cty.Value{}
|
||||||
moduleOutputs := map[string]map[addrs.InstanceKey]map[string]cty.Value{}
|
|
||||||
inputVariables := map[string]cty.Value{}
|
inputVariables := map[string]cty.Value{}
|
||||||
localValues := map[string]cty.Value{}
|
localValues := map[string]cty.Value{}
|
||||||
pathAttrs := 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)
|
diags = diags.Append(valDiags)
|
||||||
wholeModules[subj.Name] = val
|
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:
|
case addrs.InputVariable:
|
||||||
val, valDiags := normalizeRefValue(s.Data.GetInputVariable(subj, rng))
|
val, valDiags := normalizeRefValue(s.Data.GetInputVariable(subj, rng))
|
||||||
diags = diags.Append(valDiags)
|
diags = diags.Append(valDiags)
|
||||||
|
|
|
@ -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,
|
// 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
|
// while trimming off any extra values that we may have from guessing
|
||||||
// entries.
|
// the length via the state instances.
|
||||||
last := 0
|
last := 0
|
||||||
for i, v := range vals {
|
for i, v := range vals {
|
||||||
if v.IsNull() {
|
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) {
|
func (d *evaluationStateData) GetPathAttr(addr addrs.PathAttr, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
|
||||||
var diags tfdiags.Diagnostics
|
var diags tfdiags.Diagnostics
|
||||||
switch addr.Name {
|
switch addr.Name {
|
||||||
|
|
Loading…
Reference in New Issue