]>
Commit | Line | Data |
---|---|---|
bae9f6d2 JC |
1 | package terraform |
2 | ||
3 | import ( | |
bae9f6d2 JC |
4 | "log" |
5 | ||
107c1cdb | 6 | "github.com/hashicorp/terraform/states" |
bae9f6d2 JC |
7 | ) |
8 | ||
9 | // StateTransformer is a GraphTransformer that adds the elements of | |
10 | // the state to the graph. | |
11 | // | |
12 | // This transform is used for example by the DestroyPlanGraphBuilder to ensure | |
13 | // that only resources that are in the state are represented in the graph. | |
14 | type StateTransformer struct { | |
107c1cdb ND |
15 | // ConcreteCurrent and ConcreteDeposed are used to specialize the abstract |
16 | // resource instance nodes that this transformer will create. | |
17 | // | |
18 | // If either of these is nil, the objects of that type will be skipped and | |
19 | // not added to the graph at all. It doesn't make sense to use this | |
20 | // transformer without setting at least one of these, since that would | |
21 | // skip everything and thus be a no-op. | |
22 | ConcreteCurrent ConcreteResourceInstanceNodeFunc | |
23 | ConcreteDeposed ConcreteResourceInstanceDeposedNodeFunc | |
bae9f6d2 | 24 | |
107c1cdb | 25 | State *states.State |
bae9f6d2 JC |
26 | } |
27 | ||
28 | func (t *StateTransformer) Transform(g *Graph) error { | |
107c1cdb ND |
29 | if !t.State.HasResources() { |
30 | log.Printf("[TRACE] StateTransformer: state is empty, so nothing to do") | |
bae9f6d2 JC |
31 | return nil |
32 | } | |
33 | ||
107c1cdb ND |
34 | switch { |
35 | case t.ConcreteCurrent != nil && t.ConcreteDeposed != nil: | |
36 | log.Printf("[TRACE] StateTransformer: creating nodes for both current and deposed instance objects") | |
37 | case t.ConcreteCurrent != nil: | |
38 | log.Printf("[TRACE] StateTransformer: creating nodes for current instance objects only") | |
39 | case t.ConcreteDeposed != nil: | |
40 | log.Printf("[TRACE] StateTransformer: creating nodes for deposed instance objects only") | |
41 | default: | |
42 | log.Printf("[TRACE] StateTransformer: pointless no-op call, creating no nodes at all") | |
43 | } | |
44 | ||
bae9f6d2 | 45 | for _, ms := range t.State.Modules { |
107c1cdb | 46 | moduleAddr := ms.Addr |
bae9f6d2 | 47 | |
107c1cdb ND |
48 | for _, rs := range ms.Resources { |
49 | resourceAddr := rs.Addr.Absolute(moduleAddr) | |
bae9f6d2 | 50 | |
107c1cdb ND |
51 | for key, is := range rs.Instances { |
52 | addr := resourceAddr.Instance(key) | |
bae9f6d2 | 53 | |
107c1cdb ND |
54 | if obj := is.Current; obj != nil && t.ConcreteCurrent != nil { |
55 | abstract := NewNodeAbstractResourceInstance(addr) | |
56 | node := t.ConcreteCurrent(abstract) | |
57 | g.Add(node) | |
58 | log.Printf("[TRACE] StateTransformer: added %T for %s current object", node, addr) | |
59 | } | |
bae9f6d2 | 60 | |
107c1cdb ND |
61 | if t.ConcreteDeposed != nil { |
62 | for dk := range is.Deposed { | |
63 | abstract := NewNodeAbstractResourceInstance(addr) | |
64 | node := t.ConcreteDeposed(abstract, dk) | |
65 | g.Add(node) | |
66 | log.Printf("[TRACE] StateTransformer: added %T for %s deposed object %s", node, addr, dk) | |
67 | } | |
68 | } | |
bae9f6d2 | 69 | } |
bae9f6d2 JC |
70 | } |
71 | } | |
72 | ||
bae9f6d2 JC |
73 | return nil |
74 | } |