5 // DeposedTransformer is a GraphTransformer that adds deposed resources
7 type DeposedTransformer struct {
8 // State is the global state. We'll automatically find the correct
9 // ModuleState based on the Graph.Path that is being transformed.
12 // View, if non-empty, is the ModuleState.View used around the state
13 // to find deposed resources.
16 // The provider used by the resourced which were deposed
17 ResolvedProvider string
20 func (t *DeposedTransformer) Transform(g *Graph) error {
21 state := t.State.ModuleByPath(g.Path)
23 // If there is no state for our module there can't be any deposed
24 // resources, since they live in the state.
28 // If we have a view, apply it now
30 state = state.View(t.View)
33 // Go through all the resources in our state to look for deposed resources
34 for k, rs := range state.Resources {
35 // If we have no deposed resources, then move on
36 if len(rs.Deposed) == 0 {
42 for i, _ := range deposed {
43 g.Add(&graphNodeDeposedResource{
46 ResourceType: rs.Type,
47 ProviderName: rs.Provider,
48 ResolvedProvider: t.ResolvedProvider,
56 // graphNodeDeposedResource is the graph vertex representing a deposed resource.
57 type graphNodeDeposedResource struct {
62 ResolvedProvider string
65 func (n *graphNodeDeposedResource) Name() string {
66 return fmt.Sprintf("%s (deposed #%d)", n.ResourceName, n.Index)
69 func (n *graphNodeDeposedResource) ProvidedBy() string {
70 return resourceProvider(n.ResourceName, n.ProviderName)
73 func (n *graphNodeDeposedResource) SetProvider(p string) {
74 n.ResolvedProvider = p
77 // GraphNodeEvalable impl.
78 func (n *graphNodeDeposedResource) EvalTree() EvalNode {
79 var provider ResourceProvider
80 var state *InstanceState
82 seq := &EvalSequence{Nodes: make([]EvalNode, 0, 5)}
84 // Build instance info
85 info := &InstanceInfo{Id: n.Name(), Type: n.ResourceType}
86 seq.Nodes = append(seq.Nodes, &EvalInstanceInfo{Info: info})
88 // Refresh the resource
89 seq.Nodes = append(seq.Nodes, &EvalOpFilter{
90 Ops: []walkOperation{walkRefresh},
94 Name: n.ResolvedProvider,
97 &EvalReadStateDeposed{
108 &EvalWriteStateDeposed{
109 Name: n.ResourceName,
110 ResourceType: n.ResourceType,
111 Provider: n.ResolvedProvider,
120 var diff *InstanceDiff
122 seq.Nodes = append(seq.Nodes, &EvalOpFilter{
123 Ops: []walkOperation{walkApply, walkDestroy},
127 Name: n.ResolvedProvider,
130 &EvalReadStateDeposed{
131 Name: n.ResourceName,
140 // Call pre-apply hook
154 // Always write the resource back to the state deposed... if it
155 // was successfully destroyed it will be pruned. If it was not, it will
156 // be caught on the next run.
157 &EvalWriteStateDeposed{
158 Name: n.ResourceName,
159 ResourceType: n.ResourceType,
160 Provider: n.ResolvedProvider,
172 &EvalUpdateStateHook{},