remove synthetic default expression for variables
Now that variable evaluation checks for a nil expression the graph transformer does not need to generate a synthetic expression for variable defaults. This means that all default handling is now located in one place, and we are not surprised by a configuration expression showing up which doesn't actually exist in the configuration. Rename nodeModuleVariable.evalModuleCallArgument to evalModuleVariable. This method is no longer handling only the module call argument, it is also dealing with the variable declaration defaults and validation statements. Add an additional tests for validation with a non-nullable variable.
This commit is contained in:
parent
dabd7567af
commit
684ed7505d
|
@ -2062,3 +2062,36 @@ output "out" {
|
||||||
t.Fatal(diags.ErrWithWarnings())
|
t.Fatal(diags.ErrWithWarnings())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestContext2Validate_nonNullableVariableDefaultValidation(t *testing.T) {
|
||||||
|
m := testModuleInline(t, map[string]string{
|
||||||
|
"main.tf": `
|
||||||
|
module "first" {
|
||||||
|
source = "./mod"
|
||||||
|
input = null
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
|
||||||
|
"mod/main.tf": `
|
||||||
|
variable "input" {
|
||||||
|
type = string
|
||||||
|
default = "default"
|
||||||
|
nullable = false
|
||||||
|
|
||||||
|
// Validation expressions should receive the default with nullable=false and
|
||||||
|
// a null input.
|
||||||
|
validation {
|
||||||
|
condition = var.input != null
|
||||||
|
error_message = "Input cannot be null!"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
})
|
||||||
|
|
||||||
|
ctx := testContext2(t, &ContextOpts{})
|
||||||
|
|
||||||
|
diags := ctx.Validate(m)
|
||||||
|
if diags.HasErrors() {
|
||||||
|
t.Fatal(diags.ErrWithWarnings())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -149,10 +149,10 @@ func (n *nodeModuleVariable) Execute(ctx EvalContext, op walkOperation) (diags t
|
||||||
|
|
||||||
switch op {
|
switch op {
|
||||||
case walkValidate:
|
case walkValidate:
|
||||||
val, err = n.evalModuleCallArgument(ctx, true)
|
val, err = n.evalModuleVariable(ctx, true)
|
||||||
diags = diags.Append(err)
|
diags = diags.Append(err)
|
||||||
default:
|
default:
|
||||||
val, err = n.evalModuleCallArgument(ctx, false)
|
val, err = n.evalModuleVariable(ctx, false)
|
||||||
diags = diags.Append(err)
|
diags = diags.Append(err)
|
||||||
}
|
}
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
|
@ -178,7 +178,7 @@ func (n *nodeModuleVariable) DotNode(name string, opts *dag.DotOpts) *dag.DotNod
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// evalModuleCallArgument produces the value for a particular variable as will
|
// evalModuleVariable produces the value for a particular variable as will
|
||||||
// be used by a child module instance.
|
// be used by a child module instance.
|
||||||
//
|
//
|
||||||
// The result is written into a map, with its key set to the local name of the
|
// The result is written into a map, with its key set to the local name of the
|
||||||
|
@ -190,7 +190,7 @@ func (n *nodeModuleVariable) DotNode(name string, opts *dag.DotOpts) *dag.DotNod
|
||||||
// validateOnly indicates that this evaluation is only for config
|
// validateOnly indicates that this evaluation is only for config
|
||||||
// validation, and we will not have any expansion module instance
|
// validation, and we will not have any expansion module instance
|
||||||
// repetition data.
|
// repetition data.
|
||||||
func (n *nodeModuleVariable) evalModuleCallArgument(ctx EvalContext, validateOnly bool) (cty.Value, error) {
|
func (n *nodeModuleVariable) evalModuleVariable(ctx EvalContext, validateOnly bool) (cty.Value, error) {
|
||||||
var diags tfdiags.Diagnostics
|
var diags tfdiags.Diagnostics
|
||||||
var givenVal cty.Value
|
var givenVal cty.Value
|
||||||
var errSourceRange tfdiags.SourceRange
|
var errSourceRange tfdiags.SourceRange
|
||||||
|
|
|
@ -3,7 +3,6 @@ package terraform
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/hashicorp/hcl/v2/hclsyntax"
|
|
||||||
"github.com/hashicorp/terraform/internal/addrs"
|
"github.com/hashicorp/terraform/internal/addrs"
|
||||||
"github.com/hashicorp/terraform/internal/tfdiags"
|
"github.com/hashicorp/terraform/internal/tfdiags"
|
||||||
"github.com/zclconf/go-cty/cty"
|
"github.com/zclconf/go-cty/cty"
|
||||||
|
@ -94,13 +93,6 @@ func (t *ModuleVariableTransformer) transformSingle(g *Graph, parent, c *configs
|
||||||
var expr hcl.Expression
|
var expr hcl.Expression
|
||||||
if attr := content.Attributes[v.Name]; attr != nil {
|
if attr := content.Attributes[v.Name]; attr != nil {
|
||||||
expr = attr.Expr
|
expr = attr.Expr
|
||||||
} else {
|
|
||||||
// No expression provided for this variable, so we'll make a
|
|
||||||
// synthetic one using the variable's default value.
|
|
||||||
expr = &hclsyntax.LiteralValueExpr{
|
|
||||||
Val: v.Default,
|
|
||||||
SrcRange: v.DeclRange, // This is not exact, but close enough
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a plannable node, as the variable may expand
|
// Add a plannable node, as the variable may expand
|
||||||
|
|
Loading…
Reference in New Issue