WIP reference providers by full name
This turned out to be a big messy commit, since the way providers are referenced is tightly coupled throughout the code. That starts to unify how providers are referenced, using the format output node Name method. Add a new field to the internal resource data types called ResolvedProvider. This is set by a new setter method SetProvider when a resource is connected to a provider during graph creation. This allows us to later lookup the provider instance a resource is connected to, without requiring it to have the same module path. The InitProvider context method now takes 2 arguments, one if the provider type and the second is the full name of the provider. While the provider type could still be parsed from the full name, this makes it more explicit and, and changes to the name format won't effect this code.
This commit is contained in:
parent
1d54d4b10d
commit
a14fd0344c
|
@ -861,7 +861,7 @@ func TestContext2Apply_createBeforeDestroy(t *testing.T) {
|
||||||
actual := strings.TrimSpace(state.String())
|
actual := strings.TrimSpace(state.String())
|
||||||
expected := strings.TrimSpace(testTerraformApplyCreateBeforeStr)
|
expected := strings.TrimSpace(testTerraformApplyCreateBeforeStr)
|
||||||
if actual != expected {
|
if actual != expected {
|
||||||
t.Fatalf("bad: \n%s", actual)
|
t.Fatalf("expected:\n%s\ngot:\n%s", expected, actual)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -687,13 +687,10 @@ func TestContext2Plan_moduleProviderDefaultsVar(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
expected := []string{
|
expected := []string{
|
||||||
"root\n",
|
|
||||||
// this test originally verified that a parent provider config can
|
|
||||||
// partially override a child. That's no longer the case, so the child
|
|
||||||
// config is used in its entirety here.
|
|
||||||
//"root\nchild\n",
|
|
||||||
"child\nchild\n",
|
"child\nchild\n",
|
||||||
|
"root\n",
|
||||||
}
|
}
|
||||||
|
sort.Strings(calls)
|
||||||
if !reflect.DeepEqual(calls, expected) {
|
if !reflect.DeepEqual(calls, expected) {
|
||||||
t.Fatalf("expected:\n%#v\ngot:\n%#v\n", expected, calls)
|
t.Fatalf("expected:\n%#v\ngot:\n%#v\n", expected, calls)
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,11 +22,11 @@ type EvalContext interface {
|
||||||
// Input is the UIInput object for interacting with the UI.
|
// Input is the UIInput object for interacting with the UI.
|
||||||
Input() UIInput
|
Input() UIInput
|
||||||
|
|
||||||
// InitProvider initializes the provider with the given name and
|
// InitProvider initializes the provider with the given type and name, and
|
||||||
// returns the implementation of the resource provider or an error.
|
// returns the implementation of the resource provider or an error.
|
||||||
//
|
//
|
||||||
// It is an error to initialize the same provider more than once.
|
// It is an error to initialize the same provider more than once.
|
||||||
InitProvider(string) (ResourceProvider, error)
|
InitProvider(typ string, name string) (ResourceProvider, error)
|
||||||
|
|
||||||
// Provider gets the provider instance with the given name (already
|
// Provider gets the provider instance with the given name (already
|
||||||
// initialized) or returns nil if the provider isn't initialized.
|
// initialized) or returns nil if the provider isn't initialized.
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"strings"
|
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/config"
|
"github.com/hashicorp/terraform/config"
|
||||||
|
@ -79,12 +78,12 @@ func (ctx *BuiltinEvalContext) Input() UIInput {
|
||||||
return ctx.InputValue
|
return ctx.InputValue
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctx *BuiltinEvalContext) InitProvider(n string) (ResourceProvider, error) {
|
func (ctx *BuiltinEvalContext) InitProvider(typeName, name string) (ResourceProvider, error) {
|
||||||
ctx.once.Do(ctx.init)
|
ctx.once.Do(ctx.init)
|
||||||
|
|
||||||
// If we already initialized, it is an error
|
// If we already initialized, it is an error
|
||||||
if p := ctx.Provider(n); p != nil {
|
if p := ctx.Provider(name); p != nil {
|
||||||
return nil, fmt.Errorf("Provider '%s' already initialized", n)
|
return nil, fmt.Errorf("Provider '%s' already initialized", name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Warning: make sure to acquire these locks AFTER the call to Provider
|
// Warning: make sure to acquire these locks AFTER the call to Provider
|
||||||
|
@ -92,13 +91,12 @@ func (ctx *BuiltinEvalContext) InitProvider(n string) (ResourceProvider, error)
|
||||||
ctx.ProviderLock.Lock()
|
ctx.ProviderLock.Lock()
|
||||||
defer ctx.ProviderLock.Unlock()
|
defer ctx.ProviderLock.Unlock()
|
||||||
|
|
||||||
typeName := strings.SplitN(n, ".", 2)[0]
|
p, err := ctx.Components.ResourceProvider(typeName, name)
|
||||||
p, err := ctx.Components.ResourceProvider(typeName, n)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.ProviderCache[n] = p
|
ctx.ProviderCache[name] = p
|
||||||
return p, nil
|
return p, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -107,7 +107,7 @@ func (c *MockEvalContext) Input() UIInput {
|
||||||
return c.InputInput
|
return c.InputInput
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *MockEvalContext) InitProvider(n string) (ResourceProvider, error) {
|
func (c *MockEvalContext) InitProvider(t, n string) (ResourceProvider, error) {
|
||||||
c.InitProviderCalled = true
|
c.InitProviderCalled = true
|
||||||
c.InitProviderName = n
|
c.InitProviderName = n
|
||||||
return c.InitProviderProvider, c.InitProviderError
|
return c.InitProviderProvider, c.InitProviderError
|
||||||
|
|
|
@ -52,11 +52,12 @@ func (n *EvalConfigProvider) Eval(ctx EvalContext) (interface{}, error) {
|
||||||
// and returns nothing. The provider can be retrieved again with the
|
// and returns nothing. The provider can be retrieved again with the
|
||||||
// EvalGetProvider node.
|
// EvalGetProvider node.
|
||||||
type EvalInitProvider struct {
|
type EvalInitProvider struct {
|
||||||
|
TypeName string
|
||||||
Name string
|
Name string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *EvalInitProvider) Eval(ctx EvalContext) (interface{}, error) {
|
func (n *EvalInitProvider) Eval(ctx EvalContext) (interface{}, error) {
|
||||||
return ctx.InitProvider(n.Name)
|
return ctx.InitProvider(n.TypeName, n.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// EvalCloseProvider is an EvalNode implementation that closes provider
|
// EvalCloseProvider is an EvalNode implementation that closes provider
|
||||||
|
@ -129,6 +130,7 @@ func (n *EvalInputProvider) Eval(ctx EvalContext) (interface{}, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.SetProviderInput(n.Name, confMap)
|
ctx.SetProviderInput(n.Name, confMap)
|
||||||
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
|
|
|
@ -1,17 +1,24 @@
|
||||||
package terraform
|
package terraform
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/config"
|
"github.com/hashicorp/terraform/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ProviderEvalTree returns the evaluation tree for initializing and
|
// ProviderEvalTree returns the evaluation tree for initializing and
|
||||||
// configuring providers.
|
// configuring providers.
|
||||||
func ProviderEvalTree(n string, config *config.ProviderConfig) EvalNode {
|
func ProviderEvalTree(n *NodeApplyableProvider, config *config.ProviderConfig) EvalNode {
|
||||||
var provider ResourceProvider
|
var provider ResourceProvider
|
||||||
var resourceConfig *ResourceConfig
|
var resourceConfig *ResourceConfig
|
||||||
|
|
||||||
|
typeName := strings.SplitN(n.NameValue, ".", 2)[0]
|
||||||
|
|
||||||
seq := make([]EvalNode, 0, 5)
|
seq := make([]EvalNode, 0, 5)
|
||||||
seq = append(seq, &EvalInitProvider{Name: n})
|
seq = append(seq, &EvalInitProvider{
|
||||||
|
TypeName: typeName,
|
||||||
|
Name: n.Name(),
|
||||||
|
})
|
||||||
|
|
||||||
// Input stuff
|
// Input stuff
|
||||||
seq = append(seq, &EvalOpFilter{
|
seq = append(seq, &EvalOpFilter{
|
||||||
|
@ -19,7 +26,7 @@ func ProviderEvalTree(n string, config *config.ProviderConfig) EvalNode {
|
||||||
Node: &EvalSequence{
|
Node: &EvalSequence{
|
||||||
Nodes: []EvalNode{
|
Nodes: []EvalNode{
|
||||||
&EvalGetProvider{
|
&EvalGetProvider{
|
||||||
Name: n,
|
Name: n.Name(),
|
||||||
Output: &provider,
|
Output: &provider,
|
||||||
},
|
},
|
||||||
&EvalInterpolateProvider{
|
&EvalInterpolateProvider{
|
||||||
|
@ -27,12 +34,12 @@ func ProviderEvalTree(n string, config *config.ProviderConfig) EvalNode {
|
||||||
Output: &resourceConfig,
|
Output: &resourceConfig,
|
||||||
},
|
},
|
||||||
&EvalBuildProviderConfig{
|
&EvalBuildProviderConfig{
|
||||||
Provider: n,
|
Provider: n.NameValue,
|
||||||
Config: &resourceConfig,
|
Config: &resourceConfig,
|
||||||
Output: &resourceConfig,
|
Output: &resourceConfig,
|
||||||
},
|
},
|
||||||
&EvalInputProvider{
|
&EvalInputProvider{
|
||||||
Name: n,
|
Name: n.NameValue,
|
||||||
Provider: &provider,
|
Provider: &provider,
|
||||||
Config: &resourceConfig,
|
Config: &resourceConfig,
|
||||||
},
|
},
|
||||||
|
@ -45,7 +52,7 @@ func ProviderEvalTree(n string, config *config.ProviderConfig) EvalNode {
|
||||||
Node: &EvalSequence{
|
Node: &EvalSequence{
|
||||||
Nodes: []EvalNode{
|
Nodes: []EvalNode{
|
||||||
&EvalGetProvider{
|
&EvalGetProvider{
|
||||||
Name: n,
|
Name: n.Name(),
|
||||||
Output: &provider,
|
Output: &provider,
|
||||||
},
|
},
|
||||||
&EvalInterpolateProvider{
|
&EvalInterpolateProvider{
|
||||||
|
@ -53,7 +60,7 @@ func ProviderEvalTree(n string, config *config.ProviderConfig) EvalNode {
|
||||||
Output: &resourceConfig,
|
Output: &resourceConfig,
|
||||||
},
|
},
|
||||||
&EvalBuildProviderConfig{
|
&EvalBuildProviderConfig{
|
||||||
Provider: n,
|
Provider: n.NameValue,
|
||||||
Config: &resourceConfig,
|
Config: &resourceConfig,
|
||||||
Output: &resourceConfig,
|
Output: &resourceConfig,
|
||||||
},
|
},
|
||||||
|
@ -71,7 +78,7 @@ func ProviderEvalTree(n string, config *config.ProviderConfig) EvalNode {
|
||||||
Node: &EvalSequence{
|
Node: &EvalSequence{
|
||||||
Nodes: []EvalNode{
|
Nodes: []EvalNode{
|
||||||
&EvalGetProvider{
|
&EvalGetProvider{
|
||||||
Name: n,
|
Name: n.Name(),
|
||||||
Output: &provider,
|
Output: &provider,
|
||||||
},
|
},
|
||||||
&EvalInterpolateProvider{
|
&EvalInterpolateProvider{
|
||||||
|
@ -79,7 +86,7 @@ func ProviderEvalTree(n string, config *config.ProviderConfig) EvalNode {
|
||||||
Output: &resourceConfig,
|
Output: &resourceConfig,
|
||||||
},
|
},
|
||||||
&EvalBuildProviderConfig{
|
&EvalBuildProviderConfig{
|
||||||
Provider: n,
|
Provider: n.NameValue,
|
||||||
Config: &resourceConfig,
|
Config: &resourceConfig,
|
||||||
Output: &resourceConfig,
|
Output: &resourceConfig,
|
||||||
},
|
},
|
||||||
|
@ -94,7 +101,7 @@ func ProviderEvalTree(n string, config *config.ProviderConfig) EvalNode {
|
||||||
Node: &EvalSequence{
|
Node: &EvalSequence{
|
||||||
Nodes: []EvalNode{
|
Nodes: []EvalNode{
|
||||||
&EvalConfigProvider{
|
&EvalConfigProvider{
|
||||||
Provider: n,
|
Provider: n.Name(),
|
||||||
Config: &resourceConfig,
|
Config: &resourceConfig,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -52,6 +52,13 @@ func (b *ImportGraphBuilder) Steps() []GraphTransformer {
|
||||||
// Add the import steps
|
// Add the import steps
|
||||||
&ImportStateTransformer{Targets: b.ImportTargets},
|
&ImportStateTransformer{Targets: b.ImportTargets},
|
||||||
|
|
||||||
|
// add configured providers
|
||||||
|
&ProviderConfigTransformer{
|
||||||
|
Module: b.Module,
|
||||||
|
Providers: b.Providers,
|
||||||
|
Concrete: concreteProvider,
|
||||||
|
},
|
||||||
|
|
||||||
// Provider-related transformations
|
// Provider-related transformations
|
||||||
&MissingProviderTransformer{Providers: b.Providers, Concrete: concreteProvider},
|
&MissingProviderTransformer{Providers: b.Providers, Concrete: concreteProvider},
|
||||||
&ProviderTransformer{},
|
&ProviderTransformer{},
|
||||||
|
|
|
@ -126,6 +126,13 @@ func (b *RefreshGraphBuilder) Steps() []GraphTransformer {
|
||||||
// Add root variables
|
// Add root variables
|
||||||
&RootVariableTransformer{Module: b.Module},
|
&RootVariableTransformer{Module: b.Module},
|
||||||
|
|
||||||
|
// add configured providers
|
||||||
|
&ProviderConfigTransformer{
|
||||||
|
Module: b.Module,
|
||||||
|
Providers: b.Providers,
|
||||||
|
Concrete: concreteProvider,
|
||||||
|
},
|
||||||
|
|
||||||
// Create all the providers
|
// Create all the providers
|
||||||
&MissingProviderTransformer{Providers: b.Providers, Concrete: concreteProvider},
|
&MissingProviderTransformer{Providers: b.Providers, Concrete: concreteProvider},
|
||||||
&ProviderTransformer{},
|
&ProviderTransformer{},
|
||||||
|
|
|
@ -27,6 +27,7 @@ func (n *NodeRefreshableDataResource) DynamicExpand(ctx EvalContext) (*Graph, er
|
||||||
concreteResource := func(a *NodeAbstractResource) dag.Vertex {
|
concreteResource := func(a *NodeAbstractResource) dag.Vertex {
|
||||||
// Add the config and state since we don't do that via transforms
|
// Add the config and state since we don't do that via transforms
|
||||||
a.Config = n.Config
|
a.Config = n.Config
|
||||||
|
a.ResolvedProvider = n.ResolvedProvider
|
||||||
|
|
||||||
return &NodeRefreshableDataResourceInstance{
|
return &NodeRefreshableDataResourceInstance{
|
||||||
NodeAbstractResource: a,
|
NodeAbstractResource: a,
|
||||||
|
@ -185,7 +186,7 @@ func (n *NodeRefreshableDataResourceInstance) EvalTree() EvalNode {
|
||||||
// provider configurations that need this data during
|
// provider configurations that need this data during
|
||||||
// refresh/plan.
|
// refresh/plan.
|
||||||
&EvalGetProvider{
|
&EvalGetProvider{
|
||||||
Name: n.ProvidedBy()[0],
|
Name: n.ResolvedProvider,
|
||||||
Output: &provider,
|
Output: &provider,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -7,5 +7,5 @@ type NodeApplyableProvider struct {
|
||||||
|
|
||||||
// GraphNodeEvalable
|
// GraphNodeEvalable
|
||||||
func (n *NodeApplyableProvider) EvalTree() EvalNode {
|
func (n *NodeApplyableProvider) EvalTree() EvalNode {
|
||||||
return ProviderEvalTree(n.NameValue, n.ProviderConfig())
|
return ProviderEvalTree(n, n.ProviderConfig())
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,13 +24,17 @@ type NodeAbstractProvider struct {
|
||||||
Config *config.ProviderConfig
|
Config *config.ProviderConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *NodeAbstractProvider) Name() string {
|
func ResolveProviderName(name string, path []string) string {
|
||||||
result := fmt.Sprintf("provider.%s", n.NameValue)
|
name = fmt.Sprintf("provider.%s", name)
|
||||||
if len(n.PathValue) > 1 {
|
if len(path) > 1 {
|
||||||
result = fmt.Sprintf("%s.%s", modulePrefixStr(n.PathValue), result)
|
name = fmt.Sprintf("%s.%s", modulePrefixStr(path), name)
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return name
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *NodeAbstractProvider) Name() string {
|
||||||
|
return ResolveProviderName(n.NameValue, n.PathValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GraphNodeSubPath
|
// GraphNodeSubPath
|
||||||
|
|
|
@ -33,6 +33,9 @@ type NodeAbstractResource struct {
|
||||||
ResourceState *ResourceState // ResourceState is the ResourceState for this
|
ResourceState *ResourceState // ResourceState is the ResourceState for this
|
||||||
|
|
||||||
Targets []ResourceAddress // Set from GraphNodeTargetable
|
Targets []ResourceAddress // Set from GraphNodeTargetable
|
||||||
|
|
||||||
|
// The address of the provider this resource will use
|
||||||
|
ResolvedProvider string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *NodeAbstractResource) Name() string {
|
func (n *NodeAbstractResource) Name() string {
|
||||||
|
@ -170,6 +173,10 @@ func (n *NodeAbstractResource) StateReferences() []string {
|
||||||
return deps
|
return deps
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (n *NodeAbstractResource) SetProvider(p string) {
|
||||||
|
n.ResolvedProvider = p
|
||||||
|
}
|
||||||
|
|
||||||
// GraphNodeProviderConsumer
|
// GraphNodeProviderConsumer
|
||||||
func (n *NodeAbstractResource) ProvidedBy() []string {
|
func (n *NodeAbstractResource) ProvidedBy() []string {
|
||||||
// If we have a config we prefer that above all else
|
// If we have a config we prefer that above all else
|
||||||
|
|
|
@ -135,7 +135,7 @@ func (n *NodeApplyableResource) evalTreeDataResource(
|
||||||
},
|
},
|
||||||
|
|
||||||
&EvalGetProvider{
|
&EvalGetProvider{
|
||||||
Name: n.ProvidedBy()[0],
|
Name: n.ResolvedProvider,
|
||||||
Output: &provider,
|
Output: &provider,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -242,7 +242,7 @@ func (n *NodeApplyableResource) evalTreeManagedResource(
|
||||||
Output: &resourceConfig,
|
Output: &resourceConfig,
|
||||||
},
|
},
|
||||||
&EvalGetProvider{
|
&EvalGetProvider{
|
||||||
Name: n.ProvidedBy()[0],
|
Name: n.ResolvedProvider,
|
||||||
Output: &provider,
|
Output: &provider,
|
||||||
},
|
},
|
||||||
&EvalReadState{
|
&EvalReadState{
|
||||||
|
@ -283,7 +283,7 @@ func (n *NodeApplyableResource) evalTreeManagedResource(
|
||||||
},
|
},
|
||||||
|
|
||||||
&EvalGetProvider{
|
&EvalGetProvider{
|
||||||
Name: n.ProvidedBy()[0],
|
Name: n.ResolvedProvider,
|
||||||
Output: &provider,
|
Output: &provider,
|
||||||
},
|
},
|
||||||
&EvalReadState{
|
&EvalReadState{
|
||||||
|
|
|
@ -104,6 +104,7 @@ func (n *NodeDestroyResource) DynamicExpand(ctx EvalContext) (*Graph, error) {
|
||||||
steps = append(steps, &DeposedTransformer{
|
steps = append(steps, &DeposedTransformer{
|
||||||
State: state,
|
State: state,
|
||||||
View: n.Addr.stateId(),
|
View: n.Addr.stateId(),
|
||||||
|
ResolvedProvider: n.ResolvedProvider,
|
||||||
})
|
})
|
||||||
|
|
||||||
// Target
|
// Target
|
||||||
|
@ -188,7 +189,7 @@ func (n *NodeDestroyResource) EvalTree() EvalNode {
|
||||||
&EvalInstanceInfo{Info: info},
|
&EvalInstanceInfo{Info: info},
|
||||||
|
|
||||||
&EvalGetProvider{
|
&EvalGetProvider{
|
||||||
Name: n.ProvidedBy()[0],
|
Name: n.ResolvedProvider,
|
||||||
Output: &provider,
|
Output: &provider,
|
||||||
},
|
},
|
||||||
&EvalReadState{
|
&EvalReadState{
|
||||||
|
|
|
@ -27,6 +27,7 @@ func (n *NodePlannableResource) DynamicExpand(ctx EvalContext) (*Graph, error) {
|
||||||
concreteResource := func(a *NodeAbstractResource) dag.Vertex {
|
concreteResource := func(a *NodeAbstractResource) dag.Vertex {
|
||||||
// Add the config and state since we don't do that via transforms
|
// Add the config and state since we don't do that via transforms
|
||||||
a.Config = n.Config
|
a.Config = n.Config
|
||||||
|
a.ResolvedProvider = n.ResolvedProvider
|
||||||
|
|
||||||
return &NodePlannableResourceInstance{
|
return &NodePlannableResourceInstance{
|
||||||
NodeAbstractResource: a,
|
NodeAbstractResource: a,
|
||||||
|
@ -37,6 +38,7 @@ func (n *NodePlannableResource) DynamicExpand(ctx EvalContext) (*Graph, error) {
|
||||||
concreteResourceOrphan := func(a *NodeAbstractResource) dag.Vertex {
|
concreteResourceOrphan := func(a *NodeAbstractResource) dag.Vertex {
|
||||||
// Add the config and state since we don't do that via transforms
|
// Add the config and state since we don't do that via transforms
|
||||||
a.Config = n.Config
|
a.Config = n.Config
|
||||||
|
a.ResolvedProvider = n.ResolvedProvider
|
||||||
|
|
||||||
return &NodePlannableResourceOrphan{
|
return &NodePlannableResourceOrphan{
|
||||||
NodeAbstractResource: a,
|
NodeAbstractResource: a,
|
||||||
|
|
|
@ -97,7 +97,7 @@ func (n *NodePlannableResourceInstance) evalTreeDataResource(
|
||||||
},
|
},
|
||||||
|
|
||||||
&EvalGetProvider{
|
&EvalGetProvider{
|
||||||
Name: n.ProvidedBy()[0],
|
Name: n.ResolvedProvider,
|
||||||
Output: &provider,
|
Output: &provider,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -143,7 +143,7 @@ func (n *NodePlannableResourceInstance) evalTreeManagedResource(
|
||||||
Output: &resourceConfig,
|
Output: &resourceConfig,
|
||||||
},
|
},
|
||||||
&EvalGetProvider{
|
&EvalGetProvider{
|
||||||
Name: n.ProvidedBy()[0],
|
Name: n.ResolvedProvider,
|
||||||
Output: &provider,
|
Output: &provider,
|
||||||
},
|
},
|
||||||
// Re-run validation to catch any errors we missed, e.g. type
|
// Re-run validation to catch any errors we missed, e.g. type
|
||||||
|
|
|
@ -30,6 +30,7 @@ func (n *NodeRefreshableManagedResource) DynamicExpand(ctx EvalContext) (*Graph,
|
||||||
concreteResource := func(a *NodeAbstractResource) dag.Vertex {
|
concreteResource := func(a *NodeAbstractResource) dag.Vertex {
|
||||||
// Add the config and state since we don't do that via transforms
|
// Add the config and state since we don't do that via transforms
|
||||||
a.Config = n.Config
|
a.Config = n.Config
|
||||||
|
a.ResolvedProvider = n.ResolvedProvider
|
||||||
|
|
||||||
return &NodeRefreshableManagedResourceInstance{
|
return &NodeRefreshableManagedResourceInstance{
|
||||||
NodeAbstractResource: a,
|
NodeAbstractResource: a,
|
||||||
|
@ -149,7 +150,7 @@ func (n *NodeRefreshableManagedResourceInstance) evalTreeManagedResource() EvalN
|
||||||
return &EvalSequence{
|
return &EvalSequence{
|
||||||
Nodes: []EvalNode{
|
Nodes: []EvalNode{
|
||||||
&EvalGetProvider{
|
&EvalGetProvider{
|
||||||
Name: n.ProvidedBy()[0],
|
Name: n.ResolvedProvider,
|
||||||
Output: &provider,
|
Output: &provider,
|
||||||
},
|
},
|
||||||
&EvalReadState{
|
&EvalReadState{
|
||||||
|
@ -220,7 +221,7 @@ func (n *NodeRefreshableManagedResourceInstance) evalTreeManagedResourceNoState(
|
||||||
Output: &resourceConfig,
|
Output: &resourceConfig,
|
||||||
},
|
},
|
||||||
&EvalGetProvider{
|
&EvalGetProvider{
|
||||||
Name: n.ProvidedBy()[0],
|
Name: n.ResolvedProvider,
|
||||||
Output: &provider,
|
Output: &provider,
|
||||||
},
|
},
|
||||||
// Re-run validation to catch any errors we missed, e.g. type
|
// Re-run validation to catch any errors we missed, e.g. type
|
||||||
|
|
|
@ -39,6 +39,7 @@ func (n *NodeValidatableResource) DynamicExpand(ctx EvalContext) (*Graph, error)
|
||||||
concreteResource := func(a *NodeAbstractResource) dag.Vertex {
|
concreteResource := func(a *NodeAbstractResource) dag.Vertex {
|
||||||
// Add the config and state since we don't do that via transforms
|
// Add the config and state since we don't do that via transforms
|
||||||
a.Config = n.Config
|
a.Config = n.Config
|
||||||
|
a.ResolvedProvider = n.ResolvedProvider
|
||||||
|
|
||||||
return &NodeValidatableResourceInstance{
|
return &NodeValidatableResourceInstance{
|
||||||
NodeAbstractResource: a,
|
NodeAbstractResource: a,
|
||||||
|
@ -108,7 +109,7 @@ func (n *NodeValidatableResourceInstance) EvalTree() EvalNode {
|
||||||
Config: &n.Config.RawConfig,
|
Config: &n.Config.RawConfig,
|
||||||
},
|
},
|
||||||
&EvalGetProvider{
|
&EvalGetProvider{
|
||||||
Name: n.ProvidedBy()[0],
|
Name: n.ResolvedProvider,
|
||||||
Output: &provider,
|
Output: &provider,
|
||||||
},
|
},
|
||||||
&EvalInterpolate{
|
&EvalInterpolate{
|
||||||
|
|
|
@ -12,6 +12,9 @@ type DeposedTransformer struct {
|
||||||
// View, if non-empty, is the ModuleState.View used around the state
|
// View, if non-empty, is the ModuleState.View used around the state
|
||||||
// to find deposed resources.
|
// to find deposed resources.
|
||||||
View string
|
View string
|
||||||
|
|
||||||
|
// The provider used by the resourced which were deposed
|
||||||
|
ResolvedProvider string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *DeposedTransformer) Transform(g *Graph) error {
|
func (t *DeposedTransformer) Transform(g *Graph) error {
|
||||||
|
@ -33,6 +36,7 @@ func (t *DeposedTransformer) Transform(g *Graph) error {
|
||||||
if len(rs.Deposed) == 0 {
|
if len(rs.Deposed) == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
deposed := rs.Deposed
|
deposed := rs.Deposed
|
||||||
|
|
||||||
for i, _ := range deposed {
|
for i, _ := range deposed {
|
||||||
|
@ -40,7 +44,8 @@ func (t *DeposedTransformer) Transform(g *Graph) error {
|
||||||
Index: i,
|
Index: i,
|
||||||
ResourceName: k,
|
ResourceName: k,
|
||||||
ResourceType: rs.Type,
|
ResourceType: rs.Type,
|
||||||
Provider: rs.Provider,
|
ProviderName: rs.Provider,
|
||||||
|
ResolvedProvider: t.ResolvedProvider,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,7 +58,8 @@ type graphNodeDeposedResource struct {
|
||||||
Index int
|
Index int
|
||||||
ResourceName string
|
ResourceName string
|
||||||
ResourceType string
|
ResourceType string
|
||||||
Provider string
|
ProviderName string
|
||||||
|
ResolvedProvider string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *graphNodeDeposedResource) Name() string {
|
func (n *graphNodeDeposedResource) Name() string {
|
||||||
|
@ -61,7 +67,11 @@ func (n *graphNodeDeposedResource) Name() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *graphNodeDeposedResource) ProvidedBy() []string {
|
func (n *graphNodeDeposedResource) ProvidedBy() []string {
|
||||||
return []string{resourceProvider(n.ResourceName, n.Provider)}
|
return []string{resourceProvider(n.ResourceName, n.ProviderName)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *graphNodeDeposedResource) SetProvider(p string) {
|
||||||
|
n.ResolvedProvider = p
|
||||||
}
|
}
|
||||||
|
|
||||||
// GraphNodeEvalable impl.
|
// GraphNodeEvalable impl.
|
||||||
|
@ -81,7 +91,7 @@ func (n *graphNodeDeposedResource) EvalTree() EvalNode {
|
||||||
Node: &EvalSequence{
|
Node: &EvalSequence{
|
||||||
Nodes: []EvalNode{
|
Nodes: []EvalNode{
|
||||||
&EvalGetProvider{
|
&EvalGetProvider{
|
||||||
Name: n.ProvidedBy()[0],
|
Name: n.ResolvedProvider,
|
||||||
Output: &provider,
|
Output: &provider,
|
||||||
},
|
},
|
||||||
&EvalReadStateDeposed{
|
&EvalReadStateDeposed{
|
||||||
|
@ -98,7 +108,7 @@ func (n *graphNodeDeposedResource) EvalTree() EvalNode {
|
||||||
&EvalWriteStateDeposed{
|
&EvalWriteStateDeposed{
|
||||||
Name: n.ResourceName,
|
Name: n.ResourceName,
|
||||||
ResourceType: n.ResourceType,
|
ResourceType: n.ResourceType,
|
||||||
Provider: n.Provider,
|
Provider: n.ProviderName,
|
||||||
State: &state,
|
State: &state,
|
||||||
Index: n.Index,
|
Index: n.Index,
|
||||||
},
|
},
|
||||||
|
@ -114,7 +124,7 @@ func (n *graphNodeDeposedResource) EvalTree() EvalNode {
|
||||||
Node: &EvalSequence{
|
Node: &EvalSequence{
|
||||||
Nodes: []EvalNode{
|
Nodes: []EvalNode{
|
||||||
&EvalGetProvider{
|
&EvalGetProvider{
|
||||||
Name: n.ProvidedBy()[0],
|
Name: n.ResolvedProvider,
|
||||||
Output: &provider,
|
Output: &provider,
|
||||||
},
|
},
|
||||||
&EvalReadStateDeposed{
|
&EvalReadStateDeposed{
|
||||||
|
@ -147,7 +157,7 @@ func (n *graphNodeDeposedResource) EvalTree() EvalNode {
|
||||||
&EvalWriteStateDeposed{
|
&EvalWriteStateDeposed{
|
||||||
Name: n.ResourceName,
|
Name: n.ResourceName,
|
||||||
ResourceType: n.ResourceType,
|
ResourceType: n.ResourceType,
|
||||||
Provider: n.Provider,
|
Provider: n.ProviderName,
|
||||||
State: &state,
|
State: &state,
|
||||||
Index: n.Index,
|
Index: n.Index,
|
||||||
},
|
},
|
||||||
|
|
|
@ -23,7 +23,7 @@ func (t *ImportStateTransformer) Transform(g *Graph) error {
|
||||||
nodes = append(nodes, &graphNodeImportState{
|
nodes = append(nodes, &graphNodeImportState{
|
||||||
Addr: addr,
|
Addr: addr,
|
||||||
ID: target.ID,
|
ID: target.ID,
|
||||||
Provider: target.Provider,
|
ProviderName: target.Provider,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,7 +38,8 @@ func (t *ImportStateTransformer) Transform(g *Graph) error {
|
||||||
type graphNodeImportState struct {
|
type graphNodeImportState struct {
|
||||||
Addr *ResourceAddress // Addr is the resource address to import to
|
Addr *ResourceAddress // Addr is the resource address to import to
|
||||||
ID string // ID is the ID to import as
|
ID string // ID is the ID to import as
|
||||||
Provider string // Provider string
|
ProviderName string // Provider string
|
||||||
|
ResolvedProvider string // provider node address
|
||||||
|
|
||||||
states []*InstanceState
|
states []*InstanceState
|
||||||
}
|
}
|
||||||
|
@ -48,7 +49,11 @@ func (n *graphNodeImportState) Name() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *graphNodeImportState) ProvidedBy() []string {
|
func (n *graphNodeImportState) ProvidedBy() []string {
|
||||||
return []string{resourceProvider(n.Addr.Type, n.Provider)}
|
return []string{resourceProvider(n.Addr.Type, n.ProviderName)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *graphNodeImportState) SetProvider(p string) {
|
||||||
|
n.ResolvedProvider = p
|
||||||
}
|
}
|
||||||
|
|
||||||
// GraphNodeSubPath
|
// GraphNodeSubPath
|
||||||
|
@ -72,7 +77,7 @@ func (n *graphNodeImportState) EvalTree() EvalNode {
|
||||||
return &EvalSequence{
|
return &EvalSequence{
|
||||||
Nodes: []EvalNode{
|
Nodes: []EvalNode{
|
||||||
&EvalGetProvider{
|
&EvalGetProvider{
|
||||||
Name: n.ProvidedBy()[0],
|
Name: n.ResolvedProvider,
|
||||||
Output: &provider,
|
Output: &provider,
|
||||||
},
|
},
|
||||||
&EvalImportState{
|
&EvalImportState{
|
||||||
|
@ -152,7 +157,8 @@ func (n *graphNodeImportState) DynamicExpand(ctx EvalContext) (*Graph, error) {
|
||||||
Target: addrs[i],
|
Target: addrs[i],
|
||||||
Path_: n.Path(),
|
Path_: n.Path(),
|
||||||
State: state,
|
State: state,
|
||||||
Provider: n.Provider,
|
ProviderName: n.ProviderName,
|
||||||
|
ResolvedProvider: n.ResolvedProvider,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,7 +179,8 @@ type graphNodeImportStateSub struct {
|
||||||
Target *ResourceAddress
|
Target *ResourceAddress
|
||||||
State *InstanceState
|
State *InstanceState
|
||||||
Path_ []string
|
Path_ []string
|
||||||
Provider string
|
ProviderName string
|
||||||
|
ResolvedProvider string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *graphNodeImportStateSub) Name() string {
|
func (n *graphNodeImportStateSub) Name() string {
|
||||||
|
@ -216,7 +223,7 @@ func (n *graphNodeImportStateSub) EvalTree() EvalNode {
|
||||||
return &EvalSequence{
|
return &EvalSequence{
|
||||||
Nodes: []EvalNode{
|
Nodes: []EvalNode{
|
||||||
&EvalGetProvider{
|
&EvalGetProvider{
|
||||||
Name: resourceProvider(info.Type, n.Provider),
|
Name: n.ResolvedProvider,
|
||||||
Output: &provider,
|
Output: &provider,
|
||||||
},
|
},
|
||||||
&EvalRefresh{
|
&EvalRefresh{
|
||||||
|
@ -233,7 +240,7 @@ func (n *graphNodeImportStateSub) EvalTree() EvalNode {
|
||||||
&EvalWriteState{
|
&EvalWriteState{
|
||||||
Name: key.String(),
|
Name: key.String(),
|
||||||
ResourceType: info.Type,
|
ResourceType: info.Type,
|
||||||
Provider: resourceProvider(info.Type, n.Provider),
|
Provider: resourceProvider(info.Type, n.ProviderName),
|
||||||
State: &state,
|
State: &state,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -10,10 +10,12 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// GraphNodeProvider is an interface that nodes that can be a provider
|
// GraphNodeProvider is an interface that nodes that can be a provider
|
||||||
// must implement. The ProviderName returned is the name of the provider
|
// must implement.
|
||||||
// they satisfy.
|
// ProviderName returns the name of the provider this satisfies.
|
||||||
|
// Name returns the full name of the provider in the config.
|
||||||
type GraphNodeProvider interface {
|
type GraphNodeProvider interface {
|
||||||
ProviderName() string
|
ProviderName() string
|
||||||
|
Name() string
|
||||||
}
|
}
|
||||||
|
|
||||||
// GraphNodeCloseProvider is an interface that nodes that can be a close
|
// GraphNodeCloseProvider is an interface that nodes that can be a close
|
||||||
|
@ -29,6 +31,8 @@ type GraphNodeCloseProvider interface {
|
||||||
type GraphNodeProviderConsumer interface {
|
type GraphNodeProviderConsumer interface {
|
||||||
// TODO: make this return s string instead of a []string
|
// TODO: make this return s string instead of a []string
|
||||||
ProvidedBy() []string
|
ProvidedBy() []string
|
||||||
|
// Set the resolved provider address for this resource.
|
||||||
|
SetProvider(string)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProviderTransformer is a GraphTransformer that maps resources to
|
// ProviderTransformer is a GraphTransformer that maps resources to
|
||||||
|
@ -58,19 +62,16 @@ func (t *ProviderTransformer) Transform(g *Graph) error {
|
||||||
|
|
||||||
// if we don't have a provider at this level, walk up the path looking for one
|
// if we don't have a provider at this level, walk up the path looking for one
|
||||||
for i := 1; target == nil; i++ {
|
for i := 1; target == nil; i++ {
|
||||||
pathPrefix := ""
|
path := normalizeModulePath(sp.Path())
|
||||||
raw := normalizeModulePath(sp.Path())
|
if len(path) < i {
|
||||||
if len(raw) < i {
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
raw = raw[:len(raw)-i]
|
key = ResolveProviderName(p, path[:len(path)-i])
|
||||||
|
|
||||||
if len(raw) > len(rootModulePath) {
|
|
||||||
pathPrefix = modulePrefixStr(raw) + "."
|
|
||||||
}
|
|
||||||
key = pathPrefix + p
|
|
||||||
target = m[key]
|
target = m[key]
|
||||||
|
if target != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if target == nil {
|
if target == nil {
|
||||||
|
@ -80,6 +81,7 @@ func (t *ProviderTransformer) Transform(g *Graph) error {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pv.SetProvider(key)
|
||||||
g.Connect(dag.BasicEdge(v, target))
|
g.Connect(dag.BasicEdge(v, target))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -95,36 +97,32 @@ type CloseProviderTransformer struct{}
|
||||||
|
|
||||||
func (t *CloseProviderTransformer) Transform(g *Graph) error {
|
func (t *CloseProviderTransformer) Transform(g *Graph) error {
|
||||||
pm := providerVertexMap(g)
|
pm := providerVertexMap(g)
|
||||||
cpm := closeProviderVertexMap(g)
|
cpm := make(map[string]*graphNodeCloseProvider)
|
||||||
var err error
|
var err error
|
||||||
for _, v := range g.Vertices() {
|
|
||||||
if pv, ok := v.(GraphNodeProviderConsumer); ok {
|
|
||||||
for _, p := range pv.ProvidedBy() {
|
|
||||||
key := p
|
|
||||||
source := cpm[key]
|
|
||||||
|
|
||||||
if source == nil {
|
for _, v := range pm {
|
||||||
// Create a new graphNodeCloseProvider and add it to the graph
|
p := v.(GraphNodeProvider)
|
||||||
source = &graphNodeCloseProvider{ProviderNameValue: p}
|
|
||||||
g.Add(source)
|
|
||||||
|
|
||||||
// Close node needs to depend on provider
|
// get the close provider of this type if we alread created it
|
||||||
provider, ok := pm[key]
|
closer := cpm[p.ProviderName()]
|
||||||
if !ok {
|
|
||||||
err = multierror.Append(err, fmt.Errorf(
|
|
||||||
"%s: provider %s couldn't be found for closing",
|
|
||||||
dag.VertexName(v), p))
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
g.Connect(dag.BasicEdge(source, provider))
|
|
||||||
|
|
||||||
// Make sure we also add the new graphNodeCloseProvider to the map
|
if closer == nil {
|
||||||
// so we don't create and add any duplicate graphNodeCloseProviders.
|
// create a closer for this provider type
|
||||||
cpm[key] = source
|
closer = &graphNodeCloseProvider{ProviderNameValue: p.ProviderName()}
|
||||||
|
g.Add(closer)
|
||||||
|
cpm[p.ProviderName()] = closer
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close node depends on all nodes provided by the provider
|
// Close node depends on the provider itself
|
||||||
g.Connect(dag.BasicEdge(source, v))
|
// this is added unconditionally, so it will connect to all instances
|
||||||
|
// of the provider. Extra edges will be removed by transitive
|
||||||
|
// reduction.
|
||||||
|
g.Connect(dag.BasicEdge(closer, p))
|
||||||
|
|
||||||
|
// connect all the provider's resources to the close node
|
||||||
|
for _, s := range g.UpEdges(p).List() {
|
||||||
|
if _, ok := s.(GraphNodeResource); ok {
|
||||||
|
g.Connect(dag.BasicEdge(closer, s))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -187,7 +185,7 @@ func (t *MissingProviderTransformer) Transform(g *Graph) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, p := range pv.ProvidedBy() {
|
p := pv.ProvidedBy()[0]
|
||||||
// always add the parent nodes to check, since configured providers
|
// always add the parent nodes to check, since configured providers
|
||||||
// may have already been added for modules.
|
// may have already been added for modules.
|
||||||
if len(path) > 0 {
|
if len(path) > 0 {
|
||||||
|
@ -201,10 +199,6 @@ func (t *MissingProviderTransformer) Transform(g *Graph) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
key := providerMapKey(p, pv)
|
key := providerMapKey(p, pv)
|
||||||
|
|
||||||
// TODO: jbardin come back to this
|
|
||||||
// only adding root level missing providers
|
|
||||||
key = p
|
|
||||||
if _, ok := m[key]; ok {
|
if _, ok := m[key]; ok {
|
||||||
// This provider already exists as a configure node
|
// This provider already exists as a configure node
|
||||||
continue
|
continue
|
||||||
|
@ -226,15 +220,12 @@ func (t *MissingProviderTransformer) Transform(g *Graph) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the missing provider node to the graph
|
// Add the missing provider node to the graph
|
||||||
v := t.Concrete(&NodeAbstractProvider{
|
provider := t.Concrete(&NodeAbstractProvider{
|
||||||
NameValue: p,
|
NameValue: p,
|
||||||
|
PathValue: path,
|
||||||
// TODO: jbardin come back to this
|
|
||||||
// only adding root level missing providers
|
|
||||||
//PathValue: path,
|
|
||||||
}).(dag.Vertex)
|
}).(dag.Vertex)
|
||||||
m[key] = g.Add(v)
|
|
||||||
}
|
m[key] = g.Add(provider)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -274,15 +265,14 @@ func (t *ParentProviderTransformer) Transform(g *Graph) error {
|
||||||
}
|
}
|
||||||
path = normalizeModulePath(path)
|
path = normalizeModulePath(path)
|
||||||
|
|
||||||
// Build the key with path.name i.e. "child.subchild.aws"
|
key := ResolveProviderName(pn.ProviderName(), path)
|
||||||
key := fmt.Sprintf("%s.%s", strings.Join(path, "."), pn.ProviderName())
|
|
||||||
m[key] = raw
|
m[key] = raw
|
||||||
|
|
||||||
// Determine the parent if we're non-root. This is length 1 since
|
// Determine the parent if we're non-root. This is length 1 since
|
||||||
// the 0 index should be "root" since we normalize above.
|
// the 0 index should be "root" since we normalize above.
|
||||||
if len(path) > 1 {
|
if len(path) > 1 {
|
||||||
path = path[:len(path)-1]
|
path = path[:len(path)-1]
|
||||||
key := fmt.Sprintf("%s.%s", strings.Join(path, "."), pn.ProviderName())
|
key := ResolveProviderName(pn.ProviderName(), path)
|
||||||
parentMap[raw] = key
|
parentMap[raw] = key
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -323,23 +313,19 @@ func (t *PruneProviderTransformer) Transform(g *Graph) error {
|
||||||
// providerMapKey is a helper that gives us the key to use for the
|
// providerMapKey is a helper that gives us the key to use for the
|
||||||
// maps returned by things such as providerVertexMap.
|
// maps returned by things such as providerVertexMap.
|
||||||
func providerMapKey(k string, v dag.Vertex) string {
|
func providerMapKey(k string, v dag.Vertex) string {
|
||||||
pathPrefix := ""
|
// we create a dummy provider to
|
||||||
|
var path []string
|
||||||
if sp, ok := v.(GraphNodeSubPath); ok {
|
if sp, ok := v.(GraphNodeSubPath); ok {
|
||||||
raw := normalizeModulePath(sp.Path())
|
path = normalizeModulePath(sp.Path())
|
||||||
if len(raw) > len(rootModulePath) {
|
|
||||||
pathPrefix = modulePrefixStr(raw) + "."
|
|
||||||
}
|
}
|
||||||
}
|
return ResolveProviderName(k, path)
|
||||||
|
|
||||||
return pathPrefix + k
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func providerVertexMap(g *Graph) map[string]dag.Vertex {
|
func providerVertexMap(g *Graph) map[string]dag.Vertex {
|
||||||
m := make(map[string]dag.Vertex)
|
m := make(map[string]dag.Vertex)
|
||||||
for _, v := range g.Vertices() {
|
for _, v := range g.Vertices() {
|
||||||
if pv, ok := v.(GraphNodeProvider); ok {
|
if pv, ok := v.(GraphNodeProvider); ok {
|
||||||
key := providerMapKey(pv.ProviderName(), v)
|
m[pv.Name()] = v
|
||||||
m[key] = v
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -416,3 +402,5 @@ func (n *graphNodeProviderConsumerDummy) Path() []string {
|
||||||
func (n *graphNodeProviderConsumerDummy) ProvidedBy() []string {
|
func (n *graphNodeProviderConsumerDummy) ProvidedBy() []string {
|
||||||
return []string{n.ProviderValue}
|
return []string{n.ProviderValue}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (n *graphNodeProviderConsumerDummy) SetProvider(string) {}
|
||||||
|
|
|
@ -256,7 +256,7 @@ func TestMissingProviderTransformer_moduleGrandchild(t *testing.T) {
|
||||||
actual := strings.TrimSpace(g.String())
|
actual := strings.TrimSpace(g.String())
|
||||||
expected := strings.TrimSpace(testTransformMissingProviderModuleGrandchildStr)
|
expected := strings.TrimSpace(testTransformMissingProviderModuleGrandchildStr)
|
||||||
if actual != expected {
|
if actual != expected {
|
||||||
t.Fatalf("bad:\n\n%s", actual)
|
t.Fatalf("expected:\n%s\n\ngot:\n%s", expected, actual)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -335,8 +335,13 @@ func ReferenceFromInterpolatedVar(v config.InterpolatedVariable) []string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func modulePrefixStr(p []string) string {
|
func modulePrefixStr(p []string) string {
|
||||||
|
// strip "root"
|
||||||
|
if len(p) > 0 && p[0] == rootModulePath[0] {
|
||||||
|
p = p[1:]
|
||||||
|
}
|
||||||
|
|
||||||
parts := make([]string, 0, len(p)*2)
|
parts := make([]string, 0, len(p)*2)
|
||||||
for _, p := range p[1:] {
|
for _, p := range p {
|
||||||
parts = append(parts, "module", p)
|
parts = append(parts, "module", p)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,9 @@ func (t *ResourceCountTransformer) Transform(g *Graph) error {
|
||||||
addr.Index = index
|
addr.Index = index
|
||||||
|
|
||||||
// Build the abstract node and the concrete one
|
// Build the abstract node and the concrete one
|
||||||
abstract := &NodeAbstractResource{Addr: addr}
|
abstract := &NodeAbstractResource{
|
||||||
|
Addr: addr,
|
||||||
|
}
|
||||||
var node dag.Vertex = abstract
|
var node dag.Vertex = abstract
|
||||||
if f := t.Concrete; f != nil {
|
if f := t.Concrete; f != nil {
|
||||||
node = f(abstract)
|
node = f(abstract)
|
||||||
|
|
Loading…
Reference in New Issue