forked from hashicorp/terraform
-
Notifications
You must be signed in to change notification settings - Fork 7
/
graph_builder_plan.go
127 lines (102 loc) · 3.25 KB
/
graph_builder_plan.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package terraform
import (
"github.com/hashicorp/terraform/config/module"
"github.com/hashicorp/terraform/dag"
)
// PlanGraphBuilder implements GraphBuilder and is responsible for building
// a graph for planning (creating a Terraform Diff).
//
// The primary difference between this graph and others:
//
// * Based on the config since it represents the target state
//
// * Ignores lifecycle options since no lifecycle events occur here. This
// simplifies the graph significantly since complex transforms such as
// create-before-destroy can be completely ignored.
//
type PlanGraphBuilder struct {
// Module is the root module for the graph to build.
Module *module.Tree
// State is the current state
State *State
// Providers is the list of providers supported.
Providers []string
// Targets are resources to target
Targets []string
// DisableReduce, if true, will not reduce the graph. Great for testing.
DisableReduce bool
// Validate will do structural validation of the graph.
Validate bool
}
// See GraphBuilder
func (b *PlanGraphBuilder) Build(path []string) (*Graph, error) {
return (&BasicGraphBuilder{
Steps: b.Steps(),
Validate: b.Validate,
Name: "PlanGraphBuilder",
}).Build(path)
}
// See GraphBuilder
func (b *PlanGraphBuilder) Steps() []GraphTransformer {
// Custom factory for creating providers.
concreteProvider := func(a *NodeAbstractProvider) dag.Vertex {
return &NodeApplyableProvider{
NodeAbstractProvider: a,
}
}
concreteResource := func(a *NodeAbstractResource) dag.Vertex {
return &NodePlannableResource{
NodeAbstractResource: a,
}
}
concreteResourceOrphan := func(a *NodeAbstractResource) dag.Vertex {
return &NodePlannableResourceOrphan{
NodeAbstractResource: a,
}
}
steps := []GraphTransformer{
// Creates all the resources represented in the config
&ConfigTransformer{
Concrete: concreteResource,
Module: b.Module,
},
// Add the outputs
&OutputTransformer{Module: b.Module},
// Add orphan resources
&OrphanResourceTransformer{
Concrete: concreteResourceOrphan,
State: b.State,
Module: b.Module,
},
// Attach the configuration to any resources
&AttachResourceConfigTransformer{Module: b.Module},
// Attach the state
&AttachStateTransformer{State: b.State},
// Connect so that the references are ready for targeting. We'll
// have to connect again later for providers and so on.
&ReferenceTransformer{},
// Target
&TargetsTransformer{Targets: b.Targets},
// Create all the providers
&MissingProviderTransformer{Providers: b.Providers, Concrete: concreteProvider},
&ProviderTransformer{},
&DisableProviderTransformer{},
&ParentProviderTransformer{},
&AttachProviderConfigTransformer{Module: b.Module},
// Add root variables
&RootVariableTransformer{Module: b.Module},
// Add module variables
&ModuleVariableTransformer{Module: b.Module},
// Connect references again to connect the providers, module variables,
// etc. This is idempotent.
&ReferenceTransformer{},
// Single root
&RootTransformer{},
}
if !b.DisableReduce {
// Perform the transitive reduction to make our graph a bit
// more sane if possible (it usually is possible).
steps = append(steps, &TransitiveReductionTransformer{})
}
return steps
}