]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blob - vendor/github.com/hashicorp/terraform/terraform/node_output.go
Upgrade to 0.12
[github/fretlink/terraform-provider-statuscake.git] / vendor / github.com / hashicorp / terraform / terraform / node_output.go
1 package terraform
2
3 import (
4 "fmt"
5
6 "github.com/hashicorp/terraform/addrs"
7 "github.com/hashicorp/terraform/configs"
8 "github.com/hashicorp/terraform/dag"
9 "github.com/hashicorp/terraform/lang"
10 )
11
12 // NodeApplyableOutput represents an output that is "applyable":
13 // it is ready to be applied.
14 type NodeApplyableOutput struct {
15 Addr addrs.AbsOutputValue
16 Config *configs.Output // Config is the output in the config
17 }
18
19 var (
20 _ GraphNodeSubPath = (*NodeApplyableOutput)(nil)
21 _ RemovableIfNotTargeted = (*NodeApplyableOutput)(nil)
22 _ GraphNodeTargetDownstream = (*NodeApplyableOutput)(nil)
23 _ GraphNodeReferenceable = (*NodeApplyableOutput)(nil)
24 _ GraphNodeReferencer = (*NodeApplyableOutput)(nil)
25 _ GraphNodeReferenceOutside = (*NodeApplyableOutput)(nil)
26 _ GraphNodeEvalable = (*NodeApplyableOutput)(nil)
27 _ dag.GraphNodeDotter = (*NodeApplyableOutput)(nil)
28 )
29
30 func (n *NodeApplyableOutput) Name() string {
31 return n.Addr.String()
32 }
33
34 // GraphNodeSubPath
35 func (n *NodeApplyableOutput) Path() addrs.ModuleInstance {
36 return n.Addr.Module
37 }
38
39 // RemovableIfNotTargeted
40 func (n *NodeApplyableOutput) RemoveIfNotTargeted() bool {
41 // We need to add this so that this node will be removed if
42 // it isn't targeted or a dependency of a target.
43 return true
44 }
45
46 // GraphNodeTargetDownstream
47 func (n *NodeApplyableOutput) TargetDownstream(targetedDeps, untargetedDeps *dag.Set) bool {
48 // If any of the direct dependencies of an output are targeted then
49 // the output must always be targeted as well, so its value will always
50 // be up-to-date at the completion of an apply walk.
51 return true
52 }
53
54 func referenceOutsideForOutput(addr addrs.AbsOutputValue) (selfPath, referencePath addrs.ModuleInstance) {
55
56 // Output values have their expressions resolved in the context of the
57 // module where they are defined.
58 referencePath = addr.Module
59
60 // ...but they are referenced in the context of their calling module.
61 selfPath = addr.Module.Parent()
62
63 return // uses named return values
64
65 }
66
67 // GraphNodeReferenceOutside implementation
68 func (n *NodeApplyableOutput) ReferenceOutside() (selfPath, referencePath addrs.ModuleInstance) {
69 return referenceOutsideForOutput(n.Addr)
70 }
71
72 func referenceableAddrsForOutput(addr addrs.AbsOutputValue) []addrs.Referenceable {
73 // An output in the root module can't be referenced at all.
74 if addr.Module.IsRoot() {
75 return nil
76 }
77
78 // Otherwise, we can be referenced via a reference to our output name
79 // on the parent module's call, or via a reference to the entire call.
80 // e.g. module.foo.bar or just module.foo .
81 // Note that our ReferenceOutside method causes these addresses to be
82 // relative to the calling module, not the module where the output
83 // was declared.
84 _, outp := addr.ModuleCallOutput()
85 _, call := addr.Module.CallInstance()
86 return []addrs.Referenceable{outp, call}
87
88 }
89
90 // GraphNodeReferenceable
91 func (n *NodeApplyableOutput) ReferenceableAddrs() []addrs.Referenceable {
92 return referenceableAddrsForOutput(n.Addr)
93 }
94
95 func referencesForOutput(c *configs.Output) []*addrs.Reference {
96 impRefs, _ := lang.ReferencesInExpr(c.Expr)
97 expRefs, _ := lang.References(c.DependsOn)
98 l := len(impRefs) + len(expRefs)
99 if l == 0 {
100 return nil
101 }
102 refs := make([]*addrs.Reference, 0, l)
103 refs = append(refs, impRefs...)
104 refs = append(refs, expRefs...)
105 return refs
106
107 }
108
109 // GraphNodeReferencer
110 func (n *NodeApplyableOutput) References() []*addrs.Reference {
111 return appendResourceDestroyReferences(referencesForOutput(n.Config))
112 }
113
114 // GraphNodeEvalable
115 func (n *NodeApplyableOutput) EvalTree() EvalNode {
116 return &EvalSequence{
117 Nodes: []EvalNode{
118 &EvalOpFilter{
119 Ops: []walkOperation{walkRefresh, walkPlan, walkApply, walkValidate, walkDestroy, walkPlanDestroy},
120 Node: &EvalWriteOutput{
121 Addr: n.Addr.OutputValue,
122 Sensitive: n.Config.Sensitive,
123 Expr: n.Config.Expr,
124 },
125 },
126 },
127 }
128 }
129
130 // dag.GraphNodeDotter impl.
131 func (n *NodeApplyableOutput) DotNode(name string, opts *dag.DotOpts) *dag.DotNode {
132 return &dag.DotNode{
133 Name: name,
134 Attrs: map[string]string{
135 "label": n.Name(),
136 "shape": "note",
137 },
138 }
139 }
140
141 // NodeDestroyableOutput represents an output that is "destroybale":
142 // its application will remove the output from the state.
143 type NodeDestroyableOutput struct {
144 Addr addrs.AbsOutputValue
145 Config *configs.Output // Config is the output in the config
146 }
147
148 var (
149 _ GraphNodeSubPath = (*NodeDestroyableOutput)(nil)
150 _ RemovableIfNotTargeted = (*NodeDestroyableOutput)(nil)
151 _ GraphNodeTargetDownstream = (*NodeDestroyableOutput)(nil)
152 _ GraphNodeReferencer = (*NodeDestroyableOutput)(nil)
153 _ GraphNodeEvalable = (*NodeDestroyableOutput)(nil)
154 _ dag.GraphNodeDotter = (*NodeDestroyableOutput)(nil)
155 )
156
157 func (n *NodeDestroyableOutput) Name() string {
158 return fmt.Sprintf("%s (destroy)", n.Addr.String())
159 }
160
161 // GraphNodeSubPath
162 func (n *NodeDestroyableOutput) Path() addrs.ModuleInstance {
163 return n.Addr.Module
164 }
165
166 // RemovableIfNotTargeted
167 func (n *NodeDestroyableOutput) RemoveIfNotTargeted() bool {
168 // We need to add this so that this node will be removed if
169 // it isn't targeted or a dependency of a target.
170 return true
171 }
172
173 // This will keep the destroy node in the graph if its corresponding output
174 // node is also in the destroy graph.
175 func (n *NodeDestroyableOutput) TargetDownstream(targetedDeps, untargetedDeps *dag.Set) bool {
176 return true
177 }
178
179 // GraphNodeReferencer
180 func (n *NodeDestroyableOutput) References() []*addrs.Reference {
181 return referencesForOutput(n.Config)
182 }
183
184 // GraphNodeEvalable
185 func (n *NodeDestroyableOutput) EvalTree() EvalNode {
186 return &EvalDeleteOutput{
187 Addr: n.Addr.OutputValue,
188 }
189 }
190
191 // dag.GraphNodeDotter impl.
192 func (n *NodeDestroyableOutput) DotNode(name string, opts *dag.DotOpts) *dag.DotNode {
193 return &dag.DotNode{
194 Name: name,
195 Attrs: map[string]string{
196 "label": n.Name(),
197 "shape": "note",
198 },
199 }
200 }