]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blob - vendor/github.com/hashicorp/terraform/terraform/graph_builder_plan.go
deps: github.com/hashicorp/terraform@sdk-v0.11-with-go-modules
[github/fretlink/terraform-provider-statuscake.git] / vendor / github.com / hashicorp / terraform / terraform / graph_builder_plan.go
1 package terraform
2
3 import (
4 "sync"
5
6 "github.com/hashicorp/terraform/config/module"
7 "github.com/hashicorp/terraform/dag"
8 )
9
10 // PlanGraphBuilder implements GraphBuilder and is responsible for building
11 // a graph for planning (creating a Terraform Diff).
12 //
13 // The primary difference between this graph and others:
14 //
15 // * Based on the config since it represents the target state
16 //
17 // * Ignores lifecycle options since no lifecycle events occur here. This
18 // simplifies the graph significantly since complex transforms such as
19 // create-before-destroy can be completely ignored.
20 //
21 type PlanGraphBuilder struct {
22 // Module is the root module for the graph to build.
23 Module *module.Tree
24
25 // State is the current state
26 State *State
27
28 // Providers is the list of providers supported.
29 Providers []string
30
31 // Provisioners is the list of provisioners supported.
32 Provisioners []string
33
34 // Targets are resources to target
35 Targets []string
36
37 // DisableReduce, if true, will not reduce the graph. Great for testing.
38 DisableReduce bool
39
40 // Validate will do structural validation of the graph.
41 Validate bool
42
43 // CustomConcrete can be set to customize the node types created
44 // for various parts of the plan. This is useful in order to customize
45 // the plan behavior.
46 CustomConcrete bool
47 ConcreteProvider ConcreteProviderNodeFunc
48 ConcreteResource ConcreteResourceNodeFunc
49 ConcreteResourceOrphan ConcreteResourceNodeFunc
50
51 once sync.Once
52 }
53
54 // See GraphBuilder
55 func (b *PlanGraphBuilder) Build(path []string) (*Graph, error) {
56 return (&BasicGraphBuilder{
57 Steps: b.Steps(),
58 Validate: b.Validate,
59 Name: "PlanGraphBuilder",
60 }).Build(path)
61 }
62
63 // See GraphBuilder
64 func (b *PlanGraphBuilder) Steps() []GraphTransformer {
65 b.once.Do(b.init)
66
67 steps := []GraphTransformer{
68 // Creates all the resources represented in the config
69 &ConfigTransformer{
70 Concrete: b.ConcreteResource,
71 Module: b.Module,
72 },
73
74 // Add the local values
75 &LocalTransformer{Module: b.Module},
76
77 // Add the outputs
78 &OutputTransformer{Module: b.Module},
79
80 // Add orphan resources
81 &OrphanResourceTransformer{
82 Concrete: b.ConcreteResourceOrphan,
83 State: b.State,
84 Module: b.Module,
85 },
86
87 // Create orphan output nodes
88 &OrphanOutputTransformer{
89 Module: b.Module,
90 State: b.State,
91 },
92
93 // Attach the configuration to any resources
94 &AttachResourceConfigTransformer{Module: b.Module},
95
96 // Attach the state
97 &AttachStateTransformer{State: b.State},
98
99 // Add root variables
100 &RootVariableTransformer{Module: b.Module},
101
102 TransformProviders(b.Providers, b.ConcreteProvider, b.Module),
103
104 // Provisioner-related transformations. Only add these if requested.
105 GraphTransformIf(
106 func() bool { return b.Provisioners != nil },
107 GraphTransformMulti(
108 &MissingProvisionerTransformer{Provisioners: b.Provisioners},
109 &ProvisionerTransformer{},
110 ),
111 ),
112
113 // Add module variables
114 &ModuleVariableTransformer{
115 Module: b.Module,
116 },
117
118 // Remove modules no longer present in the config
119 &RemovedModuleTransformer{Module: b.Module, State: b.State},
120
121 // Connect so that the references are ready for targeting. We'll
122 // have to connect again later for providers and so on.
123 &ReferenceTransformer{},
124
125 // Add the node to fix the state count boundaries
126 &CountBoundaryTransformer{},
127
128 // Target
129 &TargetsTransformer{
130 Targets: b.Targets,
131
132 // Resource nodes from config have not yet been expanded for
133 // "count", so we must apply targeting without indices. Exact
134 // targeting will be dealt with later when these resources
135 // DynamicExpand.
136 IgnoreIndices: true,
137 },
138
139 // Close opened plugin connections
140 &CloseProviderTransformer{},
141 &CloseProvisionerTransformer{},
142
143 // Single root
144 &RootTransformer{},
145 }
146
147 if !b.DisableReduce {
148 // Perform the transitive reduction to make our graph a bit
149 // more sane if possible (it usually is possible).
150 steps = append(steps, &TransitiveReductionTransformer{})
151 }
152
153 return steps
154 }
155
156 func (b *PlanGraphBuilder) init() {
157 // Do nothing if the user requests customizing the fields
158 if b.CustomConcrete {
159 return
160 }
161
162 b.ConcreteProvider = func(a *NodeAbstractProvider) dag.Vertex {
163 return &NodeApplyableProvider{
164 NodeAbstractProvider: a,
165 }
166 }
167
168 b.ConcreteResource = func(a *NodeAbstractResource) dag.Vertex {
169 return &NodePlannableResource{
170 NodeAbstractCountResource: &NodeAbstractCountResource{
171 NodeAbstractResource: a,
172 },
173 }
174 }
175
176 b.ConcreteResourceOrphan = func(a *NodeAbstractResource) dag.Vertex {
177 return &NodePlannableResourceOrphan{
178 NodeAbstractResource: a,
179 }
180 }
181 }