7 "github.com/hashicorp/terraform/config"
8 "github.com/hashicorp/terraform/dag"
11 // NodeApplyableOutput represents an output that is "applyable":
12 // it is ready to be applied.
13 type NodeApplyableOutput struct {
15 Config *config.Output // Config is the output in the config
18 func (n *NodeApplyableOutput) Name() string {
19 result := fmt.Sprintf("output.%s", n.Config.Name)
20 if len(n.PathValue) > 1 {
21 result = fmt.Sprintf("%s.%s", modulePrefixStr(n.PathValue), result)
28 func (n *NodeApplyableOutput) Path() []string {
32 // RemovableIfNotTargeted
33 func (n *NodeApplyableOutput) RemoveIfNotTargeted() bool {
34 // We need to add this so that this node will be removed if
35 // it isn't targeted or a dependency of a target.
39 // GraphNodeTargetDownstream
40 func (n *NodeApplyableOutput) TargetDownstream(targetedDeps, untargetedDeps *dag.Set) bool {
41 // If any of the direct dependencies of an output are targeted then
42 // the output must always be targeted as well, so its value will always
43 // be up-to-date at the completion of an apply walk.
47 // GraphNodeReferenceable
48 func (n *NodeApplyableOutput) ReferenceableName() []string {
49 name := fmt.Sprintf("output.%s", n.Config.Name)
53 // GraphNodeReferencer
54 func (n *NodeApplyableOutput) References() []string {
56 result = append(result, n.Config.DependsOn...)
57 result = append(result, ReferencesFromConfig(n.Config.RawConfig)...)
58 for _, v := range result {
59 split := strings.Split(v, "/")
60 for i, s := range split {
61 split[i] = s + ".destroy"
64 result = append(result, strings.Join(split, "/"))
71 func (n *NodeApplyableOutput) EvalTree() EvalNode {
75 // Don't let interpolation errors stop Input, since it happens
77 Ops: []walkOperation{walkInput},
78 Node: &EvalWriteOutput{
80 Sensitive: n.Config.Sensitive,
81 Value: n.Config.RawConfig,
86 Ops: []walkOperation{walkRefresh, walkPlan, walkApply, walkValidate, walkDestroy, walkPlanDestroy},
87 Node: &EvalWriteOutput{
89 Sensitive: n.Config.Sensitive,
90 Value: n.Config.RawConfig,
97 // NodeDestroyableOutput represents an output that is "destroybale":
98 // its application will remove the output from the state.
99 type NodeDestroyableOutput struct {
101 Config *config.Output // Config is the output in the config
104 func (n *NodeDestroyableOutput) Name() string {
105 result := fmt.Sprintf("output.%s (destroy)", n.Config.Name)
106 if len(n.PathValue) > 1 {
107 result = fmt.Sprintf("%s.%s", modulePrefixStr(n.PathValue), result)
114 func (n *NodeDestroyableOutput) Path() []string {
118 // RemovableIfNotTargeted
119 func (n *NodeDestroyableOutput) RemoveIfNotTargeted() bool {
120 // We need to add this so that this node will be removed if
121 // it isn't targeted or a dependency of a target.
125 // This will keep the destroy node in the graph if its corresponding output
126 // node is also in the destroy graph.
127 func (n *NodeDestroyableOutput) TargetDownstream(targetedDeps, untargetedDeps *dag.Set) bool {
131 // GraphNodeReferencer
132 func (n *NodeDestroyableOutput) References() []string {
134 result = append(result, n.Config.DependsOn...)
135 result = append(result, ReferencesFromConfig(n.Config.RawConfig)...)
136 for _, v := range result {
137 split := strings.Split(v, "/")
138 for i, s := range split {
139 split[i] = s + ".destroy"
142 result = append(result, strings.Join(split, "/"))
149 func (n *NodeDestroyableOutput) EvalTree() EvalNode {
150 return &EvalDeleteOutput{