Initial steps towards AbsProviderConfig/LocalProviderConfig separation (#23978)

* Introduce "Local" terminology for non-absolute provider config addresses

In a future change AbsProviderConfig and LocalProviderConfig are going to
become two entirely distinct types, rather than Abs embedding Local as
written here. This naming change is in preparation for that subsequent
work, which will also include introducing a new "ProviderConfig" type
that is an interface that AbsProviderConfig and LocalProviderConfig both
implement.

This is intended to be largely just a naming change to get started, so
we can deal with all of the messy renaming. However, this did also require
a slight change in modeling where the Resource.DefaultProviderConfig
method has become Resource.DefaultProvider returning a Provider address
directly, because this method doesn't have enough information to construct
a true and accurate LocalProviderConfig -- it would need to refer to the
configuration to know what this module is calling the provider it has
selected.

In order to leave a trail to follow for subsequent work, all of the
changes here are intended to ensure that remaining work will become
obvious via compile-time errors when all of the following changes happen:
- The concept of "legacy" provider addresses is removed from the addrs
  package, including removing addrs.NewLegacyProvider and
  addrs.Provider.LegacyString.
- addrs.AbsProviderConfig stops having addrs.LocalProviderConfig embedded
  in it and has an addrs.Provider and a string alias directly instead.
- The provider-schema-handling parts of Terraform core are updated to
  work with addrs.Provider to identify providers, rather than legacy
  strings.

In particular, there are still several codepaths here making legacy
provider address assumptions (in order to limit the scope of this change)
but I've made sure each one is doing something that relies on at least
one of the above changes not having been made yet.

* addrs: ProviderConfig interface

In a (very) few special situations in the main "terraform" package we need
to make runtime decisions about whether a provider config is absolute
or local.

We currently do that by exploiting the fact that AbsProviderConfig has
LocalProviderConfig nested inside of it and so in the local case we can
just ignore the wrapping AbsProviderConfig and use the embedded value.

In a future change we'll be moving away from that embedding and making
these two types distinct in order to represent that mapping between them
requires consulting a lookup table in the configuration, and so here we
introduce a new interface type ProviderConfig that can represent either
AbsProviderConfig or LocalProviderConfig decided dynamically at runtime.

This also includes the Config.ResolveAbsProviderAddr method that will
eventually be responsible for that local-to-absolute translation, so
that callers with access to the configuration can normalize to an
addrs.AbsProviderConfig given a non-nil addrs.ProviderConfig. That's
currently unused because existing callers are still relying on the
simplistic structural transform, but we'll switch them over in a later
commit.

* rename LocalType to LocalName

Co-authored-by: Kristin Laemmert <mildwonkey@users.noreply.github.com>
This commit is contained in:
Martin Atkins 2020-01-31 05:23:07 -08:00 committed by GitHub
parent 93e29b71a4
commit 8b511524d6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
83 changed files with 841 additions and 476 deletions

View File

@ -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.<invalid>"
}
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
// 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,
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.

View File

@ -19,8 +19,8 @@ func TestParseAbsProviderConfig(t *testing.T) {
`provider.aws`,
AbsProviderConfig{
Module: RootModuleInstance,
ProviderConfig: ProviderConfig{
Type: "aws",
ProviderConfig: LocalProviderConfig{
LocalName: "aws",
},
},
``,
@ -29,8 +29,8 @@ func TestParseAbsProviderConfig(t *testing.T) {
`provider.aws.foo`,
AbsProviderConfig{
Module: RootModuleInstance,
ProviderConfig: ProviderConfig{
Type: "aws",
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,8 +58,8 @@ func TestParseAbsProviderConfig(t *testing.T) {
Name: "baz",
},
},
ProviderConfig: ProviderConfig{
Type: "aws",
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",
},
},
``,

View File

@ -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.

View File

@ -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))

View File

@ -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

View File

@ -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),
)

View File

@ -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)

View File

@ -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,

View File

@ -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

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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 {

View File

@ -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)
}
}

View File

@ -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,
)

View File

@ -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,
)

View File

@ -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,
)

View File

@ -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,

View File

@ -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,
)

View File

@ -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),
},
},

View File

@ -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)

View File

@ -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,

View File

@ -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),
)
})

View File

@ -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),
)
})

View File

@ -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{

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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),
)
})

View File

@ -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,
)
}

View File

@ -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)
}
})
}

View File

@ -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)

View File

@ -94,9 +94,9 @@ 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,
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)

View File

@ -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",
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.`,
},
}

View File

@ -64,13 +64,23 @@ 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,
return addrs.LocalProviderConfig{
LocalName: r.ProviderConfigRef.Name,
Alias: r.ProviderConfigRef.Alias,
}
}
@ -445,9 +455,9 @@ 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,
func (r *ProviderConfigRef) Addr() addrs.LocalProviderConfig {
return addrs.LocalProviderConfig{
LocalName: r.Name,
Alias: r.Alias,
}
}

View File

@ -0,0 +1,8 @@
terraform {
required_providers {
foo_test = {
source = "foo/test"
}
}
}

View File

@ -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)

View File

@ -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),
)

View File

@ -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

View File

@ -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]

View File

@ -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),
}

View File

@ -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,

View File

@ -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
}

View File

@ -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)

View File

@ -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),
)
})

View File

@ -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),
)

View File

@ -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(),
},
}
}
}

View File

@ -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
}

View File

@ -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,8 +10266,8 @@ func TestContext2Apply_destroyWithProviders(t *testing.T) {
}
// correct the state
s.Modules["module.mod.module.removed"].Resources["aws_instance.child"].ProviderConfig = addrs.ProviderConfig{
Type: "aws",
s.Modules["module.mod.module.removed"].Resources["aws_instance.child"].ProviderConfig = addrs.LocalProviderConfig{
LocalName: "aws",
Alias: "bar",
}.Absolute(addrs.RootModuleInstance)
@ -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),
)

View File

@ -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),
)
}),
})

View File

@ -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
}

View File

@ -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),
)
})

View File

@ -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),
)
})

View File

@ -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),
)

View File

@ -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),
),
))
}

View File

@ -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.

View File

@ -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.

View File

@ -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 {

View File

@ -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

View File

@ -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 {

View File

@ -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")
}

View File

@ -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}

View File

@ -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()),
),
))
}

View File

@ -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),
),
))
}

View File

@ -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() {

View File

@ -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

View File

@ -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
}

View File

@ -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}
}

View File

@ -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

View File

@ -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 {

View File

@ -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),
)

View File

@ -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")
}
}

View File

@ -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,
}
}

View File

@ -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

View File

@ -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)))

View File

@ -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)
}
}

View File

@ -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

View File

@ -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,

View File

@ -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{

View File

@ -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),
)
})

View File

@ -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),
)
})

View File

@ -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

View File

@ -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),
)
})