diff --git a/hcl2template/parser.go b/hcl2template/parser.go index 0ab9f1a2d..a41fc1b22 100644 --- a/hcl2template/parser.go +++ b/hcl2template/parser.go @@ -290,7 +290,7 @@ func filterVarsFromLogs(inputOrLocal Variables) { if !variable.Sensitive { continue } - value, _ := variable.Value() + value := variable.Value() _ = cty.Walk(value, func(_ cty.Path, nested cty.Value) (bool, error) { if nested.IsWhollyKnown() && !nested.IsNull() && nested.Type().Equals(cty.String) { packersdk.LogSecretFilter.Set(nested.AsString()) @@ -310,9 +310,9 @@ func (cfg *PackerConfig) Initialize(opts packer.InitializeOptions) hcl.Diagnosti return diags } - _, moreDiags = cfg.InputVariables.Values() + moreDiags = cfg.InputVariables.ValidateValues() diags = append(diags, moreDiags...) - _, moreDiags = cfg.LocalVariables.Values() + moreDiags = cfg.LocalVariables.ValidateValues() diags = append(diags, moreDiags...) diags = append(diags, cfg.evaluateDatasources(opts.SkipDatasourcesExecution)...) diags = append(diags, cfg.evaluateLocalVariables(cfg.LocalBlocks)...) diff --git a/hcl2template/types.packer_config.go b/hcl2template/types.packer_config.go index 1b9762982..e09623901 100644 --- a/hcl2template/types.packer_config.go +++ b/hcl2template/types.packer_config.go @@ -91,8 +91,8 @@ const ( // decoder in order to tell what is the actual value of a var or a local and // the list of defined functions. func (cfg *PackerConfig) EvalContext(ctx BlockContext, variables map[string]cty.Value) *hcl.EvalContext { - inputVariables, _ := cfg.InputVariables.Values() - localVariables, _ := cfg.LocalVariables.Values() + inputVariables := cfg.InputVariables.Values() + localVariables := cfg.LocalVariables.Values() ectx := &hcl.EvalContext{ Functions: Functions(cfg.Basedir), Variables: map[string]cty.Value{ @@ -594,7 +594,7 @@ func (p *PackerConfig) printVariables() string { sort.Strings(keys) for _, key := range keys { v := p.InputVariables[key] - val, _ := v.Value() + val := v.Value() fmt.Fprintf(out, "var.%s: %q\n", v.Name, PrintableCtyValue(val)) } out.WriteString("\n> local-variables:\n\n") @@ -602,7 +602,7 @@ func (p *PackerConfig) printVariables() string { sort.Strings(keys) for _, key := range keys { v := p.LocalVariables[key] - val, _ := v.Value() + val := v.Value() fmt.Fprintf(out, "local.%s: %q\n", v.Name, PrintableCtyValue(val)) } return out.String() diff --git a/hcl2template/types.variables.go b/hcl2template/types.variables.go index b56b5f5a7..61bb54345 100644 --- a/hcl2template/types.variables.go +++ b/hcl2template/types.variables.go @@ -152,9 +152,19 @@ func (v *Variable) validateValue(val VariableAssignment) (diags hcl.Diagnostics) } // Value returns the last found value from the list of variable settings. -func (v *Variable) Value() (cty.Value, hcl.Diagnostics) { +func (v *Variable) Value() cty.Value { if len(v.Values) == 0 { - return cty.UnknownVal(v.Type), hcl.Diagnostics{&hcl.Diagnostic{ + return cty.UnknownVal(v.Type) + } + val := v.Values[len(v.Values)-1] + return val.Value +} + +// ValidateValue tells if the selected value for the Variable is valid according +// to its validation settings. +func (v *Variable) ValidateValue() hcl.Diagnostics { + if len(v.Values) == 0 { + return hcl.Diagnostics{&hcl.Diagnostic{ Severity: hcl.DiagError, Summary: fmt.Sprintf("Unset variable %q", v.Name), Detail: "A used variable must be set or have a default value; see " + @@ -163,8 +173,8 @@ func (v *Variable) Value() (cty.Value, hcl.Diagnostics) { Context: v.Range.Ptr(), }} } - val := v.Values[len(v.Values)-1] - return val.Value, v.validateValue(v.Values[len(v.Values)-1]) + + return v.validateValue(v.Values[len(v.Values)-1]) } type Variables map[string]*Variable @@ -177,15 +187,21 @@ func (variables Variables) Keys() []string { return keys } -func (variables Variables) Values() (map[string]cty.Value, hcl.Diagnostics) { +func (variables Variables) Values() map[string]cty.Value { res := map[string]cty.Value{} - var diags hcl.Diagnostics for k, v := range variables { - value, moreDiags := v.Value() - diags = append(diags, moreDiags...) + value := v.Value() res[k] = value } - return res, diags + return res +} + +func (variables Variables) ValidateValues() hcl.Diagnostics { + var diags hcl.Diagnostics + for _, v := range variables { + diags = append(diags, v.ValidateValue()...) + } + return diags } // decodeVariable decodes a variable key and value into Variables diff --git a/hcl2template/types.variables_test.go b/hcl2template/types.variables_test.go index 8b10832b1..4baa8f2cc 100644 --- a/hcl2template/types.variables_test.go +++ b/hcl2template/types.variables_test.go @@ -868,7 +868,7 @@ func TestVariables_collectVariableValues(t *testing.T) { } values := map[string]cty.Value{} for k, v := range tt.variables { - value, diag := v.Value() + value, diag := v.Value(), v.ValidateValue() if diag != nil { t.Fatalf("Value %s: %v", k, diag) }