mirror of
https://github.com/opentofu/opentofu.git
synced 2024-12-26 17:01:04 -06:00
21b0a03d70
Adds an "alias" field to the provider which allows creating multiple instances of a provider under different names. This provides support for configurations such as multiple AWS providers for different regions. In each resource, the provider can be set with the "provider" field. (thanks to Cisco Cloud for their support)
158 lines
3.7 KiB
Go
158 lines
3.7 KiB
Go
package terraform
|
|
|
|
import "fmt"
|
|
|
|
// DeposedTransformer is a GraphTransformer that adds deposed resources
|
|
// to the graph.
|
|
type DeposedTransformer struct {
|
|
// State is the global state. We'll automatically find the correct
|
|
// ModuleState based on the Graph.Path that is being transformed.
|
|
State *State
|
|
|
|
// View, if non-empty, is the ModuleState.View used around the state
|
|
// to find deposed resources.
|
|
View string
|
|
}
|
|
|
|
func (t *DeposedTransformer) Transform(g *Graph) error {
|
|
state := t.State.ModuleByPath(g.Path)
|
|
if state == nil {
|
|
// If there is no state for our module there can't be any deposed
|
|
// resources, since they live in the state.
|
|
return nil
|
|
}
|
|
|
|
// If we have a view, apply it now
|
|
if t.View != "" {
|
|
state = state.View(t.View)
|
|
}
|
|
|
|
// Go through all the resources in our state to look for deposed resources
|
|
for k, rs := range state.Resources {
|
|
// If we have no deposed resources, then move on
|
|
if len(rs.Deposed) == 0 {
|
|
continue
|
|
}
|
|
deposed := rs.Deposed
|
|
|
|
for i, _ := range deposed {
|
|
g.Add(&graphNodeDeposedResource{
|
|
Index: i,
|
|
ResourceName: k,
|
|
ResourceType: rs.Type,
|
|
Provider: rs.Provider,
|
|
})
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// graphNodeDeposedResource is the graph vertex representing a deposed resource.
|
|
type graphNodeDeposedResource struct {
|
|
Index int
|
|
ResourceName string
|
|
ResourceType string
|
|
Provider string
|
|
}
|
|
|
|
func (n *graphNodeDeposedResource) Name() string {
|
|
return fmt.Sprintf("%s (deposed #%d)", n.ResourceName, n.Index)
|
|
}
|
|
|
|
func (n *graphNodeDeposedResource) ProvidedBy() []string {
|
|
return []string{resourceProvider(n.ResourceName, n.Provider)}
|
|
}
|
|
|
|
// GraphNodeEvalable impl.
|
|
func (n *graphNodeDeposedResource) EvalTree() EvalNode {
|
|
var provider ResourceProvider
|
|
var state *InstanceState
|
|
|
|
seq := &EvalSequence{Nodes: make([]EvalNode, 0, 5)}
|
|
|
|
// Build instance info
|
|
info := &InstanceInfo{Id: n.ResourceName, Type: n.ResourceType}
|
|
seq.Nodes = append(seq.Nodes, &EvalInstanceInfo{Info: info})
|
|
|
|
// Refresh the resource
|
|
seq.Nodes = append(seq.Nodes, &EvalOpFilter{
|
|
Ops: []walkOperation{walkRefresh},
|
|
Node: &EvalSequence{
|
|
Nodes: []EvalNode{
|
|
&EvalGetProvider{
|
|
Name: n.ProvidedBy()[0],
|
|
Output: &provider,
|
|
},
|
|
&EvalReadStateDeposed{
|
|
Name: n.ResourceName,
|
|
Output: &state,
|
|
Index: n.Index,
|
|
},
|
|
&EvalRefresh{
|
|
Info: info,
|
|
Provider: &provider,
|
|
State: &state,
|
|
Output: &state,
|
|
},
|
|
&EvalWriteStateDeposed{
|
|
Name: n.ResourceName,
|
|
ResourceType: n.ResourceType,
|
|
Provider: n.Provider,
|
|
State: &state,
|
|
Index: n.Index,
|
|
},
|
|
},
|
|
},
|
|
})
|
|
|
|
// Apply
|
|
var diff *InstanceDiff
|
|
var err error
|
|
seq.Nodes = append(seq.Nodes, &EvalOpFilter{
|
|
Ops: []walkOperation{walkApply},
|
|
Node: &EvalSequence{
|
|
Nodes: []EvalNode{
|
|
&EvalGetProvider{
|
|
Name: n.ProvidedBy()[0],
|
|
Output: &provider,
|
|
},
|
|
&EvalReadStateDeposed{
|
|
Name: n.ResourceName,
|
|
Output: &state,
|
|
Index: n.Index,
|
|
},
|
|
&EvalDiffDestroy{
|
|
Info: info,
|
|
State: &state,
|
|
Output: &diff,
|
|
},
|
|
&EvalApply{
|
|
Info: info,
|
|
State: &state,
|
|
Diff: &diff,
|
|
Provider: &provider,
|
|
Output: &state,
|
|
Error: &err,
|
|
},
|
|
// Always write the resource back to the state deposed... if it
|
|
// was successfully destroyed it will be pruned. If it was not, it will
|
|
// be caught on the next run.
|
|
&EvalWriteStateDeposed{
|
|
Name: n.ResourceName,
|
|
ResourceType: n.ResourceType,
|
|
Provider: n.Provider,
|
|
State: &state,
|
|
Index: n.Index,
|
|
},
|
|
&EvalReturnError{
|
|
Error: &err,
|
|
},
|
|
&EvalUpdateStateHook{},
|
|
},
|
|
},
|
|
})
|
|
|
|
return seq
|
|
}
|