terraform: remove old orphan transform
This commit is contained in:
parent
9426b71a5f
commit
4e4d51e6ba
|
@ -165,15 +165,6 @@ func (n *GraphNodeConfigResource) DynamicExpand(ctx EvalContext) (*Graph, error)
|
||||||
|
|
||||||
// Additional destroy modifications.
|
// Additional destroy modifications.
|
||||||
if n.Destroy {
|
if n.Destroy {
|
||||||
// If we're destroying a primary or tainted resource, we want to
|
|
||||||
// expand orphans, which have all the same semantics in a destroy
|
|
||||||
// as a primary or tainted resource.
|
|
||||||
steps = append(steps, &OrphanTransformer{
|
|
||||||
Resource: n.Resource,
|
|
||||||
State: state,
|
|
||||||
View: n.Resource.Id(),
|
|
||||||
})
|
|
||||||
|
|
||||||
steps = append(steps, &DeposedTransformer{
|
steps = append(steps, &DeposedTransformer{
|
||||||
State: state,
|
State: state,
|
||||||
View: n.Resource.Id(),
|
View: n.Resource.Id(),
|
||||||
|
|
|
@ -1,437 +0,0 @@
|
||||||
package terraform
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/config"
|
|
||||||
"github.com/hashicorp/terraform/config/module"
|
|
||||||
"github.com/hashicorp/terraform/dag"
|
|
||||||
)
|
|
||||||
|
|
||||||
// GraphNodeStateRepresentative is an interface that can be implemented by
|
|
||||||
// a node to say that it is representing a resource in the state.
|
|
||||||
type GraphNodeStateRepresentative interface {
|
|
||||||
StateId() []string
|
|
||||||
}
|
|
||||||
|
|
||||||
// OrphanTransformer is a GraphTransformer that adds orphans to the
|
|
||||||
// graph. This transformer adds both resource and module orphans.
|
|
||||||
type OrphanTransformer struct {
|
|
||||||
// Resource is resource configuration. This is only non-nil when
|
|
||||||
// expanding a resource that is in the configuration. It can't be
|
|
||||||
// dependend on.
|
|
||||||
Resource *config.Resource
|
|
||||||
|
|
||||||
// State is the global state. We require the global state to
|
|
||||||
// properly find module orphans at our path.
|
|
||||||
State *State
|
|
||||||
|
|
||||||
// Module is the root module. We'll look up the proper configuration
|
|
||||||
// using the graph path.
|
|
||||||
Module *module.Tree
|
|
||||||
|
|
||||||
// View, if non-nil will set a view on the module state.
|
|
||||||
View string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *OrphanTransformer) Transform(g *Graph) error {
|
|
||||||
if t.State == nil {
|
|
||||||
// If the entire state is nil, there can't be any orphans
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build up all our state representatives
|
|
||||||
resourceRep := make(map[string]struct{})
|
|
||||||
for _, v := range g.Vertices() {
|
|
||||||
if sr, ok := v.(GraphNodeStateRepresentative); ok {
|
|
||||||
for _, k := range sr.StateId() {
|
|
||||||
resourceRep[k] = struct{}{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var config *config.Config
|
|
||||||
if t.Module != nil {
|
|
||||||
if module := t.Module.Child(g.Path[1:]); module != nil {
|
|
||||||
config = module.Config()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var resourceVertexes []dag.Vertex
|
|
||||||
if state := t.State.ModuleByPath(g.Path); state != nil {
|
|
||||||
// If we have state, then we can have orphan resources
|
|
||||||
|
|
||||||
// If we have a view, get the view
|
|
||||||
if t.View != "" {
|
|
||||||
state = state.View(t.View)
|
|
||||||
}
|
|
||||||
|
|
||||||
resourceOrphans := state.Orphans(config)
|
|
||||||
|
|
||||||
resourceVertexes = make([]dag.Vertex, len(resourceOrphans))
|
|
||||||
for i, k := range resourceOrphans {
|
|
||||||
// If this orphan is represented by some other node somehow,
|
|
||||||
// then ignore it.
|
|
||||||
if _, ok := resourceRep[k]; ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
rs := state.Resources[k]
|
|
||||||
|
|
||||||
rsk, err := ParseResourceStateKey(k)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
resourceVertexes[i] = g.Add(&graphNodeOrphanResource{
|
|
||||||
Path: g.Path,
|
|
||||||
ResourceKey: rsk,
|
|
||||||
Resource: t.Resource,
|
|
||||||
Provider: rs.Provider,
|
|
||||||
dependentOn: rs.Dependencies,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Go over each module orphan and add it to the graph. We store the
|
|
||||||
// vertexes and states outside so that we can connect dependencies later.
|
|
||||||
moduleOrphans := t.State.ModuleOrphans(g.Path, config)
|
|
||||||
moduleVertexes := make([]dag.Vertex, len(moduleOrphans))
|
|
||||||
for i, path := range moduleOrphans {
|
|
||||||
var deps []string
|
|
||||||
if s := t.State.ModuleByPath(path); s != nil {
|
|
||||||
deps = s.Dependencies
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleVertexes[i] = g.Add(&graphNodeOrphanModule{
|
|
||||||
Path: path,
|
|
||||||
dependentOn: deps,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now do the dependencies. We do this _after_ adding all the orphan
|
|
||||||
// nodes above because there are cases in which the orphans themselves
|
|
||||||
// depend on other orphans.
|
|
||||||
|
|
||||||
// Resource dependencies
|
|
||||||
for _, v := range resourceVertexes {
|
|
||||||
g.ConnectDependent(v)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Module dependencies
|
|
||||||
for _, v := range moduleVertexes {
|
|
||||||
g.ConnectDependent(v)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// graphNodeOrphanModule is the graph vertex representing an orphan resource..
|
|
||||||
type graphNodeOrphanModule struct {
|
|
||||||
Path []string
|
|
||||||
|
|
||||||
dependentOn []string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *graphNodeOrphanModule) DependableName() []string {
|
|
||||||
return []string{n.dependableName()}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *graphNodeOrphanModule) DependentOn() []string {
|
|
||||||
return n.dependentOn
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *graphNodeOrphanModule) Name() string {
|
|
||||||
return fmt.Sprintf("%s (orphan)", n.dependableName())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *graphNodeOrphanModule) dependableName() string {
|
|
||||||
return fmt.Sprintf("module.%s", n.Path[len(n.Path)-1])
|
|
||||||
}
|
|
||||||
|
|
||||||
// GraphNodeExpandable
|
|
||||||
func (n *graphNodeOrphanModule) Expand(b GraphBuilder) (GraphNodeSubgraph, error) {
|
|
||||||
g, err := b.Build(n.Path)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &GraphNodeBasicSubgraph{
|
|
||||||
NameValue: n.Name(),
|
|
||||||
Graph: g,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// graphNodeOrphanResource is the graph vertex representing an orphan resource..
|
|
||||||
type graphNodeOrphanResource struct {
|
|
||||||
Path []string
|
|
||||||
ResourceKey *ResourceStateKey
|
|
||||||
Resource *config.Resource
|
|
||||||
Provider string
|
|
||||||
|
|
||||||
dependentOn []string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *graphNodeOrphanResource) ConfigType() GraphNodeConfigType {
|
|
||||||
return GraphNodeConfigTypeResource
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *graphNodeOrphanResource) ResourceAddress() *ResourceAddress {
|
|
||||||
return &ResourceAddress{
|
|
||||||
Index: n.ResourceKey.Index,
|
|
||||||
InstanceType: TypePrimary,
|
|
||||||
Name: n.ResourceKey.Name,
|
|
||||||
Path: n.Path[1:],
|
|
||||||
Type: n.ResourceKey.Type,
|
|
||||||
Mode: n.ResourceKey.Mode,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *graphNodeOrphanResource) DependableName() []string {
|
|
||||||
return []string{n.dependableName()}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *graphNodeOrphanResource) DependentOn() []string {
|
|
||||||
return n.dependentOn
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *graphNodeOrphanResource) Flatten(p []string) (dag.Vertex, error) {
|
|
||||||
return &graphNodeOrphanResourceFlat{
|
|
||||||
graphNodeOrphanResource: n,
|
|
||||||
PathValue: p,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *graphNodeOrphanResource) Name() string {
|
|
||||||
return fmt.Sprintf("%s (orphan)", n.ResourceKey)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *graphNodeOrphanResource) ProvidedBy() []string {
|
|
||||||
return []string{resourceProvider(n.ResourceKey.Type, n.Provider)}
|
|
||||||
}
|
|
||||||
|
|
||||||
// GraphNodeEvalable impl.
|
|
||||||
func (n *graphNodeOrphanResource) EvalTree() EvalNode {
|
|
||||||
|
|
||||||
seq := &EvalSequence{Nodes: make([]EvalNode, 0, 5)}
|
|
||||||
|
|
||||||
// Build instance info
|
|
||||||
info := &InstanceInfo{Id: n.ResourceKey.String(), Type: n.ResourceKey.Type}
|
|
||||||
info.uniqueExtra = "destroy"
|
|
||||||
|
|
||||||
seq.Nodes = append(seq.Nodes, &EvalInstanceInfo{Info: info})
|
|
||||||
|
|
||||||
// Each resource mode has its own lifecycle
|
|
||||||
switch n.ResourceKey.Mode {
|
|
||||||
case config.ManagedResourceMode:
|
|
||||||
seq.Nodes = append(
|
|
||||||
seq.Nodes,
|
|
||||||
n.managedResourceEvalNodes(info)...,
|
|
||||||
)
|
|
||||||
case config.DataResourceMode:
|
|
||||||
seq.Nodes = append(
|
|
||||||
seq.Nodes,
|
|
||||||
n.dataResourceEvalNodes(info)...,
|
|
||||||
)
|
|
||||||
default:
|
|
||||||
panic(fmt.Errorf("unsupported resource mode %s", n.ResourceKey.Mode))
|
|
||||||
}
|
|
||||||
|
|
||||||
return seq
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *graphNodeOrphanResource) managedResourceEvalNodes(info *InstanceInfo) []EvalNode {
|
|
||||||
var provider ResourceProvider
|
|
||||||
var state *InstanceState
|
|
||||||
|
|
||||||
nodes := make([]EvalNode, 0, 3)
|
|
||||||
|
|
||||||
// Refresh the resource
|
|
||||||
nodes = append(nodes, &EvalOpFilter{
|
|
||||||
Ops: []walkOperation{walkRefresh},
|
|
||||||
Node: &EvalSequence{
|
|
||||||
Nodes: []EvalNode{
|
|
||||||
&EvalGetProvider{
|
|
||||||
Name: n.ProvidedBy()[0],
|
|
||||||
Output: &provider,
|
|
||||||
},
|
|
||||||
&EvalReadState{
|
|
||||||
Name: n.ResourceKey.String(),
|
|
||||||
Output: &state,
|
|
||||||
},
|
|
||||||
&EvalRefresh{
|
|
||||||
Info: info,
|
|
||||||
Provider: &provider,
|
|
||||||
State: &state,
|
|
||||||
Output: &state,
|
|
||||||
},
|
|
||||||
&EvalWriteState{
|
|
||||||
Name: n.ResourceKey.String(),
|
|
||||||
ResourceType: n.ResourceKey.Type,
|
|
||||||
Provider: n.Provider,
|
|
||||||
Dependencies: n.DependentOn(),
|
|
||||||
State: &state,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
// Diff the resource
|
|
||||||
var diff *InstanceDiff
|
|
||||||
nodes = append(nodes, &EvalOpFilter{
|
|
||||||
Ops: []walkOperation{walkPlan, walkPlanDestroy},
|
|
||||||
Node: &EvalSequence{
|
|
||||||
Nodes: []EvalNode{
|
|
||||||
&EvalReadState{
|
|
||||||
Name: n.ResourceKey.String(),
|
|
||||||
Output: &state,
|
|
||||||
},
|
|
||||||
&EvalDiffDestroy{
|
|
||||||
Info: info,
|
|
||||||
State: &state,
|
|
||||||
Output: &diff,
|
|
||||||
},
|
|
||||||
&EvalCheckPreventDestroy{
|
|
||||||
Resource: n.Resource,
|
|
||||||
ResourceId: n.ResourceKey.String(),
|
|
||||||
Diff: &diff,
|
|
||||||
},
|
|
||||||
&EvalWriteDiff{
|
|
||||||
Name: n.ResourceKey.String(),
|
|
||||||
Diff: &diff,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
// Apply
|
|
||||||
var err error
|
|
||||||
nodes = append(nodes, &EvalOpFilter{
|
|
||||||
Ops: []walkOperation{walkApply, walkDestroy},
|
|
||||||
Node: &EvalSequence{
|
|
||||||
Nodes: []EvalNode{
|
|
||||||
&EvalReadDiff{
|
|
||||||
Name: n.ResourceKey.String(),
|
|
||||||
Diff: &diff,
|
|
||||||
},
|
|
||||||
&EvalGetProvider{
|
|
||||||
Name: n.ProvidedBy()[0],
|
|
||||||
Output: &provider,
|
|
||||||
},
|
|
||||||
&EvalReadState{
|
|
||||||
Name: n.ResourceKey.String(),
|
|
||||||
Output: &state,
|
|
||||||
},
|
|
||||||
&EvalApplyPre{
|
|
||||||
Info: info,
|
|
||||||
State: &state,
|
|
||||||
Diff: &diff,
|
|
||||||
},
|
|
||||||
&EvalApply{
|
|
||||||
Info: info,
|
|
||||||
State: &state,
|
|
||||||
Diff: &diff,
|
|
||||||
Provider: &provider,
|
|
||||||
Output: &state,
|
|
||||||
Error: &err,
|
|
||||||
},
|
|
||||||
&EvalWriteState{
|
|
||||||
Name: n.ResourceKey.String(),
|
|
||||||
ResourceType: n.ResourceKey.Type,
|
|
||||||
Provider: n.Provider,
|
|
||||||
Dependencies: n.DependentOn(),
|
|
||||||
State: &state,
|
|
||||||
},
|
|
||||||
&EvalApplyPost{
|
|
||||||
Info: info,
|
|
||||||
State: &state,
|
|
||||||
Error: &err,
|
|
||||||
},
|
|
||||||
&EvalUpdateStateHook{},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
return nodes
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *graphNodeOrphanResource) dataResourceEvalNodes(info *InstanceInfo) []EvalNode {
|
|
||||||
nodes := make([]EvalNode, 0, 3)
|
|
||||||
|
|
||||||
// This will remain nil, since we don't retain states for orphaned
|
|
||||||
// data resources.
|
|
||||||
var state *InstanceState
|
|
||||||
|
|
||||||
// On both refresh and apply we just drop our state altogether,
|
|
||||||
// since the config resource validation pass will have proven that the
|
|
||||||
// resources remaining in the configuration don't need it.
|
|
||||||
nodes = append(nodes, &EvalOpFilter{
|
|
||||||
Ops: []walkOperation{walkRefresh, walkApply},
|
|
||||||
Node: &EvalSequence{
|
|
||||||
Nodes: []EvalNode{
|
|
||||||
&EvalWriteState{
|
|
||||||
Name: n.ResourceKey.String(),
|
|
||||||
ResourceType: n.ResourceKey.Type,
|
|
||||||
Provider: n.Provider,
|
|
||||||
Dependencies: n.DependentOn(),
|
|
||||||
State: &state, // state is nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
return nodes
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *graphNodeOrphanResource) dependableName() string {
|
|
||||||
return n.ResourceKey.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
// GraphNodeDestroyable impl.
|
|
||||||
func (n *graphNodeOrphanResource) DestroyNode() GraphNodeDestroy {
|
|
||||||
return n
|
|
||||||
}
|
|
||||||
|
|
||||||
// GraphNodeDestroy impl.
|
|
||||||
func (n *graphNodeOrphanResource) CreateBeforeDestroy() bool {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *graphNodeOrphanResource) CreateNode() dag.Vertex {
|
|
||||||
return n
|
|
||||||
}
|
|
||||||
|
|
||||||
// Same as graphNodeOrphanResource, but for flattening
|
|
||||||
type graphNodeOrphanResourceFlat struct {
|
|
||||||
*graphNodeOrphanResource
|
|
||||||
|
|
||||||
PathValue []string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *graphNodeOrphanResourceFlat) Name() string {
|
|
||||||
return fmt.Sprintf(
|
|
||||||
"%s.%s", modulePrefixStr(n.PathValue), n.graphNodeOrphanResource.Name())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *graphNodeOrphanResourceFlat) Path() []string {
|
|
||||||
return n.PathValue
|
|
||||||
}
|
|
||||||
|
|
||||||
// GraphNodeDestroyable impl.
|
|
||||||
func (n *graphNodeOrphanResourceFlat) DestroyNode() GraphNodeDestroy {
|
|
||||||
return n
|
|
||||||
}
|
|
||||||
|
|
||||||
// GraphNodeDestroy impl.
|
|
||||||
func (n *graphNodeOrphanResourceFlat) CreateBeforeDestroy() bool {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *graphNodeOrphanResourceFlat) CreateNode() dag.Vertex {
|
|
||||||
return n
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *graphNodeOrphanResourceFlat) ProvidedBy() []string {
|
|
||||||
return modulePrefixList(
|
|
||||||
n.graphNodeOrphanResource.ProvidedBy(),
|
|
||||||
modulePrefixStr(n.PathValue))
|
|
||||||
}
|
|
|
@ -1,389 +0,0 @@
|
||||||
package terraform
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/dag"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestOrphanTransformer(t *testing.T) {
|
|
||||||
mod := testModule(t, "transform-orphan-basic")
|
|
||||||
state := &State{
|
|
||||||
Modules: []*ModuleState{
|
|
||||||
&ModuleState{
|
|
||||||
Path: RootModulePath,
|
|
||||||
Resources: map[string]*ResourceState{
|
|
||||||
"aws_instance.web": &ResourceState{
|
|
||||||
Type: "aws_instance",
|
|
||||||
Primary: &InstanceState{
|
|
||||||
ID: "foo",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
// The orphan
|
|
||||||
"aws_instance.db": &ResourceState{
|
|
||||||
Type: "aws_instance",
|
|
||||||
Primary: &InstanceState{
|
|
||||||
ID: "foo",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
g := Graph{Path: RootModulePath}
|
|
||||||
{
|
|
||||||
tf := &ConfigTransformerOld{Module: mod}
|
|
||||||
if err := tf.Transform(&g); err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
transform := &OrphanTransformer{State: state, Module: mod}
|
|
||||||
if err := transform.Transform(&g); err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
actual := strings.TrimSpace(g.String())
|
|
||||||
expected := strings.TrimSpace(testTransformOrphanBasicStr)
|
|
||||||
if actual != expected {
|
|
||||||
t.Fatalf("bad:\n\n%s", actual)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestOrphanTransformer_modules(t *testing.T) {
|
|
||||||
mod := testModule(t, "transform-orphan-modules")
|
|
||||||
state := &State{
|
|
||||||
Modules: []*ModuleState{
|
|
||||||
&ModuleState{
|
|
||||||
Path: RootModulePath,
|
|
||||||
Resources: map[string]*ResourceState{
|
|
||||||
"aws_instance.foo": &ResourceState{
|
|
||||||
Type: "aws_instance",
|
|
||||||
Primary: &InstanceState{
|
|
||||||
ID: "foo",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
// Orphan module
|
|
||||||
&ModuleState{
|
|
||||||
Path: []string{RootModuleName, "foo"},
|
|
||||||
Resources: map[string]*ResourceState{
|
|
||||||
"aws_instance.web": &ResourceState{
|
|
||||||
Type: "aws_instance",
|
|
||||||
Primary: &InstanceState{
|
|
||||||
ID: "foo",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
g := Graph{Path: RootModulePath}
|
|
||||||
{
|
|
||||||
tf := &ConfigTransformerOld{Module: mod}
|
|
||||||
if err := tf.Transform(&g); err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
transform := &OrphanTransformer{State: state, Module: mod}
|
|
||||||
if err := transform.Transform(&g); err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
actual := strings.TrimSpace(g.String())
|
|
||||||
expected := strings.TrimSpace(testTransformOrphanModulesStr)
|
|
||||||
if actual != expected {
|
|
||||||
t.Fatalf("bad:\n\n%s", actual)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestOrphanTransformer_modulesDeps(t *testing.T) {
|
|
||||||
mod := testModule(t, "transform-orphan-modules")
|
|
||||||
state := &State{
|
|
||||||
Modules: []*ModuleState{
|
|
||||||
&ModuleState{
|
|
||||||
Path: RootModulePath,
|
|
||||||
Resources: map[string]*ResourceState{
|
|
||||||
"aws_instance.foo": &ResourceState{
|
|
||||||
Type: "aws_instance",
|
|
||||||
Primary: &InstanceState{
|
|
||||||
ID: "foo",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
// Orphan module
|
|
||||||
&ModuleState{
|
|
||||||
Path: []string{RootModuleName, "foo"},
|
|
||||||
Resources: map[string]*ResourceState{
|
|
||||||
"aws_instance.web": &ResourceState{
|
|
||||||
Type: "aws_instance",
|
|
||||||
Primary: &InstanceState{
|
|
||||||
ID: "foo",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Dependencies: []string{
|
|
||||||
"aws_instance.foo",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
g := Graph{Path: RootModulePath}
|
|
||||||
{
|
|
||||||
tf := &ConfigTransformerOld{Module: mod}
|
|
||||||
if err := tf.Transform(&g); err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
transform := &OrphanTransformer{State: state, Module: mod}
|
|
||||||
if err := transform.Transform(&g); err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
actual := strings.TrimSpace(g.String())
|
|
||||||
expected := strings.TrimSpace(testTransformOrphanModulesDepsStr)
|
|
||||||
if actual != expected {
|
|
||||||
t.Fatalf("bad:\n\n%s", actual)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestOrphanTransformer_modulesDepsOrphan(t *testing.T) {
|
|
||||||
mod := testModule(t, "transform-orphan-modules")
|
|
||||||
state := &State{
|
|
||||||
Modules: []*ModuleState{
|
|
||||||
&ModuleState{
|
|
||||||
Path: RootModulePath,
|
|
||||||
Resources: map[string]*ResourceState{
|
|
||||||
"aws_instance.web": &ResourceState{
|
|
||||||
Type: "aws_instance",
|
|
||||||
Primary: &InstanceState{
|
|
||||||
ID: "foo",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
// Orphan module
|
|
||||||
&ModuleState{
|
|
||||||
Path: []string{RootModuleName, "foo"},
|
|
||||||
Resources: map[string]*ResourceState{
|
|
||||||
"aws_instance.web": &ResourceState{
|
|
||||||
Type: "aws_instance",
|
|
||||||
Primary: &InstanceState{
|
|
||||||
ID: "foo",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Dependencies: []string{
|
|
||||||
"aws_instance.web",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
g := Graph{Path: RootModulePath}
|
|
||||||
{
|
|
||||||
tf := &ConfigTransformerOld{Module: mod}
|
|
||||||
if err := tf.Transform(&g); err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
transform := &OrphanTransformer{State: state, Module: mod}
|
|
||||||
if err := transform.Transform(&g); err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
actual := strings.TrimSpace(g.String())
|
|
||||||
expected := strings.TrimSpace(testTransformOrphanModulesDepsOrphanStr)
|
|
||||||
if actual != expected {
|
|
||||||
t.Fatalf("bad:\n\n%s", actual)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestOrphanTransformer_modulesNoRoot(t *testing.T) {
|
|
||||||
mod := testModule(t, "transform-orphan-modules")
|
|
||||||
state := &State{
|
|
||||||
Modules: []*ModuleState{
|
|
||||||
// Orphan module
|
|
||||||
&ModuleState{
|
|
||||||
Path: []string{RootModuleName, "foo"},
|
|
||||||
Resources: map[string]*ResourceState{
|
|
||||||
"aws_instance.web": &ResourceState{
|
|
||||||
Type: "aws_instance",
|
|
||||||
Primary: &InstanceState{
|
|
||||||
ID: "foo",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
g := Graph{Path: RootModulePath}
|
|
||||||
{
|
|
||||||
tf := &ConfigTransformerOld{Module: mod}
|
|
||||||
if err := tf.Transform(&g); err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
transform := &OrphanTransformer{State: state, Module: mod}
|
|
||||||
if err := transform.Transform(&g); err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
actual := strings.TrimSpace(g.String())
|
|
||||||
expected := strings.TrimSpace(testTransformOrphanModulesNoRootStr)
|
|
||||||
if actual != expected {
|
|
||||||
t.Fatalf("bad:\n\n%s", actual)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestOrphanTransformer_resourceDepends(t *testing.T) {
|
|
||||||
mod := testModule(t, "transform-orphan-basic")
|
|
||||||
state := &State{
|
|
||||||
Modules: []*ModuleState{
|
|
||||||
&ModuleState{
|
|
||||||
Path: RootModulePath,
|
|
||||||
Resources: map[string]*ResourceState{
|
|
||||||
"aws_instance.web": &ResourceState{
|
|
||||||
Type: "aws_instance",
|
|
||||||
Primary: &InstanceState{
|
|
||||||
ID: "foo",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
// The orphan
|
|
||||||
"aws_instance.db": &ResourceState{
|
|
||||||
Type: "aws_instance",
|
|
||||||
Primary: &InstanceState{
|
|
||||||
ID: "foo",
|
|
||||||
},
|
|
||||||
Dependencies: []string{
|
|
||||||
"aws_instance.web",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
g := Graph{Path: RootModulePath}
|
|
||||||
{
|
|
||||||
tf := &ConfigTransformerOld{Module: mod}
|
|
||||||
if err := tf.Transform(&g); err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
transform := &OrphanTransformer{State: state, Module: mod}
|
|
||||||
if err := transform.Transform(&g); err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
actual := strings.TrimSpace(g.String())
|
|
||||||
expected := strings.TrimSpace(testTransformOrphanResourceDependsStr)
|
|
||||||
if actual != expected {
|
|
||||||
t.Fatalf("bad:\n\n%s", actual)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestOrphanTransformer_nilState(t *testing.T) {
|
|
||||||
mod := testModule(t, "transform-orphan-basic")
|
|
||||||
|
|
||||||
g := Graph{Path: RootModulePath}
|
|
||||||
{
|
|
||||||
tf := &ConfigTransformerOld{Module: mod}
|
|
||||||
if err := tf.Transform(&g); err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
transform := &OrphanTransformer{State: nil, Module: mod}
|
|
||||||
if err := transform.Transform(&g); err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
actual := strings.TrimSpace(g.String())
|
|
||||||
expected := strings.TrimSpace(testTransformOrphanNilStateStr)
|
|
||||||
if actual != expected {
|
|
||||||
t.Fatalf("bad:\n\n%s", actual)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGraphNodeOrphanModule_impl(t *testing.T) {
|
|
||||||
var _ dag.Vertex = new(graphNodeOrphanModule)
|
|
||||||
var _ dag.NamedVertex = new(graphNodeOrphanModule)
|
|
||||||
var _ GraphNodeExpandable = new(graphNodeOrphanModule)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGraphNodeOrphanResource_impl(t *testing.T) {
|
|
||||||
var _ dag.Vertex = new(graphNodeOrphanResource)
|
|
||||||
var _ dag.NamedVertex = new(graphNodeOrphanResource)
|
|
||||||
var _ GraphNodeProviderConsumer = new(graphNodeOrphanResource)
|
|
||||||
var _ GraphNodeAddressable = new(graphNodeOrphanResource)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGraphNodeOrphanResource_ProvidedBy(t *testing.T) {
|
|
||||||
n := &graphNodeOrphanResource{ResourceKey: &ResourceStateKey{Type: "aws_instance"}}
|
|
||||||
if v := n.ProvidedBy(); v[0] != "aws" {
|
|
||||||
t.Fatalf("bad: %#v", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGraphNodeOrphanResource_ProvidedBy_alias(t *testing.T) {
|
|
||||||
n := &graphNodeOrphanResource{ResourceKey: &ResourceStateKey{Type: "aws_instance"}, Provider: "aws.bar"}
|
|
||||||
if v := n.ProvidedBy(); v[0] != "aws.bar" {
|
|
||||||
t.Fatalf("bad: %#v", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const testTransformOrphanBasicStr = `
|
|
||||||
aws_instance.db (orphan)
|
|
||||||
aws_instance.web
|
|
||||||
`
|
|
||||||
|
|
||||||
const testTransformOrphanModulesStr = `
|
|
||||||
aws_instance.foo
|
|
||||||
module.foo (orphan)
|
|
||||||
`
|
|
||||||
|
|
||||||
const testTransformOrphanModulesDepsStr = `
|
|
||||||
aws_instance.foo
|
|
||||||
module.foo (orphan)
|
|
||||||
aws_instance.foo
|
|
||||||
`
|
|
||||||
|
|
||||||
const testTransformOrphanModulesDepsOrphanStr = `
|
|
||||||
aws_instance.foo
|
|
||||||
aws_instance.web (orphan)
|
|
||||||
module.foo (orphan)
|
|
||||||
aws_instance.web (orphan)
|
|
||||||
`
|
|
||||||
|
|
||||||
const testTransformOrphanNilStateStr = `
|
|
||||||
aws_instance.web
|
|
||||||
`
|
|
||||||
|
|
||||||
const testTransformOrphanResourceDependsStr = `
|
|
||||||
aws_instance.db (orphan)
|
|
||||||
aws_instance.web
|
|
||||||
aws_instance.web
|
|
||||||
`
|
|
||||||
|
|
||||||
const testTransformOrphanModulesNoRootStr = `
|
|
||||||
aws_instance.foo
|
|
||||||
module.foo (orphan)
|
|
||||||
`
|
|
Loading…
Reference in New Issue