]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blob - vendor/github.com/hashicorp/terraform/terraform/graph_builder_plan.go
a6a3a90d48607dca3ac5f9a14fd3135b07cd818a
[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{Targets: b.Targets},
121
122 // Close opened plugin connections
123 &CloseProviderTransformer{},
124 &CloseProvisionerTransformer{},
125
126 // Single root
127 &RootTransformer{},
128 }
129
130 if !b.DisableReduce {
131 // Perform the transitive reduction to make our graph a bit
132 // more sane if possible (it usually is possible).
133 steps = append(steps, &TransitiveReductionTransformer{})
134 }
135
136 return steps
137 }
138
139 func (b *PlanGraphBuilder) init() {
140 // Do nothing if the user requests customizing the fields
141 if b.CustomConcrete {
142 return
143 }
144
145 b.ConcreteProvider = func(a *NodeAbstractProvider) dag.Vertex {
146 return &NodeApplyableProvider{
147 NodeAbstractProvider: a,
148 }
149 }
150
151 b.ConcreteResource = func(a *NodeAbstractResource) dag.Vertex {
152 return &NodePlannableResource{
153 NodeAbstractCountResource: &NodeAbstractCountResource{
154 NodeAbstractResource: a,
155 },
156 }
157 }
158
159 b.ConcreteResourceOrphan = func(a *NodeAbstractResource) dag.Vertex {
160 return &NodePlannableResourceOrphan{
161 NodeAbstractResource: a,
162 }
163 }
164 }