From 4a1ec050927c3f924809d2de2ca244c4664d8d84 Mon Sep 17 00:00:00 2001 From: James Bardin Date: Wed, 11 Mar 2020 14:52:15 -0400 Subject: [PATCH 1/4] comment fixes --- terraform/node_module_expand.go | 4 ++-- terraform/node_module_removed.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/terraform/node_module_expand.go b/terraform/node_module_expand.go index 1e7d4042a..0c62d47cf 100644 --- a/terraform/node_module_expand.go +++ b/terraform/node_module_expand.go @@ -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 { diff --git a/terraform/node_module_removed.go b/terraform/node_module_removed.go index e47281490..b6ea00bff 100644 --- a/terraform/node_module_removed.go +++ b/terraform/node_module_removed.go @@ -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() } From 482ae66e18c62d4d2c5e1a2d2f4df7a0c14320ae Mon Sep 17 00:00:00 2001 From: James Bardin Date: Wed, 11 Mar 2020 17:54:46 -0400 Subject: [PATCH 2/4] minor cleanup Remove unused variables, sync.Once, and init in BuiltinEvalContext. Replace some shim calls. GraphNodeAttachProvider doesn't need to be a NodeModuleInstance. --- terraform/context_import_test.go | 4 +- terraform/eval_context_builtin.go | 40 +++++-------------- terraform/node_provider_abstract.go | 2 + terraform/node_provider_disabled.go | 2 +- terraform/transform_attach_config_provider.go | 3 -- 5 files changed, 15 insertions(+), 36 deletions(-) diff --git a/terraform/context_import_test.go b/terraform/context_import_test.go index 1f9bc21d2..1475ccfa4 100644 --- a/terraform/context_import_test.go +++ b/terraform/context_import_test.go @@ -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", diff --git a/terraform/eval_context_builtin.go b/terraform/eval_context_builtin.go index c5cae2194..746b00fe1 100644 --- a/terraform/eval_context_builtin.go +++ b/terraform/eval_context_builtin.go @@ -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() { -} diff --git a/terraform/node_provider_abstract.go b/terraform/node_provider_abstract.go index 871caefc5..5c30364ee 100644 --- a/terraform/node_provider_abstract.go +++ b/terraform/node_provider_abstract.go @@ -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() } diff --git a/terraform/node_provider_disabled.go b/terraform/node_provider_disabled.go index fc66f2e60..6f7a6d27e 100644 --- a/terraform/node_provider_disabled.go +++ b/terraform/node_provider_disabled.go @@ -14,7 +14,7 @@ type NodeDisabledProvider struct { } var ( - _ GraphNodeModuleInstance = (*NodeDisabledProvider)(nil) + _ GraphNodeModulePath = (*NodeDisabledProvider)(nil) _ RemovableIfNotTargeted = (*NodeDisabledProvider)(nil) _ GraphNodeReferencer = (*NodeDisabledProvider)(nil) _ GraphNodeProvider = (*NodeDisabledProvider)(nil) diff --git a/terraform/transform_attach_config_provider.go b/terraform/transform_attach_config_provider.go index e1cf66362..d2e3d69de 100644 --- a/terraform/transform_attach_config_provider.go +++ b/terraform/transform_attach_config_provider.go @@ -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 From 9054716caf838e04723d131d56acba7766c490d6 Mon Sep 17 00:00:00 2001 From: James Bardin Date: Thu, 12 Mar 2020 13:59:53 -0400 Subject: [PATCH 3/4] implement addrs.ConfigResource Core needs a way to address resources through unexpanded modules, as they are present in the configuration. There are already some cases of paring `addrs.Module` with `addrs.Resource` for this purpose, but it is going to be helpful to have a single type to describe that pair, as well as have the ability to use TargetContains. --- addrs/parse_target_test.go | 45 ++++++++++ addrs/resource.go | 55 +++++++++++++ addrs/target_test.go | 164 +++++++++++++++++++++++++++++++++++++ 3 files changed, 264 insertions(+) create mode 100644 addrs/target_test.go diff --git a/addrs/parse_target_test.go b/addrs/parse_target_test.go index 496fb15ce..84796084f 100644 --- a/addrs/parse_target_test.go +++ b/addrs/parse_target_test.go @@ -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{ diff --git a/addrs/resource.go b/addrs/resource.go index 94f3c3012..4bad01d15 100644 --- a/addrs/resource.go +++ b/addrs/resource.go @@ -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 diff --git a/addrs/target_test.go b/addrs/target_test.go new file mode 100644 index 000000000..a16111560 --- /dev/null +++ b/addrs/target_test.go @@ -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 +} From d65bd64955873bd854d7abf7dcf40ebad3e5ba4b Mon Sep 17 00:00:00 2001 From: James Bardin Date: Thu, 12 Mar 2020 14:47:28 -0400 Subject: [PATCH 4/4] incorporate addrs.ConfigResource --- terraform/eval_state.go | 11 +++++----- terraform/graph_builder_apply_test.go | 2 +- terraform/node_data_refresh.go | 2 +- terraform/node_data_refresh_test.go | 14 ++----------- terraform/node_resource_abstract.go | 28 ++++++++++++++----------- terraform/node_resource_apply.go | 1 - terraform/node_resource_plan.go | 1 - terraform/node_resource_refresh.go | 4 ++-- terraform/node_resource_refresh_test.go | 21 +++---------------- terraform/transform_config.go | 6 ++++-- 10 files changed, 34 insertions(+), 56 deletions(-) diff --git a/terraform/eval_state.go b/terraform/eval_state.go index ccf63d1e4..8f134d465 100644 --- a/terraform/eval_state.go +++ b/terraform/eval_state.go @@ -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) } } diff --git a/terraform/graph_builder_apply_test.go b/terraform/graph_builder_apply_test.go index 5654c49c3..0d323bfda 100644 --- a/terraform/graph_builder_apply_test.go +++ b/terraform/graph_builder_apply_test.go @@ -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": diff --git a/terraform/node_data_refresh.go b/terraform/node_data_refresh.go index 4e2460745..b16a73bd9 100644 --- a/terraform/node_data_refresh.go +++ b/terraform/node_data_refresh.go @@ -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) diff --git a/terraform/node_data_refresh_test.go b/terraform/node_data_refresh_test.go index 1f88d1bee..de1b5a787 100644 --- a/terraform/node_data_refresh_test.go +++ b/terraform/node_data_refresh_test.go @@ -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"), diff --git a/terraform/node_resource_abstract.go b/terraform/node_resource_abstract.go index 687fa0f1a..0fc3ee0ea 100644 --- a/terraform/node_resource_abstract.go +++ b/terraform/node_resource_abstract.go @@ -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 diff --git a/terraform/node_resource_apply.go b/terraform/node_resource_apply.go index 11aeb338a..c21158a9f 100644 --- a/terraform/node_resource_apply.go +++ b/terraform/node_resource_apply.go @@ -61,7 +61,6 @@ func (n *NodeApplyableResource) EvalTree() EvalNode { return &EvalWriteResourceState{ Addr: n.Addr, - Module: n.Module, Config: n.Config, ProviderAddr: n.ResolvedProvider, } diff --git a/terraform/node_resource_plan.go b/terraform/node_resource_plan.go index 0455296c8..7d61d9ce0 100644 --- a/terraform/node_resource_plan.go +++ b/terraform/node_resource_plan.go @@ -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, } diff --git a/terraform/node_resource_refresh.go b/terraform/node_resource_refresh.go index 7871918e5..ee3f084be 100644 --- a/terraform/node_resource_refresh.go +++ b/terraform/node_resource_refresh.go @@ -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. diff --git a/terraform/node_resource_refresh_test.go b/terraform/node_resource_refresh_test.go index 438010d39..f516aaecf 100644 --- a/terraform/node_resource_refresh_test.go +++ b/terraform/node_resource_refresh_test.go @@ -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), diff --git a/terraform/transform_config.go b/terraform/transform_config.go index 0c16f9b56..284fa9168 100644 --- a/terraform/transform_config.go +++ b/terraform/transform_config.go @@ -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 {