1package terraform
2
3import (
4	"github.com/hashicorp/terraform/addrs"
5	"github.com/hashicorp/terraform/configs"
6	"github.com/hashicorp/terraform/dag"
7	"github.com/hashicorp/terraform/states"
8	"github.com/hashicorp/terraform/tfdiags"
9)
10
11// DestroyPlanGraphBuilder implements GraphBuilder and is responsible for
12// planning a pure-destroy.
13//
14// Planning a pure destroy operation is simple because we can ignore most
15// ordering configuration and simply reverse the state.
16type DestroyPlanGraphBuilder struct {
17	// Config is the configuration tree to build the plan from.
18	Config *configs.Config
19
20	// State is the current state
21	State *states.State
22
23	// Components is a factory for the plug-in components (providers and
24	// provisioners) available for use.
25	Components contextComponentFactory
26
27	// Schemas is the repository of schemas we will draw from to analyse
28	// the configuration.
29	Schemas *Schemas
30
31	// Targets are resources to target
32	Targets []addrs.Targetable
33
34	// Validate will do structural validation of the graph.
35	Validate bool
36}
37
38// See GraphBuilder
39func (b *DestroyPlanGraphBuilder) Build(path addrs.ModuleInstance) (*Graph, tfdiags.Diagnostics) {
40	return (&BasicGraphBuilder{
41		Steps:    b.Steps(),
42		Validate: b.Validate,
43		Name:     "DestroyPlanGraphBuilder",
44	}).Build(path)
45}
46
47// See GraphBuilder
48func (b *DestroyPlanGraphBuilder) Steps() []GraphTransformer {
49	concreteResourceInstance := func(a *NodeAbstractResourceInstance) dag.Vertex {
50		return &NodePlanDestroyableResourceInstance{
51			NodeAbstractResourceInstance: a,
52		}
53	}
54	concreteResourceInstanceDeposed := func(a *NodeAbstractResourceInstance, key states.DeposedKey) dag.Vertex {
55		return &NodePlanDeposedResourceInstanceObject{
56			NodeAbstractResourceInstance: a,
57			DeposedKey:                   key,
58		}
59	}
60
61	concreteProvider := func(a *NodeAbstractProvider) dag.Vertex {
62		return &NodeApplyableProvider{
63			NodeAbstractProvider: a,
64		}
65	}
66
67	steps := []GraphTransformer{
68		// Creates nodes for the resource instances tracked in the state.
69		&StateTransformer{
70			ConcreteCurrent: concreteResourceInstance,
71			ConcreteDeposed: concreteResourceInstanceDeposed,
72			State:           b.State,
73		},
74
75		// Attach the configuration to any resources
76		&AttachResourceConfigTransformer{Config: b.Config},
77
78		TransformProviders(b.Components.ResourceProviders(), concreteProvider, b.Config),
79
80		// Destruction ordering. We require this only so that
81		// targeting below will prune the correct things.
82		&DestroyEdgeTransformer{
83			Config:  b.Config,
84			State:   b.State,
85			Schemas: b.Schemas,
86		},
87
88		// Target. Note we don't set "Destroy: true" here since we already
89		// created proper destroy ordering.
90		&TargetsTransformer{Targets: b.Targets},
91
92		// Single root
93		&RootTransformer{},
94	}
95
96	return steps
97}
98