From bd8802e08d87d24c828cc0412bb86b37c7768aa2 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Mon, 7 Nov 2016 08:57:27 -0800 Subject: [PATCH] terraform: plan orphan destruction --- terraform/graph_builder_plan.go | 13 ++++++ terraform/node_resource_plan_orphan.go | 59 ++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 terraform/node_resource_plan_orphan.go diff --git a/terraform/graph_builder_plan.go b/terraform/graph_builder_plan.go index e25749299..f38828f0c 100644 --- a/terraform/graph_builder_plan.go +++ b/terraform/graph_builder_plan.go @@ -55,6 +55,12 @@ func (b *PlanGraphBuilder) Steps() []GraphTransformer { } } + concreteResourceOrphan := func(a *NodeAbstractResource) dag.Vertex { + return &NodePlannableResourceOrphan{ + NodeAbstractResource: a, + } + } + steps := []GraphTransformer{ // Creates all the resources represented in the config &ConfigTransformer{ @@ -65,6 +71,13 @@ func (b *PlanGraphBuilder) Steps() []GraphTransformer { // Add the outputs &OutputTransformer{Module: b.Module}, + // Add orphan resources + &OrphanResourceTransformer{ + Concrete: concreteResourceOrphan, + State: b.State, + Module: b.Module, + }, + // Attach the configuration to any resources &AttachResourceConfigTransformer{Module: b.Module}, diff --git a/terraform/node_resource_plan_orphan.go b/terraform/node_resource_plan_orphan.go new file mode 100644 index 000000000..e8d700bde --- /dev/null +++ b/terraform/node_resource_plan_orphan.go @@ -0,0 +1,59 @@ +package terraform + +import ( + "fmt" +) + +// NodePlannableResourceOrphan represents a resource that is "applyable": +// it is ready to be applied and is represented by a diff. +type NodePlannableResourceOrphan struct { + *NodeAbstractResource +} + +func (n *NodePlannableResourceOrphan) Name() string { + return n.NodeAbstractResource.Name() + " (orphan)" +} + +// GraphNodeEvalable +func (n *NodePlannableResourceOrphan) EvalTree() EvalNode { + addr := n.NodeAbstractResource.Addr + + // stateId is the ID to put into the state + stateId := addr.stateId() + if addr.Index > -1 { + stateId = fmt.Sprintf("%s.%d", stateId, addr.Index) + } + + // Build the instance info. More of this will be populated during eval + info := &InstanceInfo{ + Id: stateId, + Type: addr.Type, + } + + // Declare a bunch of variables that are used for state during + // evaluation. Most of this are written to by-address below. + var diff *InstanceDiff + var state *InstanceState + + return &EvalSequence{ + Nodes: []EvalNode{ + &EvalReadState{ + Name: stateId, + Output: &state, + }, + &EvalDiffDestroy{ + Info: info, + State: &state, + Output: &diff, + }, + &EvalCheckPreventDestroy{ + Resource: n.Config, + Diff: &diff, + }, + &EvalWriteDiff{ + Name: stateId, + Diff: &diff, + }, + }, + } +}