diff --git a/addrs/provider_config.go b/addrs/provider_config.go index e2e002479..dd2d41a9c 100644 --- a/addrs/provider_config.go +++ b/addrs/provider_config.go @@ -9,61 +9,116 @@ import ( "github.com/hashicorp/hcl/v2/hclsyntax" ) -// ProviderConfig is the address of a provider configuration. -type ProviderConfig struct { - Type string +// ProviderConfig is an interface type whose dynamic type can be either +// LocalProviderConfig or AbsProviderConfig, in order to represent situations +// where a value might either be module-local or absolute but the decision +// cannot be made until runtime. +// +// Where possible, use either LocalProviderConfig or AbsProviderConfig directly +// instead, to make intent more clear. ProviderConfig can be used only in +// situations where the recipient of the value has some out-of-band way to +// determine a "current module" to use if the value turns out to be +// a LocalProviderConfig. +// +// Recipients of non-nil ProviderConfig values that actually need +// AbsProviderConfig values should call ResolveAbsProviderAddr on the +// *configs.Config value representing the root module configuration, which +// handles the translation from local to fully-qualified using mapping tables +// defined in the configuration. +// +// Recipients of a ProviderConfig value can assume it can contain only a +// LocalProviderConfig value, an AbsProviderConfigValue, or nil to represent +// the absense of a provider config in situations where that is meaningful. +type ProviderConfig interface { + providerConfig() +} + +// LocalProviderConfig is the address of a provider configuration from the +// perspective of references in a particular module. +// +// Finding the corresponding AbsProviderConfig will require looking up the +// LocalName in the providers table in the module's configuration; there is +// no syntax-only translation between these types. +type LocalProviderConfig struct { + LocalName string // If not empty, Alias identifies which non-default (aliased) provider // configuration this address refers to. Alias string } -// NewDefaultProviderConfig returns the address of the default (un-aliased) -// configuration for the provider with the given type name. -func NewDefaultProviderConfig(typeName string) ProviderConfig { - return ProviderConfig{ - Type: typeName, +var _ ProviderConfig = LocalProviderConfig{} + +// NewDefaultLocalProviderConfig returns the address of the default (un-aliased) +// configuration for the provider with the given local type name. +func NewDefaultLocalProviderConfig(LocalNameName string) LocalProviderConfig { + return LocalProviderConfig{ + LocalName: LocalNameName, } } +// providerConfig Implements addrs.ProviderConfig. +func (pc LocalProviderConfig) providerConfig() {} + // Absolute returns an AbsProviderConfig from the receiver and the given module // instance address. -func (pc ProviderConfig) Absolute(module ModuleInstance) AbsProviderConfig { +// +// TODO: This methold will become obsolete as part of supporting fully-qualified +// provider names in AbsProviderConfig, requiring a lookup via the module +// configuration instead. However, we continue to support it for now by +// relying on the fact that only "legacy" provider addresses are currently +// supported. +func (pc LocalProviderConfig) Absolute(module ModuleInstance) AbsProviderConfig { return AbsProviderConfig{ Module: module, ProviderConfig: pc, } } -func (pc ProviderConfig) String() string { - if pc.Type == "" { +func (pc LocalProviderConfig) String() string { + if pc.LocalName == "" { // Should never happen; always indicates a bug return "provider." } if pc.Alias != "" { - return fmt.Sprintf("provider.%s.%s", pc.Type, pc.Alias) + return fmt.Sprintf("provider.%s.%s", pc.LocalName, pc.Alias) } - return "provider." + pc.Type + return "provider." + pc.LocalName } // StringCompact is an alternative to String that returns the form that can // be parsed by ParseProviderConfigCompact, without the "provider." prefix. -func (pc ProviderConfig) StringCompact() string { +func (pc LocalProviderConfig) StringCompact() string { if pc.Alias != "" { - return fmt.Sprintf("%s.%s", pc.Type, pc.Alias) + return fmt.Sprintf("%s.%s", pc.LocalName, pc.Alias) } - return pc.Type + return pc.LocalName } // AbsProviderConfig is the absolute address of a provider configuration // within a particular module instance. type AbsProviderConfig struct { - Module ModuleInstance - ProviderConfig ProviderConfig + Module ModuleInstance + + // TODO: In a future change, this will no longer be an embedded + // LocalProviderConfig and should instead be two separate fields + // to allow AbsProviderConfig to use provider FQN rather than + // local type name: + // + // Provider Provider + // Alias string + // + // For now though, we continue to embed LocalProviderConfig until we're + // ready to teach the rest of Terraform Core about non-legacy provider + // FQNs, and update our ParseAbsProviderConfig and AbsProviderConfig.String + // methods to deal with FQNs. + ProviderConfig LocalProviderConfig } +var _ ProviderConfig = AbsProviderConfig{} + // ParseAbsProviderConfig parses the given traversal as an absolute provider // address. The following are examples of traversals that can be successfully // parsed as absolute provider configuration addresses: @@ -103,7 +158,7 @@ func ParseAbsProviderConfig(traversal hcl.Traversal) (AbsProviderConfig, tfdiags } if tt, ok := remain[1].(hcl.TraverseAttr); ok { - ret.ProviderConfig.Type = tt.Name + ret.ProviderConfig.LocalName = tt.Name } else { diags = diags.Append(&hcl.Diagnostic{ Severity: hcl.DiagError, @@ -162,27 +217,38 @@ func ParseAbsProviderConfigStr(str string) (AbsProviderConfig, tfdiags.Diagnosti // ProviderConfigDefault returns the address of the default provider config // of the given type inside the recieving module instance. +// +// TODO: The signature of this should change to accept a Provider address +// instead of a bare name once AbsProviderConfig starts having its own Provider +// and Alias fields rather than embedding LocalProviderConfig. func (m ModuleInstance) ProviderConfigDefault(name string) AbsProviderConfig { return AbsProviderConfig{ Module: m, - ProviderConfig: ProviderConfig{ - Type: name, + ProviderConfig: LocalProviderConfig{ + LocalName: name, }, } } // ProviderConfigAliased returns the address of an aliased provider config // of with given type and alias inside the recieving module instance. +// +// TODO: The signature of this should change to accept a Provider address +// instead of a bare name once AbsProviderConfig starts having its own Provider +// and Alias fields rather than embedding LocalProviderConfig. func (m ModuleInstance) ProviderConfigAliased(name, alias string) AbsProviderConfig { return AbsProviderConfig{ Module: m, - ProviderConfig: ProviderConfig{ - Type: name, - Alias: alias, + ProviderConfig: LocalProviderConfig{ + LocalName: name, + Alias: alias, }, } } +// providerConfig Implements addrs.ProviderConfig. +func (pc AbsProviderConfig) providerConfig() {} + // Inherited returns an address that the receiving configuration address might // inherit from in a parent module. The second bool return value indicates if // such inheritance is possible, and thus whether the returned address is valid. diff --git a/addrs/provider_config_test.go b/addrs/provider_config_test.go index cced0d5a5..911671099 100644 --- a/addrs/provider_config_test.go +++ b/addrs/provider_config_test.go @@ -19,8 +19,8 @@ func TestParseAbsProviderConfig(t *testing.T) { `provider.aws`, AbsProviderConfig{ Module: RootModuleInstance, - ProviderConfig: ProviderConfig{ - Type: "aws", + ProviderConfig: LocalProviderConfig{ + LocalName: "aws", }, }, ``, @@ -29,9 +29,9 @@ func TestParseAbsProviderConfig(t *testing.T) { `provider.aws.foo`, AbsProviderConfig{ Module: RootModuleInstance, - ProviderConfig: ProviderConfig{ - Type: "aws", - Alias: "foo", + ProviderConfig: LocalProviderConfig{ + LocalName: "aws", + Alias: "foo", }, }, ``, @@ -44,8 +44,8 @@ func TestParseAbsProviderConfig(t *testing.T) { Name: "baz", }, }, - ProviderConfig: ProviderConfig{ - Type: "aws", + ProviderConfig: LocalProviderConfig{ + LocalName: "aws", }, }, ``, @@ -58,9 +58,9 @@ func TestParseAbsProviderConfig(t *testing.T) { Name: "baz", }, }, - ProviderConfig: ProviderConfig{ - Type: "aws", - Alias: "foo", + ProviderConfig: LocalProviderConfig{ + LocalName: "aws", + Alias: "foo", }, }, ``, @@ -74,8 +74,8 @@ func TestParseAbsProviderConfig(t *testing.T) { InstanceKey: StringKey("foo"), }, }, - ProviderConfig: ProviderConfig{ - Type: "aws", + ProviderConfig: LocalProviderConfig{ + LocalName: "aws", }, }, ``, @@ -89,8 +89,8 @@ func TestParseAbsProviderConfig(t *testing.T) { InstanceKey: IntKey(1), }, }, - ProviderConfig: ProviderConfig{ - Type: "aws", + ProviderConfig: LocalProviderConfig{ + LocalName: "aws", }, }, ``, @@ -107,8 +107,8 @@ func TestParseAbsProviderConfig(t *testing.T) { Name: "bar", }, }, - ProviderConfig: ProviderConfig{ - Type: "aws", + ProviderConfig: LocalProviderConfig{ + LocalName: "aws", }, }, ``, diff --git a/addrs/resource.go b/addrs/resource.go index a71d8eca5..94f3c3012 100644 --- a/addrs/resource.go +++ b/addrs/resource.go @@ -50,9 +50,9 @@ func (r Resource) Absolute(module ModuleInstance) AbsResource { } } -// DefaultProviderConfig returns the address of the provider configuration -// that should be used for the resource identified by the reciever if it -// does not have a provider configuration address explicitly set in +// DefaultProvider returns the address of the provider whose default +// configuration shouldbe used for the resource identified by the reciever if +// it does not have a provider configuration address explicitly set in // configuration. // // This method is not able to verify that such a configuration exists, nor @@ -60,15 +60,18 @@ func (r Resource) Absolute(module ModuleInstance) AbsResource { // configurations from parent modules. It just does a static analysis of the // receiving address and returns an address to start from, relative to the // same module that contains the resource. -func (r Resource) DefaultProviderConfig() ProviderConfig { +func (r Resource) DefaultProvider() Provider { typeName := r.Type if under := strings.Index(typeName, "_"); under != -1 { typeName = typeName[:under] } - return ProviderConfig{ - Type: typeName, - } + // TODO: For now we're returning a _legacy_ provider address here + // because the rest of Terraform isn't yet prepared to deal with + // non-legacy ones. Once we phase out legacy addresses this should + // switch to being a _default_ provider address, i.e. one in the + // releases.hashicorp.com/hashicorp/... namespace. + return NewLegacyProvider(typeName) } // ResourceInstance is an address for a specific instance of a resource. diff --git a/backend/local/backend_plan.go b/backend/local/backend_plan.go index aec1c078a..b15466e9e 100644 --- a/backend/local/backend_plan.go +++ b/backend/local/backend_plan.go @@ -262,7 +262,7 @@ func RenderPlan(plan *plans.Plan, state *states.State, schemas *terraform.Schema if rcs.Action == plans.NoOp { continue } - providerSchema := schemas.ProviderSchema(rcs.ProviderAddr.ProviderConfig.Type) + providerSchema := schemas.ProviderSchema(rcs.ProviderAddr.ProviderConfig.LocalName) if providerSchema == nil { // Should never happen ui.Output(fmt.Sprintf("(schema missing for %s)\n", rcs.ProviderAddr)) diff --git a/backend/local/backend_plan_test.go b/backend/local/backend_plan_test.go index 1aa4183a9..fddf053b9 100644 --- a/backend/local/backend_plan_test.go +++ b/backend/local/backend_plan_test.go @@ -215,8 +215,8 @@ func TestLocal_planDeposedOnly(t *testing.T) { }] }`), }, - addrs.ProviderConfig{ - Type: "test", + addrs.LocalProviderConfig{ + LocalName: "test", }.Absolute(addrs.RootModuleInstance), ) })) @@ -658,8 +658,8 @@ func testPlanState() *states.State { }] }`), }, - addrs.ProviderConfig{ - Type: "test", + addrs.LocalProviderConfig{ + LocalName: "test", }.Absolute(addrs.RootModuleInstance), ) return state @@ -684,8 +684,8 @@ func testPlanState_withDataSource() *states.State { }] }`), }, - addrs.ProviderConfig{ - Type: "test", + addrs.LocalProviderConfig{ + LocalName: "test", }.Absolute(addrs.RootModuleInstance), ) rootModule.SetResourceInstanceCurrent( @@ -700,8 +700,8 @@ func testPlanState_withDataSource() *states.State { "filter": "foo" }`), }, - addrs.ProviderConfig{ - Type: "test", + addrs.LocalProviderConfig{ + LocalName: "test", }.Absolute(addrs.RootModuleInstance), ) return state @@ -726,8 +726,8 @@ func testPlanState_tainted() *states.State { }] }`), }, - addrs.ProviderConfig{ - Type: "test", + addrs.LocalProviderConfig{ + LocalName: "test", }.Absolute(addrs.RootModuleInstance), ) return state diff --git a/backend/testing.go b/backend/testing.go index 1fc081db5..f1b92b62d 100644 --- a/backend/testing.go +++ b/backend/testing.go @@ -150,8 +150,8 @@ func TestBackendStates(t *testing.T, b Backend) { Status: states.ObjectReady, SchemaVersion: 0, }, - addrs.ProviderConfig{ - Type: "test", + addrs.LocalProviderConfig{ + LocalName: "test", }.Absolute(addrs.RootModuleInstance), ) diff --git a/command/apply_destroy_test.go b/command/apply_destroy_test.go index 3cdf998f7..af0d5b896 100644 --- a/command/apply_destroy_test.go +++ b/command/apply_destroy_test.go @@ -29,7 +29,7 @@ func TestApply_destroy(t *testing.T) { AttrsJSON: []byte(`{"id":"bar"}`), Status: states.ObjectReady, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) }) statePath := testStateFile(t, originalState) @@ -122,7 +122,7 @@ func TestApply_destroyLockedState(t *testing.T) { AttrsJSON: []byte(`{"id":"bar"}`), Status: states.ObjectReady, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) }) statePath := testStateFile(t, originalState) @@ -194,7 +194,7 @@ func TestApply_destroyTargeted(t *testing.T) { AttrsJSON: []byte(`{"id":"i-ab123"}`), Status: states.ObjectReady, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) s.SetResourceInstanceCurrent( addrs.Resource{ @@ -206,7 +206,7 @@ func TestApply_destroyTargeted(t *testing.T) { AttrsJSON: []byte(`{"id":"i-abc123"}`), Status: states.ObjectReady, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) }) statePath := testStateFile(t, originalState) diff --git a/command/apply_test.go b/command/apply_test.go index c15718104..911e6e598 100644 --- a/command/apply_test.go +++ b/command/apply_test.go @@ -833,7 +833,7 @@ func TestApply_refresh(t *testing.T) { AttrsJSON: []byte(`{"ami":"bar"}`), Status: states.ObjectReady, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) }) statePath := testStateFile(t, originalState) @@ -987,7 +987,7 @@ func TestApply_state(t *testing.T) { AttrsJSON: []byte(`{"ami":"foo"}`), Status: states.ObjectReady, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) }) statePath := testStateFile(t, originalState) @@ -1351,7 +1351,7 @@ func TestApply_backup(t *testing.T) { AttrsJSON: []byte("{\n \"id\": \"bar\"\n }"), Status: states.ObjectReady, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) }) statePath := testStateFile(t, originalState) @@ -1652,7 +1652,7 @@ func applyFixturePlanFile(t *testing.T) string { Type: "test_instance", Name: "foo", }.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance), - ProviderAddr: addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + ProviderAddr: addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ChangeSrc: plans.ChangeSrc{ Action: plans.Create, Before: priorValRaw, diff --git a/command/command_test.go b/command/command_test.go index c5665b22e..8a5f8023b 100644 --- a/command/command_test.go +++ b/command/command_test.go @@ -271,8 +271,8 @@ func testState() *states.State { Dependencies: []addrs.AbsResource{}, DependsOn: []addrs.Referenceable{}, }, - addrs.ProviderConfig{ - Type: "test", + addrs.LocalProviderConfig{ + LocalName: "test", }.Absolute(addrs.RootModuleInstance), ) // DeepCopy is used here to ensure our synthetic state matches exactly diff --git a/command/format/diff_test.go b/command/format/diff_test.go index 96d414cb6..a048ac5c5 100644 --- a/command/format/diff_test.go +++ b/command/format/diff_test.go @@ -3157,7 +3157,7 @@ func runTestCases(t *testing.T, testCases map[string]testCase) { Type: "test_instance", Name: "example", }.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance), - ProviderAddr: addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + ProviderAddr: addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ChangeSrc: plans.ChangeSrc{ Action: tc.Action, Before: before, diff --git a/command/format/state.go b/command/format/state.go index 143edc9e1..d5bc26cea 100644 --- a/command/format/state.go +++ b/command/format/state.go @@ -139,7 +139,7 @@ func formatStateModule(p blockBodyDiffPrinter, m *states.Module, schemas *terraf } var schema *configschema.Block - provider := addr.DefaultProviderConfig().Absolute(m.Addr).ProviderConfig.StringCompact() + provider := addrs.NewDefaultLocalProviderConfig(addr.DefaultProvider().LegacyString()).Absolute(m.Addr).ProviderConfig.StringCompact() if _, exists := schemas.Providers[provider]; !exists { // This should never happen in normal use because we should've // loaded all of the schemas and checked things prior to this diff --git a/command/format/state_test.go b/command/format/state_test.go index 2b00da9b8..b40bc4891 100644 --- a/command/format/state_test.go +++ b/command/format/state_test.go @@ -243,8 +243,8 @@ func basicState(t *testing.T) *states.State { SchemaVersion: 1, AttrsJSON: []byte(`{"woozles":"confuzles"}`), }, - addrs.ProviderConfig{ - Type: "test", + addrs.LocalProviderConfig{ + LocalName: "test", }.Absolute(addrs.RootModuleInstance), ) rootModule.SetResourceInstanceCurrent( @@ -258,8 +258,8 @@ func basicState(t *testing.T) *states.State { SchemaVersion: 1, AttrsJSON: []byte(`{"compute":"sure"}`), }, - addrs.ProviderConfig{ - Type: "test", + addrs.LocalProviderConfig{ + LocalName: "test", }.Absolute(addrs.RootModuleInstance), ) return state @@ -293,8 +293,8 @@ func stateWithMoreOutputs(t *testing.T) *states.State { SchemaVersion: 1, AttrsJSON: []byte(`{"woozles":"confuzles"}`), }, - addrs.ProviderConfig{ - Type: "test", + addrs.LocalProviderConfig{ + LocalName: "test", }.Absolute(addrs.RootModuleInstance), ) return state @@ -319,8 +319,8 @@ func nestedState(t *testing.T) *states.State { SchemaVersion: 1, AttrsJSON: []byte(`{"woozles":"confuzles","nested": [{"value": "42"}]}`), }, - addrs.ProviderConfig{ - Type: "test", + addrs.LocalProviderConfig{ + LocalName: "test", }.Absolute(addrs.RootModuleInstance), ) return state @@ -341,8 +341,8 @@ func deposedState(t *testing.T) *states.State { SchemaVersion: 1, AttrsJSON: []byte(`{"woozles":"confuzles","nested": [{"value": "42"}]}`), }, - addrs.ProviderConfig{ - Type: "test", + addrs.LocalProviderConfig{ + LocalName: "test", }.Absolute(addrs.RootModuleInstance), ) return state @@ -369,8 +369,8 @@ func onlyDeposedState(t *testing.T) *states.State { SchemaVersion: 1, AttrsJSON: []byte(`{"woozles":"confuzles","nested": [{"value": "42"}]}`), }, - addrs.ProviderConfig{ - Type: "test", + addrs.LocalProviderConfig{ + LocalName: "test", }.Absolute(addrs.RootModuleInstance), ) rootModule.SetResourceInstanceDeposed( @@ -385,8 +385,8 @@ func onlyDeposedState(t *testing.T) *states.State { SchemaVersion: 1, AttrsJSON: []byte(`{"woozles":"confuzles","nested": [{"value": "42"}]}`), }, - addrs.ProviderConfig{ - Type: "test", + addrs.LocalProviderConfig{ + LocalName: "test", }.Absolute(addrs.RootModuleInstance), ) return state diff --git a/command/graph_test.go b/command/graph_test.go index b8712e603..92c99f0af 100644 --- a/command/graph_test.go +++ b/command/graph_test.go @@ -125,7 +125,7 @@ func TestGraph_plan(t *testing.T) { Before: plans.DynamicValue(`{}`), After: plans.DynamicValue(`null`), }, - ProviderAddr: addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + ProviderAddr: addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), }) emptyConfig, err := plans.NewDynamicValue(cty.EmptyObjectVal, cty.EmptyObject) if err != nil { diff --git a/command/import.go b/command/import.go index cc384405a..c818b1777 100644 --- a/command/import.go +++ b/command/import.go @@ -181,7 +181,8 @@ func (c *ImportCommand) Run(args []string) int { if rc != nil && rc.ProviderConfigRef != nil { providerAddr = rc.ProviderConfigAddr().Absolute(addr.Module) } else { - providerAddr = resourceRelAddr.DefaultProviderConfig().Absolute(addr.Module) + providerType := resourceRelAddr.DefaultProvider() + providerAddr = addrs.NewDefaultLocalProviderConfig(providerType.LegacyString()).Absolute(addr.Module) } } diff --git a/command/jsonconfig/config.go b/command/jsonconfig/config.go index 0b27c7af4..dd2d5cc24 100644 --- a/command/jsonconfig/config.go +++ b/command/jsonconfig/config.go @@ -302,7 +302,7 @@ func marshalResources(resources map[string]*configs.Resource, schemas *terraform } schema, schemaVer := schemas.ResourceTypeConfig( - v.ProviderConfigAddr().Type, + v.ProviderConfigAddr().LocalName, v.Mode, v.Type, ) diff --git a/command/jsonplan/plan.go b/command/jsonplan/plan.go index f1563abef..66598aefc 100644 --- a/command/jsonplan/plan.go +++ b/command/jsonplan/plan.go @@ -178,7 +178,7 @@ func (p *plan) marshalResourceChanges(changes *plans.Changes, schemas *terraform } schema, _ := schemas.ResourceTypeConfig( - rc.ProviderAddr.ProviderConfig.Type, + rc.ProviderAddr.ProviderConfig.LocalName, addr.Resource.Resource.Mode, addr.Resource.Resource.Type, ) diff --git a/command/jsonplan/values.go b/command/jsonplan/values.go index caa8babf4..e8f8c111a 100644 --- a/command/jsonplan/values.go +++ b/command/jsonplan/values.go @@ -181,7 +181,7 @@ func marshalPlanResources(changes *plans.Changes, ris []addrs.AbsResourceInstanc } schema, schemaVer := schemas.ResourceTypeConfig( - r.ProviderAddr.ProviderConfig.Type, + r.ProviderAddr.ProviderConfig.LocalName, r.Addr.Resource.Resource.Mode, resource.Type, ) diff --git a/command/jsonplan/values_test.go b/command/jsonplan/values_test.go index 8395ee0aa..a6bf98ae9 100644 --- a/command/jsonplan/values_test.go +++ b/command/jsonplan/values_test.go @@ -258,7 +258,7 @@ func TestMarshalPlanResources(t *testing.T) { Type: "test_thing", Name: "example", }.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance), - ProviderAddr: addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + ProviderAddr: addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ChangeSrc: plans.ChangeSrc{ Action: test.Action, Before: before, diff --git a/command/jsonstate/state.go b/command/jsonstate/state.go index 2fac8fbba..a7f1f88b5 100644 --- a/command/jsonstate/state.go +++ b/command/jsonstate/state.go @@ -274,7 +274,7 @@ func marshalResources(resources map[string]*states.Resource, schemas *terraform. } schema, _ := schemas.ResourceTypeConfig( - r.ProviderConfig.ProviderConfig.Type, + r.ProviderConfig.ProviderConfig.LocalName, r.Addr.Mode, r.Addr.Type, ) diff --git a/command/jsonstate/state_test.go b/command/jsonstate/state_test.go index e40c123c6..85c549080 100644 --- a/command/jsonstate/state_test.go +++ b/command/jsonstate/state_test.go @@ -201,8 +201,8 @@ func TestMarshalResources(t *testing.T) { }, }, }, - ProviderConfig: addrs.ProviderConfig{ - Type: "test", + ProviderConfig: addrs.LocalProviderConfig{ + LocalName: "test", }.Absolute(addrs.RootModuleInstance), }, }, @@ -244,8 +244,8 @@ func TestMarshalResources(t *testing.T) { }, }, }, - ProviderConfig: addrs.ProviderConfig{ - Type: "test", + ProviderConfig: addrs.LocalProviderConfig{ + LocalName: "test", }.Absolute(addrs.RootModuleInstance), }, }, @@ -292,8 +292,8 @@ func TestMarshalResources(t *testing.T) { }, }, }, - ProviderConfig: addrs.ProviderConfig{ - Type: "test", + ProviderConfig: addrs.LocalProviderConfig{ + LocalName: "test", }.Absolute(addrs.RootModuleInstance), }, }, diff --git a/command/plan_test.go b/command/plan_test.go index 6885810d5..75c45a3fd 100644 --- a/command/plan_test.go +++ b/command/plan_test.go @@ -124,7 +124,7 @@ func TestPlan_destroy(t *testing.T) { AttrsJSON: []byte(`{"id":"bar"}`), Status: states.ObjectReady, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) }) outPath := testTempFile(t) @@ -240,7 +240,7 @@ func TestPlan_outPathNoChange(t *testing.T) { AttrsJSON: []byte(`{"id":"bar","ami":"bar","network_interface":[{"description":"Main network interface","device_index":"0"}]}`), Status: states.ObjectReady, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) }) statePath := testStateFile(t, originalState) diff --git a/command/show_test.go b/command/show_test.go index e1f075af6..301224fb9 100644 --- a/command/show_test.go +++ b/command/show_test.go @@ -489,7 +489,7 @@ func showFixturePlanFile(t *testing.T, action plans.Action) string { Type: "test_instance", Name: "foo", }.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance), - ProviderAddr: addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + ProviderAddr: addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ChangeSrc: plans.ChangeSrc{ Action: action, Before: priorValRaw, diff --git a/command/state_mv_test.go b/command/state_mv_test.go index a3e2522a6..9cfd00486 100644 --- a/command/state_mv_test.go +++ b/command/state_mv_test.go @@ -27,7 +27,7 @@ func TestStateMv(t *testing.T) { AttrsJSON: []byte(`{"id":"bar","foo":"value","bar":"value"}`), Status: states.ObjectReady, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) s.SetResourceInstanceCurrent( addrs.Resource{ @@ -40,7 +40,7 @@ func TestStateMv(t *testing.T) { Status: states.ObjectReady, Dependencies: []addrs.AbsResource{mustResourceAddr("test_instance.foo")}, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) }) statePath := testStateFile(t, state) @@ -88,7 +88,7 @@ func TestStateMv_resourceToInstance(t *testing.T) { AttrsJSON: []byte(`{"id":"bar","foo":"value","bar":"value"}`), Status: states.ObjectReady, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) s.SetResourceInstanceCurrent( addrs.Resource{ @@ -101,7 +101,7 @@ func TestStateMv_resourceToInstance(t *testing.T) { Status: states.ObjectReady, Dependencies: []addrs.AbsResource{mustResourceAddr("test_instance.foo")}, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) s.SetResourceMeta( addrs.Resource{ @@ -110,7 +110,7 @@ func TestStateMv_resourceToInstance(t *testing.T) { Name: "bar", }.Absolute(addrs.RootModuleInstance), states.EachList, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) }) statePath := testStateFile(t, state) @@ -169,7 +169,7 @@ func TestStateMv_instanceToResource(t *testing.T) { AttrsJSON: []byte(`{"id":"bar","foo":"value","bar":"value"}`), Status: states.ObjectReady, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) s.SetResourceInstanceCurrent( addrs.Resource{ @@ -181,7 +181,7 @@ func TestStateMv_instanceToResource(t *testing.T) { AttrsJSON: []byte(`{"id":"foo","foo":"value","bar":"value"}`), Status: states.ObjectReady, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) }) statePath := testStateFile(t, state) @@ -251,7 +251,7 @@ func TestStateMv_instanceToNewResource(t *testing.T) { AttrsJSON: []byte(`{"id":"bar","foo":"value","bar":"value"}`), Status: states.ObjectReady, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) }) statePath := testStateFile(t, state) @@ -319,7 +319,7 @@ func TestStateMv_differentResourceTypes(t *testing.T) { AttrsJSON: []byte(`{"id":"bar","foo":"value","bar":"value"}`), Status: states.ObjectReady, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) }) statePath := testStateFile(t, state) @@ -369,7 +369,7 @@ func TestStateMv_explicitWithBackend(t *testing.T) { AttrsJSON: []byte(`{"id":"bar","foo":"value","bar":"value"}`), Status: states.ObjectReady, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) s.SetResourceInstanceCurrent( addrs.Resource{ @@ -381,7 +381,7 @@ func TestStateMv_explicitWithBackend(t *testing.T) { AttrsJSON: []byte(`{"id":"foo","foo":"value","bar":"value"}`), Status: states.ObjectReady, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) }) statePath := testStateFile(t, state) @@ -438,7 +438,7 @@ func TestStateMv_backupExplicit(t *testing.T) { AttrsJSON: []byte(`{"id":"bar","foo":"value","bar":"value"}`), Status: states.ObjectReady, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) s.SetResourceInstanceCurrent( addrs.Resource{ @@ -451,7 +451,7 @@ func TestStateMv_backupExplicit(t *testing.T) { Status: states.ObjectReady, Dependencies: []addrs.AbsResource{mustResourceAddr("test_instance.foo")}, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) }) statePath := testStateFile(t, state) @@ -497,7 +497,7 @@ func TestStateMv_stateOutNew(t *testing.T) { AttrsJSON: []byte(`{"id":"bar","foo":"value","bar":"value"}`), Status: states.ObjectReady, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) }) statePath := testStateFile(t, state) @@ -548,7 +548,7 @@ func TestStateMv_stateOutExisting(t *testing.T) { AttrsJSON: []byte(`{"id":"bar","foo":"value","bar":"value"}`), Status: states.ObjectReady, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) }) statePath := testStateFile(t, stateSrc) @@ -564,7 +564,7 @@ func TestStateMv_stateOutExisting(t *testing.T) { AttrsJSON: []byte(`{"id":"bar"}`), Status: states.ObjectReady, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) }) stateOutPath := testStateFile(t, stateDst) @@ -641,7 +641,7 @@ func TestStateMv_stateOutNew_count(t *testing.T) { AttrsJSON: []byte(`{"id":"foo","foo":"value","bar":"value"}`), Status: states.ObjectReady, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) s.SetResourceInstanceCurrent( addrs.Resource{ @@ -653,7 +653,7 @@ func TestStateMv_stateOutNew_count(t *testing.T) { AttrsJSON: []byte(`{"id":"bar","foo":"value","bar":"value"}`), Status: states.ObjectReady, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) s.SetResourceInstanceCurrent( addrs.Resource{ @@ -665,7 +665,7 @@ func TestStateMv_stateOutNew_count(t *testing.T) { AttrsJSON: []byte(`{"id":"bar","foo":"value","bar":"value"}`), Status: states.ObjectReady, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) }) statePath := testStateFile(t, state) @@ -720,7 +720,7 @@ func TestStateMv_stateOutNew_largeCount(t *testing.T) { AttrsJSON: []byte(fmt.Sprintf(`{"id":"foo%d","foo":"value","bar":"value"}`, i)), Status: states.ObjectReady, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) } s.SetResourceInstanceCurrent( @@ -733,7 +733,7 @@ func TestStateMv_stateOutNew_largeCount(t *testing.T) { AttrsJSON: []byte(`{"id":"bar","foo":"value","bar":"value"}`), Status: states.ObjectReady, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) }) statePath := testStateFile(t, state) @@ -784,7 +784,7 @@ func TestStateMv_stateOutNew_nestedModule(t *testing.T) { AttrsJSON: []byte(`{"id":"bar","foo":"value","bar":"value"}`), Status: states.ObjectReady, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) s.SetResourceInstanceCurrent( addrs.Resource{ @@ -796,7 +796,7 @@ func TestStateMv_stateOutNew_nestedModule(t *testing.T) { AttrsJSON: []byte(`{"id":"bar","foo":"value","bar":"value"}`), Status: states.ObjectReady, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) }) @@ -848,7 +848,7 @@ func TestStateMv_toNewModule(t *testing.T) { AttrsJSON: []byte(`{"id":"bar","foo":"value","bar":"value"}`), Status: states.ObjectReady, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) }) @@ -918,7 +918,7 @@ func TestStateMv_withinBackend(t *testing.T) { AttrsJSON: []byte(`{"id":"bar","foo":"value","bar":"value"}`), Status: states.ObjectReady, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) s.SetResourceInstanceCurrent( addrs.Resource{ @@ -931,7 +931,7 @@ func TestStateMv_withinBackend(t *testing.T) { Status: states.ObjectReady, Dependencies: []addrs.AbsResource{mustResourceAddr("test_instance.foo")}, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) }) diff --git a/command/state_rm_test.go b/command/state_rm_test.go index a35c247bb..e4fe9898d 100644 --- a/command/state_rm_test.go +++ b/command/state_rm_test.go @@ -25,7 +25,7 @@ func TestStateRm(t *testing.T) { AttrsJSON: []byte(`{"id":"bar","foo":"value","bar":"value"}`), Status: states.ObjectReady, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) s.SetResourceInstanceCurrent( addrs.Resource{ @@ -37,7 +37,7 @@ func TestStateRm(t *testing.T) { AttrsJSON: []byte(`{"id":"foo","foo":"value","bar":"value"}`), Status: states.ObjectReady, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) }) statePath := testStateFile(t, state) @@ -84,7 +84,7 @@ func TestStateRmNotChildModule(t *testing.T) { AttrsJSON: []byte(`{"id":"bar","foo":"value","bar":"value"}`), Status: states.ObjectReady, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) // This second instance has the same local address as the first but // is in a child module. Older versions of Terraform would incorrectly @@ -99,7 +99,7 @@ func TestStateRmNotChildModule(t *testing.T) { AttrsJSON: []byte(`{"id":"foo","foo":"value","bar":"value"}`), Status: states.ObjectReady, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) }) statePath := testStateFile(t, state) @@ -167,7 +167,7 @@ func TestStateRmNoArgs(t *testing.T) { AttrsJSON: []byte(`{"id":"bar","foo":"value","bar":"value"}`), Status: states.ObjectReady, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) s.SetResourceInstanceCurrent( addrs.Resource{ @@ -179,7 +179,7 @@ func TestStateRmNoArgs(t *testing.T) { AttrsJSON: []byte(`{"id":"foo","foo":"value","bar":"value"}`), Status: states.ObjectReady, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) }) statePath := testStateFile(t, state) @@ -220,7 +220,7 @@ func TestStateRmNonExist(t *testing.T) { AttrsJSON: []byte(`{"id":"bar","foo":"value","bar":"value"}`), Status: states.ObjectReady, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) s.SetResourceInstanceCurrent( addrs.Resource{ @@ -232,7 +232,7 @@ func TestStateRmNonExist(t *testing.T) { AttrsJSON: []byte(`{"id":"foo","foo":"value","bar":"value"}`), Status: states.ObjectReady, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) }) statePath := testStateFile(t, state) @@ -274,7 +274,7 @@ func TestStateRm_backupExplicit(t *testing.T) { AttrsJSON: []byte(`{"id":"bar","foo":"value","bar":"value"}`), Status: states.ObjectReady, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) s.SetResourceInstanceCurrent( addrs.Resource{ @@ -286,7 +286,7 @@ func TestStateRm_backupExplicit(t *testing.T) { AttrsJSON: []byte(`{"id":"foo","foo":"value","bar":"value"}`), Status: states.ObjectReady, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) }) statePath := testStateFile(t, state) @@ -384,7 +384,7 @@ func TestStateRm_backendState(t *testing.T) { AttrsJSON: []byte(`{"id":"bar","foo":"value","bar":"value"}`), Status: states.ObjectReady, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) s.SetResourceInstanceCurrent( addrs.Resource{ @@ -396,7 +396,7 @@ func TestStateRm_backendState(t *testing.T) { AttrsJSON: []byte(`{"id":"foo","foo":"value","bar":"value"}`), Status: states.ObjectReady, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) }) diff --git a/command/state_show.go b/command/state_show.go index c2d9abd85..318db7bcd 100644 --- a/command/state_show.go +++ b/command/state_show.go @@ -119,7 +119,7 @@ func (c *StateShowCommand) Run(args []string) int { singleInstance.EnsureModule(addr.Module).SetResourceInstanceCurrent( addr.Resource, is.Current, - addr.Resource.Resource.DefaultProviderConfig().Absolute(addr.Module), + addrs.NewDefaultLocalProviderConfig(addr.Resource.Resource.DefaultProvider().LegacyString()).Absolute(addr.Module), ) output := format.State(&format.StateOpts{ diff --git a/command/state_show_test.go b/command/state_show_test.go index e1c574e9a..e684a1ed7 100644 --- a/command/state_show_test.go +++ b/command/state_show_test.go @@ -24,7 +24,7 @@ func TestStateShow(t *testing.T) { AttrsJSON: []byte(`{"id":"bar","foo":"value","bar":"value"}`), Status: states.ObjectReady, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) }) statePath := testStateFile(t, state) @@ -79,7 +79,7 @@ func TestStateShow_multi(t *testing.T) { AttrsJSON: []byte(`{"id":"bar","foo":"value","bar":"value"}`), Status: states.ObjectReady, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) s.SetResourceInstanceCurrent( addrs.Resource{ @@ -91,7 +91,7 @@ func TestStateShow_multi(t *testing.T) { AttrsJSON: []byte(`{"id":"foo","foo":"value","bar":"value"}`), Status: states.ObjectReady, }, - addrs.ProviderConfig{Type: "test"}.Absolute(submod), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(submod), ) }) statePath := testStateFile(t, state) diff --git a/command/taint_test.go b/command/taint_test.go index bcdb76a9c..7c756cc7f 100644 --- a/command/taint_test.go +++ b/command/taint_test.go @@ -24,7 +24,7 @@ func TestTaint(t *testing.T) { AttrsJSON: []byte(`{"id":"bar"}`), Status: states.ObjectReady, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) }) statePath := testStateFile(t, state) @@ -59,7 +59,7 @@ func TestTaint_lockedState(t *testing.T) { AttrsJSON: []byte(`{"id":"bar"}`), Status: states.ObjectReady, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) }) statePath := testStateFile(t, state) @@ -245,7 +245,7 @@ func TestTaint_missing(t *testing.T) { AttrsJSON: []byte(`{"id":"bar"}`), Status: states.ObjectReady, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) }) statePath := testStateFile(t, state) @@ -278,7 +278,7 @@ func TestTaint_missingAllow(t *testing.T) { AttrsJSON: []byte(`{"id":"bar"}`), Status: states.ObjectReady, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) }) statePath := testStateFile(t, state) @@ -354,7 +354,7 @@ func TestTaint_module(t *testing.T) { AttrsJSON: []byte(`{"id":"bar"}`), Status: states.ObjectReady, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) s.SetResourceInstanceCurrent( addrs.Resource{ @@ -366,7 +366,7 @@ func TestTaint_module(t *testing.T) { AttrsJSON: []byte(`{"id":"blah"}`), Status: states.ObjectReady, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) }) statePath := testStateFile(t, state) diff --git a/command/untaint_test.go b/command/untaint_test.go index c5f7275f1..71ad9655b 100644 --- a/command/untaint_test.go +++ b/command/untaint_test.go @@ -23,7 +23,7 @@ func TestUntaint(t *testing.T) { AttrsJSON: []byte(`{"id":"bar"}`), Status: states.ObjectTainted, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) }) statePath := testStateFile(t, state) @@ -63,7 +63,7 @@ func TestUntaint_lockedState(t *testing.T) { AttrsJSON: []byte(`{"id":"bar"}`), Status: states.ObjectTainted, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) }) statePath := testStateFile(t, state) @@ -271,7 +271,7 @@ func TestUntaint_missing(t *testing.T) { AttrsJSON: []byte(`{"id":"bar"}`), Status: states.ObjectTainted, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) }) statePath := testStateFile(t, state) @@ -304,7 +304,7 @@ func TestUntaint_missingAllow(t *testing.T) { AttrsJSON: []byte(`{"id":"bar"}`), Status: states.ObjectTainted, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) }) statePath := testStateFile(t, state) @@ -389,7 +389,7 @@ func TestUntaint_module(t *testing.T) { AttrsJSON: []byte(`{"id":"bar"}`), Status: states.ObjectTainted, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) s.SetResourceInstanceCurrent( addrs.Resource{ @@ -401,7 +401,7 @@ func TestUntaint_module(t *testing.T) { AttrsJSON: []byte(`{"id":"bar"}`), Status: states.ObjectTainted, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) }) statePath := testStateFile(t, state) diff --git a/command/workspace_command_test.go b/command/workspace_command_test.go index ea645e006..e4c781694 100644 --- a/command/workspace_command_test.go +++ b/command/workspace_command_test.go @@ -241,7 +241,7 @@ func TestWorkspace_createWithState(t *testing.T) { AttrsJSON: []byte(`{"id":"bar"}`), Status: states.ObjectReady, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) }) diff --git a/configs/config.go b/configs/config.go index 9bc545955..e8f3d1d7a 100644 --- a/configs/config.go +++ b/configs/config.go @@ -1,6 +1,7 @@ package configs import ( + "fmt" "sort" version "github.com/hashicorp/go-version" @@ -170,32 +171,39 @@ func (c *Config) DescendentForInstance(path addrs.ModuleInstance) *Config { // information and so callers are expected to have already dealt with // provider version selection in an earlier step and have identified suitable // versions for each provider. -func (c *Config) ProviderTypes() []string { - m := make(map[string]struct{}) +func (c *Config) ProviderTypes() []addrs.Provider { + m := make(map[addrs.Provider]struct{}) c.gatherProviderTypes(m) - ret := make([]string, 0, len(m)) + ret := make([]addrs.Provider, 0, len(m)) for k := range m { ret = append(ret, k) } - sort.Strings(ret) + sort.Slice(ret, func(i, j int) bool { + return ret[i].String() < ret[j].String() + }) return ret } -func (c *Config) gatherProviderTypes(m map[string]struct{}) { + +func (c *Config) gatherProviderTypes(m map[addrs.Provider]struct{}) { if c == nil { return } + // FIXME: These are currently all assuming legacy provider addresses. + // As part of phasing those out we'll need to change this to look up + // the true provider addresses via the local-to-FQN mapping table + // stored inside c.Module. for _, pc := range c.Module.ProviderConfigs { - m[pc.Name] = struct{}{} + m[addrs.NewLegacyProvider(pc.Name)] = struct{}{} } for _, rc := range c.Module.ManagedResources { providerAddr := rc.ProviderConfigAddr() - m[providerAddr.Type] = struct{}{} + m[addrs.NewLegacyProvider(providerAddr.LocalName)] = struct{}{} } for _, rc := range c.Module.DataResources { providerAddr := rc.ProviderConfigAddr() - m[providerAddr.Type] = struct{}{} + m[addrs.NewLegacyProvider(providerAddr.LocalName)] = struct{}{} } // Must also visit our child modules, recursively. @@ -204,14 +212,72 @@ func (c *Config) gatherProviderTypes(m map[string]struct{}) { } } +// ResolveAbsProviderAddr returns the AbsProviderConfig represented by the given +// ProviderConfig address, which must not be nil or this method will panic. +// +// If the given address is already an AbsProviderConfig then this method returns +// it verbatim, and will always succeed. If it's a LocalProviderConfig then +// it will consult the local-to-FQN mapping table for the given module +// to find the absolute address corresponding to the given local one. +// +// The module address to resolve local addresses in must be given in the second +// argument, and must refer to a module that exists under the receiver or +// else this method will panic. +func (c *Config) ResolveAbsProviderAddr(addr addrs.ProviderConfig, inModule addrs.ModuleInstance) addrs.AbsProviderConfig { + switch addr := addr.(type) { + + case addrs.AbsProviderConfig: + return addr + + case addrs.LocalProviderConfig: + // Find the descendent Config that contains the module that this + // local config belongs to. + mc := c.DescendentForInstance(inModule) + if mc == nil { + panic(fmt.Sprintf("ResolveAbsProviderAddr with non-existent module %s", inModule.String())) + } + + var provider addrs.Provider + if providerReq, exists := c.Module.ProviderRequirements[addr.LocalName]; exists { + provider = providerReq.Type + } else { + // FIXME: For now we're returning a _legacy_ address as fallback here, + // but once we remove legacy addresses this should actually be a + // _default_ provider address. + provider = addrs.NewLegacyProvider(addr.LocalName) + } + + // FIXME: Once AbsProviderConfig starts using FQN rather than + // embedding LocalProviderConfig we will use "provider" + // properly here, but for now we'll require a legacy one because + // the rest of Terraform isn't ready to deal with non-legacy + // provider addresses yet. + return addrs.AbsProviderConfig{ + Module: inModule, + ProviderConfig: addrs.LocalProviderConfig{ + LocalName: provider.LegacyString(), + Alias: addr.Alias, + }, + } + + default: + panic(fmt.Sprintf("cannot ResolveAbsProviderAddr(%v, ...)", addr)) + } + +} + // ProviderForConfigAddr returns the FQN for a given addrs.ProviderConfig, first // by checking for the provider in module.ProviderRequirements and falling // back to addrs.NewLegacyProvider if it is not found. -// -// TODO: update to addrs.NewDefaultProvider in 0.13 -func (c *Config) ProviderForConfigAddr(addr addrs.ProviderConfig) addrs.Provider { - if provider, exists := c.Module.ProviderRequirements[addr.Type]; exists { - return provider.Type - } - return addrs.NewLegacyProvider(addr.Type) +func (c *Config) ProviderForConfigAddr(addr addrs.LocalProviderConfig) addrs.Provider { + // FIXME: Once AbsProviderAddr itself includes an addrs.Provider we + // can just return that here. + return addrs.NewLegacyProvider( + // addrs.RootModuleInstance here looks weird, but it's okay because + // ProviderForConfigAddr looks up addresses in the module directly + // connected to the receiver (rather than a descendent, as with + // ResolveAbsProviderAddr) and we're going to discard the Module field + // of the ResolveAbsProviderAddr return value anyway. + c.ResolveAbsProviderAddr(addr, addrs.RootModuleInstance).ProviderConfig.LocalName, + ) } diff --git a/configs/config_test.go b/configs/config_test.go index 7e9f9e130..2d817909c 100644 --- a/configs/config_test.go +++ b/configs/config_test.go @@ -4,6 +4,8 @@ import ( "testing" "github.com/go-test/deep" + + "github.com/hashicorp/terraform/addrs" ) func TestConfigProviderTypes(t *testing.T) { @@ -18,12 +20,84 @@ func TestConfigProviderTypes(t *testing.T) { } got := cfg.ProviderTypes() - want := []string{ - "aws", - "null", - "template", + want := []addrs.Provider{ + addrs.NewLegacyProvider("aws"), + addrs.NewLegacyProvider("null"), + addrs.NewLegacyProvider("template"), } for _, problem := range deep.Equal(got, want) { t.Error(problem) } } + +func TestConfigResolveAbsProviderAddr(t *testing.T) { + mod, diags := testModuleFromDir("testdata/providers-explicit-fqn") + if diags.HasErrors() { + t.Fatal(diags.Error()) + } + + cfg, diags := BuildConfig(mod, nil) + if diags.HasErrors() { + t.Fatal(diags.Error()) + } + + t.Run("already absolute", func(t *testing.T) { + addr := addrs.AbsProviderConfig{ + Module: addrs.RootModuleInstance, + ProviderConfig: addrs.LocalProviderConfig{ + LocalName: "test", + Alias: "boop", + }, + } + got := cfg.ResolveAbsProviderAddr(addr, addrs.RootModuleInstance) + if got, want := got.String(), addr.String(); got != want { + t.Errorf("wrong result\ngot: %s\nwant: %s", got, want) + } + }) + t.Run("local, implied mapping", func(t *testing.T) { + addr := addrs.LocalProviderConfig{ + LocalName: "implied", + Alias: "boop", + } + got := cfg.ResolveAbsProviderAddr(addr, addrs.RootModuleInstance) + want := addrs.AbsProviderConfig{ + Module: addrs.RootModuleInstance, + // FIXME: At the time of writing we still have LocalProviderConfig + // nested inside AbsProviderConfig, but a future change will + // stop tis embedding and just have an addrs.Provider and an alias + // string here, at which point the correct result will be: + // Provider as the addrs repr of "registry.terraform.io/hashicorp/implied" + // Alias as "boop". + ProviderConfig: addrs.LocalProviderConfig{ + LocalName: "implied", + Alias: "boop", + }, + } + if got, want := got.String(), want.String(); got != want { + t.Errorf("wrong result\ngot: %s\nwant: %s", got, want) + } + }) + t.Run("local, explicit mapping", func(t *testing.T) { + addr := addrs.LocalProviderConfig{ + LocalName: "foo_test", // this is explicitly set in the config + Alias: "boop", + } + got := cfg.ResolveAbsProviderAddr(addr, addrs.RootModuleInstance) + want := addrs.AbsProviderConfig{ + Module: addrs.RootModuleInstance, + // FIXME: At the time of writing we're not actually supporting + // the explicit mapping to FQNs because we're still in + // legacy-only mode, so this is temporarily correct. However, + // once we are fully supporting this we should expect to see + // the "registry.terraform.io/foo/test" FQN here, while still + // preserving the "boop" alias. + ProviderConfig: addrs.LocalProviderConfig{ + LocalName: "foo_test", + Alias: "boop", + }, + } + if got, want := got.String(), want.String(); got != want { + t.Errorf("wrong result\ngot: %s\nwant: %s", got, want) + } + }) +} diff --git a/configs/configupgrade/analysis.go b/configs/configupgrade/analysis.go index 49b63d845..e01d4a9a0 100644 --- a/configs/configupgrade/analysis.go +++ b/configs/configupgrade/analysis.go @@ -179,7 +179,7 @@ func (u *Upgrader) analyze(ms ModuleSources) (*analysis, error) { } if providerKey == "" { - providerKey = rAddr.DefaultProviderConfig().StringCompact() + providerKey = rAddr.DefaultProvider().LegacyString() } inst := moduledeps.ProviderInstance(providerKey) diff --git a/configs/provider.go b/configs/provider.go index 6d7d6f03f..0dd187045 100644 --- a/configs/provider.go +++ b/configs/provider.go @@ -94,10 +94,10 @@ func decodeProviderBlock(block *hcl.Block) (*Provider, hcl.Diagnostics) { // Addr returns the address of the receiving provider configuration, relative // to its containing module. -func (p *Provider) Addr() addrs.ProviderConfig { - return addrs.ProviderConfig{ - Type: p.Name, - Alias: p.Alias, +func (p *Provider) Addr() addrs.LocalProviderConfig { + return addrs.LocalProviderConfig{ + LocalName: p.Name, + Alias: p.Alias, } } @@ -120,10 +120,10 @@ func (p *Provider) moduleUniqueKey() string { // // If the returned diagnostics contains errors then the result value is invalid // and must not be used. -func ParseProviderConfigCompact(traversal hcl.Traversal) (addrs.ProviderConfig, tfdiags.Diagnostics) { +func ParseProviderConfigCompact(traversal hcl.Traversal) (addrs.LocalProviderConfig, tfdiags.Diagnostics) { var diags tfdiags.Diagnostics - ret := addrs.ProviderConfig{ - Type: traversal.RootName(), + ret := addrs.LocalProviderConfig{ + LocalName: traversal.RootName(), } if len(traversal) < 2 { @@ -172,13 +172,13 @@ func ParseProviderConfigCompact(traversal hcl.Traversal) (addrs.ProviderConfig, // of the traversal fails. There is no way for the caller to distinguish the // two kinds of diagnostics programmatically. If error diagnostics are returned // then the returned address is invalid. -func ParseProviderConfigCompactStr(str string) (addrs.ProviderConfig, tfdiags.Diagnostics) { +func ParseProviderConfigCompactStr(str string) (addrs.LocalProviderConfig, tfdiags.Diagnostics) { var diags tfdiags.Diagnostics traversal, parseDiags := hclsyntax.ParseTraversalAbs([]byte(str), "", hcl.Pos{Line: 1, Column: 1}) diags = diags.Append(parseDiags) if parseDiags.HasErrors() { - return addrs.ProviderConfig{}, diags + return addrs.LocalProviderConfig{}, diags } addr, addrDiags := ParseProviderConfigCompact(traversal) diff --git a/configs/provider_test.go b/configs/provider_test.go index 68535472f..7aefd8f4e 100644 --- a/configs/provider_test.go +++ b/configs/provider_test.go @@ -33,27 +33,27 @@ func TestProviderReservedNames(t *testing.T) { func TestParseProviderConfigCompact(t *testing.T) { tests := []struct { Input string - Want addrs.ProviderConfig + Want addrs.LocalProviderConfig WantDiag string }{ { `aws`, - addrs.ProviderConfig{ - Type: "aws", + addrs.LocalProviderConfig{ + LocalName: "aws", }, ``, }, { `aws.foo`, - addrs.ProviderConfig{ - Type: "aws", - Alias: "foo", + addrs.LocalProviderConfig{ + LocalName: "aws", + Alias: "foo", }, ``, }, { `aws["foo"]`, - addrs.ProviderConfig{}, + addrs.LocalProviderConfig{}, `The provider type name must either stand alone or be followed by an alias name separated with a dot.`, }, } diff --git a/configs/resource.go b/configs/resource.go index 78f6a240c..ce7a41f87 100644 --- a/configs/resource.go +++ b/configs/resource.go @@ -64,14 +64,24 @@ func (r *Resource) Addr() addrs.Resource { // that should be used for this resource. This function implements the // default behavior of extracting the type from the resource type name if // an explicit "provider" argument was not provided. -func (r *Resource) ProviderConfigAddr() addrs.ProviderConfig { +func (r *Resource) ProviderConfigAddr() addrs.LocalProviderConfig { if r.ProviderConfigRef == nil { - return r.Addr().DefaultProviderConfig() + // TODO: This will become incorrect once we move away from legacy + // provider addresses, and we'll need to refactor here so that + // this lookup is on the Module type rather than the Resource + // type and can thus look at the local-to-FQN mapping table + // to find a suitable local name to use here. + fqn := r.Addr().DefaultProvider() + return addrs.LocalProviderConfig{ + // This will panic once non-legacy addresses are in play. + // See the TODO comment above ^^ + LocalName: fqn.LegacyString(), + } } - return addrs.ProviderConfig{ - Type: r.ProviderConfigRef.Name, - Alias: r.ProviderConfigRef.Alias, + return addrs.LocalProviderConfig{ + LocalName: r.ProviderConfigRef.Name, + Alias: r.ProviderConfigRef.Alias, } } @@ -445,10 +455,10 @@ func decodeProviderConfigRef(expr hcl.Expression, argName string) (*ProviderConf // // This is a trivial conversion, essentially just discarding the source // location information and keeping just the addressing information. -func (r *ProviderConfigRef) Addr() addrs.ProviderConfig { - return addrs.ProviderConfig{ - Type: r.Name, - Alias: r.Alias, +func (r *ProviderConfigRef) Addr() addrs.LocalProviderConfig { + return addrs.LocalProviderConfig{ + LocalName: r.Name, + Alias: r.Alias, } } diff --git a/configs/testdata/providers-explicit-fqn/root.tf b/configs/testdata/providers-explicit-fqn/root.tf new file mode 100644 index 000000000..e4ec41161 --- /dev/null +++ b/configs/testdata/providers-explicit-fqn/root.tf @@ -0,0 +1,8 @@ + +terraform { + required_providers { + foo_test = { + source = "foo/test" + } + } +} diff --git a/helper/resource/state_shim.go b/helper/resource/state_shim.go index afd60b318..47f46b801 100644 --- a/helper/resource/state_shim.go +++ b/helper/resource/state_shim.go @@ -48,7 +48,7 @@ func shimNewState(newState *states.State, providers map[string]terraform.Resourc for _, res := range newMod.Resources { resType := res.Addr.Type - providerType := res.ProviderConfig.ProviderConfig.Type + providerType := res.ProviderConfig.ProviderConfig.LocalName resource := getResource(providers, providerType, res.Addr) diff --git a/helper/resource/state_shim_test.go b/helper/resource/state_shim_test.go index a9c101a45..64d478428 100644 --- a/helper/resource/state_shim_test.go +++ b/helper/resource/state_shim_test.go @@ -41,8 +41,8 @@ func TestStateShim(t *testing.T) { }, }, }, - addrs.ProviderConfig{ - Type: "test", + addrs.LocalProviderConfig{ + LocalName: "test", }.Absolute(addrs.RootModuleInstance), ) rootModule.SetResourceInstanceCurrent( @@ -56,8 +56,8 @@ func TestStateShim(t *testing.T) { AttrsFlat: map[string]string{"id": "baz", "bazzle": "dazzle"}, DependsOn: []addrs.Referenceable{}, }, - addrs.ProviderConfig{ - Type: "test", + addrs.LocalProviderConfig{ + LocalName: "test", }.Absolute(addrs.RootModuleInstance), ) @@ -74,8 +74,8 @@ func TestStateShim(t *testing.T) { AttrsJSON: []byte(`{"id": "bar", "fuzzle":"wuzzle"}`), DependsOn: []addrs.Referenceable{}, }, - addrs.ProviderConfig{ - Type: "test", + addrs.LocalProviderConfig{ + LocalName: "test", }.Absolute(childInstance), ) childModule.SetResourceInstanceCurrent( @@ -97,8 +97,8 @@ func TestStateShim(t *testing.T) { }, }, }, - addrs.ProviderConfig{ - Type: "test", + addrs.LocalProviderConfig{ + LocalName: "test", }.Absolute(childInstance), ) @@ -122,8 +122,8 @@ func TestStateShim(t *testing.T) { }, }, }, - addrs.ProviderConfig{ - Type: "test", + addrs.LocalProviderConfig{ + LocalName: "test", }.Absolute(childInstance), ) @@ -138,8 +138,8 @@ func TestStateShim(t *testing.T) { AttrsFlat: map[string]string{"id": "0", "bazzle": "dazzle"}, DependsOn: []addrs.Referenceable{}, }, - addrs.ProviderConfig{ - Type: "test", + addrs.LocalProviderConfig{ + LocalName: "test", }.Absolute(childInstance), ) childModule.SetResourceInstanceCurrent( @@ -153,8 +153,8 @@ func TestStateShim(t *testing.T) { AttrsFlat: map[string]string{"id": "1", "bazzle": "dazzle"}, DependsOn: []addrs.Referenceable{}, }, - addrs.ProviderConfig{ - Type: "test", + addrs.LocalProviderConfig{ + LocalName: "test", }.Absolute(childInstance), ) @@ -169,8 +169,8 @@ func TestStateShim(t *testing.T) { AttrsJSON: []byte(`{"id": "single", "bazzle":"dazzle"}`), DependsOn: []addrs.Referenceable{}, }, - addrs.ProviderConfig{ - Type: "test", + addrs.LocalProviderConfig{ + LocalName: "test", }.Absolute(childInstance), ) diff --git a/helper/resource/testing.go b/helper/resource/testing.go index 0e5af0933..063fadb86 100644 --- a/helper/resource/testing.go +++ b/helper/resource/testing.go @@ -727,7 +727,7 @@ func testIDOnlyRefresh(c TestCase, opts terraform.ContextOpts, step TestStep, r AttrsFlat: r.Primary.Attributes, Status: states.ObjectReady, }, - addrs.ProviderConfig{Type: "placeholder"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "placeholder"}.Absolute(addrs.RootModuleInstance), ) // Create the config module. We use the full config because Refresh diff --git a/helper/resource/testing_import_state.go b/helper/resource/testing_import_state.go index 1f3796176..50dacc348 100644 --- a/helper/resource/testing_import_state.go +++ b/helper/resource/testing_import_state.go @@ -137,7 +137,7 @@ func testStepImportState( // this shouldn't happen in any reasonable case. var rsrcSchema *schema.Resource if providerAddr, diags := addrs.ParseAbsProviderConfigStr(r.Provider); !diags.HasErrors() { - providerType := providerAddr.ProviderConfig.Type + providerType := providerAddr.ProviderConfig.LocalName if provider, ok := step.providers[providerType]; ok { if provider, ok := provider.(*schema.Provider); ok { rsrcSchema = provider.ResourcesMap[r.Type] diff --git a/plans/plan_test.go b/plans/plan_test.go index f68357072..e2be0f321 100644 --- a/plans/plan_test.go +++ b/plans/plan_test.go @@ -20,8 +20,8 @@ func TestProviderAddrs(t *testing.T) { Type: "test_thing", Name: "woot", }.Instance(addrs.IntKey(0)).Absolute(addrs.RootModuleInstance), - ProviderAddr: addrs.ProviderConfig{ - Type: "test", + ProviderAddr: addrs.LocalProviderConfig{ + LocalName: "test", }.Absolute(addrs.RootModuleInstance), }, { @@ -31,8 +31,8 @@ func TestProviderAddrs(t *testing.T) { Name: "woot", }.Instance(addrs.IntKey(0)).Absolute(addrs.RootModuleInstance), DeposedKey: "foodface", - ProviderAddr: addrs.ProviderConfig{ - Type: "test", + ProviderAddr: addrs.LocalProviderConfig{ + LocalName: "test", }.Absolute(addrs.RootModuleInstance), }, { @@ -41,8 +41,8 @@ func TestProviderAddrs(t *testing.T) { Type: "test_thing", Name: "what", }.Instance(addrs.IntKey(0)).Absolute(addrs.RootModuleInstance), - ProviderAddr: addrs.ProviderConfig{ - Type: "test", + ProviderAddr: addrs.LocalProviderConfig{ + LocalName: "test", }.Absolute(addrs.RootModuleInstance.Child("foo", addrs.NoKey)), }, }, @@ -51,11 +51,11 @@ func TestProviderAddrs(t *testing.T) { got := plan.ProviderAddrs() want := []addrs.AbsProviderConfig{ - addrs.ProviderConfig{ - Type: "test", + addrs.LocalProviderConfig{ + LocalName: "test", }.Absolute(addrs.RootModuleInstance.Child("foo", addrs.NoKey)), - addrs.ProviderConfig{ - Type: "test", + addrs.LocalProviderConfig{ + LocalName: "test", }.Absolute(addrs.RootModuleInstance), } diff --git a/plans/planfile/tfplan_test.go b/plans/planfile/tfplan_test.go index 2b49553ac..da97d0102 100644 --- a/plans/planfile/tfplan_test.go +++ b/plans/planfile/tfplan_test.go @@ -56,8 +56,8 @@ func TestTFPlanRoundTrip(t *testing.T) { Type: "test_thing", Name: "woot", }.Instance(addrs.IntKey(0)).Absolute(addrs.RootModuleInstance), - ProviderAddr: addrs.ProviderConfig{ - Type: "test", + ProviderAddr: addrs.LocalProviderConfig{ + LocalName: "test", }.Absolute(addrs.RootModuleInstance), ChangeSrc: plans.ChangeSrc{ Action: plans.DeleteThenCreate, @@ -76,8 +76,8 @@ func TestTFPlanRoundTrip(t *testing.T) { Name: "woot", }.Instance(addrs.IntKey(0)).Absolute(addrs.RootModuleInstance), DeposedKey: "foodface", - ProviderAddr: addrs.ProviderConfig{ - Type: "test", + ProviderAddr: addrs.LocalProviderConfig{ + LocalName: "test", }.Absolute(addrs.RootModuleInstance), ChangeSrc: plans.ChangeSrc{ Action: plans.Delete, @@ -194,8 +194,8 @@ func TestTFPlanRoundTripDestroy(t *testing.T) { Type: "test_thing", Name: "woot", }.Instance(addrs.IntKey(0)).Absolute(addrs.RootModuleInstance), - ProviderAddr: addrs.ProviderConfig{ - Type: "test", + ProviderAddr: addrs.LocalProviderConfig{ + LocalName: "test", }.Absolute(addrs.RootModuleInstance), ChangeSrc: plans.ChangeSrc{ Action: plans.Delete, diff --git a/providers/addressed_types.go b/providers/addressed_types.go index 7ed523f15..317ac355d 100644 --- a/providers/addressed_types.go +++ b/providers/addressed_types.go @@ -8,13 +8,21 @@ import ( // AddressedTypes is a helper that extracts all of the distinct provider // types from the given list of relative provider configuration addresses. -func AddressedTypes(providerAddrs []addrs.ProviderConfig) []string { +// +// FIXME: This function is now incorrect, because we can't do a syntax-only +// mapping from a local provider configuration to a provider type. It +// works for now by assuming legacy provider addresses, but will need to be +// replaced by something configuration-aware as part of removing legacy +// provider address reliance. +func AddressedTypes(providerAddrs []addrs.LocalProviderConfig) []addrs.Provider { if len(providerAddrs) == 0 { return nil } - m := map[string]struct{}{} + m := map[string]addrs.Provider{} for _, addr := range providerAddrs { - m[addr.Type] = struct{}{} + // FIXME: This will no longer work once we move away from legacy addresses. + legacyFQN := addrs.NewLegacyProvider(addr.LocalName) + m[legacyFQN.String()] = legacyFQN } names := make([]string, 0, len(m)) @@ -23,18 +31,27 @@ func AddressedTypes(providerAddrs []addrs.ProviderConfig) []string { } sort.Strings(names) // Stable result for tests - return names + + ret := make([]addrs.Provider, len(names)) + for i, name := range names { + ret[i] = m[name] + } + + return ret } // AddressedTypesAbs is a helper that extracts all of the distinct provider // types from the given list of absolute provider configuration addresses. -func AddressedTypesAbs(providerAddrs []addrs.AbsProviderConfig) []string { +func AddressedTypesAbs(providerAddrs []addrs.AbsProviderConfig) []addrs.Provider { if len(providerAddrs) == 0 { return nil } - m := map[string]struct{}{} + m := map[string]addrs.Provider{} for _, addr := range providerAddrs { - m[addr.ProviderConfig.Type] = struct{}{} + // FIXME: When changing AbsProviderConfig to include provider FQN, + // use that directly here instead. + legacyFQN := addrs.NewLegacyProvider(addr.ProviderConfig.LocalName) + m[legacyFQN.String()] = legacyFQN } names := make([]string, 0, len(m)) @@ -43,5 +60,11 @@ func AddressedTypesAbs(providerAddrs []addrs.AbsProviderConfig) []string { } sort.Strings(names) // Stable result for tests - return names + + ret := make([]addrs.Provider, len(names)) + for i, name := range names { + ret[i] = m[name] + } + + return ret } diff --git a/providers/addressed_types_test.go b/providers/addressed_types_test.go index 80915e3e6..41cccf466 100644 --- a/providers/addressed_types_test.go +++ b/providers/addressed_types_test.go @@ -9,19 +9,19 @@ import ( ) func TestAddressedTypes(t *testing.T) { - providerAddrs := []addrs.ProviderConfig{ - {Type: "aws"}, - {Type: "aws", Alias: "foo"}, - {Type: "azure"}, - {Type: "null"}, - {Type: "null"}, + providerAddrs := []addrs.LocalProviderConfig{ + {LocalName: "aws"}, + {LocalName: "aws", Alias: "foo"}, + {LocalName: "azure"}, + {LocalName: "null"}, + {LocalName: "null"}, } got := AddressedTypes(providerAddrs) - want := []string{ - "aws", - "azure", - "null", + want := []addrs.Provider{ + addrs.NewLegacyProvider("aws"), + addrs.NewLegacyProvider("azure"), + addrs.NewLegacyProvider("null"), } for _, problem := range deep.Equal(got, want) { t.Error(problem) @@ -30,18 +30,18 @@ func TestAddressedTypes(t *testing.T) { func TestAddressedTypesAbs(t *testing.T) { providerAddrs := []addrs.AbsProviderConfig{ - addrs.ProviderConfig{Type: "aws"}.Absolute(addrs.RootModuleInstance), - addrs.ProviderConfig{Type: "aws", Alias: "foo"}.Absolute(addrs.RootModuleInstance), - addrs.ProviderConfig{Type: "azure"}.Absolute(addrs.RootModuleInstance), - addrs.ProviderConfig{Type: "null"}.Absolute(addrs.RootModuleInstance), - addrs.ProviderConfig{Type: "null"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "aws"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "aws", Alias: "foo"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "azure"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "null"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "null"}.Absolute(addrs.RootModuleInstance), } got := AddressedTypesAbs(providerAddrs) - want := []string{ - "aws", - "azure", - "null", + want := []addrs.Provider{ + addrs.NewLegacyProvider("aws"), + addrs.NewLegacyProvider("azure"), + addrs.NewLegacyProvider("null"), } for _, problem := range deep.Equal(got, want) { t.Error(problem) diff --git a/repl/session_test.go b/repl/session_test.go index 0d2f37326..44e32ba75 100644 --- a/repl/session_test.go +++ b/repl/session_test.go @@ -45,8 +45,8 @@ func TestSession_basicState(t *testing.T) { Status: states.ObjectReady, AttrsJSON: []byte(`{"id":"bar"}`), }, - addrs.ProviderConfig{ - Type: "test", + addrs.LocalProviderConfig{ + LocalName: "test", }.Absolute(addrs.RootModuleInstance), ) s.SetResourceInstanceCurrent( @@ -59,8 +59,8 @@ func TestSession_basicState(t *testing.T) { Status: states.ObjectReady, AttrsJSON: []byte(`{"id":"bar"}`), }, - addrs.ProviderConfig{ - Type: "test", + addrs.LocalProviderConfig{ + LocalName: "test", }.Absolute(addrs.RootModuleInstance), ) }) diff --git a/states/state_test.go b/states/state_test.go index 22a43859f..7f1573f20 100644 --- a/states/state_test.go +++ b/states/state_test.go @@ -35,8 +35,8 @@ func TestState(t *testing.T) { SchemaVersion: 1, AttrsJSON: []byte(`{"woozles":"confuzles"}`), }, - addrs.ProviderConfig{ - Type: "test", + addrs.LocalProviderConfig{ + LocalName: "test", }.Absolute(addrs.RootModuleInstance), ) @@ -78,8 +78,8 @@ func TestState(t *testing.T) { Deposed: map[DeposedKey]*ResourceInstanceObjectSrc{}, }, }, - ProviderConfig: addrs.ProviderConfig{ - Type: "test", + ProviderConfig: addrs.LocalProviderConfig{ + LocalName: "test", }.Absolute(addrs.RootModuleInstance), }, }, @@ -140,8 +140,8 @@ func TestStateDeepCopy(t *testing.T) { Private: []byte("private data"), Dependencies: []addrs.AbsResource{}, }, - addrs.ProviderConfig{ - Type: "test", + addrs.LocalProviderConfig{ + LocalName: "test", }.Absolute(addrs.RootModuleInstance), ) rootModule.SetResourceInstanceCurrent( @@ -166,8 +166,8 @@ func TestStateDeepCopy(t *testing.T) { }, }, }, - addrs.ProviderConfig{ - Type: "test", + addrs.LocalProviderConfig{ + LocalName: "test", }.Absolute(addrs.RootModuleInstance), ) diff --git a/states/statefile/version3_upgrade.go b/states/statefile/version3_upgrade.go index 4e38aca34..9f21e2e6b 100644 --- a/states/statefile/version3_upgrade.go +++ b/states/statefile/version3_upgrade.go @@ -137,7 +137,17 @@ func upgradeStateV3ToV4(old *stateV3) (*stateV4, error) { } providerAddr = localAddr.Absolute(moduleAddr) } else { - providerAddr = resAddr.DefaultProviderConfig().Absolute(moduleAddr) + defaultProvider := resAddr.DefaultProvider() + // FIXME: Once AbsProviderConfig is using addrs.Provider + // instead of embedding LocalProviderConfig, just use + // the defaultProvider value as the FQN here, removing + // the reliance on legacy address forms. + providerAddr = addrs.AbsProviderConfig{ + Module: moduleAddr, + ProviderConfig: addrs.LocalProviderConfig{ + LocalName: defaultProvider.LegacyString(), + }, + } } } diff --git a/states/statemgr/testing.go b/states/statemgr/testing.go index 8b2f2cbb3..45b8a5f51 100644 --- a/states/statemgr/testing.go +++ b/states/statemgr/testing.go @@ -5,13 +5,11 @@ import ( "testing" "github.com/davecgh/go-spew/spew" - - "github.com/hashicorp/terraform/states/statefile" - - "github.com/hashicorp/terraform/addrs" "github.com/zclconf/go-cty/cty" + "github.com/hashicorp/terraform/addrs" "github.com/hashicorp/terraform/states" + "github.com/hashicorp/terraform/states/statefile" ) // TestFull is a helper for testing full state manager implementations. It @@ -152,6 +150,6 @@ func TestFullInitialState() *states.State { Type: "null_resource", Name: "foo", } - childMod.SetResourceMeta(rAddr, states.EachList, rAddr.DefaultProviderConfig().Absolute(addrs.RootModuleInstance)) + childMod.SetResourceMeta(rAddr, states.EachList, addrs.NewDefaultLocalProviderConfig(rAddr.DefaultProvider().LegacyString()).Absolute(addrs.RootModuleInstance)) return state } diff --git a/terraform/context_apply_test.go b/terraform/context_apply_test.go index 78a357eb0..59d643a85 100644 --- a/terraform/context_apply_test.go +++ b/terraform/context_apply_test.go @@ -1370,8 +1370,8 @@ func TestContext2Apply_destroyDependsOnStateOnly(t *testing.T) { AttrsJSON: []byte(`{"id":"foo"}`), Dependencies: []addrs.AbsResource{}, }, - addrs.ProviderConfig{ - Type: "aws", + addrs.LocalProviderConfig{ + LocalName: "aws", }.Absolute(addrs.RootModuleInstance), ) root.SetResourceInstanceCurrent( @@ -1394,8 +1394,8 @@ func TestContext2Apply_destroyDependsOnStateOnly(t *testing.T) { }, }, }, - addrs.ProviderConfig{ - Type: "aws", + addrs.LocalProviderConfig{ + LocalName: "aws", }.Absolute(addrs.RootModuleInstance), ) @@ -1497,8 +1497,8 @@ func TestContext2Apply_destroyDependsOnStateOnlyModule(t *testing.T) { AttrsJSON: []byte(`{"id":"foo"}`), Dependencies: []addrs.AbsResource{}, }, - addrs.ProviderConfig{ - Type: "aws", + addrs.LocalProviderConfig{ + LocalName: "aws", }.Absolute(addrs.RootModuleInstance), ) child.SetResourceInstanceCurrent( @@ -1521,8 +1521,8 @@ func TestContext2Apply_destroyDependsOnStateOnlyModule(t *testing.T) { }, }, }, - addrs.ProviderConfig{ - Type: "aws", + addrs.LocalProviderConfig{ + LocalName: "aws", }.Absolute(addrs.RootModuleInstance), ) @@ -2145,7 +2145,7 @@ func TestContext2Apply_provisionerDestroyForEach(t *testing.T) { }, ProviderConfig: addrs.AbsProviderConfig{ Module: addrs.ModuleInstance(nil), - ProviderConfig: addrs.ProviderConfig{Type: "aws", Alias: ""}, + ProviderConfig: addrs.LocalProviderConfig{LocalName: "aws", Alias: ""}, }, }, }, @@ -2965,8 +2965,8 @@ func TestContext2Apply_orphanResource(t *testing.T) { // At this point both resources should be recorded in the state, along // with the single instance associated with test_thing.one. want := states.BuildState(func(s *states.SyncState) { - providerAddr := addrs.ProviderConfig{ - Type: "test", + providerAddr := addrs.LocalProviderConfig{ + LocalName: "test", }.Absolute(addrs.RootModuleInstance) zeroAddr := addrs.Resource{ Mode: addrs.ManagedResourceMode, @@ -7390,8 +7390,8 @@ func TestContext2Apply_errorDestroy(t *testing.T) { Status: states.ObjectReady, AttrsJSON: []byte(`{"id":"baz"}`), }, - addrs.ProviderConfig{ - Type: "test", + addrs.LocalProviderConfig{ + LocalName: "test", }.Absolute(addrs.RootModuleInstance), ) }), @@ -7529,8 +7529,8 @@ func TestContext2Apply_errorUpdateNullNew(t *testing.T) { Status: states.ObjectReady, AttrsJSON: []byte(`{"value":"old"}`), }, - addrs.ProviderConfig{ - Type: "aws", + addrs.LocalProviderConfig{ + LocalName: "aws", }.Absolute(addrs.RootModuleInstance), ) }), @@ -9192,8 +9192,8 @@ func TestContext2Apply_createBefore_depends(t *testing.T) { Status: states.ObjectReady, AttrsJSON: []byte(`{"id":"bar","require_new":"ami-old"}`), }, - addrs.ProviderConfig{ - Type: "aws", + addrs.LocalProviderConfig{ + LocalName: "aws", }.Absolute(addrs.RootModuleInstance), ) @@ -9217,8 +9217,8 @@ func TestContext2Apply_createBefore_depends(t *testing.T) { }, }, }, - addrs.ProviderConfig{ - Type: "aws", + addrs.LocalProviderConfig{ + LocalName: "aws", }.Absolute(addrs.RootModuleInstance), ) @@ -9323,8 +9323,8 @@ func TestContext2Apply_singleDestroy(t *testing.T) { Status: states.ObjectReady, AttrsJSON: []byte(`{"id":"bar","require_new":"ami-old"}`), }, - addrs.ProviderConfig{ - Type: "aws", + addrs.LocalProviderConfig{ + LocalName: "aws", }.Absolute(addrs.RootModuleInstance), ) @@ -9348,8 +9348,8 @@ func TestContext2Apply_singleDestroy(t *testing.T) { }, }, }, - addrs.ProviderConfig{ - Type: "aws", + addrs.LocalProviderConfig{ + LocalName: "aws", }.Absolute(addrs.RootModuleInstance), ) @@ -10266,9 +10266,9 @@ func TestContext2Apply_destroyWithProviders(t *testing.T) { } // correct the state - s.Modules["module.mod.module.removed"].Resources["aws_instance.child"].ProviderConfig = addrs.ProviderConfig{ - Type: "aws", - Alias: "bar", + s.Modules["module.mod.module.removed"].Resources["aws_instance.child"].ProviderConfig = addrs.LocalProviderConfig{ + LocalName: "aws", + Alias: "bar", }.Absolute(addrs.RootModuleInstance) if _, diags := ctx.Plan(); diags.HasErrors() { @@ -10690,8 +10690,8 @@ func TestContext2Apply_issue19908(t *testing.T) { AttrsJSON: []byte(`{"baz":"old"}`), Status: states.ObjectReady, }, - addrs.ProviderConfig{ - Type: "test", + addrs.LocalProviderConfig{ + LocalName: "test", }.Absolute(addrs.RootModuleInstance), ) }), @@ -10817,8 +10817,8 @@ func TestContext2Apply_moduleReplaceCycle(t *testing.T) { Status: states.ObjectReady, AttrsJSON: []byte(`{"id":"a","require_new":"old"}`), }, - addrs.ProviderConfig{ - Type: "aws", + addrs.LocalProviderConfig{ + LocalName: "aws", }.Absolute(addrs.RootModuleInstance), ) @@ -10833,8 +10833,8 @@ func TestContext2Apply_moduleReplaceCycle(t *testing.T) { Status: states.ObjectReady, AttrsJSON: []byte(`{"id":"b","require_new":"old"}`), }, - addrs.ProviderConfig{ - Type: "aws", + addrs.LocalProviderConfig{ + LocalName: "aws", }.Absolute(addrs.RootModuleInstance), ) @@ -10875,8 +10875,8 @@ func TestContext2Apply_moduleReplaceCycle(t *testing.T) { Type: "aws_instance", Name: "a", }.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance.Child("a", addrs.NoKey)), - ProviderAddr: addrs.ProviderConfig{ - Type: "aws", + ProviderAddr: addrs.LocalProviderConfig{ + LocalName: "aws", }.Absolute(addrs.RootModuleInstance), ChangeSrc: plans.ChangeSrc{ Action: aAction, @@ -10890,8 +10890,8 @@ func TestContext2Apply_moduleReplaceCycle(t *testing.T) { Type: "aws_instance", Name: "b", }.Instance(addrs.IntKey(0)).Absolute(addrs.RootModuleInstance.Child("b", addrs.NoKey)), - ProviderAddr: addrs.ProviderConfig{ - Type: "aws", + ProviderAddr: addrs.LocalProviderConfig{ + LocalName: "aws", }.Absolute(addrs.RootModuleInstance), ChangeSrc: plans.ChangeSrc{ Action: plans.DeleteThenCreate, @@ -10940,8 +10940,8 @@ func TestContext2Apply_destroyDataCycle(t *testing.T) { Status: states.ObjectReady, AttrsJSON: []byte(`{"id":"a"}`), }, - addrs.ProviderConfig{ - Type: "null", + addrs.LocalProviderConfig{ + LocalName: "null", }.Absolute(addrs.RootModuleInstance), ) root.SetResourceInstanceCurrent( @@ -10954,8 +10954,8 @@ func TestContext2Apply_destroyDataCycle(t *testing.T) { Status: states.ObjectReady, AttrsJSON: []byte(`{"id":"data"}`), }, - addrs.ProviderConfig{ - Type: "null", + addrs.LocalProviderConfig{ + LocalName: "null", }.Absolute(addrs.RootModuleInstance), ) @@ -11028,8 +11028,8 @@ func TestContext2Apply_taintedDestroyFailure(t *testing.T) { Status: states.ObjectTainted, AttrsJSON: []byte(`{"id":"a","foo":"a"}`), }, - addrs.ProviderConfig{ - Type: "test", + addrs.LocalProviderConfig{ + LocalName: "test", }.Absolute(addrs.RootModuleInstance), ) root.SetResourceInstanceCurrent( @@ -11042,8 +11042,8 @@ func TestContext2Apply_taintedDestroyFailure(t *testing.T) { Status: states.ObjectTainted, AttrsJSON: []byte(`{"id":"b","foo":"b"}`), }, - addrs.ProviderConfig{ - Type: "test", + addrs.LocalProviderConfig{ + LocalName: "test", }.Absolute(addrs.RootModuleInstance), ) root.SetResourceInstanceCurrent( @@ -11056,8 +11056,8 @@ func TestContext2Apply_taintedDestroyFailure(t *testing.T) { Status: states.ObjectTainted, AttrsJSON: []byte(`{"id":"c","foo":"old"}`), }, - addrs.ProviderConfig{ - Type: "test", + addrs.LocalProviderConfig{ + LocalName: "test", }.Absolute(addrs.RootModuleInstance), ) @@ -11232,8 +11232,8 @@ func TestContext2Apply_cbdCycle(t *testing.T) { }, }, }, - addrs.ProviderConfig{ - Type: "test", + addrs.LocalProviderConfig{ + LocalName: "test", }.Absolute(addrs.RootModuleInstance), ) root.SetResourceInstanceCurrent( @@ -11256,8 +11256,8 @@ func TestContext2Apply_cbdCycle(t *testing.T) { }, }, }, - addrs.ProviderConfig{ - Type: "test", + addrs.LocalProviderConfig{ + LocalName: "test", }.Absolute(addrs.RootModuleInstance), ) root.SetResourceInstanceCurrent( @@ -11270,8 +11270,8 @@ func TestContext2Apply_cbdCycle(t *testing.T) { Status: states.ObjectReady, AttrsJSON: []byte(`{"id":"c","require_new":"old"}`), }, - addrs.ProviderConfig{ - Type: "test", + addrs.LocalProviderConfig{ + LocalName: "test", }.Absolute(addrs.RootModuleInstance), ) diff --git a/terraform/context_import_test.go b/terraform/context_import_test.go index 56d60f1b9..aea5f0e41 100644 --- a/terraform/context_import_test.go +++ b/terraform/context_import_test.go @@ -115,7 +115,7 @@ func TestContextImport_collision(t *testing.T) { }, Status: states.ObjectReady, }, - addrs.ProviderConfig{Type: "aws"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "aws"}.Absolute(addrs.RootModuleInstance), ) }), }) @@ -601,7 +601,7 @@ func TestContextImport_moduleDiff(t *testing.T) { }, Status: states.ObjectReady, }, - addrs.ProviderConfig{Type: "aws"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "aws"}.Absolute(addrs.RootModuleInstance), ) }), }) @@ -659,7 +659,7 @@ func TestContextImport_moduleExisting(t *testing.T) { }, Status: states.ObjectReady, }, - addrs.ProviderConfig{Type: "aws"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "aws"}.Absolute(addrs.RootModuleInstance), ) }), }) diff --git a/terraform/context_input.go b/terraform/context_input.go index d24adcb7c..90ea72def 100644 --- a/terraform/context_input.go +++ b/terraform/context_input.go @@ -53,7 +53,7 @@ func (c *Context) Input(mode InputMode) tfdiags.Diagnostics { // us to keep this relatively simple without significant hardship. pcs := make(map[string]*configs.Provider) - pas := make(map[string]addrs.ProviderConfig) + pas := make(map[string]addrs.LocalProviderConfig) for _, pc := range c.config.Module.ProviderConfigs { addr := pc.Addr() pcs[addr.String()] = pc @@ -96,12 +96,12 @@ func (c *Context) Input(mode InputMode) tfdiags.Diagnostics { UIInput: c.uiInput, } - schema := c.schemas.ProviderConfig(pa.Type) + schema := c.schemas.ProviderConfig(pa.LocalName) if schema == nil { // Could either be an incorrect config or just an incomplete // mock in tests. We'll let a later pass decide, and just // ignore this for the purposes of gathering input. - log.Printf("[TRACE] Context.Input: No schema available for provider type %q", pa.Type) + log.Printf("[TRACE] Context.Input: No schema available for provider type %q", pa.LocalName) continue } diff --git a/terraform/context_input_test.go b/terraform/context_input_test.go index 5782184e9..d57d8634c 100644 --- a/terraform/context_input_test.go +++ b/terraform/context_input_test.go @@ -478,7 +478,7 @@ func TestContext2Input_dataSourceRequiresRefresh(t *testing.T) { }, Status: states.ObjectReady, }, - addrs.ProviderConfig{Type: "null"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "null"}.Absolute(addrs.RootModuleInstance), ) }) diff --git a/terraform/context_plan_test.go b/terraform/context_plan_test.go index b069c3ec6..f4530e13f 100644 --- a/terraform/context_plan_test.go +++ b/terraform/context_plan_test.go @@ -4975,8 +4975,8 @@ func TestContext2Plan_ignoreChangesInMap(t *testing.T) { Status: states.ObjectReady, AttrsJSON: []byte(`{"tags":{"ignored":"from state","other":"from state"}}`), }, - addrs.ProviderConfig{ - Type: "test", + addrs.LocalProviderConfig{ + LocalName: "test", }.Absolute(addrs.RootModuleInstance), ) }) diff --git a/terraform/context_refresh_test.go b/terraform/context_refresh_test.go index 65e091e6c..851834e7e 100644 --- a/terraform/context_refresh_test.go +++ b/terraform/context_refresh_test.go @@ -103,8 +103,8 @@ func TestContext2Refresh_dynamicAttr(t *testing.T) { Status: states.ObjectReady, AttrsJSON: []byte(`{"dynamic":{"type":"string","value":"hello"}}`), }, - addrs.ProviderConfig{ - Type: "test", + addrs.LocalProviderConfig{ + LocalName: "test", }.Absolute(addrs.RootModuleInstance), ) }) @@ -1739,7 +1739,7 @@ func TestContext2Refresh_schemaUpgradeFlatmap(t *testing.T) { "id": "foo", }, }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) }) @@ -1822,7 +1822,7 @@ func TestContext2Refresh_schemaUpgradeJSON(t *testing.T) { SchemaVersion: 3, AttrsJSON: []byte(`{"id":"foo"}`), }, - addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance), + addrs.LocalProviderConfig{LocalName: "test"}.Absolute(addrs.RootModuleInstance), ) }) @@ -1990,8 +1990,8 @@ func TestRefresh_updateDependencies(t *testing.T) { }, }, }, - addrs.ProviderConfig{ - Type: "aws", + addrs.LocalProviderConfig{ + LocalName: "aws", }.Absolute(addrs.RootModuleInstance), ) root.SetResourceInstanceCurrent( @@ -2004,8 +2004,8 @@ func TestRefresh_updateDependencies(t *testing.T) { Status: states.ObjectReady, AttrsJSON: []byte(`{"id":"bar","foo":"foo"}`), }, - addrs.ProviderConfig{ - Type: "aws", + addrs.LocalProviderConfig{ + LocalName: "aws", }.Absolute(addrs.RootModuleInstance), ) diff --git a/terraform/eval_apply.go b/terraform/eval_apply.go index 215b9b657..349ca7854 100644 --- a/terraform/eval_apply.go +++ b/terraform/eval_apply.go @@ -128,7 +128,7 @@ func (n *EvalApply) Eval(ctx EvalContext) (interface{}, error) { "Provider produced invalid object", fmt.Sprintf( "Provider %q produced an invalid value after apply for %s. The result cannot not be saved in the Terraform state.\n\nThis is a bug in the provider, which should be reported in the provider's own issue tracker.", - n.ProviderAddr.ProviderConfig.Type, tfdiags.FormatErrorPrefixed(err, absAddr.String()), + n.ProviderAddr.ProviderConfig.LocalName, tfdiags.FormatErrorPrefixed(err, absAddr.String()), ), )) } @@ -198,7 +198,7 @@ func (n *EvalApply) Eval(ctx EvalContext) (interface{}, error) { // to notice in the logs if an inconsistency beyond the type system // leads to a downstream provider failure. var buf strings.Builder - fmt.Fprintf(&buf, "[WARN] Provider %q produced an unexpected new value for %s, but we are tolerating it because it is using the legacy plugin SDK.\n The following problems may be the cause of any confusing errors from downstream operations:", n.ProviderAddr.ProviderConfig.Type, absAddr) + fmt.Fprintf(&buf, "[WARN] Provider %q produced an unexpected new value for %s, but we are tolerating it because it is using the legacy plugin SDK.\n The following problems may be the cause of any confusing errors from downstream operations:", n.ProviderAddr.ProviderConfig.LocalName, absAddr) for _, err := range errs { fmt.Fprintf(&buf, "\n - %s", tfdiags.FormatError(err)) } @@ -218,7 +218,7 @@ func (n *EvalApply) Eval(ctx EvalContext) (interface{}, error) { "Provider produced inconsistent result after apply", fmt.Sprintf( "When applying changes to %s, provider %q produced an unexpected new value for %s.\n\nThis is a bug in the provider, which should be reported in the provider's own issue tracker.", - absAddr, n.ProviderAddr.ProviderConfig.Type, tfdiags.FormatError(err), + absAddr, n.ProviderAddr.ProviderConfig.LocalName, tfdiags.FormatError(err), ), )) } diff --git a/terraform/eval_context.go b/terraform/eval_context.go index ec7a3ae0e..05e272600 100644 --- a/terraform/eval_context.go +++ b/terraform/eval_context.go @@ -32,8 +32,10 @@ type EvalContext interface { // InitProvider initializes the provider with the given type and address, and // returns the implementation of the resource provider or an error. // - // It is an error to initialize the same provider more than once. - InitProvider(typ string, addr addrs.ProviderConfig) (providers.Interface, error) + // It is an error to initialize the same provider more than once. This + // method will panic if the module instance address of the given provider + // configuration does not match the Path() of the EvalContext. + InitProvider(typ string, addr addrs.AbsProviderConfig) (providers.Interface, error) // Provider gets the provider instance with the given address (already // initialized) or returns nil if the provider isn't initialized. @@ -52,18 +54,27 @@ type EvalContext interface { ProviderSchema(addrs.AbsProviderConfig) *ProviderSchema // CloseProvider closes provider connections that aren't needed anymore. - CloseProvider(addrs.ProviderConfig) error + // + // This method will panic if the module instance address of the given + // provider configuration does not match the Path() of the EvalContext. + CloseProvider(addrs.AbsProviderConfig) error // ConfigureProvider configures the provider with the given // configuration. This is a separate context call because this call // is used to store the provider configuration for inheritance lookups // with ParentProviderConfig(). - ConfigureProvider(addrs.ProviderConfig, cty.Value) tfdiags.Diagnostics + // + // This method will panic if the module instance address of the given + // provider configuration does not match the Path() of the EvalContext. + ConfigureProvider(addrs.AbsProviderConfig, cty.Value) tfdiags.Diagnostics // ProviderInput and SetProviderInput are used to configure providers // from user input. - ProviderInput(addrs.ProviderConfig) map[string]cty.Value - SetProviderInput(addrs.ProviderConfig, map[string]cty.Value) + // + // These methods will panic if the module instance address of the given + // provider configuration does not match the Path() of the EvalContext. + ProviderInput(addrs.AbsProviderConfig) map[string]cty.Value + SetProviderInput(addrs.AbsProviderConfig, map[string]cty.Value) // InitProvisioner initializes the provisioner with the given name and // returns the implementation of the resource provisioner or an error. diff --git a/terraform/eval_context_builtin.go b/terraform/eval_context_builtin.go index 283ce7785..97e89fcbe 100644 --- a/terraform/eval_context_builtin.go +++ b/terraform/eval_context_builtin.go @@ -103,9 +103,14 @@ func (ctx *BuiltinEvalContext) Input() UIInput { return ctx.InputValue } -func (ctx *BuiltinEvalContext) InitProvider(typeName string, addr addrs.ProviderConfig) (providers.Interface, error) { +func (ctx *BuiltinEvalContext) InitProvider(typeName string, addr addrs.AbsProviderConfig) (providers.Interface, error) { ctx.once.Do(ctx.init) - absAddr := addr.Absolute(ctx.Path()) + absAddr := addr + if !absAddr.Module.Equal(ctx.Path()) { + // 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())) + } // If we already initialized, it is an error if p := ctx.Provider(absAddr); p != nil { @@ -142,16 +147,23 @@ 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.ProviderConfig.Type) + // FIXME: Once AbsProviderConfig starts containing an FQN, use that directly + // here instead of addr.ProviderConfig.LocalName. + return ctx.Schemas.ProviderSchema(addr.ProviderConfig.LocalName) } -func (ctx *BuiltinEvalContext) CloseProvider(addr addrs.ProviderConfig) error { +func (ctx *BuiltinEvalContext) CloseProvider(addr addrs.AbsProviderConfig) error { ctx.once.Do(ctx.init) + if !addr.Module.Equal(ctx.Path()) { + // This indicates incorrect use of CloseProvider: it should be used + // only from the module that the provider configuration belongs to. + panic(fmt.Sprintf("%s closed by wrong module %s", addr, ctx.Path())) + } ctx.ProviderLock.Lock() defer ctx.ProviderLock.Unlock() - key := addr.Absolute(ctx.Path()).String() + key := addr.String() provider := ctx.ProviderCache[key] if provider != nil { delete(ctx.ProviderCache, key) @@ -161,9 +173,15 @@ func (ctx *BuiltinEvalContext) CloseProvider(addr addrs.ProviderConfig) error { return nil } -func (ctx *BuiltinEvalContext) ConfigureProvider(addr addrs.ProviderConfig, cfg cty.Value) tfdiags.Diagnostics { +func (ctx *BuiltinEvalContext) ConfigureProvider(addr addrs.AbsProviderConfig, cfg cty.Value) tfdiags.Diagnostics { var diags tfdiags.Diagnostics - absAddr := addr.Absolute(ctx.Path()) + absAddr := addr + if !absAddr.Module.Equal(ctx.Path()) { + // 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())) + } + p := ctx.Provider(absAddr) if p == nil { diags = diags.Append(fmt.Errorf("%s not initialized", addr)) @@ -185,10 +203,16 @@ func (ctx *BuiltinEvalContext) ConfigureProvider(addr addrs.ProviderConfig, cfg return resp.Diagnostics } -func (ctx *BuiltinEvalContext) ProviderInput(pc addrs.ProviderConfig) map[string]cty.Value { +func (ctx *BuiltinEvalContext) ProviderInput(pc addrs.AbsProviderConfig) map[string]cty.Value { ctx.ProviderLock.Lock() defer ctx.ProviderLock.Unlock() + if !pc.Module.Equal(ctx.Path()) { + // 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", pc, ctx.Path())) + } + if !ctx.Path().IsRoot() { // Only root module provider configurations can have input. return nil @@ -197,8 +221,13 @@ func (ctx *BuiltinEvalContext) ProviderInput(pc addrs.ProviderConfig) map[string return ctx.ProviderInputConfig[pc.String()] } -func (ctx *BuiltinEvalContext) SetProviderInput(pc addrs.ProviderConfig, c map[string]cty.Value) { - absProvider := pc.Absolute(ctx.Path()) +func (ctx *BuiltinEvalContext) SetProviderInput(pc addrs.AbsProviderConfig, c map[string]cty.Value) { + absProvider := pc + if !absProvider.Module.Equal(ctx.Path()) { + // 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", absProvider, ctx.Path())) + } if !ctx.Path().IsRoot() { // Only root module provider configurations can have input. diff --git a/terraform/eval_context_builtin_test.go b/terraform/eval_context_builtin_test.go index 1907d136e..c49d027ba 100644 --- a/terraform/eval_context_builtin_test.go +++ b/terraform/eval_context_builtin_test.go @@ -24,16 +24,27 @@ func TestBuiltinEvalContextProviderInput(t *testing.T) { ctx2.ProviderInputConfig = cache ctx2.ProviderLock = &lock - providerAddr := addrs.ProviderConfig{Type: "foo"} + providerAddr1 := addrs.AbsProviderConfig{ + Module: addrs.RootModuleInstance, + ProviderConfig: addrs.LocalProviderConfig{ + LocalName: "foo", + }, + } + providerAddr2 := addrs.AbsProviderConfig{ + Module: addrs.RootModuleInstance.Child("child", addrs.NoKey), + ProviderConfig: addrs.LocalProviderConfig{ + LocalName: "foo", + }, + } expected1 := map[string]cty.Value{"value": cty.StringVal("foo")} - ctx1.SetProviderInput(providerAddr, expected1) + ctx1.SetProviderInput(providerAddr1, expected1) try2 := map[string]cty.Value{"value": cty.StringVal("bar")} - ctx2.SetProviderInput(providerAddr, try2) // ignored because not a root module + ctx2.SetProviderInput(providerAddr2, try2) // ignored because not a root module - actual1 := ctx1.ProviderInput(providerAddr) - actual2 := ctx2.ProviderInput(providerAddr) + actual1 := ctx1.ProviderInput(providerAddr1) + actual2 := ctx2.ProviderInput(providerAddr2) if !reflect.DeepEqual(actual1, expected1) { t.Errorf("wrong result 1\ngot: %#v\nwant: %#v", actual1, expected1) @@ -57,8 +68,23 @@ func TestBuildingEvalContextInitProvider(t *testing.T) { }, } - providerAddrDefault := addrs.ProviderConfig{Type: "test"} - providerAddrAlias := addrs.ProviderConfig{Type: "test", Alias: "foo"} + // FIXME: Once AbsProviderConfig has a provider FQN instead of an + // embedded LocalProviderConfig, use a legacy or default provider address + // here depending on whether we've moved away from legacy provider + // addresses in general yet. + providerAddrDefault := addrs.AbsProviderConfig{ + Module: addrs.RootModuleInstance, + ProviderConfig: addrs.LocalProviderConfig{ + LocalName: "test", + }, + } + providerAddrAlias := addrs.AbsProviderConfig{ + Module: addrs.RootModuleInstance, + ProviderConfig: addrs.LocalProviderConfig{ + LocalName: "test", + Alias: "foo", + }, + } _, err := ctx.InitProvider("test", providerAddrDefault) if err != nil { diff --git a/terraform/eval_context_mock.go b/terraform/eval_context_mock.go index 0985e9e8b..7329dd31a 100644 --- a/terraform/eval_context_mock.go +++ b/terraform/eval_context_mock.go @@ -30,7 +30,7 @@ type MockEvalContext struct { InitProviderCalled bool InitProviderType string - InitProviderAddr addrs.ProviderConfig + InitProviderAddr addrs.AbsProviderConfig InitProviderProvider providers.Interface InitProviderError error @@ -43,19 +43,19 @@ type MockEvalContext struct { ProviderSchemaSchema *ProviderSchema CloseProviderCalled bool - CloseProviderAddr addrs.ProviderConfig + CloseProviderAddr addrs.AbsProviderConfig CloseProviderProvider providers.Interface ProviderInputCalled bool - ProviderInputAddr addrs.ProviderConfig + ProviderInputAddr addrs.AbsProviderConfig ProviderInputValues map[string]cty.Value SetProviderInputCalled bool - SetProviderInputAddr addrs.ProviderConfig + SetProviderInputAddr addrs.AbsProviderConfig SetProviderInputValues map[string]cty.Value ConfigureProviderCalled bool - ConfigureProviderAddr addrs.ProviderConfig + ConfigureProviderAddr addrs.AbsProviderConfig ConfigureProviderConfig cty.Value ConfigureProviderDiags tfdiags.Diagnostics @@ -150,7 +150,7 @@ func (c *MockEvalContext) Input() UIInput { return c.InputInput } -func (c *MockEvalContext) InitProvider(t string, addr addrs.ProviderConfig) (providers.Interface, error) { +func (c *MockEvalContext) InitProvider(t string, addr addrs.AbsProviderConfig) (providers.Interface, error) { c.InitProviderCalled = true c.InitProviderType = t c.InitProviderAddr = addr @@ -169,26 +169,26 @@ func (c *MockEvalContext) ProviderSchema(addr addrs.AbsProviderConfig) *Provider return c.ProviderSchemaSchema } -func (c *MockEvalContext) CloseProvider(addr addrs.ProviderConfig) error { +func (c *MockEvalContext) CloseProvider(addr addrs.AbsProviderConfig) error { c.CloseProviderCalled = true c.CloseProviderAddr = addr return nil } -func (c *MockEvalContext) ConfigureProvider(addr addrs.ProviderConfig, cfg cty.Value) tfdiags.Diagnostics { +func (c *MockEvalContext) ConfigureProvider(addr addrs.AbsProviderConfig, cfg cty.Value) tfdiags.Diagnostics { c.ConfigureProviderCalled = true c.ConfigureProviderAddr = addr c.ConfigureProviderConfig = cfg return c.ConfigureProviderDiags } -func (c *MockEvalContext) ProviderInput(addr addrs.ProviderConfig) map[string]cty.Value { +func (c *MockEvalContext) ProviderInput(addr addrs.AbsProviderConfig) map[string]cty.Value { c.ProviderInputCalled = true c.ProviderInputAddr = addr return c.ProviderInputValues } -func (c *MockEvalContext) SetProviderInput(addr addrs.ProviderConfig, vals map[string]cty.Value) { +func (c *MockEvalContext) SetProviderInput(addr addrs.AbsProviderConfig, vals map[string]cty.Value) { c.SetProviderInputCalled = true c.SetProviderInputAddr = addr c.SetProviderInputValues = vals diff --git a/terraform/eval_diff.go b/terraform/eval_diff.go index b675253e7..a0cdfc5f4 100644 --- a/terraform/eval_diff.go +++ b/terraform/eval_diff.go @@ -65,7 +65,7 @@ func (n *EvalCheckPlannedChange) Eval(ctx EvalContext) (interface{}, error) { "Provider produced inconsistent final plan", fmt.Sprintf( "When expanding the plan for %s to include new values learned so far during apply, provider %q changed the planned action from %s to %s.\n\nThis is a bug in the provider, which should be reported in the provider's own issue tracker.", - absAddr, n.ProviderAddr.ProviderConfig.Type, + absAddr, n.ProviderAddr.ProviderConfig.LocalName, plannedChange.Action, actualChange.Action, ), )) @@ -79,7 +79,7 @@ func (n *EvalCheckPlannedChange) Eval(ctx EvalContext) (interface{}, error) { "Provider produced inconsistent final plan", fmt.Sprintf( "When expanding the plan for %s to include new values learned so far during apply, provider %q produced an invalid new value for %s.\n\nThis is a bug in the provider, which should be reported in the provider's own issue tracker.", - absAddr, n.ProviderAddr.ProviderConfig.Type, tfdiags.FormatError(err), + absAddr, n.ProviderAddr.ProviderConfig.LocalName, tfdiags.FormatError(err), ), )) } @@ -120,7 +120,7 @@ func (n *EvalDiff) Eval(ctx EvalContext) (interface{}, error) { if providerSchema == nil { return nil, fmt.Errorf("provider schema is unavailable for %s", n.Addr) } - if n.ProviderAddr.ProviderConfig.Type == "" { + if n.ProviderAddr.ProviderConfig.LocalName == "" { panic(fmt.Sprintf("EvalDiff for %s does not have ProviderAddr set", n.Addr.Absolute(ctx.Path()))) } @@ -230,7 +230,7 @@ func (n *EvalDiff) Eval(ctx EvalContext) (interface{}, error) { "Provider produced invalid plan", fmt.Sprintf( "Provider %q planned an invalid value for %s.\n\nThis is a bug in the provider, which should be reported in the provider's own issue tracker.", - n.ProviderAddr.ProviderConfig.Type, tfdiags.FormatErrorPrefixed(err, absAddr.String()), + n.ProviderAddr.ProviderConfig.LocalName, tfdiags.FormatErrorPrefixed(err, absAddr.String()), ), )) } @@ -246,7 +246,7 @@ func (n *EvalDiff) Eval(ctx EvalContext) (interface{}, error) { // to notice in the logs if an inconsistency beyond the type system // leads to a downstream provider failure. var buf strings.Builder - fmt.Fprintf(&buf, "[WARN] Provider %q produced an invalid plan for %s, but we are tolerating it because it is using the legacy plugin SDK.\n The following problems may be the cause of any confusing errors from downstream operations:", n.ProviderAddr.ProviderConfig.Type, absAddr) + fmt.Fprintf(&buf, "[WARN] Provider %q produced an invalid plan for %s, but we are tolerating it because it is using the legacy plugin SDK.\n The following problems may be the cause of any confusing errors from downstream operations:", n.ProviderAddr.ProviderConfig.LocalName, absAddr) for _, err := range errs { fmt.Fprintf(&buf, "\n - %s", tfdiags.FormatError(err)) } @@ -258,7 +258,7 @@ func (n *EvalDiff) Eval(ctx EvalContext) (interface{}, error) { "Provider produced invalid plan", fmt.Sprintf( "Provider %q planned an invalid value for %s.\n\nThis is a bug in the provider, which should be reported in the provider's own issue tracker.", - n.ProviderAddr.ProviderConfig.Type, tfdiags.FormatErrorPrefixed(err, absAddr.String()), + n.ProviderAddr.ProviderConfig.LocalName, tfdiags.FormatErrorPrefixed(err, absAddr.String()), ), )) } @@ -301,7 +301,7 @@ func (n *EvalDiff) Eval(ctx EvalContext) (interface{}, error) { "Provider produced invalid plan", fmt.Sprintf( "Provider %q has indicated \"requires replacement\" on %s for a non-existent attribute path %#v.\n\nThis is a bug in the provider, which should be reported in the provider's own issue tracker.", - n.ProviderAddr.ProviderConfig.Type, absAddr, path, + n.ProviderAddr.ProviderConfig.LocalName, absAddr, path, ), )) continue @@ -397,7 +397,7 @@ func (n *EvalDiff) Eval(ctx EvalContext) (interface{}, error) { "Provider produced invalid plan", fmt.Sprintf( "Provider %q planned an invalid value for %s%s.\n\nThis is a bug in the provider, which should be reported in the provider's own issue tracker.", - n.ProviderAddr.ProviderConfig.Type, absAddr, tfdiags.FormatError(err), + n.ProviderAddr.ProviderConfig.LocalName, absAddr, tfdiags.FormatError(err), ), )) } @@ -603,7 +603,7 @@ func (n *EvalDiffDestroy) Eval(ctx EvalContext) (interface{}, error) { absAddr := n.Addr.Absolute(ctx.Path()) state := *n.State - if n.ProviderAddr.ProviderConfig.Type == "" { + if n.ProviderAddr.ProviderConfig.LocalName == "" { if n.DeposedKey == "" { panic(fmt.Sprintf("EvalDiffDestroy for %s does not have ProviderAddr set", absAddr)) } else { diff --git a/terraform/eval_provider.go b/terraform/eval_provider.go index 1b12b3cc8..9e25ad67c 100644 --- a/terraform/eval_provider.go +++ b/terraform/eval_provider.go @@ -12,7 +12,7 @@ import ( "github.com/hashicorp/terraform/tfdiags" ) -func buildProviderConfig(ctx EvalContext, addr addrs.ProviderConfig, config *configs.Provider) hcl.Body { +func buildProviderConfig(ctx EvalContext, addr addrs.AbsProviderConfig, config *configs.Provider) hcl.Body { var configBody hcl.Body if config != nil { configBody = config.Config @@ -49,7 +49,7 @@ func buildProviderConfig(ctx EvalContext, addr addrs.ProviderConfig, config *con // EvalConfigProvider is an EvalNode implementation that configures // a provider that is already initialized and retrieved. type EvalConfigProvider struct { - Addr addrs.ProviderConfig + Addr addrs.AbsProviderConfig Provider *providers.Interface Config *configs.Provider } @@ -89,7 +89,7 @@ func (n *EvalConfigProvider) Eval(ctx EvalContext) (interface{}, error) { // EvalGetProvider node. type EvalInitProvider struct { TypeName string - Addr addrs.ProviderConfig + Addr addrs.AbsProviderConfig } func (n *EvalInitProvider) Eval(ctx EvalContext) (interface{}, error) { @@ -99,7 +99,7 @@ func (n *EvalInitProvider) Eval(ctx EvalContext) (interface{}, error) { // EvalCloseProvider is an EvalNode implementation that closes provider // connections that aren't needed anymore. type EvalCloseProvider struct { - Addr addrs.ProviderConfig + Addr addrs.AbsProviderConfig } func (n *EvalCloseProvider) Eval(ctx EvalContext) (interface{}, error) { @@ -125,7 +125,7 @@ type EvalGetProvider struct { } func (n *EvalGetProvider) Eval(ctx EvalContext) (interface{}, error) { - if n.Addr.ProviderConfig.Type == "" { + if n.Addr.ProviderConfig.LocalName == "" { // Should never happen panic("EvalGetProvider used with uninitialized provider configuration address") } diff --git a/terraform/eval_provider_test.go b/terraform/eval_provider_test.go index f71688d37..61d093d63 100644 --- a/terraform/eval_provider_test.go +++ b/terraform/eval_provider_test.go @@ -16,8 +16,11 @@ func TestBuildProviderConfig(t *testing.T) { configBody := configs.SynthBody("", map[string]cty.Value{ "set_in_config": cty.StringVal("config"), }) - providerAddr := addrs.ProviderConfig{ - Type: "foo", + providerAddr := addrs.AbsProviderConfig{ + Module: addrs.RootModuleInstance, + ProviderConfig: addrs.LocalProviderConfig{ + LocalName: "foo", + }, } ctx := &MockEvalContext{ @@ -67,8 +70,14 @@ func TestEvalConfigProvider(t *testing.T) { } provider := mockProviderWithConfigSchema(simpleTestSchema()) rp := providers.Interface(provider) + providerAddr := addrs.AbsProviderConfig{ + Module: addrs.RootModuleInstance, + ProviderConfig: addrs.LocalProviderConfig{ + LocalName: "foo", + }, + } n := &EvalConfigProvider{ - Addr: addrs.ProviderConfig{Type: "foo"}, + Addr: providerAddr, Config: config, Provider: &rp, } @@ -97,8 +106,14 @@ func TestEvalInitProvider_impl(t *testing.T) { } func TestEvalInitProvider(t *testing.T) { + providerAddr := addrs.AbsProviderConfig{ + Module: addrs.RootModuleInstance, + ProviderConfig: addrs.LocalProviderConfig{ + LocalName: "foo", + }, + } n := &EvalInitProvider{ - Addr: addrs.ProviderConfig{Type: "foo"}, + Addr: providerAddr, } provider := &MockProvider{} ctx := &MockEvalContext{InitProviderProvider: provider} @@ -115,8 +130,14 @@ func TestEvalInitProvider(t *testing.T) { } func TestEvalCloseProvider(t *testing.T) { + providerAddr := addrs.AbsProviderConfig{ + Module: addrs.RootModuleInstance, + ProviderConfig: addrs.LocalProviderConfig{ + LocalName: "foo", + }, + } n := &EvalCloseProvider{ - Addr: addrs.ProviderConfig{Type: "foo"}, + Addr: providerAddr, } provider := &MockProvider{} ctx := &MockEvalContext{CloseProviderProvider: provider} diff --git a/terraform/eval_read_data.go b/terraform/eval_read_data.go index e58ec7c6e..af68d7d50 100644 --- a/terraform/eval_read_data.go +++ b/terraform/eval_read_data.go @@ -85,7 +85,7 @@ func (n *EvalReadData) Eval(ctx EvalContext) (interface{}, error) { schema, _ := providerSchema.SchemaForResourceAddr(n.Addr.ContainingResource()) if schema == nil { // Should be caught during validation, so we don't bother with a pretty error here - return nil, fmt.Errorf("provider %q does not support data source %q", n.ProviderAddr.ProviderConfig.Type, n.Addr.Resource.Type) + return nil, fmt.Errorf("provider %q does not support data source %q", n.ProviderAddr.ProviderConfig.LocalName, n.Addr.Resource.Type) } // We'll always start by evaluating the configuration. What we do after @@ -223,7 +223,7 @@ func (n *EvalReadData) Eval(ctx EvalContext) (interface{}, error) { "Provider produced invalid object", fmt.Sprintf( "Provider %q produced an invalid value for %s.\n\nThis is a bug in the provider, which should be reported in the provider's own issue tracker.", - n.ProviderAddr.ProviderConfig.Type, tfdiags.FormatErrorPrefixed(err, absAddr.String()), + n.ProviderAddr.ProviderConfig.LocalName, tfdiags.FormatErrorPrefixed(err, absAddr.String()), ), )) } @@ -237,7 +237,7 @@ func (n *EvalReadData) Eval(ctx EvalContext) (interface{}, error) { "Provider produced null object", fmt.Sprintf( "Provider %q produced a null value for %s.\n\nThis is a bug in the provider, which should be reported in the provider's own issue tracker.", - n.ProviderAddr.ProviderConfig.Type, absAddr, + n.ProviderAddr.ProviderConfig.LocalName, absAddr, ), )) } @@ -247,7 +247,7 @@ func (n *EvalReadData) Eval(ctx EvalContext) (interface{}, error) { "Provider produced invalid object", fmt.Sprintf( "Provider %q produced a value for %s that is not wholly known.\n\nThis is a bug in the provider, which should be reported in the provider's own issue tracker.", - n.ProviderAddr.ProviderConfig.Type, absAddr, + n.ProviderAddr.ProviderConfig.LocalName, absAddr, ), )) @@ -364,7 +364,7 @@ func (n *EvalReadDataApply) Eval(ctx EvalContext) (interface{}, error) { "Provider produced invalid object", fmt.Sprintf( "Provider %q planned an invalid value for %s. The result could not be saved.\n\nThis is a bug in the provider, which should be reported in the provider's own issue tracker.", - n.ProviderAddr.ProviderConfig.Type, tfdiags.FormatErrorPrefixed(err, absAddr.String()), + n.ProviderAddr.ProviderConfig.LocalName, tfdiags.FormatErrorPrefixed(err, absAddr.String()), ), )) } diff --git a/terraform/eval_refresh.go b/terraform/eval_refresh.go index fd50f873a..5beca94a5 100644 --- a/terraform/eval_refresh.go +++ b/terraform/eval_refresh.go @@ -78,7 +78,7 @@ func (n *EvalRefresh) Eval(ctx EvalContext) (interface{}, error) { "Provider produced invalid object", fmt.Sprintf( "Provider %q planned an invalid value for %s during refresh: %s.\n\nThis is a bug in the provider, which should be reported in the provider's own issue tracker.", - n.ProviderAddr.ProviderConfig.Type, absAddr, tfdiags.FormatError(err), + n.ProviderAddr.ProviderConfig.LocalName, absAddr, tfdiags.FormatError(err), ), )) } diff --git a/terraform/eval_state.go b/terraform/eval_state.go index 850f94167..71b8f3504 100644 --- a/terraform/eval_state.go +++ b/terraform/eval_state.go @@ -218,8 +218,8 @@ func (n *EvalWriteState) Eval(ctx EvalContext) (interface{}, error) { absAddr := n.Addr.Absolute(ctx.Path()) state := ctx.State() - if n.ProviderAddr.ProviderConfig.Type == "" { - return nil, fmt.Errorf("failed to write state for %s, missing provider type", absAddr) + if n.ProviderAddr.ProviderConfig.LocalName == "" { + return nil, fmt.Errorf("failed to write state for %s: missing provider type", absAddr) } obj := *n.State if obj == nil || obj.Value.IsNull() { diff --git a/terraform/eval_state_upgrade.go b/terraform/eval_state_upgrade.go index e1940005e..c468f1ec4 100644 --- a/terraform/eval_state_upgrade.go +++ b/terraform/eval_state_upgrade.go @@ -26,7 +26,8 @@ func UpgradeResourceState(addr addrs.AbsResourceInstance, provider providers.Int stateIsFlatmap := len(src.AttrsJSON) == 0 - providerType := addr.Resource.Resource.DefaultProviderConfig().Type + // TODO: This should eventually use a proper FQN. + providerType := addr.Resource.Resource.DefaultProvider().LegacyString() if src.SchemaVersion > currentVersion { log.Printf("[TRACE] UpgradeResourceState: can't downgrade state for %s from version %d to %d", addr, src.SchemaVersion, currentVersion) var diags tfdiags.Diagnostics diff --git a/terraform/eval_validate.go b/terraform/eval_validate.go index 5b2146a58..d42b49b88 100644 --- a/terraform/eval_validate.go +++ b/terraform/eval_validate.go @@ -67,7 +67,7 @@ RETURN: // EvalValidateProvider is an EvalNode implementation that validates // a provider configuration. type EvalValidateProvider struct { - Addr addrs.ProviderConfig + Addr addrs.AbsProviderConfig Provider *providers.Interface Config *configs.Provider } diff --git a/terraform/evaltree_provider.go b/terraform/evaltree_provider.go index 6b4df67aa..e99ba48ff 100644 --- a/terraform/evaltree_provider.go +++ b/terraform/evaltree_provider.go @@ -12,12 +12,11 @@ func ProviderEvalTree(n *NodeApplyableProvider, config *configs.Provider) EvalNo var provider providers.Interface addr := n.Addr - relAddr := addr.ProviderConfig seq := make([]EvalNode, 0, 5) seq = append(seq, &EvalInitProvider{ - TypeName: relAddr.Type, - Addr: addr.ProviderConfig, + TypeName: addr.ProviderConfig.LocalName, // TODO: This should be an addrs.Provider + Addr: addr, }) // Input stuff @@ -42,7 +41,7 @@ func ProviderEvalTree(n *NodeApplyableProvider, config *configs.Provider) EvalNo Output: &provider, }, &EvalValidateProvider{ - Addr: relAddr, + Addr: addr, Provider: &provider, Config: config, }, @@ -70,7 +69,7 @@ func ProviderEvalTree(n *NodeApplyableProvider, config *configs.Provider) EvalNo Node: &EvalSequence{ Nodes: []EvalNode{ &EvalConfigProvider{ - Addr: relAddr, + Addr: addr, Provider: &provider, Config: config, }, @@ -84,5 +83,5 @@ func ProviderEvalTree(n *NodeApplyableProvider, config *configs.Provider) EvalNo // CloseProviderEvalTree returns the evaluation tree for closing // provider connections that aren't needed anymore. func CloseProviderEvalTree(addr addrs.AbsProviderConfig) EvalNode { - return &EvalCloseProvider{Addr: addr.ProviderConfig} + return &EvalCloseProvider{Addr: addr} } diff --git a/terraform/evaluate.go b/terraform/evaluate.go index de1fd9a05..663f05aac 100644 --- a/terraform/evaluate.go +++ b/terraform/evaluate.go @@ -779,7 +779,9 @@ func (d *evaluationStateData) getResourceInstancesAll(addr addrs.Resource, rng t } func (d *evaluationStateData) getResourceSchema(addr addrs.Resource, providerAddr addrs.AbsProviderConfig) *configschema.Block { - providerType := providerAddr.ProviderConfig.Type + // FIXME: Once AbsProviderConfig has an addrs.Provider in it, we should + // be looking schemas up using provider FQNs rather than legacy names. + providerType := providerAddr.ProviderConfig.LocalName schemas := d.Evaluator.Schemas schema, _ := schemas.ResourceTypeConfig(providerType, addr.Mode, addr.Type) return schema diff --git a/terraform/evaluate_valid.go b/terraform/evaluate_valid.go index 9e55b2f99..d5ace7fab 100644 --- a/terraform/evaluate_valid.go +++ b/terraform/evaluate_valid.go @@ -212,10 +212,12 @@ func (d *evaluationStateData) staticValidateResourceReference(modCfg *configs.Co return diags } - // Normally accessing this directly is wrong because it doesn't take into - // account provider inheritance, etc but it's okay here because we're only - // paying attention to the type anyway. - providerType := cfg.ProviderConfigAddr().Type + // FIXME: This is wrong: it's assuming that the local type is the same + // as the type from the provider FQN, which will not hold once we eliminate + // legacy addresses. d.Evaluator.Schemas.ResourceTypeConfig below ought to + // change to take an addrs.Provider, and then that's what we should be + // passing in here. + providerType := cfg.ProviderConfigAddr().LocalName schema, _ := d.Evaluator.Schemas.ResourceTypeConfig(providerType, addr.Mode, addr.Type) if schema == nil { diff --git a/terraform/graph_builder_apply_test.go b/terraform/graph_builder_apply_test.go index fdf9b6f52..716405263 100644 --- a/terraform/graph_builder_apply_test.go +++ b/terraform/graph_builder_apply_test.go @@ -544,8 +544,8 @@ func TestApplyGraphBuilder_updateFromOrphan(t *testing.T) { Status: states.ObjectReady, AttrsJSON: []byte(`{"id":"a_id"}`), }, - addrs.ProviderConfig{ - Type: "test", + addrs.LocalProviderConfig{ + LocalName: "test", }.Absolute(addrs.RootModuleInstance), ) root.SetResourceInstanceCurrent( @@ -568,8 +568,8 @@ func TestApplyGraphBuilder_updateFromOrphan(t *testing.T) { }, }, }, - addrs.ProviderConfig{ - Type: "test", + addrs.LocalProviderConfig{ + LocalName: "test", }.Absolute(addrs.RootModuleInstance), ) diff --git a/terraform/node_data_refresh_test.go b/terraform/node_data_refresh_test.go index 6b6059fa2..1b6f353d9 100644 --- a/terraform/node_data_refresh_test.go +++ b/terraform/node_data_refresh_test.go @@ -129,8 +129,8 @@ func TestNodeRefreshableDataResourceDynamicExpand_scaleIn(t *testing.T) { ), Config: m.Module.DataResources["data.aws_instance.foo"], ResolvedProvider: addrs.AbsProviderConfig{ - ProviderConfig: addrs.ProviderConfig{ - Type: "aws", + ProviderConfig: addrs.LocalProviderConfig{ + LocalName: "aws", }, }, }, @@ -174,7 +174,7 @@ root - terraform.graphNodeRoot t.Fatal("failed to find a destroyableDataResource") } - if destroyableDataResource.ResolvedProvider.ProviderConfig.Type == "" { + if destroyableDataResource.ResolvedProvider.ProviderConfig.LocalName == "" { t.Fatal("NodeDestroyableDataResourceInstance missing provider config") } } diff --git a/terraform/node_provider_eval.go b/terraform/node_provider_eval.go index 580e60cb7..30911f388 100644 --- a/terraform/node_provider_eval.go +++ b/terraform/node_provider_eval.go @@ -11,10 +11,9 @@ type NodeEvalableProvider struct { // GraphNodeEvalable func (n *NodeEvalableProvider) EvalTree() EvalNode { addr := n.Addr - relAddr := addr.ProviderConfig return &EvalInitProvider{ - TypeName: relAddr.Type, - Addr: addr.ProviderConfig, + TypeName: addr.ProviderConfig.LocalName, // FIXME: Should be an addrs.Provider + Addr: addr, } } diff --git a/terraform/node_resource_abstract.go b/terraform/node_resource_abstract.go index fd2cfc8e5..01e60470b 100644 --- a/terraform/node_resource_abstract.go +++ b/terraform/node_resource_abstract.go @@ -324,8 +324,13 @@ func (n *NodeAbstractResource) ProvidedBy() (addrs.AbsProviderConfig, bool) { return relAddr.Absolute(n.Path()), false } - // Use our type and containing module path to guess a provider configuration address - return n.Addr.Resource.DefaultProviderConfig().Absolute(n.Addr.Module), false + // Use our type and containing module path to guess a provider configuration address. + // FIXME: This is relying on the FQN-to-local matching true only of legacy + // addresses, so this will need to switch to using an addrs.LocalProviderConfig + // with the local name here, once we've done the work elsewhere to make + // that possible. + defaultFQN := n.Addr.Resource.DefaultProvider() + return addrs.NewDefaultLocalProviderConfig(defaultFQN.LegacyString()).Absolute(n.Addr.Module), false } // GraphNodeProviderConsumer @@ -345,7 +350,12 @@ func (n *NodeAbstractResourceInstance) ProvidedBy() (addrs.AbsProviderConfig, bo } // Use our type and containing module path to guess a provider configuration address - return n.Addr.Resource.DefaultProviderConfig().Absolute(n.Path()), false + // FIXME: This is relying on the FQN-to-local matching true only of legacy + // addresses, so this will need to switch to using an addrs.LocalProviderConfig + // with the local name here, once we've done the work elsewhere to make + // that possible. + defaultFQN := n.Addr.Resource.DefaultProvider() + return addrs.NewDefaultLocalProviderConfig(defaultFQN.LegacyString()).Absolute(n.Addr.Module), false } // GraphNodeProvisionerConsumer diff --git a/terraform/node_resource_plan_destroy.go b/terraform/node_resource_plan_destroy.go index 38746f0d3..a224d0144 100644 --- a/terraform/node_resource_plan_destroy.go +++ b/terraform/node_resource_plan_destroy.go @@ -47,7 +47,7 @@ func (n *NodePlanDestroyableResourceInstance) EvalTree() EvalNode { var change *plans.ResourceInstanceChange var state *states.ResourceInstanceObject - if n.ResolvedProvider.ProviderConfig.Type == "" { + if n.ResolvedProvider.ProviderConfig.LocalName == "" { // Should never happen; indicates that the graph was not constructed // correctly since we didn't get our provider attached. panic(fmt.Sprintf("%T %q was not assigned a resolved provider", n, dag.VertexName(n))) diff --git a/terraform/schemas.go b/terraform/schemas.go index 62991c82d..f5d8f4f94 100644 --- a/terraform/schemas.go +++ b/terraform/schemas.go @@ -92,7 +92,12 @@ func LoadSchemas(config *configs.Config, state *states.State, components context func loadProviderSchemas(schemas map[string]*ProviderSchema, config *configs.Config, state *states.State, components contextComponentFactory) tfdiags.Diagnostics { var diags tfdiags.Diagnostics - ensure := func(typeName string) { + ensure := func(typeAddr addrs.Provider) { + // FIXME: Once schema lookup is ready to look up by addrs.Provider rather + // than legacy name, we'll use typeAddr directly. For now, we support + // only legacy addresses. + typeName := typeAddr.LegacyString() + if _, exists := schemas[typeName]; exists { return } @@ -171,8 +176,8 @@ func loadProviderSchemas(schemas map[string]*ProviderSchema, config *configs.Con if state != nil { needed := providers.AddressedTypesAbs(state.ProviderAddrs()) - for _, typeName := range needed { - ensure(typeName) + for _, typeAddr := range needed { + ensure(typeAddr) } } diff --git a/terraform/transform_attach_schema.go b/terraform/transform_attach_schema.go index c7695dd4e..195f9902f 100644 --- a/terraform/transform_attach_schema.go +++ b/terraform/transform_attach_schema.go @@ -59,7 +59,7 @@ func (t *AttachSchemaTransformer) Transform(g *Graph) error { mode := addr.Resource.Mode typeName := addr.Resource.Type providerAddr, _ := tv.ProvidedBy() - providerType := providerAddr.ProviderConfig.Type + providerType := providerAddr.ProviderConfig.LocalName schema, version := t.Schemas.ResourceTypeConfig(providerType, mode, typeName) if schema == nil { @@ -72,7 +72,7 @@ func (t *AttachSchemaTransformer) Transform(g *Graph) error { if tv, ok := v.(GraphNodeAttachProviderConfigSchema); ok { providerAddr := tv.ProviderAddr() - schema := t.Schemas.ProviderConfig(providerAddr.ProviderConfig.Type) + schema := t.Schemas.ProviderConfig(providerAddr.ProviderConfig.LocalName) if schema == nil { log.Printf("[ERROR] AttachSchemaTransformer: No provider config schema available for %s", providerAddr) continue diff --git a/terraform/transform_diff_test.go b/terraform/transform_diff_test.go index a83a5d75f..a2c0facf9 100644 --- a/terraform/transform_diff_test.go +++ b/terraform/transform_diff_test.go @@ -43,8 +43,8 @@ func TestDiffTransformer(t *testing.T) { Type: "aws_instance", Name: "foo", }.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance), - ProviderAddr: addrs.ProviderConfig{ - Type: "aws", + ProviderAddr: addrs.LocalProviderConfig{ + LocalName: "aws", }.Absolute(addrs.RootModuleInstance), ChangeSrc: plans.ChangeSrc{ Action: plans.Update, diff --git a/terraform/transform_import_state.go b/terraform/transform_import_state.go index ab0ecae0a..e10b739de 100644 --- a/terraform/transform_import_state.go +++ b/terraform/transform_import_state.go @@ -20,8 +20,9 @@ func (t *ImportStateTransformer) Transform(g *Graph) error { // This will be populated if the targets come from the cli, but tests // may not specify implied provider addresses. providerAddr := target.ProviderAddr - if providerAddr.ProviderConfig.Type == "" { - providerAddr = target.Addr.Resource.Resource.DefaultProviderConfig().Absolute(target.Addr.Module) + if providerAddr.ProviderConfig.LocalName == "" { + defaultFQN := target.Addr.Resource.Resource.DefaultProvider() + providerAddr = addrs.NewDefaultLocalProviderConfig(defaultFQN.LegacyString()).Absolute(target.Addr.Module) } node := &graphNodeImportState{ diff --git a/terraform/transform_orphan_count_test.go b/terraform/transform_orphan_count_test.go index 4853ce831..fcf7322b5 100644 --- a/terraform/transform_orphan_count_test.go +++ b/terraform/transform_orphan_count_test.go @@ -352,8 +352,8 @@ func TestOrphanResourceCountTransformer_ForEachEdgesAdded(t *testing.T) { }, Status: states.ObjectReady, }, - addrs.ProviderConfig{ - Type: "aws", + addrs.LocalProviderConfig{ + LocalName: "aws", }.Absolute(addrs.RootModuleInstance), ) @@ -370,8 +370,8 @@ func TestOrphanResourceCountTransformer_ForEachEdgesAdded(t *testing.T) { }, Status: states.ObjectReady, }, - addrs.ProviderConfig{ - Type: "aws", + addrs.LocalProviderConfig{ + LocalName: "aws", }.Absolute(addrs.RootModuleInstance), ) }) diff --git a/terraform/transform_orphan_resource_test.go b/terraform/transform_orphan_resource_test.go index fed351cc1..a1ec086a9 100644 --- a/terraform/transform_orphan_resource_test.go +++ b/terraform/transform_orphan_resource_test.go @@ -26,8 +26,8 @@ func TestOrphanResourceInstanceTransformer(t *testing.T) { }, Status: states.ObjectReady, }, - addrs.ProviderConfig{ - Type: "aws", + addrs.LocalProviderConfig{ + LocalName: "aws", }.Absolute(addrs.RootModuleInstance), ) @@ -44,8 +44,8 @@ func TestOrphanResourceInstanceTransformer(t *testing.T) { }, Status: states.ObjectReady, }, - addrs.ProviderConfig{ - Type: "aws", + addrs.LocalProviderConfig{ + LocalName: "aws", }.Absolute(addrs.RootModuleInstance), ) }) @@ -92,8 +92,8 @@ func TestOrphanResourceInstanceTransformer_countGood(t *testing.T) { }, Status: states.ObjectReady, }, - addrs.ProviderConfig{ - Type: "aws", + addrs.LocalProviderConfig{ + LocalName: "aws", }.Absolute(addrs.RootModuleInstance), ) s.SetResourceInstanceCurrent( @@ -108,8 +108,8 @@ func TestOrphanResourceInstanceTransformer_countGood(t *testing.T) { }, Status: states.ObjectReady, }, - addrs.ProviderConfig{ - Type: "aws", + addrs.LocalProviderConfig{ + LocalName: "aws", }.Absolute(addrs.RootModuleInstance), ) }) @@ -155,8 +155,8 @@ func TestOrphanResourceInstanceTransformer_countBad(t *testing.T) { }, Status: states.ObjectReady, }, - addrs.ProviderConfig{ - Type: "aws", + addrs.LocalProviderConfig{ + LocalName: "aws", }.Absolute(addrs.RootModuleInstance), ) s.SetResourceInstanceCurrent( @@ -171,8 +171,8 @@ func TestOrphanResourceInstanceTransformer_countBad(t *testing.T) { }, Status: states.ObjectReady, }, - addrs.ProviderConfig{ - Type: "aws", + addrs.LocalProviderConfig{ + LocalName: "aws", }.Absolute(addrs.RootModuleInstance), ) }) @@ -218,8 +218,8 @@ func TestOrphanResourceInstanceTransformer_modules(t *testing.T) { }, Status: states.ObjectReady, }, - addrs.ProviderConfig{ - Type: "aws", + addrs.LocalProviderConfig{ + LocalName: "aws", }.Absolute(addrs.RootModuleInstance), ) s.SetResourceInstanceCurrent( @@ -234,8 +234,8 @@ func TestOrphanResourceInstanceTransformer_modules(t *testing.T) { }, Status: states.ObjectReady, }, - addrs.ProviderConfig{ - Type: "aws", + addrs.LocalProviderConfig{ + LocalName: "aws", }.Absolute(addrs.RootModuleInstance), ) }) diff --git a/terraform/transform_provider.go b/terraform/transform_provider.go index 28feeaa60..fea24e415 100644 --- a/terraform/transform_provider.go +++ b/terraform/transform_provider.go @@ -309,7 +309,7 @@ func (t *MissingProviderTransformer) Transform(g *Graph) error { // We're going to create an implicit _default_ configuration for the // referenced provider type in the _root_ module, ignoring all other // aspects of the resource's declared provider address. - defaultAddr := addrs.RootModuleInstance.ProviderConfigDefault(p.ProviderConfig.Type) + defaultAddr := addrs.RootModuleInstance.ProviderConfigDefault(p.ProviderConfig.LocalName) key := defaultAddr.String() provider := m[key] @@ -719,7 +719,7 @@ func (t *ProviderConfigTransformer) attachProviderConfigs(g *Graph) error { // Go through the provider configs to find the matching config for _, p := range mc.Module.ProviderConfigs { - if p.Name == addr.ProviderConfig.Type && p.Alias == addr.ProviderConfig.Alias { + if p.Name == addr.ProviderConfig.LocalName && p.Alias == addr.ProviderConfig.Alias { log.Printf("[TRACE] ProviderConfigTransformer: attaching to %q provider configuration from %s", dag.VertexName(v), p.DeclRange) apn.AttachProvider(p) break diff --git a/terraform/transform_provisioner_test.go b/terraform/transform_provisioner_test.go index eecd67788..7c728619f 100644 --- a/terraform/transform_provisioner_test.go +++ b/terraform/transform_provisioner_test.go @@ -70,8 +70,8 @@ func TestMissingProvisionerTransformer_module(t *testing.T) { }, Status: states.ObjectReady, }, - addrs.ProviderConfig{ - Type: "aws", + addrs.LocalProviderConfig{ + LocalName: "aws", }.Absolute(addrs.RootModuleInstance), ) s.SetResourceInstanceCurrent( @@ -86,8 +86,8 @@ func TestMissingProvisionerTransformer_module(t *testing.T) { }, Status: states.ObjectReady, }, - addrs.ProviderConfig{ - Type: "aws", + addrs.LocalProviderConfig{ + LocalName: "aws", }.Absolute(addrs.RootModuleInstance), ) })