]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blob - vendor/github.com/hashicorp/terraform/terraform/graph_builder_plan.go
Upgrade to 0.12
[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/addrs"
7 "github.com/hashicorp/terraform/configs"
8 "github.com/hashicorp/terraform/dag"
9 "github.com/hashicorp/terraform/states"
10 "github.com/hashicorp/terraform/tfdiags"
11 )
12
13 // PlanGraphBuilder implements GraphBuilder and is responsible for building
14 // a graph for planning (creating a Terraform Diff).
15 //
16 // The primary difference between this graph and others:
17 //
18 // * Based on the config since it represents the target state
19 //
20 // * Ignores lifecycle options since no lifecycle events occur here. This
21 // simplifies the graph significantly since complex transforms such as
22 // create-before-destroy can be completely ignored.
23 //
24 type PlanGraphBuilder struct {
25 // Config is the configuration tree to build a plan from.
26 Config *configs.Config
27
28 // State is the current state
29 State *states.State
30
31 // Components is a factory for the plug-in components (providers and
32 // provisioners) available for use.
33 Components contextComponentFactory
34
35 // Schemas is the repository of schemas we will draw from to analyse
36 // the configuration.
37 Schemas *Schemas
38
39 // Targets are resources to target
40 Targets []addrs.Targetable
41
42 // DisableReduce, if true, will not reduce the graph. Great for testing.
43 DisableReduce bool
44
45 // Validate will do structural validation of the graph.
46 Validate bool
47
48 // CustomConcrete can be set to customize the node types created
49 // for various parts of the plan. This is useful in order to customize
50 // the plan behavior.
51 CustomConcrete bool
52 ConcreteProvider ConcreteProviderNodeFunc
53 ConcreteResource ConcreteResourceNodeFunc
54 ConcreteResourceOrphan ConcreteResourceInstanceNodeFunc
55
56 once sync.Once
57 }
58
59 // See GraphBuilder
60 func (b *PlanGraphBuilder) Build(path addrs.ModuleInstance) (*Graph, tfdiags.Diagnostics) {
61 return (&BasicGraphBuilder{
62 Steps: b.Steps(),
63 Validate: b.Validate,
64 Name: "PlanGraphBuilder",
65 }).Build(path)
66 }
67
68 // See GraphBuilder
69 func (b *PlanGraphBuilder) Steps() []GraphTransformer {
70 b.once.Do(b.init)
71
72 concreteResourceInstanceDeposed := func(a *NodeAbstractResourceInstance, key states.DeposedKey) dag.Vertex {
73 return &NodePlanDeposedResourceInstanceObject{
74 NodeAbstractResourceInstance: a,
75 DeposedKey: key,
76 }
77 }
78
79 steps := []GraphTransformer{
80 // Creates all the resources represented in the config
81 &ConfigTransformer{
82 Concrete: b.ConcreteResource,
83 Config: b.Config,
84 },
85
86 // Add the local values
87 &LocalTransformer{Config: b.Config},
88
89 // Add the outputs
90 &OutputTransformer{Config: b.Config},
91
92 // Add orphan resources
93 &OrphanResourceInstanceTransformer{
94 Concrete: b.ConcreteResourceOrphan,
95 State: b.State,
96 Config: b.Config,
97 },
98
99 // We also need nodes for any deposed instance objects present in the
100 // state, so we can plan to destroy them. (This intentionally
101 // skips creating nodes for _current_ objects, since ConfigTransformer
102 // created nodes that will do that during DynamicExpand.)
103 &StateTransformer{
104 ConcreteDeposed: concreteResourceInstanceDeposed,
105 State: b.State,
106 },
107
108 // Create orphan output nodes
109 &OrphanOutputTransformer{
110 Config: b.Config,
111 State: b.State,
112 },
113
114 // Attach the configuration to any resources
115 &AttachResourceConfigTransformer{Config: b.Config},
116
117 // Attach the state
118 &AttachStateTransformer{State: b.State},
119
120 // Add root variables
121 &RootVariableTransformer{Config: b.Config},
122
123 &MissingProvisionerTransformer{Provisioners: b.Components.ResourceProvisioners()},
124 &ProvisionerTransformer{},
125
126 // Add module variables
127 &ModuleVariableTransformer{
128 Config: b.Config,
129 },
130
131 TransformProviders(b.Components.ResourceProviders(), b.ConcreteProvider, b.Config),
132
133 // Remove modules no longer present in the config
134 &RemovedModuleTransformer{Config: b.Config, State: b.State},
135
136 // Must attach schemas before ReferenceTransformer so that we can
137 // analyze the configuration to find references.
138 &AttachSchemaTransformer{Schemas: b.Schemas},
139
140 // Connect so that the references are ready for targeting. We'll
141 // have to connect again later for providers and so on.
142 &ReferenceTransformer{},
143
144 // Add the node to fix the state count boundaries
145 &CountBoundaryTransformer{
146 Config: b.Config,
147 },
148
149 // Target
150 &TargetsTransformer{
151 Targets: b.Targets,
152
153 // Resource nodes from config have not yet been expanded for
154 // "count", so we must apply targeting without indices. Exact
155 // targeting will be dealt with later when these resources
156 // DynamicExpand.
157 IgnoreIndices: true,
158 },
159
160 // Detect when create_before_destroy must be forced on for a particular
161 // node due to dependency edges, to avoid graph cycles during apply.
162 &ForcedCBDTransformer{},
163
164 // Close opened plugin connections
165 &CloseProviderTransformer{},
166 &CloseProvisionerTransformer{},
167
168 // Single root
169 &RootTransformer{},
170 }
171
172 if !b.DisableReduce {
173 // Perform the transitive reduction to make our graph a bit
174 // more sane if possible (it usually is possible).
175 steps = append(steps, &TransitiveReductionTransformer{})
176 }
177
178 return steps
179 }
180
181 func (b *PlanGraphBuilder) init() {
182 // Do nothing if the user requests customizing the fields
183 if b.CustomConcrete {
184 return
185 }
186
187 b.ConcreteProvider = func(a *NodeAbstractProvider) dag.Vertex {
188 return &NodeApplyableProvider{
189 NodeAbstractProvider: a,
190 }
191 }
192
193 b.ConcreteResource = func(a *NodeAbstractResource) dag.Vertex {
194 return &NodePlannableResource{
195 NodeAbstractResource: a,
196 }
197 }
198
199 b.ConcreteResourceOrphan = func(a *NodeAbstractResourceInstance) dag.Vertex {
200 return &NodePlannableResourceInstanceOrphan{
201 NodeAbstractResourceInstance: a,
202 }
203 }
204 }