From 90588c036b0818b4a3450b460bf4e720268fe547 Mon Sep 17 00:00:00 2001 From: Kristin Laemmert Date: Thu, 1 Oct 2020 08:12:10 -0400 Subject: [PATCH] terraform: minor cleanup from EvalTree() refactor (#26429) * Split node_resource_abstract.go into two files, putting NodeAbstractResourceInstance methods in their own file - it was getting large enough to be tricky for (my) human eyeballs. * un-exported the functions that were created as part of the EvalTree() refactor; they did not need to be public. --- terraform/node_resource_abstract.go | 209 +----------------- terraform/node_resource_abstract_instance.go | 201 +++++++++++++++++ .../node_resource_abstract_instance_test.go | 111 ++++++++++ terraform/node_resource_abstract_test.go | 102 --------- terraform/node_resource_apply.go | 2 +- terraform/node_resource_apply_instance.go | 6 +- terraform/node_resource_destroy.go | 2 +- terraform/node_resource_plan.go | 2 +- 8 files changed, 320 insertions(+), 315 deletions(-) create mode 100644 terraform/node_resource_abstract_instance.go create mode 100644 terraform/node_resource_abstract_instance_test.go diff --git a/terraform/node_resource_abstract.go b/terraform/node_resource_abstract.go index c6fdc19b0..4606d5185 100644 --- a/terraform/node_resource_abstract.go +++ b/terraform/node_resource_abstract.go @@ -4,13 +4,11 @@ import ( "fmt" "log" - "github.com/hashicorp/hcl/v2" "github.com/hashicorp/terraform/addrs" "github.com/hashicorp/terraform/configs" "github.com/hashicorp/terraform/configs/configschema" "github.com/hashicorp/terraform/dag" "github.com/hashicorp/terraform/lang" - "github.com/hashicorp/terraform/plans" "github.com/hashicorp/terraform/states" "github.com/hashicorp/terraform/tfdiags" ) @@ -95,25 +93,6 @@ func NewNodeAbstractResource(addr addrs.ConfigResource) *NodeAbstractResource { } } -// NodeAbstractResourceInstance represents a resource instance with no -// associated operations. It embeds NodeAbstractResource but additionally -// contains an instance key, used to identify one of potentially many -// instances that were created from a resource in configuration, e.g. using -// the "count" or "for_each" arguments. -type NodeAbstractResourceInstance struct { - NodeAbstractResource - Addr addrs.AbsResourceInstance - - // These are set via the AttachState method. - instanceState *states.ResourceInstance - // storedProviderConfig is the provider address retrieved from the - // state, but since it is only stored in the whole Resource rather than the - // ResourceInstance, we extract it out here. - storedProviderConfig addrs.AbsProviderConfig - - Dependencies []addrs.ConfigResource -} - var ( _ GraphNodeModuleInstance = (*NodeAbstractResourceInstance)(nil) _ GraphNodeReferenceable = (*NodeAbstractResourceInstance)(nil) @@ -131,33 +110,10 @@ var ( _ dag.GraphNodeDotter = (*NodeAbstractResourceInstance)(nil) ) -// NewNodeAbstractResourceInstance creates an abstract resource instance graph -// node for the given absolute resource instance address. -func NewNodeAbstractResourceInstance(addr addrs.AbsResourceInstance) *NodeAbstractResourceInstance { - // Due to the fact that we embed NodeAbstractResource, the given address - // actually ends up split between the resource address in the embedded - // object and the InstanceKey field in our own struct. The - // ResourceInstanceAddr method will stick these back together again on - // request. - r := NewNodeAbstractResource(addr.ContainingResource().Config()) - return &NodeAbstractResourceInstance{ - NodeAbstractResource: *r, - Addr: addr, - } -} - func (n *NodeAbstractResource) Name() string { return n.ResourceAddr().String() } -func (n *NodeAbstractResourceInstance) Name() string { - return n.ResourceInstanceAddr().String() -} - -func (n *NodeAbstractResourceInstance) Path() addrs.ModuleInstance { - return n.Addr.Module -} - // GraphNodeModulePath func (n *NodeAbstractResource) ModulePath() addrs.Module { return n.Addr.Module @@ -168,19 +124,6 @@ func (n *NodeAbstractResource) ReferenceableAddrs() []addrs.Referenceable { return []addrs.Referenceable{n.Addr.Resource} } -// GraphNodeReferenceable -func (n *NodeAbstractResourceInstance) ReferenceableAddrs() []addrs.Referenceable { - addr := n.ResourceInstanceAddr() - return []addrs.Referenceable{ - addr.Resource, - - // A resource instance can also be referenced by the address of its - // containing resource, so that e.g. a reference to aws_instance.foo - // would match both aws_instance.foo[0] and aws_instance.foo[1]. - addr.ContainingResource().Resource, - } -} - // GraphNodeReferencer func (n *NodeAbstractResource) References() []*addrs.Reference { // If we have a config then we prefer to use that. @@ -256,52 +199,6 @@ func (n *NodeAbstractResource) DependsOn() []*addrs.Reference { return result } -// GraphNodeReferencer -func (n *NodeAbstractResourceInstance) References() []*addrs.Reference { - // If we have a configuration attached then we'll delegate to our - // embedded abstract resource, which knows how to extract dependencies - // from configuration. If there is no config, then the dependencies will - // be connected during destroy from those stored in the state. - if n.Config != nil { - if n.Schema == nil { - // We'll produce a log message about this out here so that - // we can include the full instance address, since the equivalent - // message in NodeAbstractResource.References cannot see it. - log.Printf("[WARN] no schema is attached to %s, so config references cannot be detected", n.Name()) - return nil - } - return n.NodeAbstractResource.References() - } - - // If we have neither config nor state then we have no references. - return nil -} - -// converts an instance address to the legacy dotted notation -func dottedInstanceAddr(tr addrs.ResourceInstance) string { - // The legacy state format uses dot-separated instance keys, - // rather than bracketed as in our modern syntax. - var suffix string - switch tk := tr.Key.(type) { - case addrs.IntKey: - suffix = fmt.Sprintf(".%d", int(tk)) - case addrs.StringKey: - suffix = fmt.Sprintf(".%s", string(tk)) - } - return tr.Resource.String() + suffix -} - -// StateDependencies returns the dependencies saved in the state. -func (n *NodeAbstractResourceInstance) StateDependencies() []addrs.ConfigResource { - if s := n.instanceState; s != nil { - if s.Current != nil { - return s.Current.Dependencies - } - } - - return nil -} - func (n *NodeAbstractResource) SetProvider(p addrs.AbsProviderConfig) { n.ResolvedProvider = p } @@ -332,40 +229,6 @@ func (n *NodeAbstractResource) Provider() addrs.Provider { return addrs.ImpliedProviderForUnqualifiedType(n.Addr.Resource.ImpliedProvider()) } -// GraphNodeProviderConsumer -func (n *NodeAbstractResourceInstance) ProvidedBy() (addrs.ProviderConfig, bool) { - // If we have a config we prefer that above all else - if n.Config != nil { - relAddr := n.Config.ProviderConfigAddr() - return addrs.LocalProviderConfig{ - LocalName: relAddr.LocalName, - Alias: relAddr.Alias, - }, false - } - - // See if we have a valid provider config from the state. - if n.storedProviderConfig.Provider.Type != "" { - // An address from the state must match exactly, since we must ensure - // we refresh/destroy a resource with the same provider configuration - // that created it. - return n.storedProviderConfig, true - } - - // No provider configuration found; return a default address - return addrs.AbsProviderConfig{ - Provider: n.Provider(), - Module: n.ModulePath(), - }, false -} - -// GraphNodeProviderConsumer -func (n *NodeAbstractResourceInstance) Provider() addrs.Provider { - if n.Config != nil { - return n.Config.Provider - } - return addrs.ImpliedProviderForUnqualifiedType(n.Addr.Resource.ContainingResource().ImpliedProvider()) -} - // GraphNodeProvisionerConsumer func (n *NodeAbstractResource) ProvisionedBy() []string { // If we have no configuration, then we have no provisioners @@ -396,11 +259,6 @@ func (n *NodeAbstractResource) ResourceAddr() addrs.ConfigResource { return n.Addr } -// GraphNodeResourceInstance -func (n *NodeAbstractResourceInstance) ResourceInstanceAddr() addrs.AbsResourceInstance { - return n.Addr -} - // GraphNodeTargetable func (n *NodeAbstractResource) SetTargets(targets []addrs.Targetable) { n.Targets = targets @@ -412,16 +270,6 @@ func (n *NodeAbstractResource) AttachResourceDependencies(deps []addrs.ConfigRes n.forceDependsOn = force } -// GraphNodeAttachResourceState -func (n *NodeAbstractResourceInstance) AttachResourceState(s *states.Resource) { - if s == nil { - log.Printf("[WARN] attaching nil state to %s", n.Addr) - return - } - n.instanceState = s.Instance(n.Addr.Resource.Key) - n.storedProviderConfig = s.ProviderConfig -} - // GraphNodeAttachResourceConfig func (n *NodeAbstractResource) AttachResourceConfig(c *configs.Resource) { n.Config = c @@ -449,7 +297,7 @@ func (n *NodeAbstractResource) DotNode(name string, opts *dag.DotOpts) *dag.DotN } } -// WriteResourceState ensures that a suitable resource-level state record is +// writeResourceState ensures that a suitable resource-level state record is // present in the state, if that's required for the "each mode" of that // resource. // @@ -457,7 +305,7 @@ func (n *NodeAbstractResource) DotNode(name string, opts *dag.DotOpts) *dag.DotN // eval is the only change we get to set the resource "each mode" to list // in that case, allowing expression evaluation to see it as a zero-element list // rather than as not set at all. -func (n *NodeAbstractResource) WriteResourceState(ctx EvalContext, addr addrs.AbsResource) error { +func (n *NodeAbstractResource) writeResourceState(ctx EvalContext, addr addrs.AbsResource) error { var diags tfdiags.Diagnostics state := ctx.State() @@ -542,59 +390,6 @@ func (n *NodeAbstractResource) ReadResourceInstanceState(ctx EvalContext, addr a return obj, nil } -// ReadDiff returns the planned change for a particular resource instance -// object. -func (n *NodeAbstractResourceInstance) ReadDiff(ctx EvalContext, providerSchema *ProviderSchema) (*plans.ResourceInstanceChange, error) { - changes := ctx.Changes() - addr := n.ResourceInstanceAddr() - - schema, _ := providerSchema.SchemaForResourceAddr(addr.Resource.Resource) - if schema == nil { - // Should be caught during validation, so we don't bother with a pretty error here - return nil, fmt.Errorf("provider does not support resource type %q", addr.Resource.Resource.Type) - } - - gen := states.CurrentGen - csrc := changes.GetResourceInstanceChange(addr, gen) - if csrc == nil { - log.Printf("[TRACE] EvalReadDiff: No planned change recorded for %s", n.Addr) - return nil, nil - } - - change, err := csrc.Decode(schema.ImpliedType()) - if err != nil { - return nil, fmt.Errorf("failed to decode planned changes for %s: %s", n.Addr, err) - } - - log.Printf("[TRACE] EvalReadDiff: Read %s change from plan for %s", change.Action, n.Addr) - - return change, nil -} - -func (n *NodeAbstractResourceInstance) checkPreventDestroy(change *plans.ResourceInstanceChange) error { - if change == nil || n.Config == nil || n.Config.Managed == nil { - return nil - } - - preventDestroy := n.Config.Managed.PreventDestroy - - if (change.Action == plans.Delete || change.Action.IsReplace()) && preventDestroy { - var diags tfdiags.Diagnostics - diags = diags.Append(&hcl.Diagnostic{ - Severity: hcl.DiagError, - Summary: "Instance cannot be destroyed", - Detail: fmt.Sprintf( - "Resource %s has lifecycle.prevent_destroy set, but the plan calls for this resource to be destroyed. To avoid this error and continue with the plan, either disable lifecycle.prevent_destroy or reduce the scope of the plan using the -target flag.", - n.Addr.String(), - ), - Subject: &n.Config.DeclRange, - }) - return diags.Err() - } - - return nil -} - // graphNodesAreResourceInstancesInDifferentInstancesOfSameModule is an // annoyingly-task-specific helper function that returns true if and only if // the following conditions hold: diff --git a/terraform/node_resource_abstract_instance.go b/terraform/node_resource_abstract_instance.go new file mode 100644 index 000000000..4739679ce --- /dev/null +++ b/terraform/node_resource_abstract_instance.go @@ -0,0 +1,201 @@ +package terraform + +import ( + "fmt" + "log" + + "github.com/hashicorp/hcl/v2" + "github.com/hashicorp/terraform/addrs" + "github.com/hashicorp/terraform/plans" + "github.com/hashicorp/terraform/states" + "github.com/hashicorp/terraform/tfdiags" +) + +// NodeAbstractResourceInstance represents a resource instance with no +// associated operations. It embeds NodeAbstractResource but additionally +// contains an instance key, used to identify one of potentially many +// instances that were created from a resource in configuration, e.g. using +// the "count" or "for_each" arguments. +type NodeAbstractResourceInstance struct { + NodeAbstractResource + Addr addrs.AbsResourceInstance + + // These are set via the AttachState method. + instanceState *states.ResourceInstance + // storedProviderConfig is the provider address retrieved from the + // state, but since it is only stored in the whole Resource rather than the + // ResourceInstance, we extract it out here. + storedProviderConfig addrs.AbsProviderConfig + + Dependencies []addrs.ConfigResource +} + +// NewNodeAbstractResourceInstance creates an abstract resource instance graph +// node for the given absolute resource instance address. +func NewNodeAbstractResourceInstance(addr addrs.AbsResourceInstance) *NodeAbstractResourceInstance { + // Due to the fact that we embed NodeAbstractResource, the given address + // actually ends up split between the resource address in the embedded + // object and the InstanceKey field in our own struct. The + // ResourceInstanceAddr method will stick these back together again on + // request. + r := NewNodeAbstractResource(addr.ContainingResource().Config()) + return &NodeAbstractResourceInstance{ + NodeAbstractResource: *r, + Addr: addr, + } +} + +func (n *NodeAbstractResourceInstance) Name() string { + return n.ResourceInstanceAddr().String() +} + +func (n *NodeAbstractResourceInstance) Path() addrs.ModuleInstance { + return n.Addr.Module +} + +// GraphNodeReferenceable +func (n *NodeAbstractResourceInstance) ReferenceableAddrs() []addrs.Referenceable { + addr := n.ResourceInstanceAddr() + return []addrs.Referenceable{ + addr.Resource, + + // A resource instance can also be referenced by the address of its + // containing resource, so that e.g. a reference to aws_instance.foo + // would match both aws_instance.foo[0] and aws_instance.foo[1]. + addr.ContainingResource().Resource, + } +} + +// GraphNodeReferencer +func (n *NodeAbstractResourceInstance) References() []*addrs.Reference { + // If we have a configuration attached then we'll delegate to our + // embedded abstract resource, which knows how to extract dependencies + // from configuration. If there is no config, then the dependencies will + // be connected during destroy from those stored in the state. + if n.Config != nil { + if n.Schema == nil { + // We'll produce a log message about this out here so that + // we can include the full instance address, since the equivalent + // message in NodeAbstractResource.References cannot see it. + log.Printf("[WARN] no schema is attached to %s, so config references cannot be detected", n.Name()) + return nil + } + return n.NodeAbstractResource.References() + } + + // If we have neither config nor state then we have no references. + return nil +} + +// StateDependencies returns the dependencies saved in the state. +func (n *NodeAbstractResourceInstance) StateDependencies() []addrs.ConfigResource { + if s := n.instanceState; s != nil { + if s.Current != nil { + return s.Current.Dependencies + } + } + + return nil +} + +// GraphNodeProviderConsumer +func (n *NodeAbstractResourceInstance) ProvidedBy() (addrs.ProviderConfig, bool) { + // If we have a config we prefer that above all else + if n.Config != nil { + relAddr := n.Config.ProviderConfigAddr() + return addrs.LocalProviderConfig{ + LocalName: relAddr.LocalName, + Alias: relAddr.Alias, + }, false + } + + // See if we have a valid provider config from the state. + if n.storedProviderConfig.Provider.Type != "" { + // An address from the state must match exactly, since we must ensure + // we refresh/destroy a resource with the same provider configuration + // that created it. + return n.storedProviderConfig, true + } + + // No provider configuration found; return a default address + return addrs.AbsProviderConfig{ + Provider: n.Provider(), + Module: n.ModulePath(), + }, false +} + +// GraphNodeProviderConsumer +func (n *NodeAbstractResourceInstance) Provider() addrs.Provider { + if n.Config != nil { + return n.Config.Provider + } + return addrs.ImpliedProviderForUnqualifiedType(n.Addr.Resource.ContainingResource().ImpliedProvider()) +} + +// GraphNodeResourceInstance +func (n *NodeAbstractResourceInstance) ResourceInstanceAddr() addrs.AbsResourceInstance { + return n.Addr +} + +// GraphNodeAttachResourceState +func (n *NodeAbstractResourceInstance) AttachResourceState(s *states.Resource) { + if s == nil { + log.Printf("[WARN] attaching nil state to %s", n.Addr) + return + } + n.instanceState = s.Instance(n.Addr.Resource.Key) + n.storedProviderConfig = s.ProviderConfig +} + +// readDiff returns the planned change for a particular resource instance +// object. +func (n *NodeAbstractResourceInstance) readDiff(ctx EvalContext, providerSchema *ProviderSchema) (*plans.ResourceInstanceChange, error) { + changes := ctx.Changes() + addr := n.ResourceInstanceAddr() + + schema, _ := providerSchema.SchemaForResourceAddr(addr.Resource.Resource) + if schema == nil { + // Should be caught during validation, so we don't bother with a pretty error here + return nil, fmt.Errorf("provider does not support resource type %q", addr.Resource.Resource.Type) + } + + gen := states.CurrentGen + csrc := changes.GetResourceInstanceChange(addr, gen) + if csrc == nil { + log.Printf("[TRACE] EvalReadDiff: No planned change recorded for %s", n.Addr) + return nil, nil + } + + change, err := csrc.Decode(schema.ImpliedType()) + if err != nil { + return nil, fmt.Errorf("failed to decode planned changes for %s: %s", n.Addr, err) + } + + log.Printf("[TRACE] EvalReadDiff: Read %s change from plan for %s", change.Action, n.Addr) + + return change, nil +} + +func (n *NodeAbstractResourceInstance) checkPreventDestroy(change *plans.ResourceInstanceChange) error { + if change == nil || n.Config == nil || n.Config.Managed == nil { + return nil + } + + preventDestroy := n.Config.Managed.PreventDestroy + + if (change.Action == plans.Delete || change.Action.IsReplace()) && preventDestroy { + var diags tfdiags.Diagnostics + diags = diags.Append(&hcl.Diagnostic{ + Severity: hcl.DiagError, + Summary: "Instance cannot be destroyed", + Detail: fmt.Sprintf( + "Resource %s has lifecycle.prevent_destroy set, but the plan calls for this resource to be destroyed. To avoid this error and continue with the plan, either disable lifecycle.prevent_destroy or reduce the scope of the plan using the -target flag.", + n.Addr.String(), + ), + Subject: &n.Config.DeclRange, + }) + return diags.Err() + } + + return nil +} diff --git a/terraform/node_resource_abstract_instance_test.go b/terraform/node_resource_abstract_instance_test.go new file mode 100644 index 000000000..919e4bac9 --- /dev/null +++ b/terraform/node_resource_abstract_instance_test.go @@ -0,0 +1,111 @@ +package terraform + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/addrs" + "github.com/hashicorp/terraform/configs" +) + +func TestNodeAbstractResourceInstanceProvider(t *testing.T) { + tests := []struct { + Addr addrs.AbsResourceInstance + Config *configs.Resource + Want addrs.Provider + }{ + { + Addr: addrs.Resource{ + Mode: addrs.ManagedResourceMode, + Type: "null_resource", + Name: "baz", + }.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance), + Want: addrs.Provider{ + Hostname: addrs.DefaultRegistryHost, + Namespace: "hashicorp", + Type: "null", + }, + }, + { + Addr: addrs.Resource{ + Mode: addrs.DataResourceMode, + Type: "terraform_remote_state", + Name: "baz", + }.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance), + Want: addrs.Provider{ + // As a special case, the type prefix "terraform_" maps to + // the builtin provider, not the default one. + Hostname: addrs.BuiltInProviderHost, + Namespace: addrs.BuiltInProviderNamespace, + Type: "terraform", + }, + }, + { + Addr: addrs.Resource{ + Mode: addrs.ManagedResourceMode, + Type: "null_resource", + Name: "baz", + }.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance), + Config: &configs.Resource{ + // Just enough configs.Resource for the Provider method. Not + // actually valid for general use. + Provider: addrs.Provider{ + Hostname: addrs.DefaultRegistryHost, + Namespace: "awesomecorp", + Type: "happycloud", + }, + }, + // The config overrides the default behavior. + Want: addrs.Provider{ + Hostname: addrs.DefaultRegistryHost, + Namespace: "awesomecorp", + Type: "happycloud", + }, + }, + { + Addr: addrs.Resource{ + Mode: addrs.DataResourceMode, + Type: "terraform_remote_state", + Name: "baz", + }.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance), + Config: &configs.Resource{ + // Just enough configs.Resource for the Provider method. Not + // actually valid for general use. + Provider: addrs.Provider{ + Hostname: addrs.DefaultRegistryHost, + Namespace: "awesomecorp", + Type: "happycloud", + }, + }, + // The config overrides the default behavior. + Want: addrs.Provider{ + Hostname: addrs.DefaultRegistryHost, + Namespace: "awesomecorp", + Type: "happycloud", + }, + }, + } + + for _, test := range tests { + var name string + if test.Config != nil { + name = fmt.Sprintf("%s with configured %s", test.Addr, test.Config.Provider) + } else { + name = fmt.Sprintf("%s with no configuration", test.Addr) + } + t.Run(name, func(t *testing.T) { + node := &NodeAbstractResourceInstance{ + // Just enough NodeAbstractResourceInstance for the Provider + // function. (This would not be valid for some other functions.) + Addr: test.Addr, + NodeAbstractResource: NodeAbstractResource{ + Config: test.Config, + }, + } + got := node.Provider() + if got != test.Want { + t.Errorf("wrong result\naddr: %s\nconfig: %#v\ngot: %s\nwant: %s", test.Addr, test.Config, got, test.Want) + } + }) + } +} diff --git a/terraform/node_resource_abstract_test.go b/terraform/node_resource_abstract_test.go index 570f84079..6faafe1e8 100644 --- a/terraform/node_resource_abstract_test.go +++ b/terraform/node_resource_abstract_test.go @@ -107,105 +107,3 @@ func TestNodeAbstractResourceProvider(t *testing.T) { }) } } - -func TestNodeAbstractResourceInstanceProvider(t *testing.T) { - tests := []struct { - Addr addrs.AbsResourceInstance - Config *configs.Resource - Want addrs.Provider - }{ - { - Addr: addrs.Resource{ - Mode: addrs.ManagedResourceMode, - Type: "null_resource", - Name: "baz", - }.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance), - Want: addrs.Provider{ - Hostname: addrs.DefaultRegistryHost, - Namespace: "hashicorp", - Type: "null", - }, - }, - { - Addr: addrs.Resource{ - Mode: addrs.DataResourceMode, - Type: "terraform_remote_state", - Name: "baz", - }.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance), - Want: addrs.Provider{ - // As a special case, the type prefix "terraform_" maps to - // the builtin provider, not the default one. - Hostname: addrs.BuiltInProviderHost, - Namespace: addrs.BuiltInProviderNamespace, - Type: "terraform", - }, - }, - { - Addr: addrs.Resource{ - Mode: addrs.ManagedResourceMode, - Type: "null_resource", - Name: "baz", - }.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance), - Config: &configs.Resource{ - // Just enough configs.Resource for the Provider method. Not - // actually valid for general use. - Provider: addrs.Provider{ - Hostname: addrs.DefaultRegistryHost, - Namespace: "awesomecorp", - Type: "happycloud", - }, - }, - // The config overrides the default behavior. - Want: addrs.Provider{ - Hostname: addrs.DefaultRegistryHost, - Namespace: "awesomecorp", - Type: "happycloud", - }, - }, - { - Addr: addrs.Resource{ - Mode: addrs.DataResourceMode, - Type: "terraform_remote_state", - Name: "baz", - }.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance), - Config: &configs.Resource{ - // Just enough configs.Resource for the Provider method. Not - // actually valid for general use. - Provider: addrs.Provider{ - Hostname: addrs.DefaultRegistryHost, - Namespace: "awesomecorp", - Type: "happycloud", - }, - }, - // The config overrides the default behavior. - Want: addrs.Provider{ - Hostname: addrs.DefaultRegistryHost, - Namespace: "awesomecorp", - Type: "happycloud", - }, - }, - } - - for _, test := range tests { - var name string - if test.Config != nil { - name = fmt.Sprintf("%s with configured %s", test.Addr, test.Config.Provider) - } else { - name = fmt.Sprintf("%s with no configuration", test.Addr) - } - t.Run(name, func(t *testing.T) { - node := &NodeAbstractResourceInstance{ - // Just enough NodeAbstractResourceInstance for the Provider - // function. (This would not be valid for some other functions.) - Addr: test.Addr, - NodeAbstractResource: NodeAbstractResource{ - Config: test.Config, - }, - } - got := node.Provider() - if got != test.Want { - t.Errorf("wrong result\naddr: %s\nconfig: %#v\ngot: %s\nwant: %s", test.Addr, test.Config, got, test.Want) - } - }) - } -} diff --git a/terraform/node_resource_apply.go b/terraform/node_resource_apply.go index 44ef6d509..1994563fa 100644 --- a/terraform/node_resource_apply.go +++ b/terraform/node_resource_apply.go @@ -108,6 +108,6 @@ func (n *NodeApplyableResource) Execute(ctx EvalContext, op walkOperation) error return nil } - err := n.WriteResourceState(ctx, n.Addr) + err := n.writeResourceState(ctx, n.Addr) return err } diff --git a/terraform/node_resource_apply_instance.go b/terraform/node_resource_apply_instance.go index 7ead676b1..0c77cd4e8 100644 --- a/terraform/node_resource_apply_instance.go +++ b/terraform/node_resource_apply_instance.go @@ -141,7 +141,7 @@ func (n *NodeApplyableResourceInstance) dataResourceExecute(ctx EvalContext) err return err } - change, err := n.ReadDiff(ctx, providerSchema) + change, err := n.readDiff(ctx, providerSchema) if err != nil { return err } @@ -211,7 +211,7 @@ func (n *NodeApplyableResourceInstance) managedResourceExecute(ctx EvalContext) } // Get the saved diff for apply - diffApply, err := n.ReadDiff(ctx, providerSchema) + diffApply, err := n.readDiff(ctx, providerSchema) if err != nil { return err } @@ -255,7 +255,7 @@ func (n *NodeApplyableResourceInstance) managedResourceExecute(ctx EvalContext) } // Get the saved diff - diff, err := n.ReadDiff(ctx, providerSchema) + diff, err := n.readDiff(ctx, providerSchema) if err != nil { return err } diff --git a/terraform/node_resource_destroy.go b/terraform/node_resource_destroy.go index d07b2c2e9..c54bc0cec 100644 --- a/terraform/node_resource_destroy.go +++ b/terraform/node_resource_destroy.go @@ -143,7 +143,7 @@ func (n *NodeDestroyResourceInstance) Execute(ctx EvalContext, op walkOperation) return err } - changeApply, err = n.ReadDiff(ctx, providerSchema) + changeApply, err = n.readDiff(ctx, providerSchema) if err != nil { return err } diff --git a/terraform/node_resource_plan.go b/terraform/node_resource_plan.go index 13bd1c65b..466c3a87d 100644 --- a/terraform/node_resource_plan.go +++ b/terraform/node_resource_plan.go @@ -185,7 +185,7 @@ func (n *NodePlannableResource) Execute(ctx EvalContext, op walkOperation) error return nil } - err := n.WriteResourceState(ctx, n.Addr) + err := n.writeResourceState(ctx, n.Addr) return err }