moduledeps: replace ProviderInstance with addrs.Provider (#24017)
* addrs: add ParseProviderSourceString function to parse fqns from tfconfig-inspect * moduledeps: use addrs.Provider instead of ProviderInstance
This commit is contained in:
parent
e763fd55f3
commit
7eed30595a
|
@ -1,7 +1,13 @@
|
|||
package addrs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/hcl/v2"
|
||||
svchost "github.com/hashicorp/terraform-svchost"
|
||||
"github.com/hashicorp/terraform/tfdiags"
|
||||
)
|
||||
|
||||
// Provider encapsulates a single provider type. In the future this will be
|
||||
|
@ -12,6 +18,12 @@ type Provider struct {
|
|||
Hostname svchost.Hostname
|
||||
}
|
||||
|
||||
const DefaultRegistryHost = "registry.terraform.io"
|
||||
|
||||
var (
|
||||
ValidProviderName = regexp.MustCompile("^[a-zA-Z0-9_-]+$")
|
||||
)
|
||||
|
||||
// String returns an FQN string, indended for use in output.
|
||||
func (pt Provider) String() string {
|
||||
return pt.Hostname.ForDisplay() + "/" + pt.Namespace + "/" + pt.Type
|
||||
|
@ -23,17 +35,22 @@ func NewDefaultProvider(name string) Provider {
|
|||
return Provider{
|
||||
Type: name,
|
||||
Namespace: "hashicorp",
|
||||
Hostname: "registry.terraform.io",
|
||||
Hostname: DefaultRegistryHost,
|
||||
}
|
||||
}
|
||||
|
||||
// NewLegacyProvider returns a mock address for a provider.
|
||||
// This will be removed when ProviderType is fully integrated.
|
||||
func NewLegacyProvider(name string) Provider {
|
||||
// This is intended to catch provider names with aliases, such as "null.foo"
|
||||
if !ValidProviderName.MatchString(name) {
|
||||
panic("invalid provider name")
|
||||
}
|
||||
|
||||
return Provider{
|
||||
Type: name,
|
||||
Namespace: "-",
|
||||
Hostname: "registry.terraform.io",
|
||||
Hostname: DefaultRegistryHost,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -47,3 +64,88 @@ func (pt Provider) LegacyString() string {
|
|||
}
|
||||
return pt.Type
|
||||
}
|
||||
|
||||
// ParseProviderSourceString parses the source attribute and returns a provider.
|
||||
// This is intended primarily to parse the FQN-like strings returned by
|
||||
// terraform-config-inspect.
|
||||
//
|
||||
// The following are valid source string formats:
|
||||
// name
|
||||
// namespace/name
|
||||
// hostname/namespace/name
|
||||
func ParseProviderSourceString(str string) (Provider, tfdiags.Diagnostics) {
|
||||
var ret Provider
|
||||
var diags tfdiags.Diagnostics
|
||||
|
||||
// split the source string into individual components
|
||||
parts := strings.Split(str, "/")
|
||||
if len(parts) == 0 || len(parts) > 3 {
|
||||
diags = diags.Append(&hcl.Diagnostic{
|
||||
Severity: hcl.DiagError,
|
||||
Summary: "Invalid provider source string",
|
||||
Detail: `The "source" attribute must be in the format "[hostname/][namespace/]name"`,
|
||||
})
|
||||
return ret, diags
|
||||
}
|
||||
|
||||
// check for an invalid empty string in any part
|
||||
for i := range parts {
|
||||
if parts[i] == "" {
|
||||
diags = diags.Append(&hcl.Diagnostic{
|
||||
Severity: hcl.DiagError,
|
||||
Summary: "Invalid provider source string",
|
||||
Detail: `The "source" attribute must be in the format "[hostname/][namespace/]name"`,
|
||||
})
|
||||
return ret, diags
|
||||
}
|
||||
}
|
||||
|
||||
// check the 'name' portion, which is always the last part
|
||||
name := parts[len(parts)-1]
|
||||
if !ValidProviderName.MatchString(name) {
|
||||
diags = diags.Append(&hcl.Diagnostic{
|
||||
Severity: hcl.DiagError,
|
||||
Summary: "Invalid provider type",
|
||||
Detail: fmt.Sprintf(`Invalid provider type %q in source %q: must be a provider type name"`, name, str),
|
||||
})
|
||||
return ret, diags
|
||||
}
|
||||
ret.Type = name
|
||||
ret.Hostname = DefaultRegistryHost
|
||||
|
||||
if len(parts) == 1 {
|
||||
// FIXME: update this to NewDefaultProvider in the provider source release
|
||||
return NewLegacyProvider(parts[0]), diags
|
||||
}
|
||||
|
||||
if len(parts) >= 2 {
|
||||
// the namespace is always the second-to-last part
|
||||
namespace := parts[len(parts)-2]
|
||||
if !ValidProviderName.MatchString(namespace) {
|
||||
diags = diags.Append(&hcl.Diagnostic{
|
||||
Severity: hcl.DiagError,
|
||||
Summary: "Invalid provider namespace",
|
||||
Detail: fmt.Sprintf(`Invalid provider namespace %q in source %q: must be a valid Registry Namespace"`, namespace, str),
|
||||
})
|
||||
return Provider{}, diags
|
||||
}
|
||||
ret.Namespace = namespace
|
||||
}
|
||||
|
||||
// Final Case: 3 parts
|
||||
if len(parts) == 3 {
|
||||
// the namespace is always the first part in a three-part source string
|
||||
hn, err := svchost.ForComparison(parts[0])
|
||||
if err != nil {
|
||||
diags = diags.Append(&hcl.Diagnostic{
|
||||
Severity: hcl.DiagError,
|
||||
Summary: "Invalid provider source hostname",
|
||||
Detail: fmt.Sprintf(`Invalid provider source hostname namespace %q in source %q: must be a valid Registry Namespace"`, hn, str),
|
||||
})
|
||||
return Provider{}, diags
|
||||
}
|
||||
ret.Hostname = hn
|
||||
}
|
||||
|
||||
return ret, diags
|
||||
}
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
package addrs
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/go-test/deep"
|
||||
)
|
||||
|
||||
func TestParseProviderSourceStr(t *testing.T) {
|
||||
tests := map[string]struct {
|
||||
Want Provider
|
||||
Err bool
|
||||
}{
|
||||
"registry.terraform.io/hashicorp/aws": {
|
||||
Provider{
|
||||
Type: "aws",
|
||||
Namespace: "hashicorp",
|
||||
Hostname: DefaultRegistryHost,
|
||||
},
|
||||
false,
|
||||
},
|
||||
"hashicorp/aws": {
|
||||
Provider{
|
||||
Type: "aws",
|
||||
Namespace: "hashicorp",
|
||||
Hostname: DefaultRegistryHost,
|
||||
},
|
||||
false,
|
||||
},
|
||||
"aws": {
|
||||
Provider{
|
||||
Type: "aws",
|
||||
Namespace: "-",
|
||||
Hostname: DefaultRegistryHost,
|
||||
},
|
||||
false,
|
||||
},
|
||||
"example.com/too/many/parts/here": {
|
||||
Provider{},
|
||||
true,
|
||||
},
|
||||
"/too///many//slashes": {
|
||||
Provider{},
|
||||
true,
|
||||
},
|
||||
"///": {
|
||||
Provider{},
|
||||
true,
|
||||
},
|
||||
}
|
||||
|
||||
for name, test := range tests {
|
||||
got, diags := ParseProviderSourceString(name)
|
||||
for _, problem := range deep.Equal(got, test.Want) {
|
||||
t.Errorf(problem)
|
||||
}
|
||||
if len(diags) > 0 {
|
||||
if test.Err == false {
|
||||
t.Errorf("got error, expected success")
|
||||
}
|
||||
} else {
|
||||
if test.Err {
|
||||
t.Errorf("got success, expected error")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,8 +3,8 @@ package command
|
|||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
|
||||
"github.com/hashicorp/terraform/addrs"
|
||||
"github.com/hashicorp/terraform/configs"
|
||||
"github.com/hashicorp/terraform/moduledeps"
|
||||
"github.com/hashicorp/terraform/terraform"
|
||||
|
@ -118,14 +118,13 @@ func (c *ProvidersCommand) Run(args []string) int {
|
|||
}
|
||||
|
||||
func providersCommandPopulateTreeNode(node treeprint.Tree, deps *moduledeps.Module) {
|
||||
names := make([]string, 0, len(deps.Providers))
|
||||
for name := range deps.Providers {
|
||||
names = append(names, string(name))
|
||||
fqns := make([]addrs.Provider, 0, len(deps.Providers))
|
||||
for fqn := range deps.Providers {
|
||||
fqns = append(fqns, fqn)
|
||||
}
|
||||
sort.Strings(names)
|
||||
|
||||
for _, name := range names {
|
||||
dep := deps.Providers[moduledeps.ProviderInstance(name)]
|
||||
for _, fqn := range fqns {
|
||||
dep := deps.Providers[fqn]
|
||||
versionsStr := dep.Constraints.String()
|
||||
if versionsStr != "" {
|
||||
versionsStr = " " + versionsStr
|
||||
|
@ -137,7 +136,7 @@ func providersCommandPopulateTreeNode(node treeprint.Tree, deps *moduledeps.Modu
|
|||
case moduledeps.ProviderDependencyFromState:
|
||||
reasonStr = " (from state)"
|
||||
}
|
||||
node.AddNode(fmt.Sprintf("provider.%s%s%s", name, versionsStr, reasonStr))
|
||||
node.AddNode(fmt.Sprintf("provider.%s%s%s", fqn.LegacyString(), versionsStr, reasonStr))
|
||||
}
|
||||
|
||||
for _, child := range deps.Children {
|
||||
|
|
|
@ -109,12 +109,9 @@ func (u *Upgrader) analyze(ms ModuleSources) (*analysis, error) {
|
|||
}
|
||||
}
|
||||
|
||||
inst := moduledeps.ProviderInstance(name)
|
||||
if alias != "" {
|
||||
inst = moduledeps.ProviderInstance(name + "." + alias)
|
||||
}
|
||||
log.Printf("[TRACE] Provider block requires provider %q", inst)
|
||||
m.Providers[inst] = moduledeps.ProviderDependency{
|
||||
fqn := addrs.NewLegacyProvider(name)
|
||||
log.Printf("[TRACE] Provider block requires provider %q", fqn.LegacyString())
|
||||
m.Providers[fqn] = moduledeps.ProviderDependency{
|
||||
Constraints: constraints,
|
||||
Reason: moduledeps.ProviderDependencyExplicit,
|
||||
}
|
||||
|
@ -178,18 +175,23 @@ func (u *Upgrader) analyze(ms ModuleSources) (*analysis, error) {
|
|||
}
|
||||
}
|
||||
|
||||
var fqn addrs.Provider
|
||||
if providerKey == "" {
|
||||
providerKey = rAddr.DefaultProvider().LegacyString()
|
||||
fqn = rAddr.DefaultProvider()
|
||||
} else {
|
||||
// ProviderDependencies only need to know the provider FQN
|
||||
// strip any alias from the providerKey
|
||||
parts := strings.Split(providerKey, ".")
|
||||
fqn = addrs.NewLegacyProvider(parts[0])
|
||||
}
|
||||
|
||||
inst := moduledeps.ProviderInstance(providerKey)
|
||||
log.Printf("[TRACE] Resource block for %s requires provider %q", rAddr, inst)
|
||||
if _, exists := m.Providers[inst]; !exists {
|
||||
m.Providers[inst] = moduledeps.ProviderDependency{
|
||||
log.Printf("[TRACE] Resource block for %s requires provider %q", rAddr, fqn)
|
||||
if _, exists := m.Providers[fqn]; !exists {
|
||||
m.Providers[fqn] = moduledeps.ProviderDependency{
|
||||
Reason: moduledeps.ProviderDependencyImplicit,
|
||||
}
|
||||
}
|
||||
ret.ResourceProviderType[rAddr] = inst.Type()
|
||||
ret.ResourceProviderType[rAddr] = fqn.Type
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -84,7 +84,14 @@ func (c *Config) ProviderDependencies() (*moduledeps.Module, tfdiags.Diagnostics
|
|||
|
||||
providers := make(moduledeps.Providers)
|
||||
for name, reqs := range c.Module.RequiredProviders {
|
||||
inst := moduledeps.ProviderInstance(name)
|
||||
fqn, diags := addrs.ParseProviderSourceString(name)
|
||||
if diags.HasErrors() {
|
||||
diags = diags.Append(wrapDiagnostic(tfconfig.Diagnostic{
|
||||
Severity: tfconfig.DiagError,
|
||||
Summary: "Invalid provider source",
|
||||
Detail: fmt.Sprintf("Invalid source %q for provider", name),
|
||||
}))
|
||||
}
|
||||
var constraints version.Constraints
|
||||
for _, reqStr := range reqs.VersionConstraints {
|
||||
if reqStr != "" {
|
||||
|
@ -93,14 +100,14 @@ func (c *Config) ProviderDependencies() (*moduledeps.Module, tfdiags.Diagnostics
|
|||
diags = diags.Append(wrapDiagnostic(tfconfig.Diagnostic{
|
||||
Severity: tfconfig.DiagError,
|
||||
Summary: "Invalid provider version constraint",
|
||||
Detail: fmt.Sprintf("Invalid version constraint %q for provider %s.", reqStr, name),
|
||||
Detail: fmt.Sprintf("Invalid version constraint %q for provider %s.", reqStr, fqn.LegacyString()),
|
||||
}))
|
||||
continue
|
||||
}
|
||||
constraints = append(constraints, constraint...)
|
||||
}
|
||||
}
|
||||
providers[inst] = moduledeps.ProviderDependency{
|
||||
providers[fqn] = moduledeps.ProviderDependency{
|
||||
Constraints: discovery.NewConstraints(constraints),
|
||||
Reason: moduledeps.ProviderDependencyExplicit,
|
||||
}
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
package moduledeps
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/terraform/addrs"
|
||||
"github.com/hashicorp/terraform/plugin/discovery"
|
||||
)
|
||||
|
||||
// Providers describes a set of provider dependencies for a given module.
|
||||
//
|
||||
// Each named provider instance can have one version constraint.
|
||||
type Providers map[ProviderInstance]ProviderDependency
|
||||
type Providers map[addrs.Provider]ProviderDependency
|
||||
|
||||
// ProviderDependency describes the dependency for a particular provider
|
||||
// instance, including both the set of allowed versions and the reason for
|
||||
|
|
|
@ -109,17 +109,14 @@ func (s sortModules) Swap(i, j int) {
|
|||
// and apply no particular SHA256 hash constraint.
|
||||
func (m *Module) PluginRequirements() discovery.PluginRequirements {
|
||||
ret := make(discovery.PluginRequirements)
|
||||
for inst, dep := range m.Providers {
|
||||
// m.Providers is keyed on provider names, such as "aws.foo".
|
||||
// a PluginRequirements wants keys to be provider *types*, such
|
||||
// as "aws". If there are multiple aliases for the same
|
||||
// provider then we will flatten them into a single requirement
|
||||
// by combining their constraint sets.
|
||||
pty := inst.Type()
|
||||
if existing, exists := ret[pty]; exists {
|
||||
ret[pty].Versions = existing.Versions.Append(dep.Constraints)
|
||||
for pFqn, dep := range m.Providers {
|
||||
// TODO: discovery.PluginRequirements should be refactored and use
|
||||
// addrs.Provider as the map keys
|
||||
provider := pFqn.LegacyString()
|
||||
if existing, exists := ret[provider]; exists {
|
||||
ret[provider].Versions = existing.Versions.Append(dep.Constraints)
|
||||
} else {
|
||||
ret[pty] = &discovery.PluginConstraints{
|
||||
ret[provider] = &discovery.PluginConstraints{
|
||||
Versions: dep.Constraints,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/terraform/addrs"
|
||||
"github.com/hashicorp/terraform/plugin/discovery"
|
||||
)
|
||||
|
||||
|
@ -191,13 +192,10 @@ func TestModulePluginRequirements(t *testing.T) {
|
|||
m := &Module{
|
||||
Name: "root",
|
||||
Providers: Providers{
|
||||
"foo": ProviderDependency{
|
||||
addrs.NewLegacyProvider("foo"): ProviderDependency{
|
||||
Constraints: discovery.ConstraintStr(">=1.0.0").MustParse(),
|
||||
},
|
||||
"foo.bar": ProviderDependency{
|
||||
Constraints: discovery.ConstraintStr(">=2.0.0").MustParse(),
|
||||
},
|
||||
"baz": ProviderDependency{
|
||||
addrs.NewLegacyProvider("baz"): ProviderDependency{
|
||||
Constraints: discovery.ConstraintStr(">=3.0.0").MustParse(),
|
||||
},
|
||||
},
|
||||
|
@ -207,7 +205,7 @@ func TestModulePluginRequirements(t *testing.T) {
|
|||
if len(reqd) != 2 {
|
||||
t.Errorf("wrong number of elements in %#v; want 2", reqd)
|
||||
}
|
||||
if got, want := reqd["foo"].Versions.String(), ">=1.0.0,>=2.0.0"; got != want {
|
||||
if got, want := reqd["foo"].Versions.String(), ">=1.0.0"; got != want {
|
||||
t.Errorf("wrong combination of versions for 'foo' %q; want %q", got, want)
|
||||
}
|
||||
if got, want := reqd["baz"].Versions.String(), ">=3.0.0"; got != want {
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
package moduledeps
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ProviderInstance describes a particular provider instance by its full name,
|
||||
// like "null" or "aws.foo".
|
||||
type ProviderInstance string
|
||||
|
||||
// Type returns the provider type of this instance. For example, for an instance
|
||||
// named "aws.foo" the type is "aws".
|
||||
func (p ProviderInstance) Type() string {
|
||||
t := string(p)
|
||||
if dotPos := strings.Index(t, "."); dotPos != -1 {
|
||||
t = t[:dotPos]
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
// Alias returns the alias of this provider, if any. An instance named "aws.foo"
|
||||
// has the alias "foo", while an instance named just "docker" has no alias,
|
||||
// so the empty string would be returned.
|
||||
func (p ProviderInstance) Alias() string {
|
||||
t := string(p)
|
||||
if dotPos := strings.Index(t, "."); dotPos != -1 {
|
||||
return t[dotPos+1:]
|
||||
}
|
||||
return ""
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
package moduledeps
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestProviderInstance(t *testing.T) {
|
||||
tests := []struct {
|
||||
Name string
|
||||
WantType string
|
||||
WantAlias string
|
||||
}{
|
||||
{
|
||||
Name: "aws",
|
||||
WantType: "aws",
|
||||
WantAlias: "",
|
||||
},
|
||||
{
|
||||
Name: "aws.foo",
|
||||
WantType: "aws",
|
||||
WantAlias: "foo",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.Name, func(t *testing.T) {
|
||||
inst := ProviderInstance(test.Name)
|
||||
if got, want := inst.Type(), test.WantType; got != want {
|
||||
t.Errorf("got type %q; want %q", got, want)
|
||||
}
|
||||
if got, want := inst.Alias(), test.WantAlias; got != want {
|
||||
t.Errorf("got alias %q; want %q", got, want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -58,8 +58,7 @@ func configTreeConfigDependencies(root *configs.Config, inheritProviders map[str
|
|||
// The main way to declare a provider dependency is explicitly inside
|
||||
// the "terraform" block, which allows declaring a requirement without
|
||||
// also creating a configuration.
|
||||
for fullName, req := range module.ProviderRequirements {
|
||||
inst := moduledeps.ProviderInstance(fullName)
|
||||
for _, req := range module.ProviderRequirements {
|
||||
// The handling here is a bit fiddly because the moduledeps package
|
||||
// was designed around the legacy (pre-0.12) configuration model
|
||||
// and hasn't yet been revised to handle the new model. As a result,
|
||||
|
@ -73,7 +72,7 @@ func configTreeConfigDependencies(root *configs.Config, inheritProviders map[str
|
|||
}
|
||||
discoConstraints := discovery.NewConstraints(rawConstraints)
|
||||
|
||||
providers[inst] = moduledeps.ProviderDependency{
|
||||
providers[req.Type] = moduledeps.ProviderDependency{
|
||||
Constraints: discoConstraints,
|
||||
Reason: moduledeps.ProviderDependencyExplicit,
|
||||
}
|
||||
|
@ -82,16 +81,19 @@ func configTreeConfigDependencies(root *configs.Config, inheritProviders map[str
|
|||
// Provider configurations can also include version constraints,
|
||||
// allowing for more terse declaration in situations where both a
|
||||
// configuration and a constraint are defined in the same module.
|
||||
for fullName, pCfg := range module.ProviderConfigs {
|
||||
inst := moduledeps.ProviderInstance(fullName)
|
||||
for _, pCfg := range module.ProviderConfigs {
|
||||
//FIXME: lookup the provider localname in the TBD map and see if
|
||||
//there is an FQN associated
|
||||
fqn := addrs.NewLegacyProvider(pCfg.Name)
|
||||
|
||||
discoConstraints := discovery.AllVersions
|
||||
if pCfg.Version.Required != nil {
|
||||
discoConstraints = discovery.NewConstraints(pCfg.Version.Required)
|
||||
}
|
||||
if existing, exists := providers[inst]; exists {
|
||||
if existing, exists := providers[fqn]; exists {
|
||||
existing.Constraints = existing.Constraints.Append(discoConstraints)
|
||||
} else {
|
||||
providers[inst] = moduledeps.ProviderDependency{
|
||||
providers[fqn] = moduledeps.ProviderDependency{
|
||||
Constraints: discoConstraints,
|
||||
Reason: moduledeps.ProviderDependencyExplicit,
|
||||
}
|
||||
|
@ -103,8 +105,10 @@ func configTreeConfigDependencies(root *configs.Config, inheritProviders map[str
|
|||
// an explicit dependency on the same provider.
|
||||
for _, rc := range module.ManagedResources {
|
||||
addr := rc.ProviderConfigAddr()
|
||||
inst := moduledeps.ProviderInstance(addr.StringCompact())
|
||||
if _, exists := providers[inst]; exists {
|
||||
//FIXME: lookup the provider localname in the TBD map and see if
|
||||
//there is an FQN associated
|
||||
fqn := addrs.NewLegacyProvider(addr.LocalName)
|
||||
if _, exists := providers[fqn]; exists {
|
||||
// Explicit dependency already present
|
||||
continue
|
||||
}
|
||||
|
@ -114,15 +118,17 @@ func configTreeConfigDependencies(root *configs.Config, inheritProviders map[str
|
|||
reason = moduledeps.ProviderDependencyInherited
|
||||
}
|
||||
|
||||
providers[inst] = moduledeps.ProviderDependency{
|
||||
providers[fqn] = moduledeps.ProviderDependency{
|
||||
Constraints: discovery.AllVersions,
|
||||
Reason: reason,
|
||||
}
|
||||
}
|
||||
for _, rc := range module.DataResources {
|
||||
addr := rc.ProviderConfigAddr()
|
||||
inst := moduledeps.ProviderInstance(addr.StringCompact())
|
||||
if _, exists := providers[inst]; exists {
|
||||
//FIXME: lookup the provider localname in the TBD map and see if
|
||||
//there is an FQN associated
|
||||
fqn := addrs.NewLegacyProvider(addr.LocalName)
|
||||
if _, exists := providers[fqn]; exists {
|
||||
// Explicit dependency already present
|
||||
continue
|
||||
}
|
||||
|
@ -132,7 +138,7 @@ func configTreeConfigDependencies(root *configs.Config, inheritProviders map[str
|
|||
reason = moduledeps.ProviderDependencyInherited
|
||||
}
|
||||
|
||||
providers[inst] = moduledeps.ProviderDependency{
|
||||
providers[fqn] = moduledeps.ProviderDependency{
|
||||
Constraints: discovery.AllVersions,
|
||||
Reason: reason,
|
||||
}
|
||||
|
@ -189,9 +195,11 @@ func configTreeMergeStateDependencies(root *moduledeps.Module, state *states.Sta
|
|||
module := findModule(ms.Addr)
|
||||
|
||||
for _, rs := range ms.Resources {
|
||||
inst := moduledeps.ProviderInstance(rs.ProviderConfig.ProviderConfig.StringCompact())
|
||||
if _, exists := module.Providers[inst]; !exists {
|
||||
module.Providers[inst] = moduledeps.ProviderDependency{
|
||||
//FIXME: lookup the provider localname in the TBD map and see if
|
||||
//there is an FQN associated
|
||||
fqn := addrs.NewLegacyProvider(rs.ProviderConfig.ProviderConfig.LocalName)
|
||||
if _, exists := module.Providers[fqn]; !exists {
|
||||
module.Providers[fqn] = moduledeps.ProviderDependency{
|
||||
Constraints: discovery.AllVersions,
|
||||
Reason: moduledeps.ProviderDependencyFromState,
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
|
||||
"github.com/hashicorp/terraform/addrs"
|
||||
"github.com/hashicorp/terraform/configs"
|
||||
"github.com/hashicorp/terraform/moduledeps"
|
||||
"github.com/hashicorp/terraform/plugin/discovery"
|
||||
|
@ -40,14 +41,10 @@ func TestModuleTreeDependencies(t *testing.T) {
|
|||
&moduledeps.Module{
|
||||
Name: "root",
|
||||
Providers: moduledeps.Providers{
|
||||
"foo": moduledeps.ProviderDependency{
|
||||
addrs.NewLegacyProvider("foo"): moduledeps.ProviderDependency{
|
||||
Constraints: discovery.ConstraintStr(">=1.0.0").MustParse(),
|
||||
Reason: moduledeps.ProviderDependencyExplicit,
|
||||
},
|
||||
"foo.bar": moduledeps.ProviderDependency{
|
||||
Constraints: discovery.ConstraintStr(">=2.0.0").MustParse(),
|
||||
Reason: moduledeps.ProviderDependencyExplicit,
|
||||
},
|
||||
},
|
||||
Children: nil,
|
||||
},
|
||||
|
@ -58,7 +55,7 @@ func TestModuleTreeDependencies(t *testing.T) {
|
|||
&moduledeps.Module{
|
||||
Name: "root",
|
||||
Providers: moduledeps.Providers{
|
||||
"foo": moduledeps.ProviderDependency{
|
||||
addrs.NewLegacyProvider("foo"): moduledeps.ProviderDependency{
|
||||
Constraints: discovery.ConstraintStr(">=1.0.0").MustParse(),
|
||||
Reason: moduledeps.ProviderDependencyExplicit,
|
||||
},
|
||||
|
@ -72,7 +69,7 @@ func TestModuleTreeDependencies(t *testing.T) {
|
|||
&moduledeps.Module{
|
||||
Name: "root",
|
||||
Providers: moduledeps.Providers{
|
||||
"foo": moduledeps.ProviderDependency{
|
||||
addrs.NewLegacyProvider("foo"): moduledeps.ProviderDependency{
|
||||
Constraints: discovery.AllVersions,
|
||||
Reason: moduledeps.ProviderDependencyExplicit,
|
||||
},
|
||||
|
@ -86,11 +83,7 @@ func TestModuleTreeDependencies(t *testing.T) {
|
|||
&moduledeps.Module{
|
||||
Name: "root",
|
||||
Providers: moduledeps.Providers{
|
||||
"foo": moduledeps.ProviderDependency{
|
||||
Constraints: discovery.AllVersions,
|
||||
Reason: moduledeps.ProviderDependencyImplicit,
|
||||
},
|
||||
"foo.baz": moduledeps.ProviderDependency{
|
||||
addrs.NewLegacyProvider("foo"): moduledeps.ProviderDependency{
|
||||
Constraints: discovery.AllVersions,
|
||||
Reason: moduledeps.ProviderDependencyImplicit,
|
||||
},
|
||||
|
@ -104,7 +97,7 @@ func TestModuleTreeDependencies(t *testing.T) {
|
|||
&moduledeps.Module{
|
||||
Name: "root",
|
||||
Providers: moduledeps.Providers{
|
||||
"foo": moduledeps.ProviderDependency{
|
||||
addrs.NewLegacyProvider("foo"): moduledeps.ProviderDependency{
|
||||
Constraints: discovery.ConstraintStr(">=1.0.0").MustParse(),
|
||||
Reason: moduledeps.ProviderDependencyExplicit,
|
||||
},
|
||||
|
@ -118,11 +111,11 @@ func TestModuleTreeDependencies(t *testing.T) {
|
|||
&moduledeps.Module{
|
||||
Name: "root",
|
||||
Providers: moduledeps.Providers{
|
||||
"foo": moduledeps.ProviderDependency{
|
||||
addrs.NewLegacyProvider("foo"): moduledeps.ProviderDependency{
|
||||
Constraints: discovery.AllVersions,
|
||||
Reason: moduledeps.ProviderDependencyExplicit,
|
||||
},
|
||||
"bar": moduledeps.ProviderDependency{
|
||||
addrs.NewLegacyProvider("bar"): moduledeps.ProviderDependency{
|
||||
Constraints: discovery.AllVersions,
|
||||
Reason: moduledeps.ProviderDependencyExplicit,
|
||||
},
|
||||
|
@ -131,11 +124,11 @@ func TestModuleTreeDependencies(t *testing.T) {
|
|||
{
|
||||
Name: "child",
|
||||
Providers: moduledeps.Providers{
|
||||
"foo": moduledeps.ProviderDependency{
|
||||
addrs.NewLegacyProvider("foo"): moduledeps.ProviderDependency{
|
||||
Constraints: discovery.AllVersions,
|
||||
Reason: moduledeps.ProviderDependencyInherited,
|
||||
},
|
||||
"baz": moduledeps.ProviderDependency{
|
||||
addrs.NewLegacyProvider("baz"): moduledeps.ProviderDependency{
|
||||
Constraints: discovery.AllVersions,
|
||||
Reason: moduledeps.ProviderDependencyImplicit,
|
||||
},
|
||||
|
@ -144,11 +137,11 @@ func TestModuleTreeDependencies(t *testing.T) {
|
|||
{
|
||||
Name: "grandchild",
|
||||
Providers: moduledeps.Providers{
|
||||
"bar": moduledeps.ProviderDependency{
|
||||
addrs.NewLegacyProvider("bar"): moduledeps.ProviderDependency{
|
||||
Constraints: discovery.AllVersions,
|
||||
Reason: moduledeps.ProviderDependencyInherited,
|
||||
},
|
||||
"foo": moduledeps.ProviderDependency{
|
||||
addrs.NewLegacyProvider("foo"): moduledeps.ProviderDependency{
|
||||
Constraints: discovery.AllVersions,
|
||||
Reason: moduledeps.ProviderDependencyExplicit,
|
||||
},
|
||||
|
@ -177,7 +170,7 @@ func TestModuleTreeDependencies(t *testing.T) {
|
|||
&moduledeps.Module{
|
||||
Name: "root",
|
||||
Providers: moduledeps.Providers{
|
||||
"foo": moduledeps.ProviderDependency{
|
||||
addrs.NewLegacyProvider("foo"): moduledeps.ProviderDependency{
|
||||
Constraints: discovery.AllVersions,
|
||||
Reason: moduledeps.ProviderDependencyFromState,
|
||||
},
|
||||
|
@ -196,10 +189,6 @@ func TestModuleTreeDependencies(t *testing.T) {
|
|||
Type: "foo_bar",
|
||||
Provider: "",
|
||||
},
|
||||
"foo_bar.test2": {
|
||||
Type: "foo_bar",
|
||||
Provider: "foo.bar",
|
||||
},
|
||||
"baz_bar.test": {
|
||||
Type: "baz_bar",
|
||||
Provider: "",
|
||||
|
@ -223,15 +212,11 @@ func TestModuleTreeDependencies(t *testing.T) {
|
|||
&moduledeps.Module{
|
||||
Name: "root",
|
||||
Providers: moduledeps.Providers{
|
||||
"foo": moduledeps.ProviderDependency{
|
||||
addrs.NewLegacyProvider("foo"): moduledeps.ProviderDependency{
|
||||
Constraints: discovery.ConstraintStr(">=1.0.0").MustParse(),
|
||||
Reason: moduledeps.ProviderDependencyExplicit,
|
||||
},
|
||||
"foo.bar": moduledeps.ProviderDependency{
|
||||
Constraints: discovery.ConstraintStr(">=2.0.0").MustParse(),
|
||||
Reason: moduledeps.ProviderDependencyExplicit,
|
||||
},
|
||||
"baz": moduledeps.ProviderDependency{
|
||||
addrs.NewLegacyProvider("baz"): moduledeps.ProviderDependency{
|
||||
Constraints: discovery.AllVersions,
|
||||
Reason: moduledeps.ProviderDependencyFromState,
|
||||
},
|
||||
|
@ -244,7 +229,7 @@ func TestModuleTreeDependencies(t *testing.T) {
|
|||
{
|
||||
Name: "grandchild",
|
||||
Providers: moduledeps.Providers{
|
||||
"banana": moduledeps.ProviderDependency{
|
||||
addrs.NewLegacyProvider("banana"): moduledeps.ProviderDependency{
|
||||
Constraints: discovery.AllVersions,
|
||||
Reason: moduledeps.ProviderDependencyFromState,
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue