mirror of
https://github.com/opentofu/opentofu.git
synced 2024-12-25 16:31:10 -06:00
ff4ea042c2
The existing "type" argument allows specifying a type constraint that allows for some basic validation, but often there are more constraints on a variable value than just its type. This new feature (requiring an experiment opt-in for now, while we refine it) allows specifying arbitrary validation rules for any variable which can then cause custom error messages to be returned when a caller provides an inappropriate value. variable "example" { validation { condition = var.example != "nope" error_message = "Example value must not be \"nope\"." } } The core parts of this are designed to do as little new work as possible when no validations are specified, and thus the main new checking codepath here can therefore only run when the experiment is enabled in order to permit having validations.
65 lines
1.6 KiB
Go
65 lines
1.6 KiB
Go
package terraform
|
|
|
|
import (
|
|
"github.com/hashicorp/terraform/addrs"
|
|
"github.com/hashicorp/terraform/configs"
|
|
"github.com/hashicorp/terraform/dag"
|
|
)
|
|
|
|
// NodeRootVariable represents a root variable input.
|
|
type NodeRootVariable struct {
|
|
Addr addrs.InputVariable
|
|
Config *configs.Variable
|
|
}
|
|
|
|
var (
|
|
_ GraphNodeSubPath = (*NodeRootVariable)(nil)
|
|
_ GraphNodeReferenceable = (*NodeRootVariable)(nil)
|
|
_ dag.GraphNodeDotter = (*NodeApplyableModuleVariable)(nil)
|
|
)
|
|
|
|
func (n *NodeRootVariable) Name() string {
|
|
return n.Addr.String()
|
|
}
|
|
|
|
// GraphNodeSubPath
|
|
func (n *NodeRootVariable) Path() addrs.ModuleInstance {
|
|
return addrs.RootModuleInstance
|
|
}
|
|
|
|
// GraphNodeReferenceable
|
|
func (n *NodeRootVariable) ReferenceableAddrs() []addrs.Referenceable {
|
|
return []addrs.Referenceable{n.Addr}
|
|
}
|
|
|
|
// GraphNodeEvalable
|
|
func (n *NodeRootVariable) EvalTree() EvalNode {
|
|
// We don't actually need to _evaluate_ a root module variable, because
|
|
// its value is always constant and already stashed away in our EvalContext.
|
|
// However, we might need to run some user-defined validation rules against
|
|
// the value.
|
|
|
|
if n.Config == nil || len(n.Config.Validations) == 0 {
|
|
return &EvalSequence{} // nothing to do
|
|
}
|
|
|
|
return &evalVariableValidations{
|
|
Addr: addrs.RootModuleInstance.InputVariable(n.Addr.Name),
|
|
Config: n.Config,
|
|
Expr: nil, // not set for root module variables
|
|
|
|
IgnoreDiagnostics: false,
|
|
}
|
|
}
|
|
|
|
// dag.GraphNodeDotter impl.
|
|
func (n *NodeRootVariable) DotNode(name string, opts *dag.DotOpts) *dag.DotNode {
|
|
return &dag.DotNode{
|
|
Name: name,
|
|
Attrs: map[string]string{
|
|
"label": n.Name(),
|
|
"shape": "note",
|
|
},
|
|
}
|
|
}
|