6 "github.com/hashicorp/terraform/dag"
9 // OrphanResourceCountTransformer is a GraphTransformer that adds orphans
10 // for an expanded count to the graph. The determination of this depends
11 // on the count argument given.
13 // Orphans are found by comparing the count to what is found in the state.
14 // This transform assumes that if an element in the state is within the count
15 // bounds given, that it is not an orphan.
16 type OrphanResourceCountTransformer struct {
17 Concrete ConcreteResourceNodeFunc
19 Count int // Actual count of the resource
20 Addr *ResourceAddress // Addr of the resource to look for orphans
21 State *State // Full global state
24 func (t *OrphanResourceCountTransformer) Transform(g *Graph) error {
25 log.Printf("[TRACE] OrphanResourceCount: Starting...")
27 // Grab the module in the state just for this resource address
28 ms := t.State.ModuleByPath(normalizeModulePath(t.Addr.Path))
30 // If no state, there can't be orphans
39 // Go through the orphans and add them all to the state
40 for key, _ := range ms.Resources {
42 addr, err := parseResourceAddressInternal(key)
46 addr.Path = ms.Path[1:]
48 // Copy the address for comparison. If we aren't looking at
49 // the same resource, then just ignore it.
50 addrCopy := addr.Copy()
52 if !addrCopy.Equals(t.Addr) {
56 log.Printf("[TRACE] OrphanResourceCount: Checking: %s", addr)
60 // If we have zero and the index here is 0 or 1, then we
61 // change the index to a high number so that we treat it as
63 if t.Count <= 0 && idx <= 0 {
67 // If we have a count greater than 0 and we're at the zero index,
68 // we do a special case check to see if our state also has a
69 // -1 index value. If so, this is an orphan because our rules are
70 // that if both a -1 and 0 are in the state, the 0 is destroyed.
71 if t.Count > 0 && idx == orphanIndex {
72 // This is a piece of cleverness (beware), but its simple:
73 // if orphanIndex is 0, then check -1, else check 0.
74 checkIndex := (orphanIndex + 1) * -1
76 key := &ResourceStateKey{
83 if _, ok := ms.Resources[key.String()]; ok {
84 // We have a -1 index, too. Make an arbitrarily high
85 // index so that we always mark this as an orphan.
87 "[WARN] OrphanResourceCount: %q both -1 and 0 index found, orphaning %d",
93 // If the index is within the count bounds, it is not an orphan
98 // Build the abstract node and the concrete one
99 abstract := &NodeAbstractResource{Addr: addr}
100 var node dag.Vertex = abstract
101 if f := t.Concrete; f != nil {
105 // Add it to the graph