]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blob - vendor/github.com/hashicorp/terraform/terraform/graph_builder_plan.go
vendor: github.com/hashicorp/terraform/...@v0.10.0
[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 outputs
75 &OutputTransformer{Module: b.Module},
76
77 // Add orphan resources
78 &OrphanResourceTransformer{
79 Concrete: b.ConcreteResourceOrphan,
80 State: b.State,
81 Module: b.Module,
82 },
83
84 // Attach the configuration to any resources
85 &AttachResourceConfigTransformer{Module: b.Module},
86
87 // Attach the state
88 &AttachStateTransformer{State: b.State},
89
90 // Add root variables
91 &RootVariableTransformer{Module: b.Module},
92
93 // Create all the providers
94 &MissingProviderTransformer{Providers: b.Providers, Concrete: b.ConcreteProvider},
95 &ProviderTransformer{},
96 &DisableProviderTransformer{},
97 &ParentProviderTransformer{},
98 &AttachProviderConfigTransformer{Module: b.Module},
99
100 // Provisioner-related transformations. Only add these if requested.
101 GraphTransformIf(
102 func() bool { return b.Provisioners != nil },
103 GraphTransformMulti(
104 &MissingProvisionerTransformer{Provisioners: b.Provisioners},
105 &ProvisionerTransformer{},
106 ),
107 ),
108
109 // Add module variables
110 &ModuleVariableTransformer{Module: b.Module},
111
112 // Connect so that the references are ready for targeting. We'll
113 // have to connect again later for providers and so on.
114 &ReferenceTransformer{},
115
116 // Add the node to fix the state count boundaries
117 &CountBoundaryTransformer{},
118
119 // Target
120 &TargetsTransformer{
121 Targets: b.Targets,
122
123 // Resource nodes from config have not yet been expanded for
124 // "count", so we must apply targeting without indices. Exact
125 // targeting will be dealt with later when these resources
126 // DynamicExpand.
127 IgnoreIndices: true,
128 },
129
130 // Close opened plugin connections
131 &CloseProviderTransformer{},
132 &CloseProvisionerTransformer{},
133
134 // Single root
135 &RootTransformer{},
136 }
137
138 if !b.DisableReduce {
139 // Perform the transitive reduction to make our graph a bit
140 // more sane if possible (it usually is possible).
141 steps = append(steps, &TransitiveReductionTransformer{})
142 }
143
144 return steps
145 }
146
147 func (b *PlanGraphBuilder) init() {
148 // Do nothing if the user requests customizing the fields
149 if b.CustomConcrete {
150 return
151 }
152
153 b.ConcreteProvider = func(a *NodeAbstractProvider) dag.Vertex {
154 return &NodeApplyableProvider{
155 NodeAbstractProvider: a,
156 }
157 }
158
159 b.ConcreteResource = func(a *NodeAbstractResource) dag.Vertex {
160 return &NodePlannableResource{
161 NodeAbstractCountResource: &NodeAbstractCountResource{
162 NodeAbstractResource: a,
163 },
164 }
165 }
166
167 b.ConcreteResourceOrphan = func(a *NodeAbstractResource) dag.Vertex {
168 return &NodePlannableResourceOrphan{
169 NodeAbstractResource: a,
170 }
171 }
172 }