]>
Commit | Line | Data |
---|---|---|
bae9f6d2 JC |
1 | package terraform |
2 | ||
3 | import ( | |
4 | "log" | |
5 | ||
6 | "github.com/hashicorp/terraform/dag" | |
107c1cdb | 7 | "github.com/hashicorp/terraform/states" |
bae9f6d2 JC |
8 | ) |
9 | ||
10 | // GraphNodeAttachResourceState is an interface that can be implemented | |
11 | // to request that a ResourceState is attached to the node. | |
107c1cdb ND |
12 | // |
13 | // Due to a historical naming inconsistency, the type ResourceState actually | |
14 | // represents the state for a particular _instance_, while InstanceState | |
15 | // represents the values for that instance during a particular phase | |
16 | // (e.g. primary vs. deposed). Consequently, GraphNodeAttachResourceState | |
17 | // is supported only for nodes that represent resource instances, even though | |
18 | // the name might suggest it is for containing resources. | |
bae9f6d2 | 19 | type GraphNodeAttachResourceState interface { |
107c1cdb | 20 | GraphNodeResourceInstance |
bae9f6d2 JC |
21 | |
22 | // Sets the state | |
107c1cdb | 23 | AttachResourceState(*states.Resource) |
bae9f6d2 JC |
24 | } |
25 | ||
26 | // AttachStateTransformer goes through the graph and attaches | |
27 | // state to nodes that implement the interfaces above. | |
28 | type AttachStateTransformer struct { | |
107c1cdb | 29 | State *states.State // State is the root state |
bae9f6d2 JC |
30 | } |
31 | ||
32 | func (t *AttachStateTransformer) Transform(g *Graph) error { | |
33 | // If no state, then nothing to do | |
34 | if t.State == nil { | |
107c1cdb | 35 | log.Printf("[DEBUG] Not attaching any node states: overall state is nil") |
bae9f6d2 JC |
36 | return nil |
37 | } | |
38 | ||
bae9f6d2 | 39 | for _, v := range g.Vertices() { |
107c1cdb | 40 | // Nodes implement this interface to request state attachment. |
bae9f6d2 JC |
41 | an, ok := v.(GraphNodeAttachResourceState) |
42 | if !ok { | |
43 | continue | |
44 | } | |
107c1cdb | 45 | addr := an.ResourceInstanceAddr() |
bae9f6d2 | 46 | |
107c1cdb ND |
47 | rs := t.State.Resource(addr.ContainingResource()) |
48 | if rs == nil { | |
49 | log.Printf("[DEBUG] Resource state not found for node %q, instance %s", dag.VertexName(v), addr) | |
50 | continue | |
bae9f6d2 JC |
51 | } |
52 | ||
107c1cdb ND |
53 | is := rs.Instance(addr.Resource.Key) |
54 | if is == nil { | |
55 | // We don't actually need this here, since we'll attach the whole | |
56 | // resource state, but we still check because it'd be weird | |
57 | // for the specific instance we're attaching to not to exist. | |
58 | log.Printf("[DEBUG] Resource instance state not found for node %q, instance %s", dag.VertexName(v), addr) | |
59 | continue | |
bae9f6d2 JC |
60 | } |
61 | ||
107c1cdb ND |
62 | // make sure to attach a copy of the state, so instances can modify the |
63 | // same ResourceState. | |
64 | an.AttachResourceState(rs.DeepCopy()) | |
bae9f6d2 JC |
65 | } |
66 | ||
67 | return nil | |
68 | } |