From 7d14463660bf3fe8dd7c75d9db7adfc5f93bfd48 Mon Sep 17 00:00:00 2001 From: Paddy Carver Date: Mon, 13 Jan 2020 02:13:22 -0800 Subject: [PATCH] Update in response to review. So thanks to review, we have a few changes all rolled up in one here, to account for a design change. First, the codebase has marched on while we wrote this, meaning we need to refer to providers as addrs.Provider, not as strings. This is for the best, but is a lot of replacing through the codebase. Second, some methods were missing from the provider-side GRPC implementations, so we added those. Third, it turns out that attaching the meta configs to resources in transform_provider wouldn't actually work, because resources aren't guaranteed to be in the same module as the provider config powering them. So we need to attach them in transform_attach_config_resource, not in transform_provider, so they'll be on the right side of the module boundary. Unfortunately, this means we're going to have to stop passing around the provider's provider_meta specifically, and are going to have to pass the entire block, because we don't have the provider data we need when we attach the config to filter out just what we need. We now separate them out in the Eval methods. This, unfortunately, also causes us issues, because we don't have that info already when we call EvalValidate, which means we're either going to need to pipe new info through to it, or we're not going to be able to validate the schema pre-plan-time. There's still a recommendation for an end-to-end test to do, but I'm hopeful. --- configs/module.go | 9 +++-- helper/plugin/grpc_provider.go | 20 ++++++++++ terraform/context_apply_test.go | 6 +-- terraform/eval_apply.go | 38 +++++++++--------- terraform/eval_diff.go | 34 ++++++++-------- terraform/eval_read_data.go | 34 ++++++++-------- terraform/eval_refresh.go | 40 ++++++++++--------- terraform/eval_validate.go | 35 +++++++++------- terraform/node_data_refresh.go | 17 ++++---- terraform/node_resource_abstract.go | 35 ++++++++-------- terraform/node_resource_apply_instance.go | 6 +-- terraform/node_resource_destroy.go | 2 +- terraform/node_resource_destroy_deposed.go | 2 +- terraform/node_resource_plan.go | 4 +- terraform/node_resource_plan_instance.go | 4 +- terraform/node_resource_refresh.go | 4 +- terraform/node_resource_validate.go | 2 +- .../transform_attach_config_provider_meta.go | 3 +- terraform/transform_attach_config_resource.go | 36 +++++++++++++++++ terraform/transform_provider.go | 21 ---------- 20 files changed, 203 insertions(+), 149 deletions(-) diff --git a/configs/module.go b/configs/module.go index 159cdfdca9..ac98d0ee2b 100644 --- a/configs/module.go +++ b/configs/module.go @@ -31,7 +31,7 @@ type Module struct { Backend *Backend ProviderConfigs map[string]*Provider ProviderRequirements map[string][]VersionConstraint - ProviderMetas map[string]*ProviderMeta + ProviderMetas map[addrs.Provider]*ProviderMeta Variables map[string]*Variable Locals map[string]*Local @@ -93,7 +93,7 @@ func NewModule(primaryFiles, overrideFiles []*File) (*Module, hcl.Diagnostics) { ModuleCalls: map[string]*ModuleCall{}, ManagedResources: map[string]*Resource{}, DataResources: map[string]*Resource{}, - ProviderMetas: map[string]*ProviderMeta{}, + ProviderMetas: map[addrs.Provider]*ProviderMeta{}, } for _, file := range primaryFiles { @@ -178,7 +178,8 @@ func (m *Module) appendFile(file *File) hcl.Diagnostics { } for _, pm := range file.ProviderMetas { - if existing, exists := m.ProviderMetas[pm.Provider]; exists { + // TODO(paddy): pm.Provider is a string, but we need to build an addrs.Provider out of it somehow + if existing, exists := m.ProviderMetas[addrs.NewLegacyProvider(pm.Provider)]; exists { diags = append(diags, &hcl.Diagnostic{ Severity: hcl.DiagError, Summary: "Duplicate provider_meta block", @@ -186,7 +187,7 @@ func (m *Module) appendFile(file *File) hcl.Diagnostics { Subject: &pm.DeclRange, }) } - m.ProviderMetas[pm.Provider] = pm + m.ProviderMetas[addrs.NewLegacyProvider(pm.Provider)] = pm } for _, v := range file.Variables { diff --git a/helper/plugin/grpc_provider.go b/helper/plugin/grpc_provider.go index 60fd7412c4..06ebaf4214 100644 --- a/helper/plugin/grpc_provider.go +++ b/helper/plugin/grpc_provider.go @@ -530,6 +530,16 @@ func (s *GRPCProviderServer) ReadResource(_ context.Context, req *proto.ReadReso } instanceState.Meta = private + pmSchemaBlock := s.getProviderMetaSchemaBlock() + if pmSchemaBlock != nil && req.ProviderMeta != nil { + providerSchemaVal, err := msgpack.Unmarshal(req.ProviderMeta.Msgpack, pmSchemaBlock.ImpliedType()) + if err != nil { + resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, err) + return resp, nil + } + instanceState.ProviderMeta = providerSchemaVal + } + newInstanceState, err := res.RefreshWithoutUpgrade(instanceState, s.provider.Meta()) if err != nil { resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, err) @@ -629,6 +639,16 @@ func (s *GRPCProviderServer) PlanResourceChange(_ context.Context, req *proto.Pl priorState.Meta = priorPrivate + pmSchemaBlock := s.getProviderMetaSchemaBlock() + if pmSchemaBlock != nil && req.ProviderMeta != nil { + providerSchemaVal, err := msgpack.Unmarshal(req.ProviderMeta.Msgpack, pmSchemaBlock.ImpliedType()) + if err != nil { + resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, err) + return resp, nil + } + priorState.ProviderMeta = providerSchemaVal + } + // Ensure there are no nulls that will cause helper/schema to panic. if err := validateConfigNulls(proposedNewStateVal, nil); err != nil { resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, err) diff --git a/terraform/context_apply_test.go b/terraform/context_apply_test.go index ed8b1c55bb..f3db68ce7d 100644 --- a/terraform/context_apply_test.go +++ b/terraform/context_apply_test.go @@ -11862,13 +11862,13 @@ func TestContext2Apply_ProviderMeta_refreshdata_set(t *testing.T) { }), } - _, diags := ctx.Refresh() + _, diags := ctx.Plan() assertNoErrors(t, diags) - _, diags = ctx.Plan() + _, diags = ctx.Apply() assertNoErrors(t, diags) - _, diags = ctx.Apply() + _, diags = ctx.Refresh() assertNoErrors(t, diags) if !p.ReadDataSourceCalled { diff --git a/terraform/eval_apply.go b/terraform/eval_apply.go index cacb38a1b3..f7fa331212 100644 --- a/terraform/eval_apply.go +++ b/terraform/eval_apply.go @@ -28,7 +28,7 @@ type EvalApply struct { Change **plans.ResourceInstanceChange ProviderAddr addrs.AbsProviderConfig Provider *providers.Interface - ProviderMeta *configs.ProviderMeta + ProviderMetas map[addrs.Provider]*configs.ProviderMeta ProviderSchema **ProviderSchema Output **states.ResourceInstanceObject CreateNew *bool @@ -78,24 +78,26 @@ func (n *EvalApply) Eval(ctx EvalContext) (interface{}, error) { } metaConfigVal := cty.NullVal(cty.DynamicPseudoType) - if n.ProviderMeta != nil { + if n.ProviderMetas != nil { log.Printf("[DEBUG] EvalApply: ProviderMeta config value set") - // if the provider doesn't support this feature, throw an error - if (*n.ProviderSchema).ProviderMeta == nil { - log.Printf("[DEBUG] EvalApply: no ProviderMeta schema") - diags = diags.Append(&hcl.Diagnostic{ - Severity: hcl.DiagError, - Summary: fmt.Sprintf("Provider %s doesn't support provider_meta", (*n.Config).ProviderConfigAddr()), - Detail: fmt.Sprintf("The resource %s belongs to a provider that doesn't support provider_meta blocks", n.Addr), - Subject: &n.ProviderMeta.ProviderRange, - }) - } else { - log.Printf("[DEBUG] EvalApply: ProviderMeta schema found") - var configDiags tfdiags.Diagnostics - metaConfigVal, _, configDiags = ctx.EvaluateBlock(n.ProviderMeta.Config, (*n.ProviderSchema).ProviderMeta, nil, EvalDataForNoInstanceKey) - diags = diags.Append(configDiags) - if configDiags.HasErrors() { - return nil, diags.Err() + if m, ok := n.ProviderMetas[n.ProviderAddr.ProviderConfig.Type]; ok && m != nil { + // if the provider doesn't support this feature, throw an error + if (*n.ProviderSchema).ProviderMeta == nil { + log.Printf("[DEBUG] EvalApply: no ProviderMeta schema") + diags = diags.Append(&hcl.Diagnostic{ + Severity: hcl.DiagError, + Summary: fmt.Sprintf("Provider %s doesn't support provider_meta", (*n.Config).ProviderConfigAddr()), + Detail: fmt.Sprintf("The resource %s belongs to a provider that doesn't support provider_meta blocks", n.Addr), + Subject: &m.ProviderRange, + }) + } else { + log.Printf("[DEBUG] EvalApply: ProviderMeta schema found") + var configDiags tfdiags.Diagnostics + metaConfigVal, _, configDiags = ctx.EvaluateBlock(m.Config, (*n.ProviderSchema).ProviderMeta, nil, EvalDataForNoInstanceKey) + diags = diags.Append(configDiags) + if configDiags.HasErrors() { + return nil, diags.Err() + } } } } diff --git a/terraform/eval_diff.go b/terraform/eval_diff.go index 29c00596b0..15a56b7afd 100644 --- a/terraform/eval_diff.go +++ b/terraform/eval_diff.go @@ -93,7 +93,7 @@ type EvalDiff struct { Config *configs.Resource Provider *providers.Interface ProviderAddr addrs.AbsProviderConfig - ProviderMeta *configs.ProviderMeta + ProviderMetas map[addrs.Provider]*configs.ProviderMeta ProviderSchema **ProviderSchema State **states.ResourceInstanceObject PreviousDiff **plans.ResourceInstanceChange @@ -142,21 +142,23 @@ func (n *EvalDiff) Eval(ctx EvalContext) (interface{}, error) { } metaConfigVal := cty.NullVal(cty.DynamicPseudoType) - if n.ProviderMeta != nil { - // if the provider doesn't support this feature, throw an error - if (*n.ProviderSchema).ProviderMeta == nil { - diags = diags.Append(&hcl.Diagnostic{ - Severity: hcl.DiagError, - Summary: fmt.Sprintf("Provider %s doesn't support provider_meta", (*n.Config).ProviderConfigAddr().StringCompact()), - Detail: fmt.Sprintf("The resource %s belongs to a provider that doesn't support provider_meta blocks", n.Addr), - Subject: &n.ProviderMeta.ProviderRange, - }) - } else { - var configDiags tfdiags.Diagnostics - metaConfigVal, _, configDiags = ctx.EvaluateBlock(n.ProviderMeta.Config, (*n.ProviderSchema).ProviderMeta, nil, EvalDataForNoInstanceKey) - diags = diags.Append(configDiags) - if configDiags.HasErrors() { - return nil, diags.Err() + if n.ProviderMetas != nil { + if m, ok := n.ProviderMetas[n.ProviderAddr.ProviderConfig.Type]; ok && m != nil { + // if the provider doesn't support this feature, throw an error + if (*n.ProviderSchema).ProviderMeta == nil { + diags = diags.Append(&hcl.Diagnostic{ + Severity: hcl.DiagError, + Summary: fmt.Sprintf("Provider %s doesn't support provider_meta", (*n.Config).ProviderConfigAddr().StringCompact()), + Detail: fmt.Sprintf("The resource %s belongs to a provider that doesn't support provider_meta blocks", n.Addr), + Subject: &m.ProviderRange, + }) + } else { + var configDiags tfdiags.Diagnostics + metaConfigVal, _, configDiags = ctx.EvaluateBlock(m.Config, (*n.ProviderSchema).ProviderMeta, nil, EvalDataForNoInstanceKey) + diags = diags.Append(configDiags) + if configDiags.HasErrors() { + return nil, diags.Err() + } } } } diff --git a/terraform/eval_read_data.go b/terraform/eval_read_data.go index 4ce2daf40d..7567ba496d 100644 --- a/terraform/eval_read_data.go +++ b/terraform/eval_read_data.go @@ -24,7 +24,7 @@ type EvalReadData struct { Config *configs.Resource Provider *providers.Interface ProviderAddr addrs.AbsProviderConfig - ProviderMeta *configs.ProviderMeta + ProviderMetas map[addrs.Provider]*configs.ProviderMeta ProviderSchema **ProviderSchema // Planned is set when dealing with data resources that were deferred to @@ -107,21 +107,23 @@ func (n *EvalReadData) Eval(ctx EvalContext) (interface{}, error) { } metaConfigVal := cty.NullVal(cty.DynamicPseudoType) - if n.ProviderMeta != nil { - // if the provider doesn't support this feature, throw an error - if (*n.ProviderSchema).ProviderMeta == nil { - diags = diags.Append(&hcl.Diagnostic{ - Severity: hcl.DiagError, - Summary: fmt.Sprintf("Provider %s doesn't support provider_meta", (*n.Config).ProviderConfigAddr().StringCompact()), - Detail: fmt.Sprintf("The resource %s belongs to a provider that doesn't support provider_meta blocks", n.Addr), - Subject: &n.ProviderMeta.ProviderRange, - }) - } else { - var configDiags tfdiags.Diagnostics - metaConfigVal, _, configDiags = ctx.EvaluateBlock(n.ProviderMeta.Config, (*n.ProviderSchema).ProviderMeta, nil, EvalDataForNoInstanceKey) - diags = diags.Append(configDiags) - if configDiags.HasErrors() { - return nil, diags.Err() + if n.ProviderMetas != nil { + if m, ok := n.ProviderMetas[n.ProviderAddr.ProviderConfig.Type]; ok && m != nil { + // if the provider doesn't support this feature, throw an error + if (*n.ProviderSchema).ProviderMeta == nil { + diags = diags.Append(&hcl.Diagnostic{ + Severity: hcl.DiagError, + Summary: fmt.Sprintf("Provider %s doesn't support provider_meta", (*n.Config).ProviderConfigAddr().StringCompact()), + Detail: fmt.Sprintf("The resource %s belongs to a provider that doesn't support provider_meta blocks", n.Addr), + Subject: &m.ProviderRange, + }) + } else { + var configDiags tfdiags.Diagnostics + metaConfigVal, _, configDiags = ctx.EvaluateBlock(m.Config, (*n.ProviderSchema).ProviderMeta, nil, EvalDataForNoInstanceKey) + diags = diags.Append(configDiags) + if configDiags.HasErrors() { + return nil, diags.Err() + } } } } diff --git a/terraform/eval_refresh.go b/terraform/eval_refresh.go index 9927343ab5..e14311307e 100644 --- a/terraform/eval_refresh.go +++ b/terraform/eval_refresh.go @@ -20,7 +20,7 @@ type EvalRefresh struct { Addr addrs.ResourceInstance ProviderAddr addrs.AbsProviderConfig Provider *providers.Interface - ProviderMeta *configs.ProviderMeta + ProviderMetas map[addrs.Provider]*configs.ProviderMeta ProviderSchema **ProviderSchema State **states.ResourceInstanceObject Output **states.ResourceInstanceObject @@ -46,24 +46,26 @@ func (n *EvalRefresh) Eval(ctx EvalContext) (interface{}, error) { } metaConfigVal := cty.NullVal(cty.DynamicPseudoType) - if n.ProviderMeta != nil { - log.Printf("[DEBUG] EvalRefresh: ProviderMeta config value set") - // if the provider doesn't support this feature, throw an error - if (*n.ProviderSchema).ProviderMeta == nil { - log.Printf("[DEBUG] EvalRefresh: no ProviderMeta schema") - diags = diags.Append(&hcl.Diagnostic{ - Severity: hcl.DiagError, - Summary: fmt.Sprintf("Provider %s doesn't support provider_meta", n.ProviderAddr.ProviderConfig.StringCompact()), - Detail: fmt.Sprintf("The resource %s belongs to a provider that doesn't support provider_meta blocks", n.Addr), - Subject: &n.ProviderMeta.ProviderRange, - }) - } else { - log.Printf("[DEBUG] EvalRefresh: ProviderMeta schema found: %+v", (*n.ProviderSchema).ProviderMeta) - var configDiags tfdiags.Diagnostics - metaConfigVal, _, configDiags = ctx.EvaluateBlock(n.ProviderMeta.Config, (*n.ProviderSchema).ProviderMeta, nil, EvalDataForNoInstanceKey) - diags = diags.Append(configDiags) - if configDiags.HasErrors() { - return nil, diags.Err() + if n.ProviderMetas != nil { + if m, ok := n.ProviderMetas[n.ProviderAddr.ProviderConfig.Type]; ok && m != nil { + log.Printf("[DEBUG] EvalRefresh: ProviderMeta config value set") + // if the provider doesn't support this feature, throw an error + if (*n.ProviderSchema).ProviderMeta == nil { + log.Printf("[DEBUG] EvalRefresh: no ProviderMeta schema") + diags = diags.Append(&hcl.Diagnostic{ + Severity: hcl.DiagError, + Summary: fmt.Sprintf("Provider %s doesn't support provider_meta", n.ProviderAddr.ProviderConfig.StringCompact()), + Detail: fmt.Sprintf("The resource %s belongs to a provider that doesn't support provider_meta blocks", n.Addr), + Subject: &m.ProviderRange, + }) + } else { + log.Printf("[DEBUG] EvalRefresh: ProviderMeta schema found: %+v", (*n.ProviderSchema).ProviderMeta) + var configDiags tfdiags.Diagnostics + metaConfigVal, _, configDiags = ctx.EvaluateBlock(m.Config, (*n.ProviderSchema).ProviderMeta, nil, EvalDataForNoInstanceKey) + diags = diags.Append(configDiags) + if configDiags.HasErrors() { + return nil, diags.Err() + } } } } diff --git a/terraform/eval_validate.go b/terraform/eval_validate.go index 06aefc8fa8..49ad8f13b5 100644 --- a/terraform/eval_validate.go +++ b/terraform/eval_validate.go @@ -349,7 +349,7 @@ type EvalValidateResource struct { Provider *providers.Interface ProviderSchema **ProviderSchema Config *configs.Resource - ProviderMeta *configs.ProviderMeta + ProviderMetas map[addrs.Provider]*configs.ProviderMeta // IgnoreWarnings means that warnings will not be passed through. This allows // "just-in-time" passes of validation to continue execution through warnings. @@ -436,20 +436,27 @@ func (n *EvalValidateResource) Eval(ctx EvalContext) (interface{}, error) { // used only in limited cases with heavy coordination with the // Terraform team, so we're going to defer that solution for a future // enhancement to this functionality. - if n.ProviderMeta != nil { - // if the provider doesn't support this feature, throw an error - if (*n.ProviderSchema).ProviderMeta == nil { - diags = diags.Append(&hcl.Diagnostic{ - Severity: hcl.DiagError, - Summary: fmt.Sprintf("Provider %s doesn't support provider_meta", cfg.ProviderConfigAddr()), - Detail: fmt.Sprintf("The resource %s belongs to a provider that doesn't support provider_meta blocks", n.Addr), - Subject: &n.ProviderMeta.ProviderRange, - }) - } else { - _, _, metaDiags := ctx.EvaluateBlock(n.ProviderMeta.Config, (*n.ProviderSchema).ProviderMeta, nil, EvalDataForNoInstanceKey) - diags = diags.Append(metaDiags) + /* + if n.ProviderMetas != nil { + if m, ok := n.ProviderMetas[n.ProviderAddr.ProviderConfig.Type]; ok && m != nil { + // if the provider doesn't support this feature, throw an error + if (*n.ProviderSchema).ProviderMeta == nil { + diags = diags.Append(&hcl.Diagnostic{ + Severity: hcl.DiagError, + Summary: fmt.Sprintf("Provider %s doesn't support provider_meta", cfg.ProviderConfigAddr()), + Detail: fmt.Sprintf("The resource %s belongs to a provider that doesn't support provider_meta blocks", n.Addr), + Subject: &m.ProviderRange, + }) + } else { + _, _, metaDiags := ctx.EvaluateBlock(m.Config, (*n.ProviderSchema).ProviderMeta, nil, EvalDataForNoInstanceKey) + diags = diags.Append(metaDiags) + } + } } - } + */ + // BUG(paddy): we're not validating provider_meta blocks on EvalValidate right now + // because the ProviderAddr for the resource isn't available on the EvalValidate + // struct. // Provider entry point varies depending on resource mode, because // managed resources and data resources are two distinct concepts diff --git a/terraform/node_data_refresh.go b/terraform/node_data_refresh.go index 18edd4d028..89d88c962d 100644 --- a/terraform/node_data_refresh.go +++ b/terraform/node_data_refresh.go @@ -15,12 +15,13 @@ type NodeRefreshableDataResource struct { } var ( - _ GraphNodeSubPath = (*NodeRefreshableDataResource)(nil) - _ GraphNodeDynamicExpandable = (*NodeRefreshableDataResource)(nil) - _ GraphNodeReferenceable = (*NodeRefreshableDataResource)(nil) - _ GraphNodeReferencer = (*NodeRefreshableDataResource)(nil) - _ GraphNodeResource = (*NodeRefreshableDataResource)(nil) - _ GraphNodeAttachResourceConfig = (*NodeRefreshableDataResource)(nil) + _ GraphNodeSubPath = (*NodeRefreshableDataResource)(nil) + _ GraphNodeDynamicExpandable = (*NodeRefreshableDataResource)(nil) + _ GraphNodeReferenceable = (*NodeRefreshableDataResource)(nil) + _ GraphNodeReferencer = (*NodeRefreshableDataResource)(nil) + _ GraphNodeResource = (*NodeRefreshableDataResource)(nil) + _ GraphNodeAttachResourceConfig = (*NodeRefreshableDataResource)(nil) + _ GraphNodeAttachProviderMetaConfigs = (*NodeAbstractResource)(nil) ) // GraphNodeDynamicExpandable @@ -63,7 +64,7 @@ func (n *NodeRefreshableDataResource) DynamicExpand(ctx EvalContext) (*Graph, er // Add the config and state since we don't do that via transforms a.Config = n.Config a.ResolvedProvider = n.ResolvedProvider - a.ProviderMeta = n.ProviderMeta + a.ProviderMetas = n.ProviderMetas return &NodeRefreshableDataResourceInstance{ NodeAbstractResourceInstance: a, @@ -172,7 +173,7 @@ func (n *NodeRefreshableDataResourceInstance) EvalTree() EvalNode { Config: n.Config, Provider: &provider, ProviderAddr: n.ResolvedProvider, - ProviderMeta: n.ProviderMeta, + ProviderMetas: n.ProviderMetas, ProviderSchema: &providerSchema, OutputChange: &change, OutputConfigValue: &configVal, diff --git a/terraform/node_resource_abstract.go b/terraform/node_resource_abstract.go index 7ca4369bc1..c01bf78e76 100644 --- a/terraform/node_resource_abstract.go +++ b/terraform/node_resource_abstract.go @@ -54,8 +54,8 @@ type NodeAbstractResource struct { SchemaVersion uint64 // Schema version of "Schema", as decided by the provider Config *configs.Resource // Config is the resource in the config - // ProviderMeta is the provider_meta config for this resource - ProviderMeta *configs.ProviderMeta + // ProviderMetas is the provider_meta configs for the module this resource belongs to + ProviderMetas map[addrs.Provider]*configs.ProviderMeta ProvisionerSchemas map[string]*configschema.Block @@ -105,19 +105,20 @@ type NodeAbstractResourceInstance struct { } var ( - _ GraphNodeSubPath = (*NodeAbstractResourceInstance)(nil) - _ GraphNodeReferenceable = (*NodeAbstractResourceInstance)(nil) - _ GraphNodeReferencer = (*NodeAbstractResourceInstance)(nil) - _ GraphNodeProviderConsumer = (*NodeAbstractResourceInstance)(nil) - _ GraphNodeProvisionerConsumer = (*NodeAbstractResourceInstance)(nil) - _ GraphNodeResource = (*NodeAbstractResourceInstance)(nil) - _ GraphNodeResourceInstance = (*NodeAbstractResourceInstance)(nil) - _ GraphNodeAttachResourceState = (*NodeAbstractResourceInstance)(nil) - _ GraphNodeAttachResourceConfig = (*NodeAbstractResourceInstance)(nil) - _ GraphNodeAttachResourceSchema = (*NodeAbstractResourceInstance)(nil) - _ GraphNodeAttachProvisionerSchema = (*NodeAbstractResourceInstance)(nil) - _ GraphNodeTargetable = (*NodeAbstractResourceInstance)(nil) - _ dag.GraphNodeDotter = (*NodeAbstractResourceInstance)(nil) + _ GraphNodeSubPath = (*NodeAbstractResourceInstance)(nil) + _ GraphNodeReferenceable = (*NodeAbstractResourceInstance)(nil) + _ GraphNodeReferencer = (*NodeAbstractResourceInstance)(nil) + _ GraphNodeProviderConsumer = (*NodeAbstractResourceInstance)(nil) + _ GraphNodeProvisionerConsumer = (*NodeAbstractResourceInstance)(nil) + _ GraphNodeResource = (*NodeAbstractResourceInstance)(nil) + _ GraphNodeResourceInstance = (*NodeAbstractResourceInstance)(nil) + _ GraphNodeAttachResourceState = (*NodeAbstractResourceInstance)(nil) + _ GraphNodeAttachResourceConfig = (*NodeAbstractResourceInstance)(nil) + _ GraphNodeAttachResourceSchema = (*NodeAbstractResourceInstance)(nil) + _ GraphNodeAttachProvisionerSchema = (*NodeAbstractResourceInstance)(nil) + _ GraphNodeAttachProviderMetaConfigs = (*NodeAbstractResourceInstance)(nil) + _ GraphNodeTargetable = (*NodeAbstractResourceInstance)(nil) + _ dag.GraphNodeDotter = (*NodeAbstractResourceInstance)(nil) ) // NewNodeAbstractResourceInstance creates an abstract resource instance graph @@ -414,8 +415,8 @@ func (n *NodeAbstractResource) AttachResourceSchema(schema *configschema.Block, } // GraphNodeAttachProviderMetaConfigs impl -func (n *NodeAbstractResource) AttachProviderMetaConfigs(c *configs.ProviderMeta) { - n.ProviderMeta = c +func (n *NodeAbstractResource) AttachProviderMetaConfigs(c map[addrs.Provider]*configs.ProviderMeta) { + n.ProviderMetas = c } // GraphNodeDotter impl. diff --git a/terraform/node_resource_apply_instance.go b/terraform/node_resource_apply_instance.go index b32144be45..84c1fd1484 100644 --- a/terraform/node_resource_apply_instance.go +++ b/terraform/node_resource_apply_instance.go @@ -180,7 +180,7 @@ func (n *NodeApplyableResourceInstance) evalTreeDataResource(addr addrs.AbsResou Planned: &change, // setting this indicates that the result must be complete Provider: &provider, ProviderAddr: n.ResolvedProvider, - ProviderMeta: n.ProviderMeta, + ProviderMetas: n.ProviderMetas, ProviderSchema: &providerSchema, OutputState: &state, }, @@ -288,7 +288,7 @@ func (n *NodeApplyableResourceInstance) evalTreeManagedResource(addr addrs.AbsRe Config: n.Config, Provider: &provider, ProviderAddr: n.ResolvedProvider, - ProviderMeta: n.ProviderMeta, + ProviderMetas: n.ProviderMetas, ProviderSchema: &providerSchema, State: &state, PreviousDiff: &diff, @@ -352,7 +352,7 @@ func (n *NodeApplyableResourceInstance) evalTreeManagedResource(addr addrs.AbsRe Change: &diffApply, Provider: &provider, ProviderAddr: n.ResolvedProvider, - ProviderMeta: n.ProviderMeta, + ProviderMetas: n.ProviderMetas, ProviderSchema: &providerSchema, Output: &state, Error: &err, diff --git a/terraform/node_resource_destroy.go b/terraform/node_resource_destroy.go index 3d8fa5a246..d4fb952607 100644 --- a/terraform/node_resource_destroy.go +++ b/terraform/node_resource_destroy.go @@ -246,7 +246,7 @@ func (n *NodeDestroyResourceInstance) EvalTree() EvalNode { Change: &changeApply, Provider: &provider, ProviderAddr: n.ResolvedProvider, - ProviderMeta: n.ProviderMeta, + ProviderMetas: n.ProviderMetas, ProviderSchema: &providerSchema, Output: &state, Error: &err, diff --git a/terraform/node_resource_destroy_deposed.go b/terraform/node_resource_destroy_deposed.go index 0ad538cbbe..7afab72bc4 100644 --- a/terraform/node_resource_destroy_deposed.go +++ b/terraform/node_resource_destroy_deposed.go @@ -97,7 +97,7 @@ func (n *NodePlanDeposedResourceInstanceObject) EvalTree() EvalNode { Addr: addr.Resource, ProviderAddr: n.ResolvedProvider, Provider: &provider, - ProviderMeta: n.ProviderMeta, + ProviderMetas: n.ProviderMetas, ProviderSchema: &providerSchema, State: &state, Output: &state, diff --git a/terraform/node_resource_plan.go b/terraform/node_resource_plan.go index 7e3c7c1376..0778818c59 100644 --- a/terraform/node_resource_plan.go +++ b/terraform/node_resource_plan.go @@ -98,7 +98,7 @@ func (n *NodePlannableResource) DynamicExpand(ctx EvalContext) (*Graph, error) { a.ResolvedProvider = n.ResolvedProvider a.Schema = n.Schema a.ProvisionerSchemas = n.ProvisionerSchemas - a.ProviderMeta = n.ProviderMeta + a.ProviderMetas = n.ProviderMetas return &NodePlannableResourceInstance{ NodeAbstractResourceInstance: a, @@ -117,7 +117,7 @@ func (n *NodePlannableResource) DynamicExpand(ctx EvalContext) (*Graph, error) { a.ResolvedProvider = n.ResolvedProvider a.Schema = n.Schema a.ProvisionerSchemas = n.ProvisionerSchemas - a.ProviderMeta = n.ProviderMeta + a.ProviderMetas = n.ProviderMetas return &NodePlannableResourceInstanceOrphan{ NodeAbstractResourceInstance: a, diff --git a/terraform/node_resource_plan_instance.go b/terraform/node_resource_plan_instance.go index 329a639e94..e9a3c60f55 100644 --- a/terraform/node_resource_plan_instance.go +++ b/terraform/node_resource_plan_instance.go @@ -116,7 +116,7 @@ func (n *NodePlannableResourceInstance) evalTreeDataResource(addr addrs.AbsResou Config: n.Config, Provider: &provider, ProviderAddr: n.ResolvedProvider, - ProviderMeta: n.ProviderMeta, + ProviderMetas: n.ProviderMetas, ProviderSchema: &providerSchema, ForcePlanRead: true, // _always_ produce a Read change, even if the config seems ready OutputChange: &change, @@ -175,7 +175,7 @@ func (n *NodePlannableResourceInstance) evalTreeManagedResource(addr addrs.AbsRe CreateBeforeDestroy: n.ForceCreateBeforeDestroy, Provider: &provider, ProviderAddr: n.ResolvedProvider, - ProviderMeta: n.ProviderMeta, + ProviderMetas: n.ProviderMetas, ProviderSchema: &providerSchema, State: &state, OutputChange: &change, diff --git a/terraform/node_resource_refresh.go b/terraform/node_resource_refresh.go index 7693d5854d..e475a124c9 100644 --- a/terraform/node_resource_refresh.go +++ b/terraform/node_resource_refresh.go @@ -69,7 +69,7 @@ func (n *NodeRefreshableManagedResource) DynamicExpand(ctx EvalContext) (*Graph, a.Config = n.Config a.ResolvedProvider = n.ResolvedProvider a.Dependencies = n.Dependencies - a.ProviderMeta = n.ProviderMeta + a.ProviderMetas = n.ProviderMetas return &NodeRefreshableManagedResourceInstance{ NodeAbstractResourceInstance: a, @@ -224,7 +224,7 @@ func (n *NodeRefreshableManagedResourceInstance) evalTreeManagedResource() EvalN Addr: addr.Resource, ProviderAddr: n.ResolvedProvider, Provider: &provider, - ProviderMeta: n.ProviderMeta, + ProviderMetas: n.ProviderMetas, ProviderSchema: &providerSchema, State: &state, Output: &state, diff --git a/terraform/node_resource_validate.go b/terraform/node_resource_validate.go index b0a11c1555..dec63d8df9 100644 --- a/terraform/node_resource_validate.go +++ b/terraform/node_resource_validate.go @@ -46,7 +46,7 @@ func (n *NodeValidatableResource) EvalTree() EvalNode { &EvalValidateResource{ Addr: addr.Resource, Provider: &provider, - ProviderMeta: n.ProviderMeta, + ProviderMetas: n.ProviderMetas, ProviderSchema: &providerSchema, Config: config, ConfigVal: &configVal, diff --git a/terraform/transform_attach_config_provider_meta.go b/terraform/transform_attach_config_provider_meta.go index 6ad3a733c8..9947d120c4 100644 --- a/terraform/transform_attach_config_provider_meta.go +++ b/terraform/transform_attach_config_provider_meta.go @@ -1,6 +1,7 @@ package terraform import ( + "github.com/hashicorp/terraform/addrs" "github.com/hashicorp/terraform/configs" ) @@ -10,5 +11,5 @@ type GraphNodeAttachProviderMetaConfigs interface { GraphNodeResource // Sets the configuration - AttachProviderMetaConfigs(*configs.ProviderMeta) + AttachProviderMetaConfigs(map[addrs.Provider]*configs.ProviderMeta) } diff --git a/terraform/transform_attach_config_resource.go b/terraform/transform_attach_config_resource.go index 03f8564d7e..68c758b80a 100644 --- a/terraform/transform_attach_config_resource.go +++ b/terraform/transform_attach_config_resource.go @@ -56,6 +56,24 @@ func (t *AttachResourceConfigTransformer) Transform(g *Graph) error { log.Printf("[TRACE] AttachResourceConfigTransformer: attaching to %q (%T) config from %s", dag.VertexName(v), v, r.DeclRange) arn.AttachResourceConfig(r) + + // attach the provider_meta info + if gnapmc, ok := v.(GraphNodeAttachProviderMetaConfigs); ok { + log.Printf("[TRACE] AttachResourceConfigTransformer: attaching provider meta configs to %s", dag.VertexName(v)) + if t.Config == nil { + log.Printf("[TRACE] AttachResourceConfigTransformer: no config set on the transformer for %s", dag.VertexName(v)) + continue + } + if t.Config.Module == nil { + log.Printf("[TRACE] AttachResourceConfigTransformer: no module in config for %s", dag.VertexName(v)) + continue + } + if t.Config.Module.ProviderMetas == nil { + log.Printf("[TRACE] AttachResourceConfigTransformer: no provider metas defined for %s", dag.VertexName(v)) + continue + } + gnapmc.AttachProviderMetaConfigs(t.Config.Module.ProviderMetas) + } } for _, r := range config.Module.DataResources { rAddr := r.Addr() @@ -67,6 +85,24 @@ func (t *AttachResourceConfigTransformer) Transform(g *Graph) error { log.Printf("[TRACE] AttachResourceConfigTransformer: attaching to %q (%T) config from %#v", dag.VertexName(v), v, r.DeclRange) arn.AttachResourceConfig(r) + + // attach the provider_meta info + if gnapmc, ok := v.(GraphNodeAttachProviderMetaConfigs); ok { + log.Printf("[TRACE] AttachResourceConfigTransformer: attaching provider meta configs to %s", dag.VertexName(v)) + if t.Config == nil { + log.Printf("[TRACE] AttachResourceConfigTransformer: no config set on the transformer for %s", dag.VertexName(v)) + continue + } + if t.Config.Module == nil { + log.Printf("[TRACE] AttachResourceConfigTransformer: no module in config for %s", dag.VertexName(v)) + continue + } + if t.Config.Module.ProviderMetas == nil { + log.Printf("[TRACE] AttachResourceConfigTransformer: no provider metas defined for %s", dag.VertexName(v)) + continue + } + gnapmc.AttachProviderMetaConfigs(t.Config.Module.ProviderMetas) + } } } diff --git a/terraform/transform_provider.go b/terraform/transform_provider.go index e39585aa8e..8cfb0b5cb5 100644 --- a/terraform/transform_provider.go +++ b/terraform/transform_provider.go @@ -124,27 +124,6 @@ func (t *ProviderTransformer) Transform(g *Graph) error { // Direct references need the provider configured as well as initialized needConfigured[p.String()] = p - - // attach the provider_meta info - if gnapmc, ok := v.(GraphNodeAttachProviderMetaConfigs); ok { - log.Printf("[TRACE] ProviderTransformer: attaching provider meta config for %s to %s", p, dag.VertexName(v)) - if t.Config == nil { - log.Printf("[TRACE] ProviderTransformer: no config set on the transformer for %s", dag.VertexName(v)) - continue - } - if t.Config.Module == nil { - log.Printf("[TRACE] ProviderTransformer: no module in config for %s", dag.VertexName(v)) - continue - } - if t.Config.Module.ProviderMetas == nil { - log.Printf("[TRACE] ProviderTransformer: no provider metas defined for %s", dag.VertexName(v)) - continue - } - // BUG(paddy): we should probably change this to include the host / namespace - if meta, ok := t.Config.Module.ProviderMetas[p.ProviderConfig.Type.Type]; ok { - gnapmc.AttachProviderMetaConfigs(meta) - } - } } }