terraform: use addrs.Provider as map keys for provider schemas (#24002)

This is a stepping-stone PR for the provider source project. In this PR
"legcay-stype" FQNs are created from the provider name string. Future
work involves encoding the FQN directly in the AbsProviderConfig and
removing the calls to addrs.NewLegacyProvider().
This commit is contained in:
Kristin Laemmert 2020-02-03 08:18:04 -05:00 committed by GitHub
parent 3e07ae3ff6
commit 80ab551867
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 87 additions and 63 deletions

View File

@ -262,7 +262,10 @@ func RenderPlan(plan *plans.Plan, state *states.State, schemas *terraform.Schema
if rcs.Action == plans.NoOp { if rcs.Action == plans.NoOp {
continue continue
} }
providerSchema := schemas.ProviderSchema(rcs.ProviderAddr.ProviderConfig.LocalName)
// FIXME: update this once the provider fqn is available in the AbsProviderConfig
providerFqn := addrs.NewLegacyProvider(rcs.ProviderAddr.ProviderConfig.LocalName)
providerSchema := schemas.ProviderSchema(providerFqn)
if providerSchema == nil { if providerSchema == nil {
// Should never happen // Should never happen
ui.Output(fmt.Sprintf("(schema missing for %s)\n", rcs.ProviderAddr)) ui.Output(fmt.Sprintf("(schema missing for %s)\n", rcs.ProviderAddr))

View File

@ -139,7 +139,9 @@ func formatStateModule(p blockBodyDiffPrinter, m *states.Module, schemas *terraf
} }
var schema *configschema.Block var schema *configschema.Block
provider := addrs.NewDefaultLocalProviderConfig(addr.DefaultProvider().LegacyString()).Absolute(m.Addr).ProviderConfig.StringCompact()
// TODO: Get the provider FQN when it is available from the AbsoluteProviderConfig, in state
provider := addr.DefaultProvider()
if _, exists := schemas.Providers[provider]; !exists { if _, exists := schemas.Providers[provider]; !exists {
// This should never happen in normal use because we should've // This should never happen in normal use because we should've
// loaded all of the schemas and checked things prior to this // loaded all of the schemas and checked things prior to this

View File

@ -138,8 +138,8 @@ func testProviderSchema() *terraform.ProviderSchema {
func testSchemas() *terraform.Schemas { func testSchemas() *terraform.Schemas {
provider := testProvider() provider := testProvider()
return &terraform.Schemas{ return &terraform.Schemas{
Providers: map[string]*terraform.ProviderSchema{ Providers: map[addrs.Provider]*terraform.ProviderSchema{
"test": provider.GetSchemaReturn, addrs.NewLegacyProvider("test"): provider.GetSchemaReturn,
}, },
} }
} }

View File

@ -139,7 +139,9 @@ func marshalProviderConfigs(
} }
for k, pc := range c.Module.ProviderConfigs { for k, pc := range c.Module.ProviderConfigs {
schema := schemas.ProviderConfig(pc.Name) // FIXME: lookup providerFqn from config
providerFqn := addrs.NewLegacyProvider(pc.Name)
schema := schemas.ProviderConfig(providerFqn)
p := providerConfig{ p := providerConfig{
Name: pc.Name, Name: pc.Name,
Alias: pc.Alias, Alias: pc.Alias,
@ -301,8 +303,10 @@ func marshalResources(resources map[string]*configs.Resource, schemas *terraform
} }
} }
// TODO: get actual providerFqn
providerFqn := addrs.NewLegacyProvider(v.ProviderConfigAddr().LocalName)
schema, schemaVer := schemas.ResourceTypeConfig( schema, schemaVer := schemas.ResourceTypeConfig(
v.ProviderConfigAddr().LocalName, providerFqn,
v.Mode, v.Mode,
v.Type, v.Type,
) )

View File

@ -177,8 +177,10 @@ func (p *plan) marshalResourceChanges(changes *plans.Changes, schemas *terraform
continue continue
} }
// FIXME: update this once the provider fqn is available in the AbsProviderConfig
providerFqn := addrs.NewLegacyProvider(rc.ProviderAddr.ProviderConfig.LocalName)
schema, _ := schemas.ResourceTypeConfig( schema, _ := schemas.ResourceTypeConfig(
rc.ProviderAddr.ProviderConfig.LocalName, providerFqn,
addr.Resource.Resource.Mode, addr.Resource.Resource.Mode,
addr.Resource.Resource.Type, addr.Resource.Resource.Type,
) )

View File

@ -180,8 +180,10 @@ func marshalPlanResources(changes *plans.Changes, ris []addrs.AbsResourceInstanc
) )
} }
// FIXME: update this once the provider fqn is available in the AbsProviderConfig
providerFqn := addrs.NewLegacyProvider(r.ProviderAddr.ProviderConfig.LocalName)
schema, schemaVer := schemas.ResourceTypeConfig( schema, schemaVer := schemas.ResourceTypeConfig(
r.ProviderAddr.ProviderConfig.LocalName, providerFqn,
r.Addr.Resource.Resource.Mode, r.Addr.Resource.Resource.Mode,
resource.Type, resource.Type,
) )

View File

@ -290,8 +290,8 @@ func TestMarshalPlanResources(t *testing.T) {
func testSchemas() *terraform.Schemas { func testSchemas() *terraform.Schemas {
return &terraform.Schemas{ return &terraform.Schemas{
Providers: map[string]*terraform.ProviderSchema{ Providers: map[addrs.Provider]*terraform.ProviderSchema{
"test": &terraform.ProviderSchema{ addrs.NewLegacyProvider("test"): &terraform.ProviderSchema{
ResourceTypes: map[string]*configschema.Block{ ResourceTypes: map[string]*configschema.Block{
"test_thing": { "test_thing": {
Attributes: map[string]*configschema.Attribute{ Attributes: map[string]*configschema.Attribute{

View File

@ -35,7 +35,7 @@ func Marshal(s *terraform.Schemas) ([]byte, error) {
providers := newProviders() providers := newProviders()
for k, v := range s.Providers { for k, v := range s.Providers {
providers.Schemas[k] = marshalProvider(v) providers.Schemas[k.LegacyString()] = marshalProvider(v)
} }
ret, err := json.Marshal(providers) ret, err := json.Marshal(providers)

View File

@ -7,6 +7,7 @@ import (
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
"github.com/zclconf/go-cty/cty" "github.com/zclconf/go-cty/cty"
"github.com/hashicorp/terraform/addrs"
"github.com/hashicorp/terraform/configs/configschema" "github.com/hashicorp/terraform/configs/configschema"
"github.com/hashicorp/terraform/terraform" "github.com/hashicorp/terraform/terraform"
) )
@ -117,8 +118,8 @@ func TestMarshalProvider(t *testing.T) {
func testProviders() *terraform.Schemas { func testProviders() *terraform.Schemas {
return &terraform.Schemas{ return &terraform.Schemas{
Providers: map[string]*terraform.ProviderSchema{ Providers: map[addrs.Provider]*terraform.ProviderSchema{
"test": testProvider(), addrs.NewLegacyProvider("test"): testProvider(),
}, },
} }
} }

View File

@ -273,8 +273,10 @@ func marshalResources(resources map[string]*states.Resource, schemas *terraform.
current.Index = k current.Index = k
} }
// FIXME: lookup providerFqn from state
providerFqn := addrs.NewLegacyProvider(r.ProviderConfig.ProviderConfig.LocalName)
schema, _ := schemas.ResourceTypeConfig( schema, _ := schemas.ResourceTypeConfig(
r.ProviderConfig.ProviderConfig.LocalName, providerFqn,
r.Addr.Mode, r.Addr.Mode,
r.Addr.Type, r.Addr.Type,
) )

View File

@ -351,8 +351,8 @@ func TestMarshalResources(t *testing.T) {
func testSchemas() *terraform.Schemas { func testSchemas() *terraform.Schemas {
return &terraform.Schemas{ return &terraform.Schemas{
Providers: map[string]*terraform.ProviderSchema{ Providers: map[addrs.Provider]*terraform.ProviderSchema{
"test": &terraform.ProviderSchema{ addrs.NewLegacyProvider("test"): &terraform.ProviderSchema{
ResourceTypes: map[string]*configschema.Block{ ResourceTypes: map[string]*configschema.Block{
"test_thing": { "test_thing": {
Attributes: map[string]*configschema.Attribute{ Attributes: map[string]*configschema.Attribute{

View File

@ -163,7 +163,7 @@ func (c *Config) DescendentForInstance(path addrs.ModuleInstance) *Config {
return current return current
} }
// ProviderTypes returns the names of each distinct provider type referenced // ProviderTypes returns the FQNs of each distinct provider type referenced
// in the receiving configuration. // in the receiving configuration.
// //
// This is a helper for easily determining which provider types are required // This is a helper for easily determining which provider types are required

View File

@ -96,7 +96,9 @@ func (c *Context) Input(mode InputMode) tfdiags.Diagnostics {
UIInput: c.uiInput, UIInput: c.uiInput,
} }
schema := c.schemas.ProviderConfig(pa.LocalName) // TODO: get provider FQN
providerFqn := addrs.NewLegacyProvider(pa.LocalName)
schema := c.schemas.ProviderConfig(providerFqn)
if schema == nil { if schema == nil {
// Could either be an incorrect config or just an incomplete // Could either be an incorrect config or just an incomplete
// mock in tests. We'll let a later pass decide, and just // mock in tests. We'll let a later pass decide, and just

View File

@ -149,7 +149,7 @@ func (ctx *BuiltinEvalContext) ProviderSchema(addr addrs.AbsProviderConfig) *Pro
// FIXME: Once AbsProviderConfig starts containing an FQN, use that directly // FIXME: Once AbsProviderConfig starts containing an FQN, use that directly
// here instead of addr.ProviderConfig.LocalName. // here instead of addr.ProviderConfig.LocalName.
return ctx.Schemas.ProviderSchema(addr.ProviderConfig.LocalName) return ctx.Schemas.ProviderSchema(addrs.NewLegacyProvider(addr.ProviderConfig.LocalName))
} }
func (ctx *BuiltinEvalContext) CloseProvider(addr addrs.AbsProviderConfig) error { func (ctx *BuiltinEvalContext) CloseProvider(addr addrs.AbsProviderConfig) error {

View File

@ -781,9 +781,9 @@ func (d *evaluationStateData) getResourceInstancesAll(addr addrs.Resource, rng t
func (d *evaluationStateData) getResourceSchema(addr addrs.Resource, providerAddr addrs.AbsProviderConfig) *configschema.Block { func (d *evaluationStateData) getResourceSchema(addr addrs.Resource, providerAddr addrs.AbsProviderConfig) *configschema.Block {
// FIXME: Once AbsProviderConfig has an addrs.Provider in it, we should // FIXME: Once AbsProviderConfig has an addrs.Provider in it, we should
// be looking schemas up using provider FQNs rather than legacy names. // be looking schemas up using provider FQNs rather than legacy names.
providerType := providerAddr.ProviderConfig.LocalName providerFqn := addrs.NewLegacyProvider(providerAddr.ProviderConfig.LocalName)
schemas := d.Evaluator.Schemas schemas := d.Evaluator.Schemas
schema, _ := schemas.ResourceTypeConfig(providerType, addr.Mode, addr.Type) schema, _ := schemas.ResourceTypeConfig(providerFqn, addr.Mode, addr.Type)
return schema return schema
} }

View File

@ -217,8 +217,8 @@ func (d *evaluationStateData) staticValidateResourceReference(modCfg *configs.Co
// legacy addresses. d.Evaluator.Schemas.ResourceTypeConfig below ought to // legacy addresses. d.Evaluator.Schemas.ResourceTypeConfig below ought to
// change to take an addrs.Provider, and then that's what we should be // change to take an addrs.Provider, and then that's what we should be
// passing in here. // passing in here.
providerType := cfg.ProviderConfigAddr().LocalName providerFqn := addrs.NewLegacyProvider(cfg.ProviderConfigAddr().LocalName)
schema, _ := d.Evaluator.Schemas.ResourceTypeConfig(providerType, addr.Mode, addr.Type) schema, _ := d.Evaluator.Schemas.ResourceTypeConfig(providerFqn, addr.Mode, addr.Type)
if schema == nil { if schema == nil {
// Prior validation should've taken care of a resource block with an // Prior validation should've taken care of a resource block with an
@ -227,7 +227,7 @@ func (d *evaluationStateData) staticValidateResourceReference(modCfg *configs.Co
diags = diags.Append(&hcl.Diagnostic{ diags = diags.Append(&hcl.Diagnostic{
Severity: hcl.DiagError, Severity: hcl.DiagError,
Summary: `Invalid resource type`, Summary: `Invalid resource type`,
Detail: fmt.Sprintf(`A %s resource type %q is not supported by provider %q.`, modeAdjective, addr.Type, providerType), Detail: fmt.Sprintf(`A %s resource type %q is not supported by provider %q.`, modeAdjective, addr.Type, providerFqn.LegacyString()),
Subject: rng.ToHCL().Ptr(), Subject: rng.ToHCL().Ptr(),
}) })
return diags return diags

View File

@ -6,6 +6,7 @@ import (
"github.com/hashicorp/hcl/v2" "github.com/hashicorp/hcl/v2"
"github.com/hashicorp/hcl/v2/hclsyntax" "github.com/hashicorp/hcl/v2/hclsyntax"
"github.com/hashicorp/terraform/addrs"
"github.com/hashicorp/terraform/configs/configschema" "github.com/hashicorp/terraform/configs/configschema"
"github.com/hashicorp/terraform/lang" "github.com/hashicorp/terraform/lang"
) )
@ -55,8 +56,8 @@ For example, to correlate with indices of a referring resource, use:
evaluator := &Evaluator{ evaluator := &Evaluator{
Config: cfg, Config: cfg,
Schemas: &Schemas{ Schemas: &Schemas{
Providers: map[string]*ProviderSchema{ Providers: map[addrs.Provider]*ProviderSchema{
"aws": { addrs.NewLegacyProvider("aws"): {
ResourceTypes: map[string]*configschema.Block{ ResourceTypes: map[string]*configschema.Block{
"aws_instance": {}, "aws_instance": {},
}, },

View File

@ -500,7 +500,7 @@ func TestApplyGraphBuilder_targetModule(t *testing.T) {
// that resource is destroyed. // that resource is destroyed.
func TestApplyGraphBuilder_updateFromOrphan(t *testing.T) { func TestApplyGraphBuilder_updateFromOrphan(t *testing.T) {
schemas := simpleTestSchemas() schemas := simpleTestSchemas()
instanceSchema := schemas.Providers["test"].ResourceTypes["test_object"] instanceSchema := schemas.Providers[addrs.NewLegacyProvider("test")].ResourceTypes["test_object"]
bBefore, _ := plans.NewDynamicValue( bBefore, _ := plans.NewDynamicValue(
cty.ObjectVal(map[string]cty.Value{ cty.ObjectVal(map[string]cty.Value{

View File

@ -44,9 +44,9 @@ func TestPlanGraphBuilder(t *testing.T) {
Config: testModule(t, "graph-builder-plan-basic"), Config: testModule(t, "graph-builder-plan-basic"),
Components: components, Components: components,
Schemas: &Schemas{ Schemas: &Schemas{
Providers: map[string]*ProviderSchema{ Providers: map[addrs.Provider]*ProviderSchema{
"aws": awsProvider.GetSchemaReturn, addrs.NewLegacyProvider("aws"): awsProvider.GetSchemaReturn,
"openstack": openstackProvider.GetSchemaReturn, addrs.NewLegacyProvider("openstack"): openstackProvider.GetSchemaReturn,
}, },
}, },
DisableReduce: true, DisableReduce: true,
@ -101,8 +101,8 @@ func TestPlanGraphBuilder_dynamicBlock(t *testing.T) {
Config: testModule(t, "graph-builder-plan-dynblock"), Config: testModule(t, "graph-builder-plan-dynblock"),
Components: components, Components: components,
Schemas: &Schemas{ Schemas: &Schemas{
Providers: map[string]*ProviderSchema{ Providers: map[addrs.Provider]*ProviderSchema{
"test": provider.GetSchemaReturn, addrs.NewLegacyProvider("test"): provider.GetSchemaReturn,
}, },
}, },
DisableReduce: true, DisableReduce: true,
@ -180,8 +180,8 @@ func TestPlanGraphBuilder_attrAsBlocks(t *testing.T) {
Config: testModule(t, "graph-builder-plan-attr-as-blocks"), Config: testModule(t, "graph-builder-plan-attr-as-blocks"),
Components: components, Components: components,
Schemas: &Schemas{ Schemas: &Schemas{
Providers: map[string]*ProviderSchema{ Providers: map[addrs.Provider]*ProviderSchema{
"test": provider.GetSchemaReturn, addrs.NewLegacyProvider("test"): provider.GetSchemaReturn,
}, },
}, },
DisableReduce: true, DisableReduce: true,
@ -267,8 +267,8 @@ func TestPlanGraphBuilder_forEach(t *testing.T) {
Config: testModule(t, "plan-for-each"), Config: testModule(t, "plan-for-each"),
Components: components, Components: components,
Schemas: &Schemas{ Schemas: &Schemas{
Providers: map[string]*ProviderSchema{ Providers: map[addrs.Provider]*ProviderSchema{
"aws": awsProvider.GetSchemaReturn, addrs.NewLegacyProvider("aws"): awsProvider.GetSchemaReturn,
}, },
}, },
DisableReduce: true, DisableReduce: true,

View File

@ -15,7 +15,7 @@ import (
// Schemas is a container for various kinds of schema that Terraform needs // Schemas is a container for various kinds of schema that Terraform needs
// during processing. // during processing.
type Schemas struct { type Schemas struct {
Providers map[string]*ProviderSchema Providers map[addrs.Provider]*ProviderSchema
Provisioners map[string]*configschema.Block Provisioners map[string]*configschema.Block
} }
@ -24,17 +24,17 @@ type Schemas struct {
// //
// It's usually better to go use the more precise methods offered by type // It's usually better to go use the more precise methods offered by type
// Schemas to handle this detail automatically. // Schemas to handle this detail automatically.
func (ss *Schemas) ProviderSchema(typeName string) *ProviderSchema { func (ss *Schemas) ProviderSchema(provider addrs.Provider) *ProviderSchema {
if ss.Providers == nil { if ss.Providers == nil {
return nil return nil
} }
return ss.Providers[typeName] return ss.Providers[provider]
} }
// ProviderConfig returns the schema for the provider configuration of the // ProviderConfig returns the schema for the provider configuration of the
// given provider type, or nil if no such schema is available. // given provider type, or nil if no such schema is available.
func (ss *Schemas) ProviderConfig(typeName string) *configschema.Block { func (ss *Schemas) ProviderConfig(provider addrs.Provider) *configschema.Block {
ps := ss.ProviderSchema(typeName) ps := ss.ProviderSchema(provider)
if ps == nil { if ps == nil {
return nil return nil
} }
@ -50,8 +50,8 @@ func (ss *Schemas) ProviderConfig(typeName string) *configschema.Block {
// a resource using the "provider" meta-argument. Therefore it's important to // a resource using the "provider" meta-argument. Therefore it's important to
// always pass the correct provider name, even though it many cases it feels // always pass the correct provider name, even though it many cases it feels
// redundant. // redundant.
func (ss *Schemas) ResourceTypeConfig(providerType string, resourceMode addrs.ResourceMode, resourceType string) (block *configschema.Block, schemaVersion uint64) { func (ss *Schemas) ResourceTypeConfig(provider addrs.Provider, resourceMode addrs.ResourceMode, resourceType string) (block *configschema.Block, schemaVersion uint64) {
ps := ss.ProviderSchema(providerType) ps := ss.ProviderSchema(provider)
if ps == nil || ps.ResourceTypes == nil { if ps == nil || ps.ResourceTypes == nil {
return nil, 0 return nil, 0
} }
@ -76,7 +76,7 @@ func (ss *Schemas) ProvisionerConfig(name string) *configschema.Block {
// still valid but may be incomplete. // still valid but may be incomplete.
func LoadSchemas(config *configs.Config, state *states.State, components contextComponentFactory) (*Schemas, error) { func LoadSchemas(config *configs.Config, state *states.State, components contextComponentFactory) (*Schemas, error) {
schemas := &Schemas{ schemas := &Schemas{
Providers: map[string]*ProviderSchema{}, Providers: map[addrs.Provider]*ProviderSchema{},
Provisioners: map[string]*configschema.Block{}, Provisioners: map[string]*configschema.Block{},
} }
var diags tfdiags.Diagnostics var diags tfdiags.Diagnostics
@ -89,16 +89,14 @@ func LoadSchemas(config *configs.Config, state *states.State, components context
return schemas, diags.Err() return schemas, diags.Err()
} }
func loadProviderSchemas(schemas map[string]*ProviderSchema, config *configs.Config, state *states.State, components contextComponentFactory) tfdiags.Diagnostics { func loadProviderSchemas(schemas map[addrs.Provider]*ProviderSchema, config *configs.Config, state *states.State, components contextComponentFactory) tfdiags.Diagnostics {
var diags tfdiags.Diagnostics var diags tfdiags.Diagnostics
ensure := func(typeAddr addrs.Provider) { ensure := func(fqn addrs.Provider) {
// FIXME: Once schema lookup is ready to look up by addrs.Provider rather // TODO: LegacyString() will be removed in an upcoming release
// than legacy name, we'll use typeAddr directly. For now, we support typeName := fqn.LegacyString()
// only legacy addresses.
typeName := typeAddr.LegacyString()
if _, exists := schemas[typeName]; exists { if _, exists := schemas[fqn]; exists {
return return
} }
@ -107,7 +105,7 @@ func loadProviderSchemas(schemas map[string]*ProviderSchema, config *configs.Con
if err != nil { if err != nil {
// We'll put a stub in the map so we won't re-attempt this on // We'll put a stub in the map so we won't re-attempt this on
// future calls. // future calls.
schemas[typeName] = &ProviderSchema{} schemas[fqn] = &ProviderSchema{}
diags = diags.Append( diags = diags.Append(
fmt.Errorf("Failed to instantiate provider %q to obtain schema: %s", typeName, err), fmt.Errorf("Failed to instantiate provider %q to obtain schema: %s", typeName, err),
) )
@ -121,7 +119,7 @@ func loadProviderSchemas(schemas map[string]*ProviderSchema, config *configs.Con
if resp.Diagnostics.HasErrors() { if resp.Diagnostics.HasErrors() {
// We'll put a stub in the map so we won't re-attempt this on // We'll put a stub in the map so we won't re-attempt this on
// future calls. // future calls.
schemas[typeName] = &ProviderSchema{} schemas[fqn] = &ProviderSchema{}
diags = diags.Append( diags = diags.Append(
fmt.Errorf("Failed to retrieve schema from provider %q: %s", typeName, resp.Diagnostics.Err()), fmt.Errorf("Failed to retrieve schema from provider %q: %s", typeName, resp.Diagnostics.Err()),
) )
@ -165,12 +163,12 @@ func loadProviderSchemas(schemas map[string]*ProviderSchema, config *configs.Con
} }
} }
schemas[typeName] = s schemas[fqn] = s
} }
if config != nil { if config != nil {
for _, typeName := range config.ProviderTypes() { for _, fqn := range config.ProviderTypes() {
ensure(typeName) ensure(fqn)
} }
} }

View File

@ -1,6 +1,7 @@
package terraform package terraform
import ( import (
"github.com/hashicorp/terraform/addrs"
"github.com/hashicorp/terraform/configs/configschema" "github.com/hashicorp/terraform/configs/configschema"
) )
@ -8,8 +9,8 @@ func simpleTestSchemas() *Schemas {
provider := simpleMockProvider() provider := simpleMockProvider()
provisioner := simpleMockProvisioner() provisioner := simpleMockProvisioner()
return &Schemas{ return &Schemas{
Providers: map[string]*ProviderSchema{ Providers: map[addrs.Provider]*ProviderSchema{
"test": provider.GetSchemaReturn, addrs.NewLegacyProvider("test"): provider.GetSchemaReturn,
}, },
Provisioners: map[string]*configschema.Block{ Provisioners: map[string]*configschema.Block{
"test": provisioner.GetSchemaResponse.Provisioner, "test": provisioner.GetSchemaResponse.Provisioner,

View File

@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"log" "log"
"github.com/hashicorp/terraform/addrs"
"github.com/hashicorp/terraform/configs/configschema" "github.com/hashicorp/terraform/configs/configschema"
"github.com/hashicorp/terraform/dag" "github.com/hashicorp/terraform/dag"
) )
@ -59,9 +60,11 @@ func (t *AttachSchemaTransformer) Transform(g *Graph) error {
mode := addr.Resource.Mode mode := addr.Resource.Mode
typeName := addr.Resource.Type typeName := addr.Resource.Type
providerAddr, _ := tv.ProvidedBy() providerAddr, _ := tv.ProvidedBy()
providerType := providerAddr.ProviderConfig.LocalName
schema, version := t.Schemas.ResourceTypeConfig(providerType, mode, typeName) // TODO: get providerFQN directly from AbsProviderConfig
providerFqn := addrs.NewLegacyProvider(providerAddr.ProviderConfig.LocalName)
schema, version := t.Schemas.ResourceTypeConfig(providerFqn, mode, typeName)
if schema == nil { if schema == nil {
log.Printf("[ERROR] AttachSchemaTransformer: No resource schema available for %s", addr) log.Printf("[ERROR] AttachSchemaTransformer: No resource schema available for %s", addr)
continue continue
@ -72,7 +75,10 @@ func (t *AttachSchemaTransformer) Transform(g *Graph) error {
if tv, ok := v.(GraphNodeAttachProviderConfigSchema); ok { if tv, ok := v.(GraphNodeAttachProviderConfigSchema); ok {
providerAddr := tv.ProviderAddr() providerAddr := tv.ProviderAddr()
schema := t.Schemas.ProviderConfig(providerAddr.ProviderConfig.LocalName) // TODO: get providerFQN directly from AbsProviderConfig
providerFqn := addrs.NewLegacyProvider(providerAddr.ProviderConfig.LocalName)
schema := t.Schemas.ProviderConfig(providerFqn)
if schema == nil { if schema == nil {
log.Printf("[ERROR] AttachSchemaTransformer: No provider config schema available for %s", providerAddr) log.Printf("[ERROR] AttachSchemaTransformer: No provider config schema available for %s", providerAddr)
continue continue

View File

@ -31,8 +31,8 @@ func TestTransitiveReductionTransformer(t *testing.T) {
{ {
transform := &AttachSchemaTransformer{ transform := &AttachSchemaTransformer{
Schemas: &Schemas{ Schemas: &Schemas{
Providers: map[string]*ProviderSchema{ Providers: map[addrs.Provider]*ProviderSchema{
"aws": { addrs.NewLegacyProvider("aws"): {
ResourceTypes: map[string]*configschema.Block{ ResourceTypes: map[string]*configschema.Block{
"aws_instance": &configschema.Block{ "aws_instance": &configschema.Block{
Attributes: map[string]*configschema.Attribute{ Attributes: map[string]*configschema.Attribute{