github.com/kanishk98/terraform@v1.3.0-dev.0.20220917174235-661ca8088a6a/internal/terraform/node_root_variable.go (about) 1 package terraform 2 3 import ( 4 "log" 5 6 "github.com/hashicorp/terraform/internal/addrs" 7 "github.com/hashicorp/terraform/internal/configs" 8 "github.com/hashicorp/terraform/internal/dag" 9 "github.com/hashicorp/terraform/internal/tfdiags" 10 "github.com/zclconf/go-cty/cty" 11 ) 12 13 // NodeRootVariable represents a root variable input. 14 type NodeRootVariable struct { 15 Addr addrs.InputVariable 16 Config *configs.Variable 17 18 // RawValue is the value for the variable set from outside Terraform 19 // Core, such as on the command line, or from an environment variable, 20 // or similar. This is the raw value that was provided, not yet 21 // converted or validated, and can be nil for a variable that isn't 22 // set at all. 23 RawValue *InputValue 24 } 25 26 var ( 27 _ GraphNodeModuleInstance = (*NodeRootVariable)(nil) 28 _ GraphNodeReferenceable = (*NodeRootVariable)(nil) 29 ) 30 31 func (n *NodeRootVariable) Name() string { 32 return n.Addr.String() 33 } 34 35 // GraphNodeModuleInstance 36 func (n *NodeRootVariable) Path() addrs.ModuleInstance { 37 return addrs.RootModuleInstance 38 } 39 40 func (n *NodeRootVariable) ModulePath() addrs.Module { 41 return addrs.RootModule 42 } 43 44 // GraphNodeReferenceable 45 func (n *NodeRootVariable) ReferenceableAddrs() []addrs.Referenceable { 46 return []addrs.Referenceable{n.Addr} 47 } 48 49 // GraphNodeExecutable 50 func (n *NodeRootVariable) Execute(ctx EvalContext, op walkOperation) tfdiags.Diagnostics { 51 // Root module variables are special in that they are provided directly 52 // by the caller (usually, the CLI layer) and so we don't really need to 53 // evaluate them in the usual sense, but we do need to process the raw 54 // values given by the caller to match what the module is expecting, and 55 // make sure the values are valid. 56 var diags tfdiags.Diagnostics 57 58 addr := addrs.RootModuleInstance.InputVariable(n.Addr.Name) 59 log.Printf("[TRACE] NodeRootVariable: evaluating %s", addr) 60 61 if n.Config == nil { 62 // Because we build NodeRootVariable from configuration in the normal 63 // case it's strange to get here, but we tolerate it to allow for 64 // tests that might not populate the inputs fully. 65 return nil 66 } 67 68 givenVal := n.RawValue 69 if givenVal == nil { 70 // We'll use cty.NilVal to represent the variable not being set at 71 // all, which for historical reasons is unfortunately different than 72 // explicitly setting it to null in some cases. In normal code we 73 // should never get here because all variables should have raw 74 // values, but we can get here in some historical tests that call 75 // in directly and don't necessarily obey the rules. 76 givenVal = &InputValue{ 77 Value: cty.NilVal, 78 SourceType: ValueFromUnknown, 79 } 80 } 81 82 finalVal, moreDiags := prepareFinalInputVariableValue( 83 addr, 84 givenVal, 85 n.Config, 86 ) 87 diags = diags.Append(moreDiags) 88 if moreDiags.HasErrors() { 89 // No point in proceeding to validations then, because they'll 90 // probably fail trying to work with a value of the wrong type. 91 return diags 92 } 93 94 ctx.SetRootModuleArgument(addr.Variable, finalVal) 95 96 moreDiags = evalVariableValidations( 97 addrs.RootModuleInstance.InputVariable(n.Addr.Name), 98 n.Config, 99 nil, // not set for root module variables 100 ctx, 101 ) 102 diags = diags.Append(moreDiags) 103 return diags 104 } 105 106 // dag.GraphNodeDotter impl. 107 func (n *NodeRootVariable) DotNode(name string, opts *dag.DotOpts) *dag.DotNode { 108 return &dag.DotNode{ 109 Name: name, 110 Attrs: map[string]string{ 111 "label": n.Name(), 112 "shape": "note", 113 }, 114 } 115 }