Merge pull request #24362 from hashicorp/jbardin/module-expansion-some-more
implement addrs.ConfigResource
This commit is contained in:
commit
50077eabe9
|
@ -249,6 +249,51 @@ func TestParseTarget(t *testing.T) {
|
|||
},
|
||||
``,
|
||||
},
|
||||
{
|
||||
`module.foo.module.bar[0].data.aws_instance.baz`,
|
||||
&Target{
|
||||
Subject: AbsResource{
|
||||
Resource: Resource{
|
||||
Mode: DataResourceMode,
|
||||
Type: "aws_instance",
|
||||
Name: "baz",
|
||||
},
|
||||
Module: ModuleInstance{
|
||||
{Name: "foo", InstanceKey: NoKey},
|
||||
{Name: "bar", InstanceKey: IntKey(0)},
|
||||
},
|
||||
},
|
||||
SourceRange: tfdiags.SourceRange{
|
||||
Start: tfdiags.SourcePos{Line: 1, Column: 1, Byte: 0},
|
||||
End: tfdiags.SourcePos{Line: 1, Column: 47, Byte: 46},
|
||||
},
|
||||
},
|
||||
``,
|
||||
},
|
||||
{
|
||||
`module.foo.module.bar["a"].data.aws_instance.baz["hello"]`,
|
||||
&Target{
|
||||
Subject: AbsResourceInstance{
|
||||
Resource: ResourceInstance{
|
||||
Resource: Resource{
|
||||
Mode: DataResourceMode,
|
||||
Type: "aws_instance",
|
||||
Name: "baz",
|
||||
},
|
||||
Key: StringKey("hello"),
|
||||
},
|
||||
Module: ModuleInstance{
|
||||
{Name: "foo", InstanceKey: NoKey},
|
||||
{Name: "bar", InstanceKey: StringKey("a")},
|
||||
},
|
||||
},
|
||||
SourceRange: tfdiags.SourceRange{
|
||||
Start: tfdiags.SourcePos{Line: 1, Column: 1, Byte: 0},
|
||||
End: tfdiags.SourcePos{Line: 1, Column: 58, Byte: 57},
|
||||
},
|
||||
},
|
||||
``,
|
||||
},
|
||||
{
|
||||
`module.foo.module.bar.data.aws_instance.baz["hello"]`,
|
||||
&Target{
|
||||
|
|
|
@ -253,6 +253,61 @@ func (r AbsResourceInstance) Less(o AbsResourceInstance) bool {
|
|||
}
|
||||
}
|
||||
|
||||
// ConfigResource is an address for a resource within a configuration.
|
||||
type ConfigResource struct {
|
||||
targetable
|
||||
Module Module
|
||||
Resource Resource
|
||||
}
|
||||
|
||||
// Resource returns the address of a particular resource within the module.
|
||||
func (m Module) Resource(mode ResourceMode, typeName string, name string) ConfigResource {
|
||||
return ConfigResource{
|
||||
Module: m,
|
||||
Resource: Resource{
|
||||
Mode: mode,
|
||||
Type: typeName,
|
||||
Name: name,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Absolute produces the address for the receiver within a specific module instance.
|
||||
func (r ConfigResource) Absolute(module ModuleInstance) AbsResource {
|
||||
return AbsResource{
|
||||
Module: module,
|
||||
Resource: r.Resource,
|
||||
}
|
||||
}
|
||||
|
||||
// TargetContains implements Targetable by returning true if the given other
|
||||
// address is either equal to the receiver or is an instance of the
|
||||
// receiver.
|
||||
func (r ConfigResource) TargetContains(other Targetable) bool {
|
||||
switch to := other.(type) {
|
||||
case ConfigResource:
|
||||
// We'll use our stringification as a cheat-ish way to test for equality.
|
||||
return to.String() == r.String()
|
||||
case AbsResource:
|
||||
return r.TargetContains(ConfigResource{Module: to.Module.Module(), Resource: to.Resource})
|
||||
case AbsResourceInstance:
|
||||
return r.TargetContains(to.ContainingResource())
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func (r ConfigResource) String() string {
|
||||
if len(r.Module) == 0 {
|
||||
return r.Resource.String()
|
||||
}
|
||||
return fmt.Sprintf("%s.%s", r.Module.String(), r.Resource.String())
|
||||
}
|
||||
|
||||
func (r ConfigResource) Equal(o ConfigResource) bool {
|
||||
return r.String() == o.String()
|
||||
}
|
||||
|
||||
// ResourceMode defines which lifecycle applies to a given resource. Each
|
||||
// resource lifecycle has a slightly different address format.
|
||||
type ResourceMode rune
|
||||
|
|
|
@ -0,0 +1,164 @@
|
|||
package addrs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestTargetContains(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
addr, other Targetable
|
||||
expect bool
|
||||
}{
|
||||
{
|
||||
mustParseTarget("module.foo"),
|
||||
mustParseTarget("module.bar"),
|
||||
false,
|
||||
},
|
||||
{
|
||||
mustParseTarget("module.foo"),
|
||||
mustParseTarget("module.foo"),
|
||||
true,
|
||||
},
|
||||
{
|
||||
// module.foo is an unkeyed module instance here, so it cannot
|
||||
// contain another instance
|
||||
mustParseTarget("module.foo"),
|
||||
mustParseTarget("module.foo[0]"),
|
||||
false,
|
||||
},
|
||||
{
|
||||
RootModuleInstance,
|
||||
mustParseTarget("module.foo"),
|
||||
true,
|
||||
},
|
||||
{
|
||||
mustParseTarget("module.foo"),
|
||||
RootModuleInstance,
|
||||
false,
|
||||
},
|
||||
{
|
||||
mustParseTarget("module.foo"),
|
||||
mustParseTarget("module.foo.module.bar[0]"),
|
||||
true,
|
||||
},
|
||||
{
|
||||
mustParseTarget("module.foo"),
|
||||
mustParseTarget("module.foo.module.bar[0]"),
|
||||
true,
|
||||
},
|
||||
{
|
||||
mustParseTarget("module.foo[2]"),
|
||||
mustParseTarget("module.foo[2].module.bar[0]"),
|
||||
true,
|
||||
},
|
||||
{
|
||||
mustParseTarget("module.foo"),
|
||||
mustParseTarget("module.foo.test_resource.bar"),
|
||||
true,
|
||||
},
|
||||
{
|
||||
mustParseTarget("module.foo"),
|
||||
mustParseTarget("module.foo.test_resource.bar[0]"),
|
||||
true,
|
||||
},
|
||||
|
||||
// Resources
|
||||
{
|
||||
mustParseTarget("test_resource.foo"),
|
||||
mustParseTarget("test_resource.foo[\"bar\"]"),
|
||||
true,
|
||||
},
|
||||
{
|
||||
mustParseTarget(`test_resource.foo["bar"]`),
|
||||
mustParseTarget(`test_resource.foo["bar"]`),
|
||||
true,
|
||||
},
|
||||
{
|
||||
mustParseTarget("test_resource.foo"),
|
||||
mustParseTarget("test_resource.foo[2]"),
|
||||
true,
|
||||
},
|
||||
{
|
||||
mustParseTarget("test_resource.foo"),
|
||||
mustParseTarget("module.bar.test_resource.foo[2]"),
|
||||
false,
|
||||
},
|
||||
{
|
||||
mustParseTarget("module.bar.test_resource.foo"),
|
||||
mustParseTarget("module.bar.test_resource.foo[2]"),
|
||||
true,
|
||||
},
|
||||
{
|
||||
mustParseTarget("module.bar.test_resource.foo"),
|
||||
mustParseTarget("module.bar[0].test_resource.foo[2]"),
|
||||
false,
|
||||
},
|
||||
|
||||
// Config paths, while never returned from parsing a target, must still be targetable
|
||||
{
|
||||
ConfigResource{
|
||||
Module: []string{"bar"},
|
||||
Resource: Resource{
|
||||
Mode: ManagedResourceMode,
|
||||
Type: "test_resource",
|
||||
Name: "foo",
|
||||
},
|
||||
},
|
||||
mustParseTarget("module.bar.test_resource.foo[2]"),
|
||||
true,
|
||||
},
|
||||
{
|
||||
ConfigResource{
|
||||
Resource: Resource{
|
||||
Mode: ManagedResourceMode,
|
||||
Type: "test_resource",
|
||||
Name: "foo",
|
||||
},
|
||||
},
|
||||
mustParseTarget("module.bar.test_resource.foo[2]"),
|
||||
false,
|
||||
},
|
||||
{
|
||||
ConfigResource{
|
||||
Module: []string{"bar"},
|
||||
Resource: Resource{
|
||||
Mode: ManagedResourceMode,
|
||||
Type: "test_resource",
|
||||
Name: "foo",
|
||||
},
|
||||
},
|
||||
mustParseTarget("module.bar[0].test_resource.foo"),
|
||||
true,
|
||||
},
|
||||
} {
|
||||
t.Run(fmt.Sprintf("%s-in-%s", test.other, test.addr), func(t *testing.T) {
|
||||
got := test.addr.TargetContains(test.other)
|
||||
if got != test.expect {
|
||||
t.Fatalf("expected %q.TargetContains(%q) == %t", test.addr, test.other, test.expect)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestResourceContains(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
in, other Targetable
|
||||
expect bool
|
||||
}{} {
|
||||
t.Run(fmt.Sprintf("%s-in-%s", test.other, test.in), func(t *testing.T) {
|
||||
got := test.in.TargetContains(test.other)
|
||||
if got != test.expect {
|
||||
t.Fatalf("expected %q.TargetContains(%q) == %t", test.in, test.other, test.expect)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func mustParseTarget(str string) Targetable {
|
||||
t, diags := ParseTargetStr(str)
|
||||
if diags != nil {
|
||||
panic(fmt.Sprintf("%s: %s", str, diags.ErrWithWarnings()))
|
||||
}
|
||||
return t.Subject
|
||||
}
|
|
@ -597,7 +597,7 @@ func TestContextImport_moduleDiff(t *testing.T) {
|
|||
Mode: addrs.ManagedResourceMode,
|
||||
Type: "aws_instance",
|
||||
Name: "bar",
|
||||
}.Instance(addrs.NoKey).Absolute(addrs.Module{"bar"}.UnkeyedInstanceShim()),
|
||||
}.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance.Child("bar", addrs.NoKey)),
|
||||
&states.ResourceInstanceObjectSrc{
|
||||
AttrsFlat: map[string]string{
|
||||
"id": "bar",
|
||||
|
@ -658,7 +658,7 @@ func TestContextImport_moduleExisting(t *testing.T) {
|
|||
Mode: addrs.ManagedResourceMode,
|
||||
Type: "aws_instance",
|
||||
Name: "bar",
|
||||
}.Instance(addrs.NoKey).Absolute(addrs.Module{"foo"}.UnkeyedInstanceShim()),
|
||||
}.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance.Child("foo", addrs.NoKey)),
|
||||
&states.ResourceInstanceObjectSrc{
|
||||
AttrsFlat: map[string]string{
|
||||
"id": "bar",
|
||||
|
|
|
@ -65,8 +65,6 @@ type BuiltinEvalContext struct {
|
|||
ChangesValue *plans.ChangesSync
|
||||
StateValue *states.SyncState
|
||||
InstanceExpanderValue *instances.Expander
|
||||
|
||||
once sync.Once
|
||||
}
|
||||
|
||||
// BuiltinEvalContext implements EvalContext
|
||||
|
@ -106,16 +104,14 @@ func (ctx *BuiltinEvalContext) Input() UIInput {
|
|||
}
|
||||
|
||||
func (ctx *BuiltinEvalContext) InitProvider(addr addrs.AbsProviderConfig) (providers.Interface, error) {
|
||||
ctx.once.Do(ctx.init)
|
||||
absAddr := addr
|
||||
if !absAddr.Module.Equal(ctx.Path().Module()) {
|
||||
if !addr.Module.Equal(ctx.Path().Module()) {
|
||||
// This indicates incorrect use of InitProvider: it should be used
|
||||
// only from the module that the provider configuration belongs to.
|
||||
panic(fmt.Sprintf("%s initialized by wrong module %s", absAddr, ctx.Path()))
|
||||
panic(fmt.Sprintf("%s initialized by wrong module %s", addr, ctx.Path()))
|
||||
}
|
||||
|
||||
// If we already initialized, it is an error
|
||||
if p := ctx.Provider(absAddr); p != nil {
|
||||
if p := ctx.Provider(addr); p != nil {
|
||||
return nil, fmt.Errorf("%s is already initialized", addr)
|
||||
}
|
||||
|
||||
|
@ -124,22 +120,20 @@ func (ctx *BuiltinEvalContext) InitProvider(addr addrs.AbsProviderConfig) (provi
|
|||
ctx.ProviderLock.Lock()
|
||||
defer ctx.ProviderLock.Unlock()
|
||||
|
||||
key := absAddr.String()
|
||||
key := addr.String()
|
||||
|
||||
p, err := ctx.Components.ResourceProvider(addr.Provider)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
log.Printf("[TRACE] BuiltinEvalContext: Initialized %q provider for %s", addr.LegacyString(), absAddr)
|
||||
log.Printf("[TRACE] BuiltinEvalContext: Initialized %q provider for %s", addr.LegacyString(), addr)
|
||||
ctx.ProviderCache[key] = p
|
||||
|
||||
return p, nil
|
||||
}
|
||||
|
||||
func (ctx *BuiltinEvalContext) Provider(addr addrs.AbsProviderConfig) providers.Interface {
|
||||
ctx.once.Do(ctx.init)
|
||||
|
||||
ctx.ProviderLock.Lock()
|
||||
defer ctx.ProviderLock.Unlock()
|
||||
|
||||
|
@ -147,12 +141,10 @@ func (ctx *BuiltinEvalContext) Provider(addr addrs.AbsProviderConfig) providers.
|
|||
}
|
||||
|
||||
func (ctx *BuiltinEvalContext) ProviderSchema(addr addrs.AbsProviderConfig) *ProviderSchema {
|
||||
ctx.once.Do(ctx.init)
|
||||
return ctx.Schemas.ProviderSchema(addr.Provider)
|
||||
}
|
||||
|
||||
func (ctx *BuiltinEvalContext) CloseProvider(addr addrs.AbsProviderConfig) error {
|
||||
ctx.once.Do(ctx.init)
|
||||
if !addr.Module.Equal(ctx.Path().Module()) {
|
||||
// This indicates incorrect use of CloseProvider: it should be used
|
||||
// only from the module that the provider configuration belongs to.
|
||||
|
@ -174,22 +166,21 @@ func (ctx *BuiltinEvalContext) CloseProvider(addr addrs.AbsProviderConfig) error
|
|||
|
||||
func (ctx *BuiltinEvalContext) ConfigureProvider(addr addrs.AbsProviderConfig, cfg cty.Value) tfdiags.Diagnostics {
|
||||
var diags tfdiags.Diagnostics
|
||||
absAddr := addr
|
||||
if !absAddr.Module.Equal(ctx.Path().Module()) {
|
||||
if !addr.Module.Equal(ctx.Path().Module()) {
|
||||
// This indicates incorrect use of ConfigureProvider: it should be used
|
||||
// only from the module that the provider configuration belongs to.
|
||||
panic(fmt.Sprintf("%s configured by wrong module %s", absAddr, ctx.Path()))
|
||||
panic(fmt.Sprintf("%s configured by wrong module %s", addr, ctx.Path()))
|
||||
}
|
||||
|
||||
p := ctx.Provider(absAddr)
|
||||
p := ctx.Provider(addr)
|
||||
if p == nil {
|
||||
diags = diags.Append(fmt.Errorf("%s not initialized", addr))
|
||||
return diags
|
||||
}
|
||||
|
||||
providerSchema := ctx.ProviderSchema(absAddr)
|
||||
providerSchema := ctx.ProviderSchema(addr)
|
||||
if providerSchema == nil {
|
||||
diags = diags.Append(fmt.Errorf("schema for %s is not available", absAddr))
|
||||
diags = diags.Append(fmt.Errorf("schema for %s is not available", addr))
|
||||
return diags
|
||||
}
|
||||
|
||||
|
@ -241,8 +232,6 @@ func (ctx *BuiltinEvalContext) SetProviderInput(pc addrs.AbsProviderConfig, c ma
|
|||
}
|
||||
|
||||
func (ctx *BuiltinEvalContext) InitProvisioner(n string) (provisioners.Interface, error) {
|
||||
ctx.once.Do(ctx.init)
|
||||
|
||||
// If we already initialized, it is an error
|
||||
if p := ctx.Provisioner(n); p != nil {
|
||||
return nil, fmt.Errorf("Provisioner '%s' already initialized", n)
|
||||
|
@ -264,8 +253,6 @@ func (ctx *BuiltinEvalContext) InitProvisioner(n string) (provisioners.Interface
|
|||
}
|
||||
|
||||
func (ctx *BuiltinEvalContext) Provisioner(n string) provisioners.Interface {
|
||||
ctx.once.Do(ctx.init)
|
||||
|
||||
ctx.ProvisionerLock.Lock()
|
||||
defer ctx.ProvisionerLock.Unlock()
|
||||
|
||||
|
@ -273,14 +260,10 @@ func (ctx *BuiltinEvalContext) Provisioner(n string) provisioners.Interface {
|
|||
}
|
||||
|
||||
func (ctx *BuiltinEvalContext) ProvisionerSchema(n string) *configschema.Block {
|
||||
ctx.once.Do(ctx.init)
|
||||
|
||||
return ctx.Schemas.ProvisionerConfig(n)
|
||||
}
|
||||
|
||||
func (ctx *BuiltinEvalContext) CloseProvisioner(n string) error {
|
||||
ctx.once.Do(ctx.init)
|
||||
|
||||
ctx.ProvisionerLock.Lock()
|
||||
defer ctx.ProvisionerLock.Unlock()
|
||||
|
||||
|
@ -361,6 +344,3 @@ func (ctx *BuiltinEvalContext) State() *states.SyncState {
|
|||
func (ctx *BuiltinEvalContext) InstanceExpander() *instances.Expander {
|
||||
return ctx.InstanceExpanderValue
|
||||
}
|
||||
|
||||
func (ctx *BuiltinEvalContext) init() {
|
||||
}
|
||||
|
|
|
@ -452,8 +452,7 @@ func (n *EvalMaybeRestoreDeposedObject) Eval(ctx EvalContext) (interface{}, erro
|
|||
// in that case, allowing expression evaluation to see it as a zero-element
|
||||
// list rather than as not set at all.
|
||||
type EvalWriteResourceState struct {
|
||||
Addr addrs.Resource
|
||||
Module addrs.Module
|
||||
Addr addrs.ConfigResource
|
||||
Config *configs.Resource
|
||||
ProviderAddr addrs.AbsProviderConfig
|
||||
}
|
||||
|
@ -489,18 +488,18 @@ func (n *EvalWriteResourceState) Eval(ctx EvalContext) (interface{}, error) {
|
|||
// can refer to it. Since this node represents the abstract module, we need
|
||||
// to expand the module here to create all resources.
|
||||
expander := ctx.InstanceExpander()
|
||||
for _, module := range expander.ExpandModule(n.Module) {
|
||||
for _, module := range expander.ExpandModule(n.Addr.Module) {
|
||||
// This method takes care of all of the business logic of updating this
|
||||
// while ensuring that any existing instances are preserved, etc.
|
||||
state.SetResourceMeta(n.Addr.Absolute(module), eachMode, n.ProviderAddr)
|
||||
|
||||
switch eachMode {
|
||||
case states.EachList:
|
||||
expander.SetResourceCount(module, n.Addr, count)
|
||||
expander.SetResourceCount(module, n.Addr.Resource, count)
|
||||
case states.EachMap:
|
||||
expander.SetResourceForEach(module, n.Addr, forEach)
|
||||
expander.SetResourceForEach(module, n.Addr.Resource, forEach)
|
||||
default:
|
||||
expander.SetResourceSingle(module, n.Addr)
|
||||
expander.SetResourceSingle(module, n.Addr.Resource)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -209,7 +209,7 @@ func TestApplyGraphBuilder_doubleCBD(t *testing.T) {
|
|||
continue
|
||||
}
|
||||
|
||||
switch tv.Addr.Name {
|
||||
switch tv.Addr.Resource.Name {
|
||||
case "A":
|
||||
destroyA = fmt.Sprintf("test_object.A (destroy deposed %s)", tv.DeposedKey)
|
||||
case "B":
|
||||
|
|
|
@ -59,7 +59,7 @@ func (n *NodeRefreshableDataResource) DynamicExpand(ctx EvalContext) (*Graph, er
|
|||
// Inform our instance expander about our expansion results above,
|
||||
// and then use it to calculate the instance addresses we'll expand for.
|
||||
expander := ctx.InstanceExpander()
|
||||
for _, path := range expander.ExpandModule(n.Module) {
|
||||
for _, path := range expander.ExpandModule(n.Addr.Module) {
|
||||
switch {
|
||||
case count >= 0:
|
||||
expander.SetResourceCount(path, n.ResourceAddr().Resource, count)
|
||||
|
|
|
@ -40,12 +40,7 @@ func TestNodeRefreshableDataResourceDynamicExpand_scaleOut(t *testing.T) {
|
|||
|
||||
n := &NodeRefreshableDataResource{
|
||||
NodeAbstractResource: &NodeAbstractResource{
|
||||
Addr: addrs.Resource{
|
||||
Mode: addrs.DataResourceMode,
|
||||
Type: "aws_instance",
|
||||
Name: "foo",
|
||||
},
|
||||
Module: addrs.RootModule,
|
||||
Addr: addrs.RootModule.Resource(addrs.DataResourceMode, "aws_instance", "foo"),
|
||||
Config: m.Module.DataResources["data.aws_instance.foo"],
|
||||
},
|
||||
}
|
||||
|
@ -125,12 +120,7 @@ func TestNodeRefreshableDataResourceDynamicExpand_scaleIn(t *testing.T) {
|
|||
|
||||
n := &NodeRefreshableDataResource{
|
||||
NodeAbstractResource: &NodeAbstractResource{
|
||||
Addr: addrs.Resource{
|
||||
Mode: addrs.DataResourceMode,
|
||||
Type: "aws_instance",
|
||||
Name: "foo",
|
||||
},
|
||||
Module: addrs.RootModule,
|
||||
Addr: addrs.RootModule.Resource(addrs.DataResourceMode, "aws_instance", "foo"),
|
||||
Config: m.Module.DataResources["data.aws_instance.foo"],
|
||||
ResolvedProvider: addrs.AbsProviderConfig{
|
||||
Provider: addrs.NewLegacyProvider("aws"),
|
||||
|
|
|
@ -110,8 +110,8 @@ func (n *evalPrepareModuleExpansion) Eval(ctx EvalContext) (interface{}, error)
|
|||
eachMode = states.EachMap
|
||||
}
|
||||
|
||||
// nodeExpandModule itself does not have visibility into how it's ancestors
|
||||
// were expended, so we use the expander here to provide all possible paths
|
||||
// nodeExpandModule itself does not have visibility into how its ancestors
|
||||
// were expanded, so we use the expander here to provide all possible paths
|
||||
// to our module, and register module instances with each of them.
|
||||
for _, path := range expander.ExpandModule(n.Addr.Parent()) {
|
||||
switch eachMode {
|
||||
|
|
|
@ -32,7 +32,7 @@ func (n *NodeModuleRemoved) Path() addrs.ModuleInstance {
|
|||
// GraphNodeModulePath implementation
|
||||
func (n *NodeModuleRemoved) ModulePath() addrs.Module {
|
||||
// This node represents the module call within a module,
|
||||
// so return the CallerAddr as the path as the module
|
||||
// so return the CallerAddr as the path, as the module
|
||||
// call may expand into multiple child instances
|
||||
return n.Addr.Module()
|
||||
}
|
||||
|
|
|
@ -41,6 +41,8 @@ func (n *NodeAbstractProvider) Name() string {
|
|||
|
||||
// GraphNodeModuleInstance
|
||||
func (n *NodeAbstractProvider) Path() addrs.ModuleInstance {
|
||||
// Providers cannot be contained inside an expanded module, so this shim
|
||||
// converts our module path to the correct ModuleInstance.
|
||||
return n.Addr.Module.UnkeyedInstanceShim()
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ type NodeDisabledProvider struct {
|
|||
}
|
||||
|
||||
var (
|
||||
_ GraphNodeModuleInstance = (*NodeDisabledProvider)(nil)
|
||||
_ GraphNodeModulePath = (*NodeDisabledProvider)(nil)
|
||||
_ RemovableIfNotTargeted = (*NodeDisabledProvider)(nil)
|
||||
_ GraphNodeReferencer = (*NodeDisabledProvider)(nil)
|
||||
_ GraphNodeProvider = (*NodeDisabledProvider)(nil)
|
||||
|
|
|
@ -43,8 +43,7 @@ type GraphNodeResourceInstance interface {
|
|||
// operations. It registers all the interfaces for a resource that common
|
||||
// across multiple operation types.
|
||||
type NodeAbstractResource struct {
|
||||
Addr addrs.Resource
|
||||
Module addrs.Module
|
||||
Addr addrs.ConfigResource
|
||||
|
||||
// The fields below will be automatically set using the Attach
|
||||
// interfaces if you're running those transforms, but also be explicitly
|
||||
|
@ -80,15 +79,18 @@ var (
|
|||
)
|
||||
|
||||
func (n *NodeAbstractResource) addr() addrs.AbsResource {
|
||||
return n.Addr.Absolute(n.Module.UnkeyedInstanceShim())
|
||||
return n.Addr.Absolute(n.Addr.Module.UnkeyedInstanceShim())
|
||||
}
|
||||
|
||||
// NewNodeAbstractResource creates an abstract resource graph node for
|
||||
// the given absolute resource address.
|
||||
func NewNodeAbstractResource(addr addrs.AbsResource) *NodeAbstractResource {
|
||||
// FIXME: this should probably accept a ConfigResource
|
||||
return &NodeAbstractResource{
|
||||
Addr: addr.Resource,
|
||||
Module: addr.Module.Module(),
|
||||
Addr: addrs.ConfigResource{
|
||||
Resource: addr.Resource,
|
||||
Module: addr.Module.Module(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -136,8 +138,10 @@ func NewNodeAbstractResourceInstance(addr addrs.AbsResourceInstance) *NodeAbstra
|
|||
// request.
|
||||
return &NodeAbstractResourceInstance{
|
||||
NodeAbstractResource: NodeAbstractResource{
|
||||
Addr: addr.Resource.Resource,
|
||||
Module: addr.Module.Module(),
|
||||
Addr: addrs.ConfigResource{
|
||||
Resource: addr.Resource.Resource,
|
||||
Module: addr.Module.Module(),
|
||||
},
|
||||
},
|
||||
ModuleInstance: addr.Module,
|
||||
InstanceKey: addr.Resource.Key,
|
||||
|
@ -154,7 +158,7 @@ func (n *NodeAbstractResourceInstance) Name() string {
|
|||
|
||||
// GraphNodeModuleInstance
|
||||
func (n *NodeAbstractResource) Path() addrs.ModuleInstance {
|
||||
return n.Module.UnkeyedInstanceShim()
|
||||
return n.Addr.Module.UnkeyedInstanceShim()
|
||||
}
|
||||
|
||||
func (n *NodeAbstractResourceInstance) Path() addrs.ModuleInstance {
|
||||
|
@ -163,12 +167,12 @@ func (n *NodeAbstractResourceInstance) Path() addrs.ModuleInstance {
|
|||
|
||||
// GraphNodeModulePath
|
||||
func (n *NodeAbstractResource) ModulePath() addrs.Module {
|
||||
return n.Module
|
||||
return n.Addr.Module
|
||||
}
|
||||
|
||||
// GraphNodeReferenceable
|
||||
func (n *NodeAbstractResource) ReferenceableAddrs() []addrs.Referenceable {
|
||||
return []addrs.Referenceable{n.Addr}
|
||||
return []addrs.Referenceable{n.Addr.Resource}
|
||||
}
|
||||
|
||||
// GraphNodeReferenceable
|
||||
|
@ -314,7 +318,7 @@ func (n *NodeAbstractResource) ProvidedBy() (addrs.ProviderConfig, bool) {
|
|||
|
||||
// GraphNodeProviderConsumer
|
||||
func (n *NodeAbstractResource) ImpliedProvider() addrs.Provider {
|
||||
return n.Addr.DefaultProvider()
|
||||
return n.Addr.Resource.DefaultProvider()
|
||||
}
|
||||
|
||||
// GraphNodeProviderConsumer
|
||||
|
@ -342,7 +346,7 @@ func (n *NodeAbstractResourceInstance) ProvidedBy() (addrs.ProviderConfig, bool)
|
|||
|
||||
// GraphNodeProviderConsumer
|
||||
func (n *NodeAbstractResourceInstance) ImpliedProvider() addrs.Provider {
|
||||
return n.Addr.DefaultProvider()
|
||||
return n.Addr.Resource.DefaultProvider()
|
||||
}
|
||||
|
||||
// GraphNodeProvisionerConsumer
|
||||
|
|
|
@ -61,7 +61,6 @@ func (n *NodeApplyableResource) EvalTree() EvalNode {
|
|||
|
||||
return &EvalWriteResourceState{
|
||||
Addr: n.Addr,
|
||||
Module: n.Module,
|
||||
Config: n.Config,
|
||||
ProviderAddr: n.ResolvedProvider,
|
||||
}
|
||||
|
|
|
@ -38,7 +38,6 @@ func (n *NodePlannableResource) EvalTree() EvalNode {
|
|||
// this ensures we can reference the resource even if the count is 0
|
||||
return &EvalWriteResourceState{
|
||||
Addr: n.Addr,
|
||||
Module: n.Module,
|
||||
Config: n.Config,
|
||||
ProviderAddr: n.ResolvedProvider,
|
||||
}
|
||||
|
|
|
@ -60,7 +60,7 @@ func (n *NodeRefreshableManagedResource) DynamicExpand(ctx EvalContext) (*Graph,
|
|||
// Inform our instance expander about our expansion results above,
|
||||
// and then use it to calculate the instance addresses we'll expand for.
|
||||
expander := ctx.InstanceExpander()
|
||||
for _, module := range expander.ExpandModule(n.Module) {
|
||||
for _, module := range expander.ExpandModule(n.Addr.Module) {
|
||||
switch {
|
||||
case count >= 0:
|
||||
expander.SetResourceCount(module, n.ResourceAddr().Resource, count)
|
||||
|
@ -70,7 +70,7 @@ func (n *NodeRefreshableManagedResource) DynamicExpand(ctx EvalContext) (*Graph,
|
|||
expander.SetResourceSingle(module, n.ResourceAddr().Resource)
|
||||
}
|
||||
}
|
||||
instanceAddrs := expander.ExpandResource(n.Module, n.ResourceAddr().Resource)
|
||||
instanceAddrs := expander.ExpandResource(n.Addr.Module, n.ResourceAddr().Resource)
|
||||
|
||||
// Our graph transformers require access to the full state, so we'll
|
||||
// temporarily lock it while we work on this.
|
||||
|
|
|
@ -42,12 +42,7 @@ func TestNodeRefreshableManagedResourceDynamicExpand_scaleOut(t *testing.T) {
|
|||
|
||||
n := &NodeRefreshableManagedResource{
|
||||
NodeAbstractResource: &NodeAbstractResource{
|
||||
Addr: addrs.Resource{
|
||||
Mode: addrs.ManagedResourceMode,
|
||||
Type: "aws_instance",
|
||||
Name: "foo",
|
||||
},
|
||||
Module: addrs.RootModule,
|
||||
Addr: addrs.RootModule.Resource(addrs.ManagedResourceMode, "aws_instance", "foo"),
|
||||
Config: m.Module.ManagedResources["aws_instance.foo"],
|
||||
},
|
||||
}
|
||||
|
@ -127,12 +122,7 @@ func TestNodeRefreshableManagedResourceDynamicExpand_scaleIn(t *testing.T) {
|
|||
|
||||
n := &NodeRefreshableManagedResource{
|
||||
NodeAbstractResource: &NodeAbstractResource{
|
||||
Addr: addrs.Resource{
|
||||
Mode: addrs.ManagedResourceMode,
|
||||
Type: "aws_instance",
|
||||
Name: "foo",
|
||||
},
|
||||
Module: addrs.RootModule,
|
||||
Addr: addrs.RootModule.Resource(addrs.ManagedResourceMode, "aws_instance", "foo"),
|
||||
Config: m.Module.ManagedResources["aws_instance.foo"],
|
||||
},
|
||||
}
|
||||
|
@ -172,12 +162,7 @@ func TestNodeRefreshableManagedResourceEvalTree_scaleOut(t *testing.T) {
|
|||
n := &NodeRefreshableManagedResourceInstance{
|
||||
NodeAbstractResourceInstance: &NodeAbstractResourceInstance{
|
||||
NodeAbstractResource: NodeAbstractResource{
|
||||
Addr: addrs.Resource{
|
||||
Mode: addrs.ManagedResourceMode,
|
||||
Type: "aws_instance",
|
||||
Name: "foo",
|
||||
},
|
||||
Module: addrs.RootModule,
|
||||
Addr: addrs.RootModule.Resource(addrs.ManagedResourceMode, "aws_instance", "foo"),
|
||||
Config: m.Module.ManagedResources["aws_instance.foo"],
|
||||
},
|
||||
InstanceKey: addrs.IntKey(2),
|
||||
|
|
|
@ -8,9 +8,6 @@ import (
|
|||
// GraphNodeAttachProvider is an interface that must be implemented by nodes
|
||||
// that want provider configurations attached.
|
||||
type GraphNodeAttachProvider interface {
|
||||
// Must be implemented to determine the path for the configuration
|
||||
GraphNodeModuleInstance
|
||||
|
||||
// ProviderName with no module prefix. Example: "aws".
|
||||
ProviderAddr() addrs.AbsProviderConfig
|
||||
|
||||
|
|
|
@ -111,8 +111,10 @@ func (t *ConfigTransformer) transformSingle(g *Graph, config *configs.Config) er
|
|||
}
|
||||
|
||||
abstract := &NodeAbstractResource{
|
||||
Addr: relAddr,
|
||||
Module: path,
|
||||
Addr: addrs.ConfigResource{
|
||||
Resource: relAddr,
|
||||
Module: path,
|
||||
},
|
||||
}
|
||||
|
||||
if _, ok := t.uniqueMap[abstract.Name()]; ok {
|
||||
|
|
Loading…
Reference in New Issue