Create non-specific ModuleCallOutput

This commit is contained in:
Pam Selle 2020-03-20 12:18:48 -04:00
parent 34cab3bc99
commit f738f85241
10 changed files with 32 additions and 20 deletions

View File

@ -51,31 +51,43 @@ func (c ModuleCallInstance) ModuleInstance(caller ModuleInstance) ModuleInstance
return caller.Child(c.Call.Name, c.Key) return caller.Child(c.Call.Name, c.Key)
} }
// Output returns the address of an output of the receiver identified by its // Output returns the absolute address of an output of the receiver identified by its
// name. // name.
func (c ModuleCallInstance) Output(name string) ModuleCallOutput { func (c ModuleCallInstance) Output(name string) AbsModuleCallOutput {
return ModuleCallOutput{ return AbsModuleCallOutput{
Call: c, Call: c,
Name: name, Name: name,
} }
} }
// ModuleCallOutput is the address of a particular named output produced by // ModuleCallOutput is the address of a named output and its associated
// an instance of a module call. // ModuleCall, which may expand into multiple module instances
type ModuleCallOutput struct { type ModuleCallOutput struct {
referenceable
Call ModuleCall
Name string
}
func (m ModuleCallOutput) String() string {
return fmt.Sprintf("%s.%s", m.Call.String(), m.Name)
}
// AbsModuleCallOutput is the address of a particular named output produced by
// an instance of a module call.
type AbsModuleCallOutput struct {
referenceable referenceable
Call ModuleCallInstance Call ModuleCallInstance
Name string Name string
} }
func (co ModuleCallOutput) String() string { func (co AbsModuleCallOutput) String() string {
return fmt.Sprintf("%s.%s", co.Call.String(), co.Name) return fmt.Sprintf("%s.%s", co.Call.String(), co.Name)
} }
// AbsOutputValue returns the absolute output value address that corresponds // AbsOutputValue returns the absolute output value address that corresponds
// to the receving module call output address, once resolved in the given // to the receving module call output address, once resolved in the given
// calling module. // calling module.
func (co ModuleCallOutput) AbsOutputValue(caller ModuleInstance) AbsOutputValue { func (co AbsModuleCallOutput) AbsOutputValue(caller ModuleInstance) AbsOutputValue {
moduleAddr := co.Call.ModuleInstance(caller) moduleAddr := co.Call.ModuleInstance(caller)
return moduleAddr.OutputValue(co.Name) return moduleAddr.OutputValue(co.Name)
} }

View File

