save resolved providers for resources to state
Use the ResourceState.Provider field to store the full name of the provider used during apply. This field is only used when a resource is removed from the config, and will allow that resource to be removed by the exact same provider with which it was created. Modify the locations which might accept the alue of the ResourceState.Provider field to detect that the name is resolved.
This commit is contained in:
parent
990acca758
commit
b79adeae02
|
@ -261,7 +261,9 @@ func (r *Resource) ProviderFullName() string {
|
|||
// the provider name is inferred from the resource type name.
|
||||
func ResourceProviderFullName(resourceType, explicitProvider string) string {
|
||||
if explicitProvider != "" {
|
||||
return explicitProvider
|
||||
// check for an explicit provider name, or return the original
|
||||
parts := strings.SplitAfter(explicitProvider, "provider.")
|
||||
return parts[len(parts)-1]
|
||||
}
|
||||
|
||||
idx := strings.IndexRune(resourceType, '_')
|
||||
|
|
|
@ -147,6 +147,7 @@ func TestNewContextState(t *testing.T) {
|
|||
}
|
||||
|
||||
func testContext2(t *testing.T, opts *ContextOpts) *Context {
|
||||
t.Helper()
|
||||
// Enable the shadow graph
|
||||
opts.Shadow = true
|
||||
|
||||
|
|
|
@ -108,7 +108,9 @@ func (n *NodeRefreshableDataResourceInstance) EvalTree() EvalNode {
|
|||
// Get the state if we have it, if not we build it
|
||||
rs := n.ResourceState
|
||||
if rs == nil {
|
||||
rs = &ResourceState{}
|
||||
rs = &ResourceState{
|
||||
Provider: n.ResolvedProvider,
|
||||
}
|
||||
}
|
||||
|
||||
// If the config isn't empty we update the state
|
||||
|
|
|
@ -2,6 +2,7 @@ package terraform
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/terraform/config"
|
||||
"github.com/hashicorp/terraform/dag"
|
||||
|
@ -25,6 +26,11 @@ type NodeAbstractProvider struct {
|
|||
}
|
||||
|
||||
func ResolveProviderName(name string, path []string) string {
|
||||
if strings.Contains(name, "provider.") {
|
||||
// already resolved
|
||||
return name
|
||||
}
|
||||
|
||||
name = fmt.Sprintf("provider.%s", name)
|
||||
if len(path) >= 1 {
|
||||
name = fmt.Sprintf("%s.%s", modulePrefixStr(path), name)
|
||||
|
|
|
@ -158,7 +158,7 @@ func (n *NodeApplyableResource) evalTreeDataResource(
|
|||
&EvalWriteState{
|
||||
Name: stateId,
|
||||
ResourceType: n.Config.Type,
|
||||
Provider: n.Config.Provider,
|
||||
Provider: n.ResolvedProvider,
|
||||
Dependencies: stateDeps,
|
||||
State: &state,
|
||||
},
|
||||
|
@ -308,7 +308,7 @@ func (n *NodeApplyableResource) evalTreeManagedResource(
|
|||
&EvalWriteState{
|
||||
Name: stateId,
|
||||
ResourceType: n.Config.Type,
|
||||
Provider: n.Config.Provider,
|
||||
Provider: n.ResolvedProvider,
|
||||
Dependencies: stateDeps,
|
||||
State: &state,
|
||||
},
|
||||
|
@ -332,7 +332,7 @@ func (n *NodeApplyableResource) evalTreeManagedResource(
|
|||
Else: &EvalWriteState{
|
||||
Name: stateId,
|
||||
ResourceType: n.Config.Type,
|
||||
Provider: n.Config.Provider,
|
||||
Provider: n.ResolvedProvider,
|
||||
Dependencies: stateDeps,
|
||||
State: &state,
|
||||
},
|
||||
|
|
|
@ -149,7 +149,9 @@ func (n *NodeDestroyResource) EvalTree() EvalNode {
|
|||
// Get our state
|
||||
rs := n.ResourceState
|
||||
if rs == nil {
|
||||
rs = &ResourceState{}
|
||||
rs = &ResourceState{
|
||||
Provider: n.ResolvedProvider,
|
||||
}
|
||||
}
|
||||
|
||||
var diffApply *InstanceDiff
|
||||
|
|
|
@ -112,7 +112,7 @@ func (n *NodePlannableResourceInstance) evalTreeDataResource(
|
|||
&EvalWriteState{
|
||||
Name: stateId,
|
||||
ResourceType: n.Config.Type,
|
||||
Provider: n.Config.Provider,
|
||||
Provider: n.ResolvedProvider,
|
||||
Dependencies: stateDeps,
|
||||
State: &state,
|
||||
},
|
||||
|
@ -177,7 +177,7 @@ func (n *NodePlannableResourceInstance) evalTreeManagedResource(
|
|||
&EvalWriteState{
|
||||
Name: stateId,
|
||||
ResourceType: n.Config.Type,
|
||||
Provider: n.Config.Provider,
|
||||
Provider: n.ResolvedProvider,
|
||||
Dependencies: stateDeps,
|
||||
State: &state,
|
||||
},
|
||||
|
|
|
@ -251,7 +251,7 @@ func (n *NodeRefreshableManagedResourceInstance) evalTreeManagedResourceNoState(
|
|||
&EvalWriteState{
|
||||
Name: stateID,
|
||||
ResourceType: n.Config.Type,
|
||||
Provider: n.Config.Provider,
|
||||
Provider: n.ResolvedProvider,
|
||||
Dependencies: stateDeps,
|
||||
State: &state,
|
||||
},
|
||||
|
|
|
@ -108,7 +108,7 @@ func (n *graphNodeDeposedResource) EvalTree() EvalNode {
|
|||
&EvalWriteStateDeposed{
|
||||
Name: n.ResourceName,
|
||||
ResourceType: n.ResourceType,
|
||||
Provider: n.ProviderName,
|
||||
Provider: n.ResolvedProvider,
|
||||
State: &state,
|
||||
Index: n.Index,
|
||||
},
|
||||
|
@ -157,7 +157,7 @@ func (n *graphNodeDeposedResource) EvalTree() EvalNode {
|
|||
&EvalWriteStateDeposed{
|
||||
Name: n.ResourceName,
|
||||
ResourceType: n.ResourceType,
|
||||
Provider: n.ProviderName,
|
||||
Provider: n.ResolvedProvider,
|
||||
State: &state,
|
||||
Index: n.Index,
|
||||
},
|
||||
|
|
|
@ -52,7 +52,8 @@ type GraphNodeCloseProvider interface {
|
|||
|
||||
// GraphNodeProviderConsumer is an interface that nodes that require
|
||||
// a provider must implement. ProvidedBy must return the name of the provider
|
||||
// to use.
|
||||
// to use. This may be a provider by type, type.alias or a fully resolved
|
||||
// provider name
|
||||
type GraphNodeProviderConsumer interface {
|
||||
ProvidedBy() string
|
||||
// Set the resolved provider address for this resource.
|
||||
|
@ -127,7 +128,6 @@ func (t *ProviderTransformer) Transform(g *Graph) error {
|
|||
// in the graph are evaluated.
|
||||
type CloseProviderTransformer struct{}
|
||||
|
||||
// FIXME: this doesn't close providers if the root provider is disabled
|
||||
func (t *CloseProviderTransformer) Transform(g *Graph) error {
|
||||
pm := providerVertexMap(g)
|
||||
cpm := make(map[string]*graphNodeCloseProvider)
|
||||
|
@ -286,6 +286,11 @@ func (t *PruneProviderTransformer) Transform(g *Graph) error {
|
|||
// providerMapKey is a helper that gives us the key to use for the
|
||||
// maps returned by things such as providerVertexMap.
|
||||
func providerMapKey(k string, v dag.Vertex) string {
|
||||
if strings.Contains(k, "provider.") {
|
||||
// this is already resolved
|
||||
return k
|
||||
}
|
||||
|
||||
// we create a dummy provider to
|
||||
var path []string
|
||||
if sp, ok := v.(GraphNodeSubPath); ok {
|
||||
|
|
Loading…
Reference in New Issue