all variables must have a value.
A variable's default value can be set to null to force user to set it.
This commit is contained in:
parent
6d8cce501e
commit
0ccff0d5b9
|
@ -126,6 +126,11 @@ func (p *Parser) parse(filename string, vars map[string]string) (*PackerConfig,
|
||||||
diags = append(diags, cfg.collectInputVariableValues(os.Environ(), varFiles, vars)...)
|
diags = append(diags, cfg.collectInputVariableValues(os.Environ(), varFiles, vars)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_, moreDiags := cfg.InputVariables.Values()
|
||||||
|
diags = append(diags, moreDiags...)
|
||||||
|
_, moreDiags = cfg.LocalVariables.Values()
|
||||||
|
diags = append(diags, moreDiags...)
|
||||||
|
|
||||||
// decode the actual content
|
// decode the actual content
|
||||||
for _, file := range files {
|
for _, file := range files {
|
||||||
diags = append(diags, p.decodeConfig(file, cfg)...)
|
diags = append(diags, p.decodeConfig(file, cfg)...)
|
||||||
|
|
|
@ -29,6 +29,7 @@ variable "super_secret_password" {
|
||||||
description = <<IMSENSIBLE
|
description = <<IMSENSIBLE
|
||||||
Handle with care plz
|
Handle with care plz
|
||||||
IMSENSIBLE
|
IMSENSIBLE
|
||||||
|
default = null
|
||||||
}
|
}
|
||||||
|
|
||||||
locals {
|
locals {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
|
|
||||||
variable "broken_type" {
|
variable "broken_variable" {
|
||||||
invalid = true
|
invalid = true
|
||||||
|
default = true
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,11 +39,13 @@ type ValidationOptions struct {
|
||||||
// decoder in order to tell what is the actual value of a var or a local and
|
// decoder in order to tell what is the actual value of a var or a local and
|
||||||
// the list of defined functions.
|
// the list of defined functions.
|
||||||
func (cfg *PackerConfig) EvalContext() *hcl.EvalContext {
|
func (cfg *PackerConfig) EvalContext() *hcl.EvalContext {
|
||||||
|
inputVariables, _ := cfg.InputVariables.Values()
|
||||||
|
localVariables, _ := cfg.LocalVariables.Values()
|
||||||
ectx := &hcl.EvalContext{
|
ectx := &hcl.EvalContext{
|
||||||
Functions: Functions(cfg.Basedir),
|
Functions: Functions(cfg.Basedir),
|
||||||
Variables: map[string]cty.Value{
|
Variables: map[string]cty.Value{
|
||||||
"var": cty.ObjectVal(cfg.InputVariables.Values()),
|
"var": cty.ObjectVal(inputVariables),
|
||||||
"local": cty.ObjectVal(cfg.LocalVariables.Values()),
|
"local": cty.ObjectVal(localVariables),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
return ectx
|
return ectx
|
||||||
|
|
|
@ -62,7 +62,7 @@ func (v *Variable) Value() (cty.Value, *hcl.Diagnostic) {
|
||||||
v.EnvValue,
|
v.EnvValue,
|
||||||
v.DefaultValue,
|
v.DefaultValue,
|
||||||
} {
|
} {
|
||||||
if !value.IsNull() {
|
if value != cty.NilVal {
|
||||||
return value, nil
|
return value, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,23 +73,26 @@ func (v *Variable) Value() (cty.Value, *hcl.Diagnostic) {
|
||||||
Severity: hcl.DiagError,
|
Severity: hcl.DiagError,
|
||||||
Summary: fmt.Sprintf("Unset variable %q", v.Name),
|
Summary: fmt.Sprintf("Unset variable %q", v.Name),
|
||||||
Detail: "A used variable must be set or have a default value; see " +
|
Detail: "A used variable must be set or have a default value; see " +
|
||||||
"https://packer.io/docs/configuration/from-1.5/syntax.html for details.",
|
"https://packer.io/docs/configuration/from-1.5/syntax.html for " +
|
||||||
|
"details.",
|
||||||
Context: v.Range.Ptr(),
|
Context: v.Range.Ptr(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type Variables map[string]*Variable
|
type Variables map[string]*Variable
|
||||||
|
|
||||||
func (variables Variables) Values() map[string]cty.Value {
|
func (variables Variables) Values() (map[string]cty.Value, hcl.Diagnostics) {
|
||||||
res := map[string]cty.Value{}
|
res := map[string]cty.Value{}
|
||||||
|
var diags hcl.Diagnostics
|
||||||
for k, v := range variables {
|
for k, v := range variables {
|
||||||
res[k], _ = v.Value()
|
value, diag := v.Value()
|
||||||
// here the value might not be used and in that case we don't want to
|
if diag != nil {
|
||||||
// force users to set it. So this error is ignored. we still set it as
|
diags = append(diags, diag)
|
||||||
// it can be a `cty.NullVal(cty.DynamicPseudoType)`, which is the go
|
continue
|
||||||
// cty value for 'unknown value' and should error when used.
|
|
||||||
}
|
}
|
||||||
return res
|
res[k] = value
|
||||||
|
}
|
||||||
|
return res, diags
|
||||||
}
|
}
|
||||||
|
|
||||||
// decodeVariable decodes a variable key and value into Variables
|
// decodeVariable decodes a variable key and value into Variables
|
||||||
|
|
|
@ -54,6 +54,7 @@ func TestParse_variables(t *testing.T) {
|
||||||
"super_secret_password": &Variable{
|
"super_secret_password": &Variable{
|
||||||
Name: "super_secret_password",
|
Name: "super_secret_password",
|
||||||
Sensitive: true,
|
Sensitive: true,
|
||||||
|
DefaultValue: cty.NullVal(cty.String),
|
||||||
Description: fmt.Sprintln("Handle with care plz"),
|
Description: fmt.Sprintln("Handle with care plz"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -117,14 +118,16 @@ func TestParse_variables(t *testing.T) {
|
||||||
[]packer.Build{},
|
[]packer.Build{},
|
||||||
false,
|
false,
|
||||||
},
|
},
|
||||||
|
|
||||||
{"unknown key",
|
{"unknown key",
|
||||||
defaultParser,
|
defaultParser,
|
||||||
parseTestArgs{"testdata/variables/unknown_key.pkr.hcl", nil},
|
parseTestArgs{"testdata/variables/unknown_key.pkr.hcl", nil},
|
||||||
&PackerConfig{
|
&PackerConfig{
|
||||||
Basedir: filepath.Join("testdata", "variables"),
|
Basedir: filepath.Join("testdata", "variables"),
|
||||||
InputVariables: Variables{
|
InputVariables: Variables{
|
||||||
"broken_type": &Variable{
|
"broken_variable": &Variable{
|
||||||
Name: "broken_type",
|
Name: "broken_variable",
|
||||||
|
DefaultValue: cty.BoolVal(true),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -132,6 +135,7 @@ func TestParse_variables(t *testing.T) {
|
||||||
[]packer.Build{},
|
[]packer.Build{},
|
||||||
false,
|
false,
|
||||||
},
|
},
|
||||||
|
|
||||||
{"unset used variable",
|
{"unset used variable",
|
||||||
defaultParser,
|
defaultParser,
|
||||||
parseTestArgs{"testdata/variables/unset_used_string_variable.pkr.hcl", nil},
|
parseTestArgs{"testdata/variables/unset_used_string_variable.pkr.hcl", nil},
|
||||||
|
@ -170,7 +174,7 @@ func TestParse_variables(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
false, false,
|
true, true,
|
||||||
[]packer.Build{
|
[]packer.Build{
|
||||||
&packer.CoreBuild{
|
&packer.CoreBuild{
|
||||||
Type: "null",
|
Type: "null",
|
||||||
|
|
Loading…
Reference in New Issue