opentofu/internal/tofu/transform_orphan_count.go
namgyalangmo cb2e9119aa
Update copyright notice (#1232)
Signed-off-by: namgyalangmo <75657887+namgyalangmo@users.noreply.github.com>
2024-02-08 09:48:59 +00:00

67 lines
2.1 KiB
Go

// Copyright (c) The OpenTofu Authors
// SPDX-License-Identifier: MPL-2.0
// Copyright (c) 2023 HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package tofu
import (
"log"
"github.com/opentofu/opentofu/internal/addrs"
"github.com/opentofu/opentofu/internal/dag"
"github.com/opentofu/opentofu/internal/states"
)
// OrphanResourceInstanceCountTransformer is a GraphTransformer that adds orphans
// for an expanded count to the graph. The determination of this depends
// on the count argument given.
//
// Orphans are found by comparing the count to what is found in the state.
// This transform assumes that if an element in the state is within the count
// bounds given, that it is not an orphan.
type OrphanResourceInstanceCountTransformer struct {
Concrete ConcreteResourceInstanceNodeFunc
Addr addrs.AbsResource // Addr of the resource to look for orphans
InstanceAddrs []addrs.AbsResourceInstance // Addresses that currently exist in config
State *states.State // Full global state
}
func (t *OrphanResourceInstanceCountTransformer) Transform(g *Graph) error {
rs := t.State.Resource(t.Addr)
if rs == nil {
return nil // Resource doesn't exist in state, so nothing to do!
}
// This is an O(n*m) analysis, which we accept for now because the
// number of instances of a single resource ought to always be small in any
// reasonable OpenTofu configuration.
Have:
for key, inst := range rs.Instances {
// Instances which have no current objects (only one or more
// deposed objects) will be taken care of separately
if inst.Current == nil {
continue
}
thisAddr := rs.Addr.Instance(key)
for _, wantAddr := range t.InstanceAddrs {
if wantAddr.Equal(thisAddr) {
continue Have
}
}
// If thisAddr is not in t.InstanceAddrs then we've found an "orphan"
abstract := NewNodeAbstractResourceInstance(thisAddr)
var node dag.Vertex = abstract
if f := t.Concrete; f != nil {
node = f(abstract)
}
log.Printf("[TRACE] OrphanResourceInstanceCountTransformer: adding %s as %T", thisAddr, node)
g.Add(node)
}
return nil
}