configs: attach provider fqn to Resource (#24382)
* configs: attach provider fqn to Resource
This commit is contained in:
parent
42f7beff31
commit
ef19fb6203
|
@ -33,7 +33,7 @@ func TestConfigProviderTypes_nested(t *testing.T) {
|
||||||
t.Fatalf("wrong result!\ngot: %#v\nwant: nil\n", got)
|
t.Fatalf("wrong result!\ngot: %#v\nwant: nil\n", got)
|
||||||
}
|
}
|
||||||
|
|
||||||
// config with two provider sources
|
// config with two provider sources, and one implicit (default) provider
|
||||||
cfg, diags := testNestedModuleConfigFromDir(t, "testdata/valid-modules/nested-providers-fqns")
|
cfg, diags := testNestedModuleConfigFromDir(t, "testdata/valid-modules/nested-providers-fqns")
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
t.Fatal(diags.Error())
|
t.Fatal(diags.Error())
|
||||||
|
@ -41,6 +41,8 @@ func TestConfigProviderTypes_nested(t *testing.T) {
|
||||||
|
|
||||||
got = cfg.ProviderTypes()
|
got = cfg.ProviderTypes()
|
||||||
want := []addrs.Provider{
|
want := []addrs.Provider{
|
||||||
|
// FIXME: this will be updated to NewDefaultProvider as we remove `Legacy*`
|
||||||
|
addrs.NewLegacyProvider("test"),
|
||||||
addrs.NewProvider(addrs.DefaultRegistryHost, "bar", "test"),
|
addrs.NewProvider(addrs.DefaultRegistryHost, "bar", "test"),
|
||||||
addrs.NewProvider(addrs.DefaultRegistryHost, "foo", "test"),
|
addrs.NewProvider(addrs.DefaultRegistryHost, "foo", "test"),
|
||||||
}
|
}
|
||||||
|
|
|
@ -280,6 +280,21 @@ func (m *Module) appendFile(file *File) hcl.Diagnostics {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
m.ManagedResources[key] = r
|
m.ManagedResources[key] = r
|
||||||
|
|
||||||
|
// set the provider FQN for the resource
|
||||||
|
var provider addrs.Provider
|
||||||
|
if r.ProviderConfigRef != nil {
|
||||||
|
if existing, exists := m.ProviderRequirements[r.ProviderConfigAddr().LocalName]; exists {
|
||||||
|
provider = existing.Type
|
||||||
|
} else {
|
||||||
|
// FIXME: This will be a NewDefaultProvider
|
||||||
|
provider = addrs.NewLegacyProvider(r.ProviderConfigAddr().LocalName)
|
||||||
|
}
|
||||||
|
r.Provider = provider
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// FIXME: r.Addr().DefaultProvider() will be refactored to return a string
|
||||||
|
r.Provider = r.Addr().DefaultProvider()
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, r := range file.DataResources {
|
for _, r := range file.DataResources {
|
||||||
|
@ -294,6 +309,21 @@ func (m *Module) appendFile(file *File) hcl.Diagnostics {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
m.DataResources[key] = r
|
m.DataResources[key] = r
|
||||||
|
|
||||||
|
// set the provider FQN for the resource
|
||||||
|
var provider addrs.Provider
|
||||||
|
if r.ProviderConfigRef != nil {
|
||||||
|
if existing, exists := m.ProviderRequirements[r.ProviderConfigAddr().LocalName]; exists {
|
||||||
|
provider = existing.Type
|
||||||
|
} else {
|
||||||
|
// FIXME: This will be a NewDefaultProvider
|
||||||
|
provider = addrs.NewLegacyProvider(r.ProviderConfigAddr().LocalName)
|
||||||
|
}
|
||||||
|
r.Provider = provider
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// FIXME: r.Addr().DefaultProvider() will be refactored to return a string
|
||||||
|
r.Provider = r.Addr().DefaultProvider()
|
||||||
}
|
}
|
||||||
|
|
||||||
return diags
|
return diags
|
||||||
|
@ -436,7 +466,7 @@ func (m *Module) mergeFile(file *File) hcl.Diagnostics {
|
||||||
})
|
})
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
mergeDiags := existing.merge(r)
|
mergeDiags := existing.merge(r, m.ProviderRequirements)
|
||||||
diags = append(diags, mergeDiags...)
|
diags = append(diags, mergeDiags...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -452,7 +482,7 @@ func (m *Module) mergeFile(file *File) hcl.Diagnostics {
|
||||||
})
|
})
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
mergeDiags := existing.merge(r)
|
mergeDiags := existing.merge(r, m.ProviderRequirements)
|
||||||
diags = append(diags, mergeDiags...)
|
diags = append(diags, mergeDiags...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -197,7 +197,7 @@ func (mc *ModuleCall) merge(omc *ModuleCall) hcl.Diagnostics {
|
||||||
return diags
|
return diags
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Resource) merge(or *Resource) hcl.Diagnostics {
|
func (r *Resource) merge(or *Resource, prs map[string]ProviderRequirements) hcl.Diagnostics {
|
||||||
var diags hcl.Diagnostics
|
var diags hcl.Diagnostics
|
||||||
|
|
||||||
if r.Mode != or.Mode {
|
if r.Mode != or.Mode {
|
||||||
|
@ -212,9 +212,18 @@ func (r *Resource) merge(or *Resource) hcl.Diagnostics {
|
||||||
if or.ForEach != nil {
|
if or.ForEach != nil {
|
||||||
r.ForEach = or.ForEach
|
r.ForEach = or.ForEach
|
||||||
}
|
}
|
||||||
|
|
||||||
if or.ProviderConfigRef != nil {
|
if or.ProviderConfigRef != nil {
|
||||||
r.ProviderConfigRef = or.ProviderConfigRef
|
r.ProviderConfigRef = or.ProviderConfigRef
|
||||||
|
if existing, exists := prs[or.ProviderConfigRef.Name]; exists {
|
||||||
|
r.Provider = existing.Type
|
||||||
|
} else {
|
||||||
|
r.Provider = addrs.NewLegacyProvider(r.ProviderConfigRef.Name)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Provider FQN is set by Terraform during Merge
|
||||||
|
|
||||||
if r.Mode == addrs.ManagedResourceMode {
|
if r.Mode == addrs.ManagedResourceMode {
|
||||||
// or.Managed is always non-nil for managed resource mode
|
// or.Managed is always non-nil for managed resource mode
|
||||||
|
|
||||||
|
|
|
@ -202,6 +202,37 @@ func TestModuleOverrideDynamic(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestModuleOverrideResourceFQNs(t *testing.T) {
|
||||||
|
mod, diags := testModuleFromDir("testdata/valid-modules/override-resource-provider")
|
||||||
|
assertNoDiagnostics(t, diags)
|
||||||
|
|
||||||
|
got := mod.ManagedResources["test_instance.explicit"]
|
||||||
|
wantProvider := addrs.NewProvider(addrs.DefaultRegistryHost, "bar", "test")
|
||||||
|
wantProviderCfg := &ProviderConfigRef{
|
||||||
|
Name: "bar-test",
|
||||||
|
NameRange: hcl.Range{
|
||||||
|
Filename: "testdata/valid-modules/override-resource-provider/a_override.tf",
|
||||||
|
Start: hcl.Pos{Line: 2, Column: 14, Byte: 51},
|
||||||
|
End: hcl.Pos{Line: 2, Column: 22, Byte: 59},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if !got.Provider.Equals(wantProvider) {
|
||||||
|
t.Fatalf("wrong provider %s, want %s", got.Provider, wantProvider)
|
||||||
|
}
|
||||||
|
assertResultDeepEqual(t, got.ProviderConfigRef, wantProviderCfg)
|
||||||
|
|
||||||
|
// now verify that a resource with no provider config falls back to default
|
||||||
|
got = mod.ManagedResources["test_instance.default"]
|
||||||
|
wantProvider = addrs.NewLegacyProvider("test")
|
||||||
|
if !got.Provider.Equals(wantProvider) {
|
||||||
|
t.Fatalf("wrong provider %s, want %s", got.Provider, wantProvider)
|
||||||
|
}
|
||||||
|
if got.ProviderConfigRef != nil {
|
||||||
|
t.Fatalf("wrong result: found provider config ref %s, expected nil", got.ProviderConfigRef)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestMergeProviderVersionConstraints(t *testing.T) {
|
func TestMergeProviderVersionConstraints(t *testing.T) {
|
||||||
v1, _ := version.NewConstraint("1.0.0")
|
v1, _ := version.NewConstraint("1.0.0")
|
||||||
vc1 := VersionConstraint{
|
vc1 := VersionConstraint{
|
||||||
|
|
|
@ -29,6 +29,50 @@ func TestNewModule_provider_local_name(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This test validates the provider FQNs set in each Resource
|
||||||
|
func TestNewModule_resource_providers(t *testing.T) {
|
||||||
|
cfg, diags := testNestedModuleConfigFromDir(t, "testdata/valid-modules/nested-providers-fqns")
|
||||||
|
if diags.HasErrors() {
|
||||||
|
t.Fatal(diags.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
// both the root and child module have two resources, one which should use
|
||||||
|
// the default implied provider and one explicitly using a provider set in
|
||||||
|
// required_providers
|
||||||
|
wantImplicit := addrs.NewLegacyProvider("test")
|
||||||
|
wantFoo := addrs.NewProvider(addrs.DefaultRegistryHost, "foo", "test")
|
||||||
|
wantBar := addrs.NewProvider(addrs.DefaultRegistryHost, "bar", "test")
|
||||||
|
|
||||||
|
// root module
|
||||||
|
if !cfg.Module.ManagedResources["test_instance.explicit"].Provider.Equals(wantFoo) {
|
||||||
|
t.Fatalf("wrong provider for \"test_instance.explicit\"\ngot: %s\nwant: %s",
|
||||||
|
cfg.Module.ManagedResources["test_instance.explicit"].Provider,
|
||||||
|
wantFoo,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if !cfg.Module.ManagedResources["test_instance.implicit"].Provider.Equals(wantImplicit) {
|
||||||
|
t.Fatalf("wrong provider for \"test_instance.implicit\"\ngot: %s\nwant: %s",
|
||||||
|
cfg.Module.ManagedResources["test_instance.implicit"].Provider,
|
||||||
|
wantImplicit,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// child module
|
||||||
|
cm := cfg.Children["child"].Module
|
||||||
|
if !cm.ManagedResources["test_instance.explicit"].Provider.Equals(wantBar) {
|
||||||
|
t.Fatalf("wrong provider for \"module.child.test_instance.explicit\"\ngot: %s\nwant: %s",
|
||||||
|
cfg.Module.ManagedResources["test_instance.explicit"].Provider,
|
||||||
|
wantBar,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if !cm.ManagedResources["test_instance.implicit"].Provider.Equals(wantImplicit) {
|
||||||
|
t.Fatalf("wrong provider for \"module.child.test_instance.implicit\"\ngot: %s\nwant: %s",
|
||||||
|
cfg.Module.ManagedResources["test_instance.implicit"].Provider,
|
||||||
|
wantImplicit,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestProviderForLocalConfig(t *testing.T) {
|
func TestProviderForLocalConfig(t *testing.T) {
|
||||||
mod, diags := testModuleFromDir("testdata/providers-explicit-fqn")
|
mod, diags := testModuleFromDir("testdata/providers-explicit-fqn")
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
|
|
|
@ -20,6 +20,7 @@ type Resource struct {
|
||||||
ForEach hcl.Expression
|
ForEach hcl.Expression
|
||||||
|
|
||||||
ProviderConfigRef *ProviderConfigRef
|
ProviderConfigRef *ProviderConfigRef
|
||||||
|
Provider addrs.Provider
|
||||||
|
|
||||||
DependsOn []hcl.Traversal
|
DependsOn []hcl.Traversal
|
||||||
|
|
||||||
|
|
|
@ -7,3 +7,13 @@ terraform {
|
||||||
}
|
}
|
||||||
|
|
||||||
provider "bar-test" {}
|
provider "bar-test" {}
|
||||||
|
|
||||||
|
resource "test_instance" "explicit" {
|
||||||
|
// explicitly setting provider bar-test
|
||||||
|
provider = bar-test
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "test_instance" "implicit" {
|
||||||
|
// since the provider type name "test" does not match an entry in
|
||||||
|
// required_providers, the default provider "test" should be used
|
||||||
|
}
|
||||||
|
|
|
@ -11,3 +11,12 @@ provider "foo-test" {}
|
||||||
module "child" {
|
module "child" {
|
||||||
source = "./child"
|
source = "./child"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resource "test_instance" "explicit" {
|
||||||
|
provider = foo-test
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "test_instance" "implicit" {
|
||||||
|
// since the provider type name "test" does not match an entry in
|
||||||
|
// required_providers, the default provider "test" should be used
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
resource "test_instance" "explicit" {
|
||||||
|
provider = bar-test
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
terraform {
|
||||||
|
required_providers {
|
||||||
|
foo-test = {
|
||||||
|
source = "foo/test"
|
||||||
|
}
|
||||||
|
bar-test = {
|
||||||
|
source = "bar/test"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "test_instance" "explicit" {
|
||||||
|
provider = foo-test
|
||||||
|
}
|
||||||
|
|
||||||
|
// the provider for this resource should default to "hashicorp/test"
|
||||||
|
resource "test_instance" "default" {}
|
Loading…
Reference in New Issue