github.com/trawler/terraform@v0.10.8-0.20171106022149-4b1c7a1d9b48/terraform/node_output.go (about) 1 package terraform 2 3 import ( 4 "fmt" 5 "strings" 6 7 "github.com/hashicorp/terraform/config" 8 "github.com/hashicorp/terraform/dag" 9 ) 10 11 // NodeApplyableOutput represents an output that is "applyable": 12 // it is ready to be applied. 13 type NodeApplyableOutput struct { 14 PathValue []string 15 Config *config.Output // Config is the output in the config 16 } 17 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) 22 } 23 24 return result 25 } 26 27 // GraphNodeSubPath 28 func (n *NodeApplyableOutput) Path() []string { 29 return n.PathValue 30 } 31 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. 36 return true 37 } 38 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. 44 return true 45 } 46 47 // GraphNodeReferenceable 48 func (n *NodeApplyableOutput) ReferenceableName() []string { 49 name := fmt.Sprintf("output.%s", n.Config.Name) 50 return []string{name} 51 } 52 53 // GraphNodeReferencer 54 func (n *NodeApplyableOutput) References() []string { 55 var result []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" 62 } 63 64 result = append(result, strings.Join(split, "/")) 65 } 66 67 return result 68 } 69 70 // GraphNodeEvalable 71 func (n *NodeApplyableOutput) EvalTree() EvalNode { 72 return &EvalSequence{ 73 Nodes: []EvalNode{ 74 &EvalOpFilter{ 75 // Don't let interpolation errors stop Input, since it happens 76 // before Refresh. 77 Ops: []walkOperation{walkInput}, 78 Node: &EvalWriteOutput{ 79 Name: n.Config.Name, 80 Sensitive: n.Config.Sensitive, 81 Value: n.Config.RawConfig, 82 ContinueOnErr: true, 83 }, 84 }, 85 &EvalOpFilter{ 86 Ops: []walkOperation{walkRefresh, walkPlan, walkApply, walkValidate}, 87 Node: &EvalWriteOutput{ 88 Name: n.Config.Name, 89 Sensitive: n.Config.Sensitive, 90 Value: n.Config.RawConfig, 91 }, 92 }, 93 &EvalOpFilter{ 94 Ops: []walkOperation{walkDestroy, walkPlanDestroy}, 95 Node: &EvalDeleteOutput{ 96 Name: n.Config.Name, 97 }, 98 }, 99 }, 100 } 101 }