@ -62,13 +62,13 @@ func (v AbsOutputValue) String() string {
// //
// The root module does not have a call, and so this method cannot be used // The root module does not have a call, and so this method cannot be used
// with outputs in the root module, and will panic in that case. // with outputs in the root module, and will panic in that case.
func (v AbsOutputValue) ModuleCallOutput() (ModuleInstance, ModuleCallOutput) { func (v AbsOutputValue) ModuleCallOutput() (ModuleInstance, AbsModuleCallOutput) {
if v.Module.IsRoot() { if v.Module.IsRoot() {
panic("ReferenceFromCall used with root module output") panic("ReferenceFromCall used with root module output")
} }
caller, call := v.Module.CallInstance() caller, call := v.Module.CallInstance()
return caller, ModuleCallOutput{ return caller, AbsModuleCallOutput{
Call: call, Call: call,
Name: v.OutputValue.Name, Name: v.OutputValue.Name,
} }

View File

@ -171,7 +171,7 @@ func parseRef(traversal hcl.Traversal) (*Reference, tfdiags.Diagnostics) {
if attrTrav, ok := remain[0].(hcl.TraverseAttr); ok { if attrTrav, ok := remain[0].(hcl.TraverseAttr); ok {
remain = remain[1:] remain = remain[1:]
return &Reference{ return &Reference{
Subject: ModuleCallOutput{ Subject: AbsModuleCallOutput{
Name: attrTrav.Name, Name: attrTrav.Name,
Call: callInstance, Call: callInstance,
}, },

View File

@ -296,7 +296,7 @@ func TestParseRef(t *testing.T) {
{ {
`module.foo.bar`, `module.foo.bar`,
&Reference{ &Reference{
Subject: ModuleCallOutput{ Subject: AbsModuleCallOutput{
Call: ModuleCallInstance{ Call: ModuleCallInstance{
Call: ModuleCall{ Call: ModuleCall{
Name: "foo", Name: "foo",
@ -314,7 +314,7 @@ func TestParseRef(t *testing.T) {
{ {
`module.foo.bar.baz`, `module.foo.bar.baz`,
&Reference{ &Reference{
Subject: ModuleCallOutput{ Subject: AbsModuleCallOutput{
Call: ModuleCallInstance{ Call: ModuleCallInstance{
Call: ModuleCall{ Call: ModuleCall{
Name: "foo", Name: "foo",
@ -357,7 +357,7 @@ func TestParseRef(t *testing.T) {
{ {
`module.foo["baz"].bar`, `module.foo["baz"].bar`,
&Reference{ &Reference{
Subject: ModuleCallOutput{ Subject: AbsModuleCallOutput{
Call: ModuleCallInstance{ Call: ModuleCallInstance{
Call: ModuleCall{ Call: ModuleCall{
Name: "foo", Name: "foo",
@ -376,7 +376,7 @@ func TestParseRef(t *testing.T) {
{ {
`module.foo["baz"].bar.boop`, `module.foo["baz"].bar.boop`,
&Reference{ &Reference{
Subject: ModuleCallOutput{ Subject: AbsModuleCallOutput{
Call: ModuleCallInstance{ Call: ModuleCallInstance{
Call: ModuleCall{ Call: ModuleCall{
Name: "foo", Name: "foo",

View File

@ -27,7 +27,7 @@ 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)
GetModuleInstance(addrs.ModuleCallInstance, tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) GetModuleInstance(addrs.ModuleCallInstance, tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics)
GetModuleInstanceOutput(addrs.ModuleCallOutput, 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)

View File

@ -47,7 +47,7 @@ func (d *dataForTests) GetModuleInstance(addr addrs.ModuleCallInstance, rng tfdi
return d.Modules[addr.String()], nil return d.Modules[addr.String()], nil
} }
func (d *dataForTests) GetModuleInstanceOutput(addr addrs.ModuleCallOutput, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) { func (d *dataForTests) GetModuleInstanceOutput(addr addrs.AbsModuleCallOutput, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
// This will panic if the module object does not have the requested attribute // This will panic if the module object does not have the requested attribute
obj := d.Modules[addr.Call.String()] obj := d.Modules[addr.Call.String()]
return obj.GetAttr(addr.Name), nil return obj.GetAttr(addr.Name), nil

View File

@ -293,7 +293,7 @@ func (s *Scope) evalContext(refs []*addrs.Reference, selfAddr addrs.Referenceabl
} }
wholeModules[subj.Call.Name][subj.Key] = val wholeModules[subj.Call.Name][subj.Key] = val
case addrs.ModuleCallOutput: case addrs.AbsModuleCallOutput:
val, valDiags := normalizeRefValue(s.Data.GetModuleInstanceOutput(subj, rng)) val, valDiags := normalizeRefValue(s.Data.GetModuleInstanceOutput(subj, rng))
diags = diags.Append(valDiags) diags = diags.Append(valDiags)

View File

@ -386,7 +386,7 @@ func (d *evaluationStateData) GetModuleInstance(addr addrs.ModuleCallInstance, r
return cty.ObjectVal(vals), diags return cty.ObjectVal(vals), diags
} }
func (d *evaluationStateData) GetModuleInstanceOutput(addr addrs.ModuleCallOutput, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) { func (d *evaluationStateData) GetModuleInstanceOutput(addr addrs.AbsModuleCallOutput, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
var diags tfdiags.Diagnostics var diags tfdiags.Diagnostics
// Output results live in the module that declares them, which is one of // Output results live in the module that declares them, which is one of

View File

@ -91,7 +91,7 @@ func (d *evaluationStateData) staticValidateReference(ref *addrs.Reference, self
return d.staticValidateModuleCallReference(modCfg, addr, ref.Remaining, ref.SourceRange) return d.staticValidateModuleCallReference(modCfg, addr, ref.Remaining, ref.SourceRange)
case addrs.ModuleCallInstance: case addrs.ModuleCallInstance:
return d.staticValidateModuleCallReference(modCfg, addr.Call, ref.Remaining, ref.SourceRange) return d.staticValidateModuleCallReference(modCfg, addr.Call, ref.Remaining, ref.SourceRange)
case addrs.ModuleCallOutput: case addrs.AbsModuleCallOutput:
// This one is a funny one because we will take the output name referenced // This one is a funny one because we will take the output name referenced
// and use it to fake up a "remaining" that would make sense for the // and use it to fake up a "remaining" that would make sense for the
// module call itself, rather than for the specific output, and then // module call itself, rather than for the specific output, and then

View File

@ -64,7 +64,7 @@ func (n *NodePlannableOutput) ReferenceableAddrs() []addrs.Referenceable {
// module itself. // module itself.
_, call := n.Module.Call() _, call := n.Module.Call()
callOutput := addrs.ModuleCallOutput{ callOutput := addrs.ModuleCallOutput{
Call: call.Instance(addrs.NoKey), Call: call,
Name: n.Addr.Name, Name: n.Addr.Name,
} }