]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blame - 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
CommitLineData
bae9f6d2
JC
1package terraform
2
3import (
4 "fmt"
bae9f6d2 5
107c1cdb
ND
6 "github.com/hashicorp/terraform/addrs"
7 "github.com/hashicorp/terraform/configs"
9b12e4fe 8 "github.com/hashicorp/terraform/dag"
107c1cdb 9 "github.com/hashicorp/terraform/lang"
bae9f6d2
JC
10)
11
12// NodeApplyableOutput represents an output that is "applyable":
13// it is ready to be applied.
14type NodeApplyableOutput struct {
107c1cdb
ND
15 Addr addrs.AbsOutputValue
16 Config *configs.Output // Config is the output in the config
bae9f6d2
JC
17}
18
107c1cdb
ND
19var (
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)
bae9f6d2 29
107c1cdb
ND
30func (n *NodeApplyableOutput) Name() string {
31 return n.Addr.String()
bae9f6d2
JC
32}
33
34// GraphNodeSubPath
107c1cdb
ND
35func (n *NodeApplyableOutput) Path() addrs.ModuleInstance {
36 return n.Addr.Module
bae9f6d2
JC
37}
38
39// RemovableIfNotTargeted
40func (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
9b12e4fe
JC
46// GraphNodeTargetDownstream
47func (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
107c1cdb
ND
54func 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
68func (n *NodeApplyableOutput) ReferenceOutside() (selfPath, referencePath addrs.ModuleInstance) {
69 return referenceOutsideForOutput(n.Addr)
70}
71
72func 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
bae9f6d2 90// GraphNodeReferenceable
107c1cdb
ND
91func (n *NodeApplyableOutput) ReferenceableAddrs() []addrs.Referenceable {
92 return referenceableAddrsForOutput(n.Addr)
bae9f6d2
JC
93}
94
107c1cdb
ND
95func 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
bae9f6d2 101 }
107c1cdb
ND
102 refs := make([]*addrs.Reference, 0, l)
103 refs = append(refs, impRefs...)
104 refs = append(refs, expRefs...)
105 return refs
bae9f6d2 106
107c1cdb
ND
107}
108
109// GraphNodeReferencer
110func (n *NodeApplyableOutput) References() []*addrs.Reference {
111 return appendResourceDestroyReferences(referencesForOutput(n.Config))
bae9f6d2
JC
112}
113
114// GraphNodeEvalable
115func (n *NodeApplyableOutput) EvalTree() EvalNode {
15c0b25d
AP
116 return &EvalSequence{
117 Nodes: []EvalNode{
15c0b25d
AP
118 &EvalOpFilter{
119 Ops: []walkOperation{walkRefresh, walkPlan, walkApply, walkValidate, walkDestroy, walkPlanDestroy},
120 Node: &EvalWriteOutput{
107c1cdb 121 Addr: n.Addr.OutputValue,
bae9f6d2 122 Sensitive: n.Config.Sensitive,
107c1cdb 123 Expr: n.Config.Expr,
bae9f6d2
JC
124 },
125 },
126 },
127 }
128}
15c0b25d 129
107c1cdb
ND
130// dag.GraphNodeDotter impl.
131func (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
15c0b25d
AP
141// NodeDestroyableOutput represents an output that is "destroybale":
142// its application will remove the output from the state.
143type NodeDestroyableOutput struct {
107c1cdb
ND
144 Addr addrs.AbsOutputValue
145 Config *configs.Output // Config is the output in the config
15c0b25d
AP
146}
147
107c1cdb
ND
148var (
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)
15c0b25d 156
107c1cdb
ND
157func (n *NodeDestroyableOutput) Name() string {
158 return fmt.Sprintf("%s (destroy)", n.Addr.String())
15c0b25d
AP
159}
160
161// GraphNodeSubPath
107c1cdb
ND
162func (n *NodeDestroyableOutput) Path() addrs.ModuleInstance {
163 return n.Addr.Module
15c0b25d
AP
164}
165
166// RemovableIfNotTargeted
167func (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.
175func (n *NodeDestroyableOutput) TargetDownstream(targetedDeps, untargetedDeps *dag.Set) bool {
176 return true
177}
178
179// GraphNodeReferencer
107c1cdb
ND
180func (n *NodeDestroyableOutput) References() []*addrs.Reference {
181 return referencesForOutput(n.Config)
15c0b25d
AP
182}
183
184// GraphNodeEvalable
185func (n *NodeDestroyableOutput) EvalTree() EvalNode {
186 return &EvalDeleteOutput{
107c1cdb
ND
187 Addr: n.Addr.OutputValue,
188 }
189}
190
191// dag.GraphNodeDotter impl.
192func (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 },
15c0b25d
AP
199 }
200}