github.com/opentofu/opentofu@v1.7.1/internal/tofu/transform_orphan_count.go (about) 1 // Copyright (c) The OpenTofu Authors 2 // SPDX-License-Identifier: MPL-2.0 3 // Copyright (c) 2023 HashiCorp, Inc. 4 // SPDX-License-Identifier: MPL-2.0 5 6 package tofu 7 8 import ( 9 "log" 10 11 "github.com/opentofu/opentofu/internal/addrs" 12 "github.com/opentofu/opentofu/internal/dag" 13 "github.com/opentofu/opentofu/internal/states" 14 ) 15 16 // OrphanResourceInstanceCountTransformer is a GraphTransformer that adds orphans 17 // for an expanded count to the graph. The determination of this depends 18 // on the count argument given. 19 // 20 // Orphans are found by comparing the count to what is found in the state. 21 // This transform assumes that if an element in the state is within the count 22 // bounds given, that it is not an orphan. 23 type OrphanResourceInstanceCountTransformer struct { 24 Concrete ConcreteResourceInstanceNodeFunc 25 26 Addr addrs.AbsResource // Addr of the resource to look for orphans 27 InstanceAddrs []addrs.AbsResourceInstance // Addresses that currently exist in config 28 State *states.State // Full global state 29 } 30 31 func (t *OrphanResourceInstanceCountTransformer) Transform(g *Graph) error { 32 rs := t.State.Resource(t.Addr) 33 if rs == nil { 34 return nil // Resource doesn't exist in state, so nothing to do! 35 } 36 37 // This is an O(n*m) analysis, which we accept for now because the 38 // number of instances of a single resource ought to always be small in any 39 // reasonable OpenTofu configuration. 40 Have: 41 for key, inst := range rs.Instances { 42 // Instances which have no current objects (only one or more 43 // deposed objects) will be taken care of separately 44 if inst.Current == nil { 45 continue 46 } 47 48 thisAddr := rs.Addr.Instance(key) 49 for _, wantAddr := range t.InstanceAddrs { 50 if wantAddr.Equal(thisAddr) { 51 continue Have 52 } 53 } 54 // If thisAddr is not in t.InstanceAddrs then we've found an "orphan" 55 56 abstract := NewNodeAbstractResourceInstance(thisAddr) 57 var node dag.Vertex = abstract 58 if f := t.Concrete; f != nil { 59 node = f(abstract) 60 } 61 log.Printf("[TRACE] OrphanResourceInstanceCountTransformer: adding %s as %T", thisAddr, node) 62 g.Add(node) 63 } 64 65 return nil 66 }