]>
Commit | Line | Data |
---|---|---|
bae9f6d2 JC |
1 | package terraform |
2 | ||
3 | import ( | |
9b12e4fe JC |
4 | "log" |
5 | ||
bae9f6d2 JC |
6 | "github.com/hashicorp/terraform/config" |
7 | "github.com/hashicorp/terraform/config/module" | |
8 | "github.com/hashicorp/terraform/dag" | |
9 | ) | |
10 | ||
11 | // RefreshGraphBuilder implements GraphBuilder and is responsible for building | |
12 | // a graph for refreshing (updating the Terraform state). | |
13 | // | |
14 | // The primary difference between this graph and others: | |
15 | // | |
16 | // * Based on the state since it represents the only resources that | |
17 | // need to be refreshed. | |
18 | // | |
19 | // * Ignores lifecycle options since no lifecycle events occur here. This | |
20 | // simplifies the graph significantly since complex transforms such as | |
21 | // create-before-destroy can be completely ignored. | |
22 | // | |
23 | type RefreshGraphBuilder struct { | |
24 | // Module is the root module for the graph to build. | |
25 | Module *module.Tree | |
26 | ||
27 | // State is the current state | |
28 | State *State | |
29 | ||
30 | // Providers is the list of providers supported. | |
31 | Providers []string | |
32 | ||
33 | // Targets are resources to target | |
34 | Targets []string | |
35 | ||
36 | // DisableReduce, if true, will not reduce the graph. Great for testing. | |
37 | DisableReduce bool | |
38 | ||
39 | // Validate will do structural validation of the graph. | |
40 | Validate bool | |
41 | } | |
42 | ||
43 | // See GraphBuilder | |
44 | func (b *RefreshGraphBuilder) Build(path []string) (*Graph, error) { | |
45 | return (&BasicGraphBuilder{ | |
46 | Steps: b.Steps(), | |
47 | Validate: b.Validate, | |
48 | Name: "RefreshGraphBuilder", | |
49 | }).Build(path) | |
50 | } | |
51 | ||
52 | // See GraphBuilder | |
53 | func (b *RefreshGraphBuilder) Steps() []GraphTransformer { | |
54 | // Custom factory for creating providers. | |
55 | concreteProvider := func(a *NodeAbstractProvider) dag.Vertex { | |
56 | return &NodeApplyableProvider{ | |
57 | NodeAbstractProvider: a, | |
58 | } | |
59 | } | |
60 | ||
9b12e4fe JC |
61 | concreteManagedResource := func(a *NodeAbstractResource) dag.Vertex { |
62 | return &NodeRefreshableManagedResource{ | |
63 | NodeAbstractCountResource: &NodeAbstractCountResource{ | |
64 | NodeAbstractResource: a, | |
65 | }, | |
66 | } | |
67 | } | |
68 | ||
69 | concreteManagedResourceInstance := func(a *NodeAbstractResource) dag.Vertex { | |
70 | return &NodeRefreshableManagedResourceInstance{ | |
bae9f6d2 JC |
71 | NodeAbstractResource: a, |
72 | } | |
73 | } | |
74 | ||
75 | concreteDataResource := func(a *NodeAbstractResource) dag.Vertex { | |
76 | return &NodeRefreshableDataResource{ | |
77 | NodeAbstractCountResource: &NodeAbstractCountResource{ | |
78 | NodeAbstractResource: a, | |
79 | }, | |
80 | } | |
81 | } | |
82 | ||
83 | steps := []GraphTransformer{ | |
9b12e4fe JC |
84 | // Creates all the managed resources that aren't in the state, but only if |
85 | // we have a state already. No resources in state means there's not | |
86 | // anything to refresh. | |
87 | func() GraphTransformer { | |
88 | if b.State.HasResources() { | |
89 | return &ConfigTransformer{ | |
90 | Concrete: concreteManagedResource, | |
91 | Module: b.Module, | |
92 | Unique: true, | |
93 | ModeFilter: true, | |
94 | Mode: config.ManagedResourceMode, | |
95 | } | |
96 | } | |
97 | log.Println("[TRACE] No managed resources in state during refresh, skipping managed resource transformer") | |
98 | return nil | |
99 | }(), | |
bae9f6d2 | 100 | |
9b12e4fe JC |
101 | // Creates all the data resources that aren't in the state. This will also |
102 | // add any orphans from scaling in as destroy nodes. | |
bae9f6d2 JC |
103 | &ConfigTransformer{ |
104 | Concrete: concreteDataResource, | |
105 | Module: b.Module, | |
106 | Unique: true, | |
107 | ModeFilter: true, | |
108 | Mode: config.DataResourceMode, | |
109 | }, | |
110 | ||
9b12e4fe JC |
111 | // Add any fully-orphaned resources from config (ones that have been |
112 | // removed completely, not ones that are just orphaned due to a scaled-in | |
113 | // count. | |
114 | &OrphanResourceTransformer{ | |
115 | Concrete: concreteManagedResourceInstance, | |
116 | State: b.State, | |
117 | Module: b.Module, | |
118 | }, | |
119 | ||
bae9f6d2 JC |
120 | // Attach the state |
121 | &AttachStateTransformer{State: b.State}, | |
122 | ||
123 | // Attach the configuration to any resources | |
124 | &AttachResourceConfigTransformer{Module: b.Module}, | |
125 | ||
126 | // Add root variables | |
127 | &RootVariableTransformer{Module: b.Module}, | |
128 | ||
129 | // Create all the providers | |
130 | &MissingProviderTransformer{Providers: b.Providers, Concrete: concreteProvider}, | |
131 | &ProviderTransformer{}, | |
132 | &DisableProviderTransformer{}, | |
133 | &ParentProviderTransformer{}, | |
134 | &AttachProviderConfigTransformer{Module: b.Module}, | |
135 | ||
136 | // Add the outputs | |
137 | &OutputTransformer{Module: b.Module}, | |
138 | ||
139 | // Add module variables | |
140 | &ModuleVariableTransformer{Module: b.Module}, | |
141 | ||
142 | // Connect so that the references are ready for targeting. We'll | |
143 | // have to connect again later for providers and so on. | |
144 | &ReferenceTransformer{}, | |
145 | ||
146 | // Target | |
c680a8e1 RS |
147 | &TargetsTransformer{ |
148 | Targets: b.Targets, | |
149 | ||
150 | // Resource nodes from config have not yet been expanded for | |
151 | // "count", so we must apply targeting without indices. Exact | |
152 | // targeting will be dealt with later when these resources | |
153 | // DynamicExpand. | |
154 | IgnoreIndices: true, | |
155 | }, | |
bae9f6d2 JC |
156 | |
157 | // Close opened plugin connections | |
158 | &CloseProviderTransformer{}, | |
159 | ||
160 | // Single root | |
161 | &RootTransformer{}, | |
162 | } | |
163 | ||
164 | if !b.DisableReduce { | |
165 | // Perform the transitive reduction to make our graph a bit | |
166 | // more sane if possible (it usually is possible). | |
167 | steps = append(steps, &TransitiveReductionTransformer{}) | |
168 | } | |
169 | ||
170 | return steps | |
171 | } |