2019-10-14 11:02:53 -04:00
package hcl2template
import (
Hcl2 input variables, local variables and functions (#8588)
Mainly redefine or reused what Terraform did.
* allow to used `variables`, `variable` and `local` blocks
* import the following functions and their docs from Terraform: abs, abspath, basename, base64decode, base64encode, bcrypt, can, ceil, chomp, chunklist, cidrhost, cidrnetmask, cidrsubnet, cidrsubnets, coalesce, coalescelist, compact, concat, contains, convert, csvdecode, dirname, distinct, element, file, fileexists, fileset, flatten, floor, format, formatdate, formatlist, indent, index, join, jsondecode, jsonencode, keys, length, log, lookup, lower, max, md5, merge, min, parseint, pathexpand, pow, range, reverse, rsadecrypt, setintersection, setproduct, setunion, sha1, sha256, sha512, signum, slice, sort, split, strrev, substr, timestamp, timeadd, title, trim, trimprefix, trimspace, trimsuffix, try, upper, urlencode, uuidv4, uuidv5, values, yamldecode, yamlencode, zipmap.
2020-02-06 05:49:21 -05:00
"fmt"
2020-10-30 10:38:29 -04:00
"log"
Hcl2 input variables, local variables and functions (#8588)
Mainly redefine or reused what Terraform did.
* allow to used `variables`, `variable` and `local` blocks
* import the following functions and their docs from Terraform: abs, abspath, basename, base64decode, base64encode, bcrypt, can, ceil, chomp, chunklist, cidrhost, cidrnetmask, cidrsubnet, cidrsubnets, coalesce, coalescelist, compact, concat, contains, convert, csvdecode, dirname, distinct, element, file, fileexists, fileset, flatten, floor, format, formatdate, formatlist, indent, index, join, jsondecode, jsonencode, keys, length, log, lookup, lower, max, md5, merge, min, parseint, pathexpand, pow, range, reverse, rsadecrypt, setintersection, setproduct, setunion, sha1, sha256, sha512, signum, slice, sort, split, strrev, substr, timestamp, timeadd, title, trim, trimprefix, trimspace, trimsuffix, try, upper, urlencode, uuidv4, uuidv5, values, yamldecode, yamlencode, zipmap.
2020-02-06 05:49:21 -05:00
"strings"
2020-10-30 07:26:22 -04:00
"unicode"
Hcl2 input variables, local variables and functions (#8588)
Mainly redefine or reused what Terraform did.
* allow to used `variables`, `variable` and `local` blocks
* import the following functions and their docs from Terraform: abs, abspath, basename, base64decode, base64encode, bcrypt, can, ceil, chomp, chunklist, cidrhost, cidrnetmask, cidrsubnet, cidrsubnets, coalesce, coalescelist, compact, concat, contains, convert, csvdecode, dirname, distinct, element, file, fileexists, fileset, flatten, floor, format, formatdate, formatlist, indent, index, join, jsondecode, jsonencode, keys, length, log, lookup, lower, max, md5, merge, min, parseint, pathexpand, pow, range, reverse, rsadecrypt, setintersection, setproduct, setunion, sha1, sha256, sha512, signum, slice, sort, split, strrev, substr, timestamp, timeadd, title, trim, trimprefix, trimspace, trimsuffix, try, upper, urlencode, uuidv4, uuidv5, values, yamldecode, yamlencode, zipmap.
2020-02-06 05:49:21 -05:00
2019-10-14 11:02:53 -04:00
"github.com/hashicorp/hcl/v2"
Hcl2 input variables, local variables and functions (#8588)
Mainly redefine or reused what Terraform did.
* allow to used `variables`, `variable` and `local` blocks
* import the following functions and their docs from Terraform: abs, abspath, basename, base64decode, base64encode, bcrypt, can, ceil, chomp, chunklist, cidrhost, cidrnetmask, cidrsubnet, cidrsubnets, coalesce, coalescelist, compact, concat, contains, convert, csvdecode, dirname, distinct, element, file, fileexists, fileset, flatten, floor, format, formatdate, formatlist, indent, index, join, jsondecode, jsonencode, keys, length, log, lookup, lower, max, md5, merge, min, parseint, pathexpand, pow, range, reverse, rsadecrypt, setintersection, setproduct, setunion, sha1, sha256, sha512, signum, slice, sort, split, strrev, substr, timestamp, timeadd, title, trim, trimprefix, trimspace, trimsuffix, try, upper, urlencode, uuidv4, uuidv5, values, yamldecode, yamlencode, zipmap.
2020-02-06 05:49:21 -05:00
"github.com/hashicorp/hcl/v2/ext/typeexpr"
2019-10-15 05:34:26 -04:00
"github.com/hashicorp/hcl/v2/gohcl"
Hcl2 input variables, local variables and functions (#8588)
Mainly redefine or reused what Terraform did.
* allow to used `variables`, `variable` and `local` blocks
* import the following functions and their docs from Terraform: abs, abspath, basename, base64decode, base64encode, bcrypt, can, ceil, chomp, chunklist, cidrhost, cidrnetmask, cidrsubnet, cidrsubnets, coalesce, coalescelist, compact, concat, contains, convert, csvdecode, dirname, distinct, element, file, fileexists, fileset, flatten, floor, format, formatdate, formatlist, indent, index, join, jsondecode, jsonencode, keys, length, log, lookup, lower, max, md5, merge, min, parseint, pathexpand, pow, range, reverse, rsadecrypt, setintersection, setproduct, setunion, sha1, sha256, sha512, signum, slice, sort, split, strrev, substr, timestamp, timeadd, title, trim, trimprefix, trimspace, trimsuffix, try, upper, urlencode, uuidv4, uuidv5, values, yamldecode, yamlencode, zipmap.
2020-02-06 05:49:21 -05:00
"github.com/hashicorp/hcl/v2/hclsyntax"
2020-10-30 07:26:22 -04:00
"github.com/hashicorp/packer/hcl2template/addrs"
Hcl2 input variables, local variables and functions (#8588)
Mainly redefine or reused what Terraform did.
* allow to used `variables`, `variable` and `local` blocks
* import the following functions and their docs from Terraform: abs, abspath, basename, base64decode, base64encode, bcrypt, can, ceil, chomp, chunklist, cidrhost, cidrnetmask, cidrsubnet, cidrsubnets, coalesce, coalescelist, compact, concat, contains, convert, csvdecode, dirname, distinct, element, file, fileexists, fileset, flatten, floor, format, formatdate, formatlist, indent, index, join, jsondecode, jsonencode, keys, length, log, lookup, lower, max, md5, merge, min, parseint, pathexpand, pow, range, reverse, rsadecrypt, setintersection, setproduct, setunion, sha1, sha256, sha512, signum, slice, sort, split, strrev, substr, timestamp, timeadd, title, trim, trimprefix, trimspace, trimsuffix, try, upper, urlencode, uuidv4, uuidv5, values, yamldecode, yamlencode, zipmap.
2020-02-06 05:49:21 -05:00
"github.com/zclconf/go-cty/cty"
"github.com/zclconf/go-cty/cty/convert"
2019-10-14 11:02:53 -04:00
)
2020-10-30 07:26:22 -04:00
// A consistent detail message for all "not a valid identifier" diagnostics.
const badIdentifierDetail = "A name must start with a letter or underscore and may contain only letters, digits, underscores, and dashes."
2020-10-27 05:03:36 -04:00
// Local represents a single entry from a "locals" block in a file.
2020-02-21 06:12:30 -05:00
// The "locals" block itself is not represented, because it serves only to
// provide context for us to interpret its contents.
2020-07-24 04:58:03 -04:00
type LocalBlock struct {
2020-02-21 06:12:30 -05:00
Name string
Expr hcl . Expression
2021-01-26 04:21:44 -05:00
// When Sensitive is set to true Packer will try its best to hide/obfuscate
// the variable from the output stream. By replacing the text.
Sensitive bool
2020-02-21 06:12:30 -05:00
}
2020-11-02 05:49:40 -05:00
// VariableAssignment represents a way a variable was set: the expression
// setting it and the value of that expression. It helps pinpoint were
// something was set in diagnostics.
type VariableAssignment struct {
// From tells were it was taken from, command/varfile/env/default
From string
Value cty . Value
Expr hcl . Expression
}
Hcl2 input variables, local variables and functions (#8588)
Mainly redefine or reused what Terraform did.
* allow to used `variables`, `variable` and `local` blocks
* import the following functions and their docs from Terraform: abs, abspath, basename, base64decode, base64encode, bcrypt, can, ceil, chomp, chunklist, cidrhost, cidrnetmask, cidrsubnet, cidrsubnets, coalesce, coalescelist, compact, concat, contains, convert, csvdecode, dirname, distinct, element, file, fileexists, fileset, flatten, floor, format, formatdate, formatlist, indent, index, join, jsondecode, jsonencode, keys, length, log, lookup, lower, max, md5, merge, min, parseint, pathexpand, pow, range, reverse, rsadecrypt, setintersection, setproduct, setunion, sha1, sha256, sha512, signum, slice, sort, split, strrev, substr, timestamp, timeadd, title, trim, trimprefix, trimspace, trimsuffix, try, upper, urlencode, uuidv4, uuidv5, values, yamldecode, yamlencode, zipmap.
2020-02-06 05:49:21 -05:00
type Variable struct {
2020-11-02 05:49:40 -05:00
// Values contains possible values for the variable; The last value set
// from these will be the one used. If none is set; an error will be
// returned by Value().
Values [ ] VariableAssignment
// Validations contains all variables validation rules to be applied to the
// used value. Only the used value - the last value from Values - is
// validated.
Validations [ ] * VariableValidation
2019-10-14 11:02:53 -04:00
Hcl2 input variables, local variables and functions (#8588)
Mainly redefine or reused what Terraform did.
* allow to used `variables`, `variable` and `local` blocks
* import the following functions and their docs from Terraform: abs, abspath, basename, base64decode, base64encode, bcrypt, can, ceil, chomp, chunklist, cidrhost, cidrnetmask, cidrsubnet, cidrsubnets, coalesce, coalescelist, compact, concat, contains, convert, csvdecode, dirname, distinct, element, file, fileexists, fileset, flatten, floor, format, formatdate, formatlist, indent, index, join, jsondecode, jsonencode, keys, length, log, lookup, lower, max, md5, merge, min, parseint, pathexpand, pow, range, reverse, rsadecrypt, setintersection, setproduct, setunion, sha1, sha256, sha512, signum, slice, sort, split, strrev, substr, timestamp, timeadd, title, trim, trimprefix, trimspace, trimsuffix, try, upper, urlencode, uuidv4, uuidv5, values, yamldecode, yamlencode, zipmap.
2020-02-06 05:49:21 -05:00
// Cty Type of the variable. If the default value or a collected value is
// not of this type nor can be converted to this type an error diagnostic
// will show up. This allows us to assume that values are valid later in
// code.
//
// When a default value - and no type - is passed in the variable
// declaration, the type of the default variable will be used. This will
// allow to ensure that users set this variable correctly.
Type cty . Type
2020-02-17 12:05:15 -05:00
// Common name of the variable
Name string
Hcl2 input variables, local variables and functions (#8588)
Mainly redefine or reused what Terraform did.
* allow to used `variables`, `variable` and `local` blocks
* import the following functions and their docs from Terraform: abs, abspath, basename, base64decode, base64encode, bcrypt, can, ceil, chomp, chunklist, cidrhost, cidrnetmask, cidrsubnet, cidrsubnets, coalesce, coalescelist, compact, concat, contains, convert, csvdecode, dirname, distinct, element, file, fileexists, fileset, flatten, floor, format, formatdate, formatlist, indent, index, join, jsondecode, jsonencode, keys, length, log, lookup, lower, max, md5, merge, min, parseint, pathexpand, pow, range, reverse, rsadecrypt, setintersection, setproduct, setunion, sha1, sha256, sha512, signum, slice, sort, split, strrev, substr, timestamp, timeadd, title, trim, trimprefix, trimspace, trimsuffix, try, upper, urlencode, uuidv4, uuidv5, values, yamldecode, yamlencode, zipmap.
2020-02-06 05:49:21 -05:00
// Description of the variable
Description string
// When Sensitive is set to true Packer will try it best to hide/obfuscate
// the variable from the output stream. By replacing the text.
Sensitive bool
2020-03-04 07:19:07 -05:00
Range hcl . Range
2019-10-14 11:02:53 -04:00
}
Hcl2 input variables, local variables and functions (#8588)
Mainly redefine or reused what Terraform did.
* allow to used `variables`, `variable` and `local` blocks
* import the following functions and their docs from Terraform: abs, abspath, basename, base64decode, base64encode, bcrypt, can, ceil, chomp, chunklist, cidrhost, cidrnetmask, cidrsubnet, cidrsubnets, coalesce, coalescelist, compact, concat, contains, convert, csvdecode, dirname, distinct, element, file, fileexists, fileset, flatten, floor, format, formatdate, formatlist, indent, index, join, jsondecode, jsonencode, keys, length, log, lookup, lower, max, md5, merge, min, parseint, pathexpand, pow, range, reverse, rsadecrypt, setintersection, setproduct, setunion, sha1, sha256, sha512, signum, slice, sort, split, strrev, substr, timestamp, timeadd, title, trim, trimprefix, trimspace, trimsuffix, try, upper, urlencode, uuidv4, uuidv5, values, yamldecode, yamlencode, zipmap.
2020-02-06 05:49:21 -05:00
func ( v * Variable ) GoString ( ) string {
2020-11-02 05:49:40 -05:00
b := & strings . Builder { }
fmt . Fprintf ( b , "{type:%s" , v . Type . GoString ( ) )
for _ , vv := range v . Values {
fmt . Fprintf ( b , ",%s:%s" , vv . From , vv . Value )
}
fmt . Fprintf ( b , "}" )
return b . String ( )
Hcl2 input variables, local variables and functions (#8588)
Mainly redefine or reused what Terraform did.
* allow to used `variables`, `variable` and `local` blocks
* import the following functions and their docs from Terraform: abs, abspath, basename, base64decode, base64encode, bcrypt, can, ceil, chomp, chunklist, cidrhost, cidrnetmask, cidrsubnet, cidrsubnets, coalesce, coalescelist, compact, concat, contains, convert, csvdecode, dirname, distinct, element, file, fileexists, fileset, flatten, floor, format, formatdate, formatlist, indent, index, join, jsondecode, jsonencode, keys, length, log, lookup, lower, max, md5, merge, min, parseint, pathexpand, pow, range, reverse, rsadecrypt, setintersection, setproduct, setunion, sha1, sha256, sha512, signum, slice, sort, split, strrev, substr, timestamp, timeadd, title, trim, trimprefix, trimspace, trimsuffix, try, upper, urlencode, uuidv4, uuidv5, values, yamldecode, yamlencode, zipmap.
2020-02-06 05:49:21 -05:00
}
2019-10-14 11:02:53 -04:00
2020-10-30 10:38:29 -04:00
// validateValue ensures that all of the configured custom validations for a
// variable value are passing.
2020-11-02 05:49:40 -05:00
func ( v * Variable ) validateValue ( val VariableAssignment ) ( diags hcl . Diagnostics ) {
2020-10-30 10:38:29 -04:00
if len ( v . Validations ) == 0 {
2021-02-15 06:25:45 -05:00
log . Printf ( "[TRACE] validateValue: not active for %s, so skipping" , v . Name )
2020-10-30 10:38:29 -04:00
return nil
}
hclCtx := & hcl . EvalContext {
Variables : map [ string ] cty . Value {
"var" : cty . ObjectVal ( map [ string ] cty . Value {
2020-11-02 05:49:40 -05:00
v . Name : val . Value ,
2020-10-30 10:38:29 -04:00
} ) ,
} ,
Functions : Functions ( "" ) ,
}
for _ , validation := range v . Validations {
const errInvalidCondition = "Invalid variable validation result"
result , moreDiags := validation . Condition . Value ( hclCtx )
diags = append ( diags , moreDiags ... )
if moreDiags . HasErrors ( ) {
log . Printf ( "[TRACE] evalVariableValidations: %s rule %s condition expression failed: %s" , v . Name , validation . DeclRange , moreDiags . Error ( ) )
}
if ! result . IsKnown ( ) {
log . Printf ( "[TRACE] evalVariableValidations: %s rule %s condition value is unknown, so skipping validation for now" , v . Name , validation . DeclRange )
continue // We'll wait until we've learned more, then.
}
if result . IsNull ( ) {
diags = append ( diags , & hcl . Diagnostic {
Severity : hcl . DiagError ,
Summary : errInvalidCondition ,
Detail : "Validation condition expression must return either true or false, not null." ,
Subject : validation . Condition . Range ( ) . Ptr ( ) ,
Expression : validation . Condition ,
EvalContext : hclCtx ,
} )
continue
}
var err error
result , err = convert . Convert ( result , cty . Bool )
if err != nil {
diags = append ( diags , & hcl . Diagnostic {
Severity : hcl . DiagError ,
Summary : errInvalidCondition ,
Detail : fmt . Sprintf ( "Invalid validation condition result value: %s." , err ) ,
Subject : validation . Condition . Range ( ) . Ptr ( ) ,
Expression : validation . Condition ,
EvalContext : hclCtx ,
} )
continue
}
if result . False ( ) {
2020-11-02 05:49:40 -05:00
subj := validation . DeclRange . Ptr ( )
if val . Expr != nil {
subj = val . Expr . Range ( ) . Ptr ( )
}
2020-10-30 10:38:29 -04:00
diags = append ( diags , & hcl . Diagnostic {
Severity : hcl . DiagError ,
2020-11-02 05:49:40 -05:00
Summary : fmt . Sprintf ( "Invalid value for %s variable" , val . From ) ,
2020-10-30 10:38:29 -04:00
Detail : fmt . Sprintf ( "%s\n\nThis was checked by the validation rule at %s." , validation . ErrorMessage , validation . DeclRange . String ( ) ) ,
2020-11-02 05:49:40 -05:00
Subject : subj ,
2020-10-30 10:38:29 -04:00
} )
}
}
return diags
}
2020-11-02 05:49:40 -05:00
// Value returns the last found value from the list of variable settings.
2021-03-30 14:58:26 -04:00
func ( v * Variable ) Value ( ) cty . Value {
2020-11-02 05:49:40 -05:00
if len ( v . Values ) == 0 {
2021-03-30 14:58:26 -04:00
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 {
2020-11-02 05:49:40 -05:00
Severity : hcl . DiagError ,
Summary : fmt . Sprintf ( "Unset variable %q" , v . Name ) ,
Detail : "A used variable must be set or have a default value; see " +
2021-01-14 17:38:28 -05:00
"https://packer.io/docs/templates/hcl_templates/syntax for " +
2020-11-02 05:49:40 -05:00
"details." ,
Context : v . Range . Ptr ( ) ,
} }
2019-10-14 11:02:53 -04:00
}
2021-03-30 14:58:26 -04:00
return v . validateValue ( v . Values [ len ( v . Values ) - 1 ] )
Hcl2 input variables, local variables and functions (#8588)
Mainly redefine or reused what Terraform did.
* allow to used `variables`, `variable` and `local` blocks
* import the following functions and their docs from Terraform: abs, abspath, basename, base64decode, base64encode, bcrypt, can, ceil, chomp, chunklist, cidrhost, cidrnetmask, cidrsubnet, cidrsubnets, coalesce, coalescelist, compact, concat, contains, convert, csvdecode, dirname, distinct, element, file, fileexists, fileset, flatten, floor, format, formatdate, formatlist, indent, index, join, jsondecode, jsonencode, keys, length, log, lookup, lower, max, md5, merge, min, parseint, pathexpand, pow, range, reverse, rsadecrypt, setintersection, setproduct, setunion, sha1, sha256, sha512, signum, slice, sort, split, strrev, substr, timestamp, timeadd, title, trim, trimprefix, trimspace, trimsuffix, try, upper, urlencode, uuidv4, uuidv5, values, yamldecode, yamlencode, zipmap.
2020-02-06 05:49:21 -05:00
}
type Variables map [ string ] * Variable
2019-10-14 11:02:53 -04:00
2020-09-01 09:27:01 -04:00
func ( variables Variables ) Keys ( ) [ ] string {
keys := make ( [ ] string , 0 , len ( variables ) )
for key := range variables {
keys = append ( keys , key )
}
return keys
}
2021-03-30 14:58:26 -04:00
func ( variables Variables ) Values ( ) map [ string ] cty . Value {
Hcl2 input variables, local variables and functions (#8588)
Mainly redefine or reused what Terraform did.
* allow to used `variables`, `variable` and `local` blocks
* import the following functions and their docs from Terraform: abs, abspath, basename, base64decode, base64encode, bcrypt, can, ceil, chomp, chunklist, cidrhost, cidrnetmask, cidrsubnet, cidrsubnets, coalesce, coalescelist, compact, concat, contains, convert, csvdecode, dirname, distinct, element, file, fileexists, fileset, flatten, floor, format, formatdate, formatlist, indent, index, join, jsondecode, jsonencode, keys, length, log, lookup, lower, max, md5, merge, min, parseint, pathexpand, pow, range, reverse, rsadecrypt, setintersection, setproduct, setunion, sha1, sha256, sha512, signum, slice, sort, split, strrev, substr, timestamp, timeadd, title, trim, trimprefix, trimspace, trimsuffix, try, upper, urlencode, uuidv4, uuidv5, values, yamldecode, yamlencode, zipmap.
2020-02-06 05:49:21 -05:00
res := map [ string ] cty . Value { }
for k , v := range variables {
2021-03-30 14:58:26 -04:00
value := v . Value ( )
2020-03-09 12:25:56 -04:00
res [ k ] = value
Hcl2 input variables, local variables and functions (#8588)
Mainly redefine or reused what Terraform did.
* allow to used `variables`, `variable` and `local` blocks
* import the following functions and their docs from Terraform: abs, abspath, basename, base64decode, base64encode, bcrypt, can, ceil, chomp, chunklist, cidrhost, cidrnetmask, cidrsubnet, cidrsubnets, coalesce, coalescelist, compact, concat, contains, convert, csvdecode, dirname, distinct, element, file, fileexists, fileset, flatten, floor, format, formatdate, formatlist, indent, index, join, jsondecode, jsonencode, keys, length, log, lookup, lower, max, md5, merge, min, parseint, pathexpand, pow, range, reverse, rsadecrypt, setintersection, setproduct, setunion, sha1, sha256, sha512, signum, slice, sort, split, strrev, substr, timestamp, timeadd, title, trim, trimprefix, trimspace, trimsuffix, try, upper, urlencode, uuidv4, uuidv5, values, yamldecode, yamlencode, zipmap.
2020-02-06 05:49:21 -05:00
}
2021-03-30 14:58:26 -04:00
return res
}
func ( variables Variables ) ValidateValues ( ) hcl . Diagnostics {
var diags hcl . Diagnostics
for _ , v := range variables {
diags = append ( diags , v . ValidateValue ( ) ... )
}
return diags
2019-10-14 11:02:53 -04:00
}
Hcl2 input variables, local variables and functions (#8588)
Mainly redefine or reused what Terraform did.
* allow to used `variables`, `variable` and `local` blocks
* import the following functions and their docs from Terraform: abs, abspath, basename, base64decode, base64encode, bcrypt, can, ceil, chomp, chunklist, cidrhost, cidrnetmask, cidrsubnet, cidrsubnets, coalesce, coalescelist, compact, concat, contains, convert, csvdecode, dirname, distinct, element, file, fileexists, fileset, flatten, floor, format, formatdate, formatlist, indent, index, join, jsondecode, jsonencode, keys, length, log, lookup, lower, max, md5, merge, min, parseint, pathexpand, pow, range, reverse, rsadecrypt, setintersection, setproduct, setunion, sha1, sha256, sha512, signum, slice, sort, split, strrev, substr, timestamp, timeadd, title, trim, trimprefix, trimspace, trimsuffix, try, upper, urlencode, uuidv4, uuidv5, values, yamldecode, yamlencode, zipmap.
2020-02-06 05:49:21 -05:00
2020-02-21 06:12:30 -05:00
// decodeVariable decodes a variable key and value into Variables
func ( variables * Variables ) decodeVariable ( key string , attr * hcl . Attribute , ectx * hcl . EvalContext ) hcl . Diagnostics {
var diags hcl . Diagnostics
Hcl2 input variables, local variables and functions (#8588)
Mainly redefine or reused what Terraform did.
* allow to used `variables`, `variable` and `local` blocks
* import the following functions and their docs from Terraform: abs, abspath, basename, base64decode, base64encode, bcrypt, can, ceil, chomp, chunklist, cidrhost, cidrnetmask, cidrsubnet, cidrsubnets, coalesce, coalescelist, compact, concat, contains, convert, csvdecode, dirname, distinct, element, file, fileexists, fileset, flatten, floor, format, formatdate, formatlist, indent, index, join, jsondecode, jsonencode, keys, length, log, lookup, lower, max, md5, merge, min, parseint, pathexpand, pow, range, reverse, rsadecrypt, setintersection, setproduct, setunion, sha1, sha256, sha512, signum, slice, sort, split, strrev, substr, timestamp, timeadd, title, trim, trimprefix, trimspace, trimsuffix, try, upper, urlencode, uuidv4, uuidv5, values, yamldecode, yamlencode, zipmap.
2020-02-06 05:49:21 -05:00
if ( * variables ) == nil {
( * variables ) = Variables { }
}
2020-02-21 06:12:30 -05:00
if _ , found := ( * variables ) [ key ] ; found {
diags = append ( diags , & hcl . Diagnostic {
Severity : hcl . DiagError ,
Summary : "Duplicate variable" ,
Detail : "Duplicate " + key + " variable definition found." ,
Subject : attr . NameRange . Ptr ( ) ,
} )
Hcl2 input variables, local variables and functions (#8588)
Mainly redefine or reused what Terraform did.
* allow to used `variables`, `variable` and `local` blocks
* import the following functions and their docs from Terraform: abs, abspath, basename, base64decode, base64encode, bcrypt, can, ceil, chomp, chunklist, cidrhost, cidrnetmask, cidrsubnet, cidrsubnets, coalesce, coalescelist, compact, concat, contains, convert, csvdecode, dirname, distinct, element, file, fileexists, fileset, flatten, floor, format, formatdate, formatlist, indent, index, join, jsondecode, jsonencode, keys, length, log, lookup, lower, max, md5, merge, min, parseint, pathexpand, pow, range, reverse, rsadecrypt, setintersection, setproduct, setunion, sha1, sha256, sha512, signum, slice, sort, split, strrev, substr, timestamp, timeadd, title, trim, trimprefix, trimspace, trimsuffix, try, upper, urlencode, uuidv4, uuidv5, values, yamldecode, yamlencode, zipmap.
2020-02-06 05:49:21 -05:00
return diags
}
2020-02-21 06:12:30 -05:00
value , moreDiags := attr . Expr . Value ( ectx )
diags = append ( diags , moreDiags ... )
if moreDiags . HasErrors ( ) {
return diags
}
( * variables ) [ key ] = & Variable {
2020-11-02 05:49:40 -05:00
Name : key ,
Values : [ ] VariableAssignment { {
From : "default" ,
Value : value ,
Expr : attr . Expr ,
} } ,
Type : value . Type ( ) ,
Range : attr . Range ,
Hcl2 input variables, local variables and functions (#8588)
Mainly redefine or reused what Terraform did.
* allow to used `variables`, `variable` and `local` blocks
* import the following functions and their docs from Terraform: abs, abspath, basename, base64decode, base64encode, bcrypt, can, ceil, chomp, chunklist, cidrhost, cidrnetmask, cidrsubnet, cidrsubnets, coalesce, coalescelist, compact, concat, contains, convert, csvdecode, dirname, distinct, element, file, fileexists, fileset, flatten, floor, format, formatdate, formatlist, indent, index, join, jsondecode, jsonencode, keys, length, log, lookup, lower, max, md5, merge, min, parseint, pathexpand, pow, range, reverse, rsadecrypt, setintersection, setproduct, setunion, sha1, sha256, sha512, signum, slice, sort, split, strrev, substr, timestamp, timeadd, title, trim, trimprefix, trimspace, trimsuffix, try, upper, urlencode, uuidv4, uuidv5, values, yamldecode, yamlencode, zipmap.
2020-02-06 05:49:21 -05:00
}
return diags
}
2020-10-30 07:26:22 -04:00
var variableBlockSchema = & hcl . BodySchema {
Attributes : [ ] hcl . AttributeSchema {
{
Name : "description" ,
} ,
{
Name : "default" ,
} ,
{
Name : "type" ,
} ,
{
Name : "sensitive" ,
} ,
} ,
Blocks : [ ] hcl . BlockHeaderSchema {
{
Type : "validation" ,
} ,
} ,
}
2021-01-26 04:21:44 -05:00
var localBlockSchema = & hcl . BodySchema {
Attributes : [ ] hcl . AttributeSchema {
{
Name : "expression" ,
} ,
{
Name : "sensitive" ,
} ,
} ,
}
func decodeLocalBlock ( block * hcl . Block , locals [ ] * LocalBlock ) ( * LocalBlock , hcl . Diagnostics ) {
name := block . Labels [ 0 ]
for _ , loc := range locals {
if loc . Name == name {
return nil , [ ] * hcl . Diagnostic { {
Severity : hcl . DiagError ,
Summary : "Duplicate variable" ,
Detail : "Duplicate " + block . Labels [ 0 ] + " variable definition found." ,
Context : block . DefRange . Ptr ( ) ,
} }
}
}
content , diags := block . Body . Content ( localBlockSchema )
if ! hclsyntax . ValidIdentifier ( name ) {
diags = append ( diags , & hcl . Diagnostic {
Severity : hcl . DiagError ,
Summary : "Invalid local name" ,
Detail : badIdentifierDetail ,
Subject : & block . LabelRanges [ 0 ] ,
} )
}
l := & LocalBlock {
Name : name ,
}
if attr , exists := content . Attributes [ "sensitive" ] ; exists {
valDiags := gohcl . DecodeExpression ( attr . Expr , nil , & l . Sensitive )
diags = append ( diags , valDiags ... )
}
if def , ok := content . Attributes [ "expression" ] ; ok {
l . Expr = def . Expr
}
return l , diags
}
2020-11-11 05:27:32 -05:00
// decodeVariableBlock decodes a "variable" block
// ectx is passed only in the evaluation of the default value.
2020-02-21 06:12:30 -05:00
func ( variables * Variables ) decodeVariableBlock ( block * hcl . Block , ectx * hcl . EvalContext ) hcl . Diagnostics {
Hcl2 input variables, local variables and functions (#8588)
Mainly redefine or reused what Terraform did.
* allow to used `variables`, `variable` and `local` blocks
* import the following functions and their docs from Terraform: abs, abspath, basename, base64decode, base64encode, bcrypt, can, ceil, chomp, chunklist, cidrhost, cidrnetmask, cidrsubnet, cidrsubnets, coalesce, coalescelist, compact, concat, contains, convert, csvdecode, dirname, distinct, element, file, fileexists, fileset, flatten, floor, format, formatdate, formatlist, indent, index, join, jsondecode, jsonencode, keys, length, log, lookup, lower, max, md5, merge, min, parseint, pathexpand, pow, range, reverse, rsadecrypt, setintersection, setproduct, setunion, sha1, sha256, sha512, signum, slice, sort, split, strrev, substr, timestamp, timeadd, title, trim, trimprefix, trimspace, trimsuffix, try, upper, urlencode, uuidv4, uuidv5, values, yamldecode, yamlencode, zipmap.
2020-02-06 05:49:21 -05:00
if ( * variables ) == nil {
( * variables ) = Variables { }
}
if _ , found := ( * variables ) [ block . Labels [ 0 ] ] ; found {
return [ ] * hcl . Diagnostic { {
Severity : hcl . DiagError ,
Summary : "Duplicate variable" ,
Detail : "Duplicate " + block . Labels [ 0 ] + " variable definition found." ,
Context : block . DefRange . Ptr ( ) ,
} }
}
2020-10-30 07:26:22 -04:00
name := block . Labels [ 0 ]
Hcl2 input variables, local variables and functions (#8588)
Mainly redefine or reused what Terraform did.
* allow to used `variables`, `variable` and `local` blocks
* import the following functions and their docs from Terraform: abs, abspath, basename, base64decode, base64encode, bcrypt, can, ceil, chomp, chunklist, cidrhost, cidrnetmask, cidrsubnet, cidrsubnets, coalesce, coalescelist, compact, concat, contains, convert, csvdecode, dirname, distinct, element, file, fileexists, fileset, flatten, floor, format, formatdate, formatlist, indent, index, join, jsondecode, jsonencode, keys, length, log, lookup, lower, max, md5, merge, min, parseint, pathexpand, pow, range, reverse, rsadecrypt, setintersection, setproduct, setunion, sha1, sha256, sha512, signum, slice, sort, split, strrev, substr, timestamp, timeadd, title, trim, trimprefix, trimspace, trimsuffix, try, upper, urlencode, uuidv4, uuidv5, values, yamldecode, yamlencode, zipmap.
2020-02-06 05:49:21 -05:00
2020-10-30 07:26:22 -04:00
content , diags := block . Body . Content ( variableBlockSchema )
if ! hclsyntax . ValidIdentifier ( name ) {
diags = append ( diags , & hcl . Diagnostic {
Severity : hcl . DiagError ,
Summary : "Invalid variable name" ,
Detail : badIdentifierDetail ,
Subject : & block . LabelRanges [ 0 ] ,
} )
Hcl2 input variables, local variables and functions (#8588)
Mainly redefine or reused what Terraform did.
* allow to used `variables`, `variable` and `local` blocks
* import the following functions and their docs from Terraform: abs, abspath, basename, base64decode, base64encode, bcrypt, can, ceil, chomp, chunklist, cidrhost, cidrnetmask, cidrsubnet, cidrsubnets, coalesce, coalescelist, compact, concat, contains, convert, csvdecode, dirname, distinct, element, file, fileexists, fileset, flatten, floor, format, formatdate, formatlist, indent, index, join, jsondecode, jsonencode, keys, length, log, lookup, lower, max, md5, merge, min, parseint, pathexpand, pow, range, reverse, rsadecrypt, setintersection, setproduct, setunion, sha1, sha256, sha512, signum, slice, sort, split, strrev, substr, timestamp, timeadd, title, trim, trimprefix, trimspace, trimsuffix, try, upper, urlencode, uuidv4, uuidv5, values, yamldecode, yamlencode, zipmap.
2020-02-06 05:49:21 -05:00
}
2020-10-30 07:26:22 -04:00
v := & Variable {
Name : name ,
Range : block . DefRange ,
Hcl2 input variables, local variables and functions (#8588)
Mainly redefine or reused what Terraform did.
* allow to used `variables`, `variable` and `local` blocks
* import the following functions and their docs from Terraform: abs, abspath, basename, base64decode, base64encode, bcrypt, can, ceil, chomp, chunklist, cidrhost, cidrnetmask, cidrsubnet, cidrsubnets, coalesce, coalescelist, compact, concat, contains, convert, csvdecode, dirname, distinct, element, file, fileexists, fileset, flatten, floor, format, formatdate, formatlist, indent, index, join, jsondecode, jsonencode, keys, length, log, lookup, lower, max, md5, merge, min, parseint, pathexpand, pow, range, reverse, rsadecrypt, setintersection, setproduct, setunion, sha1, sha256, sha512, signum, slice, sort, split, strrev, substr, timestamp, timeadd, title, trim, trimprefix, trimspace, trimsuffix, try, upper, urlencode, uuidv4, uuidv5, values, yamldecode, yamlencode, zipmap.
2020-02-06 05:49:21 -05:00
}
2020-10-30 07:26:22 -04:00
if attr , exists := content . Attributes [ "description" ] ; exists {
valDiags := gohcl . DecodeExpression ( attr . Expr , nil , & v . Description )
diags = append ( diags , valDiags ... )
}
Hcl2 input variables, local variables and functions (#8588)
Mainly redefine or reused what Terraform did.
* allow to used `variables`, `variable` and `local` blocks
* import the following functions and their docs from Terraform: abs, abspath, basename, base64decode, base64encode, bcrypt, can, ceil, chomp, chunklist, cidrhost, cidrnetmask, cidrsubnet, cidrsubnets, coalesce, coalescelist, compact, concat, contains, convert, csvdecode, dirname, distinct, element, file, fileexists, fileset, flatten, floor, format, formatdate, formatlist, indent, index, join, jsondecode, jsonencode, keys, length, log, lookup, lower, max, md5, merge, min, parseint, pathexpand, pow, range, reverse, rsadecrypt, setintersection, setproduct, setunion, sha1, sha256, sha512, signum, slice, sort, split, strrev, substr, timestamp, timeadd, title, trim, trimprefix, trimspace, trimsuffix, try, upper, urlencode, uuidv4, uuidv5, values, yamldecode, yamlencode, zipmap.
2020-02-06 05:49:21 -05:00
2020-10-30 07:26:22 -04:00
if t , ok := content . Attributes [ "type" ] ; ok {
Hcl2 input variables, local variables and functions (#8588)
Mainly redefine or reused what Terraform did.
* allow to used `variables`, `variable` and `local` blocks
* import the following functions and their docs from Terraform: abs, abspath, basename, base64decode, base64encode, bcrypt, can, ceil, chomp, chunklist, cidrhost, cidrnetmask, cidrsubnet, cidrsubnets, coalesce, coalescelist, compact, concat, contains, convert, csvdecode, dirname, distinct, element, file, fileexists, fileset, flatten, floor, format, formatdate, formatlist, indent, index, join, jsondecode, jsonencode, keys, length, log, lookup, lower, max, md5, merge, min, parseint, pathexpand, pow, range, reverse, rsadecrypt, setintersection, setproduct, setunion, sha1, sha256, sha512, signum, slice, sort, split, strrev, substr, timestamp, timeadd, title, trim, trimprefix, trimspace, trimsuffix, try, upper, urlencode, uuidv4, uuidv5, values, yamldecode, yamlencode, zipmap.
2020-02-06 05:49:21 -05:00
tp , moreDiags := typeexpr . Type ( t . Expr )
diags = append ( diags , moreDiags ... )
if moreDiags . HasErrors ( ) {
return diags
}
2020-10-30 07:26:22 -04:00
v . Type = tp
}
if attr , exists := content . Attributes [ "sensitive" ] ; exists {
valDiags := gohcl . DecodeExpression ( attr . Expr , nil , & v . Sensitive )
diags = append ( diags , valDiags ... )
Hcl2 input variables, local variables and functions (#8588)
Mainly redefine or reused what Terraform did.
* allow to used `variables`, `variable` and `local` blocks
* import the following functions and their docs from Terraform: abs, abspath, basename, base64decode, base64encode, bcrypt, can, ceil, chomp, chunklist, cidrhost, cidrnetmask, cidrsubnet, cidrsubnets, coalesce, coalescelist, compact, concat, contains, convert, csvdecode, dirname, distinct, element, file, fileexists, fileset, flatten, floor, format, formatdate, formatlist, indent, index, join, jsondecode, jsonencode, keys, length, log, lookup, lower, max, md5, merge, min, parseint, pathexpand, pow, range, reverse, rsadecrypt, setintersection, setproduct, setunion, sha1, sha256, sha512, signum, slice, sort, split, strrev, substr, timestamp, timeadd, title, trim, trimprefix, trimspace, trimsuffix, try, upper, urlencode, uuidv4, uuidv5, values, yamldecode, yamlencode, zipmap.
2020-02-06 05:49:21 -05:00
}
2020-10-30 07:26:22 -04:00
if def , ok := content . Attributes [ "default" ] ; ok {
Hcl2 input variables, local variables and functions (#8588)
Mainly redefine or reused what Terraform did.
* allow to used `variables`, `variable` and `local` blocks
* import the following functions and their docs from Terraform: abs, abspath, basename, base64decode, base64encode, bcrypt, can, ceil, chomp, chunklist, cidrhost, cidrnetmask, cidrsubnet, cidrsubnets, coalesce, coalescelist, compact, concat, contains, convert, csvdecode, dirname, distinct, element, file, fileexists, fileset, flatten, floor, format, formatdate, formatlist, indent, index, join, jsondecode, jsonencode, keys, length, log, lookup, lower, max, md5, merge, min, parseint, pathexpand, pow, range, reverse, rsadecrypt, setintersection, setproduct, setunion, sha1, sha256, sha512, signum, slice, sort, split, strrev, substr, timestamp, timeadd, title, trim, trimprefix, trimspace, trimsuffix, try, upper, urlencode, uuidv4, uuidv5, values, yamldecode, yamlencode, zipmap.
2020-02-06 05:49:21 -05:00
defaultValue , moreDiags := def . Expr . Value ( ectx )
diags = append ( diags , moreDiags ... )
if moreDiags . HasErrors ( ) {
return diags
}
2020-10-30 07:26:22 -04:00
if v . Type != cty . NilType {
Hcl2 input variables, local variables and functions (#8588)
Mainly redefine or reused what Terraform did.
* allow to used `variables`, `variable` and `local` blocks
* import the following functions and their docs from Terraform: abs, abspath, basename, base64decode, base64encode, bcrypt, can, ceil, chomp, chunklist, cidrhost, cidrnetmask, cidrsubnet, cidrsubnets, coalesce, coalescelist, compact, concat, contains, convert, csvdecode, dirname, distinct, element, file, fileexists, fileset, flatten, floor, format, formatdate, formatlist, indent, index, join, jsondecode, jsonencode, keys, length, log, lookup, lower, max, md5, merge, min, parseint, pathexpand, pow, range, reverse, rsadecrypt, setintersection, setproduct, setunion, sha1, sha256, sha512, signum, slice, sort, split, strrev, substr, timestamp, timeadd, title, trim, trimprefix, trimspace, trimsuffix, try, upper, urlencode, uuidv4, uuidv5, values, yamldecode, yamlencode, zipmap.
2020-02-06 05:49:21 -05:00
var err error
2020-10-30 07:26:22 -04:00
defaultValue , err = convert . Convert ( defaultValue , v . Type )
Hcl2 input variables, local variables and functions (#8588)
Mainly redefine or reused what Terraform did.
* allow to used `variables`, `variable` and `local` blocks
* import the following functions and their docs from Terraform: abs, abspath, basename, base64decode, base64encode, bcrypt, can, ceil, chomp, chunklist, cidrhost, cidrnetmask, cidrsubnet, cidrsubnets, coalesce, coalescelist, compact, concat, contains, convert, csvdecode, dirname, distinct, element, file, fileexists, fileset, flatten, floor, format, formatdate, formatlist, indent, index, join, jsondecode, jsonencode, keys, length, log, lookup, lower, max, md5, merge, min, parseint, pathexpand, pow, range, reverse, rsadecrypt, setintersection, setproduct, setunion, sha1, sha256, sha512, signum, slice, sort, split, strrev, substr, timestamp, timeadd, title, trim, trimprefix, trimspace, trimsuffix, try, upper, urlencode, uuidv4, uuidv5, values, yamldecode, yamlencode, zipmap.
2020-02-06 05:49:21 -05:00
if err != nil {
diags = append ( diags , & hcl . Diagnostic {
Severity : hcl . DiagError ,
Summary : "Invalid default value for variable" ,
Detail : fmt . Sprintf ( "This default value is not compatible with the variable's type constraint: %s." , err ) ,
Subject : def . Expr . Range ( ) . Ptr ( ) ,
} )
defaultValue = cty . DynamicVal
}
}
2020-11-02 05:49:40 -05:00
v . Values = append ( v . Values , VariableAssignment {
From : "default" ,
Value : defaultValue ,
Expr : def . Expr ,
} )
2020-03-06 09:12:26 -05:00
2020-08-27 05:54:06 -04:00
// It's possible no type attribute was assigned so lets make sure we
// have a valid type otherwise there could be issues parsing the value.
2020-10-30 07:26:22 -04:00
if v . Type == cty . NilType {
2020-11-02 05:49:40 -05:00
v . Type = defaultValue . Type ( )
2020-03-06 09:12:26 -05:00
}
Hcl2 input variables, local variables and functions (#8588)
Mainly redefine or reused what Terraform did.
* allow to used `variables`, `variable` and `local` blocks
* import the following functions and their docs from Terraform: abs, abspath, basename, base64decode, base64encode, bcrypt, can, ceil, chomp, chunklist, cidrhost, cidrnetmask, cidrsubnet, cidrsubnets, coalesce, coalescelist, compact, concat, contains, convert, csvdecode, dirname, distinct, element, file, fileexists, fileset, flatten, floor, format, formatdate, formatlist, indent, index, join, jsondecode, jsonencode, keys, length, log, lookup, lower, max, md5, merge, min, parseint, pathexpand, pow, range, reverse, rsadecrypt, setintersection, setproduct, setunion, sha1, sha256, sha512, signum, slice, sort, split, strrev, substr, timestamp, timeadd, title, trim, trimprefix, trimspace, trimsuffix, try, upper, urlencode, uuidv4, uuidv5, values, yamldecode, yamlencode, zipmap.
2020-02-06 05:49:21 -05:00
}
2020-10-30 07:26:22 -04:00
for _ , block := range content . Blocks {
switch block . Type {
case "validation" :
vv , moreDiags := decodeVariableValidationBlock ( v . Name , block )
diags = append ( diags , moreDiags ... )
v . Validations = append ( v . Validations , vv )
Hcl2 input variables, local variables and functions (#8588)
Mainly redefine or reused what Terraform did.
* allow to used `variables`, `variable` and `local` blocks
* import the following functions and their docs from Terraform: abs, abspath, basename, base64decode, base64encode, bcrypt, can, ceil, chomp, chunklist, cidrhost, cidrnetmask, cidrsubnet, cidrsubnets, coalesce, coalescelist, compact, concat, contains, convert, csvdecode, dirname, distinct, element, file, fileexists, fileset, flatten, floor, format, formatdate, formatlist, indent, index, join, jsondecode, jsonencode, keys, length, log, lookup, lower, max, md5, merge, min, parseint, pathexpand, pow, range, reverse, rsadecrypt, setintersection, setproduct, setunion, sha1, sha256, sha512, signum, slice, sort, split, strrev, substr, timestamp, timeadd, title, trim, trimprefix, trimspace, trimsuffix, try, upper, urlencode, uuidv4, uuidv5, values, yamldecode, yamlencode, zipmap.
2020-02-06 05:49:21 -05:00
}
}
2020-10-30 07:26:22 -04:00
( * variables ) [ name ] = v
Hcl2 input variables, local variables and functions (#8588)
Mainly redefine or reused what Terraform did.
* allow to used `variables`, `variable` and `local` blocks
* import the following functions and their docs from Terraform: abs, abspath, basename, base64decode, base64encode, bcrypt, can, ceil, chomp, chunklist, cidrhost, cidrnetmask, cidrsubnet, cidrsubnets, coalesce, coalescelist, compact, concat, contains, convert, csvdecode, dirname, distinct, element, file, fileexists, fileset, flatten, floor, format, formatdate, formatlist, indent, index, join, jsondecode, jsonencode, keys, length, log, lookup, lower, max, md5, merge, min, parseint, pathexpand, pow, range, reverse, rsadecrypt, setintersection, setproduct, setunion, sha1, sha256, sha512, signum, slice, sort, split, strrev, substr, timestamp, timeadd, title, trim, trimprefix, trimspace, trimsuffix, try, upper, urlencode, uuidv4, uuidv5, values, yamldecode, yamlencode, zipmap.
2020-02-06 05:49:21 -05:00
return diags
}
2020-10-30 07:26:22 -04:00
var variableValidationBlockSchema = & hcl . BodySchema {
Attributes : [ ] hcl . AttributeSchema {
{
Name : "condition" ,
Required : true ,
} ,
{
Name : "error_message" ,
Required : true ,
} ,
} ,
}
// VariableValidation represents a configuration-defined validation rule
// for a particular input variable, given as a "validation" block inside
// a "variable" block.
type VariableValidation struct {
// Condition is an expression that refers to the variable being tested and
// contains no other references. The expression must return true to
// indicate that the value is valid or false to indicate that it is
// invalid. If the expression produces an error, that's considered a bug in
// the block defining the validation rule, not an error in the caller.
Condition hcl . Expression
2020-11-04 07:13:45 -05:00
// ErrorMessage is one or more full sentences, which _should_ be in English
// for consistency with the rest of the error message output but can in
// practice be in any language as long as it ends with a period. The
// message should describe what is required for the condition to return
2020-10-30 07:26:22 -04:00
// true in a way that would make sense to a caller of the module.
ErrorMessage string
DeclRange hcl . Range
}
func decodeVariableValidationBlock ( varName string , block * hcl . Block ) ( * VariableValidation , hcl . Diagnostics ) {
var diags hcl . Diagnostics
vv := & VariableValidation {
DeclRange : block . DefRange ,
}
content , moreDiags := block . Body . Content ( variableValidationBlockSchema )
diags = append ( diags , moreDiags ... )
if attr , exists := content . Attributes [ "condition" ] ; exists {
vv . Condition = attr . Expr
// The validation condition must refer to the variable itself and
// nothing else; to ensure that the variable declaration can't create
// additional edges in the dependency graph.
goodRefs := 0
for _ , traversal := range vv . Condition . Variables ( ) {
ref , moreDiags := addrs . ParseRef ( traversal )
if ! moreDiags . HasErrors ( ) {
if addr , ok := ref . Subject . ( addrs . InputVariable ) ; ok {
if addr . Name == varName {
goodRefs ++
continue // Reference is valid
}
}
}
// If we fall out here then the reference is invalid.
diags = diags . Append ( & hcl . Diagnostic {
Severity : hcl . DiagError ,
Summary : "Invalid reference in variable validation" ,
Detail : fmt . Sprintf ( "The condition for variable %q can only refer to the variable itself, using var.%s." , varName , varName ) ,
Subject : traversal . SourceRange ( ) . Ptr ( ) ,
} )
}
if goodRefs < 1 {
diags = diags . Append ( & hcl . Diagnostic {
Severity : hcl . DiagError ,
Summary : "Invalid variable validation condition" ,
Detail : fmt . Sprintf ( "The condition for variable %q must refer to var.%s in order to test incoming values." , varName , varName ) ,
Subject : attr . Expr . Range ( ) . Ptr ( ) ,
} )
}
}
if attr , exists := content . Attributes [ "error_message" ] ; exists {
moreDiags := gohcl . DecodeExpression ( attr . Expr , nil , & vv . ErrorMessage )
diags = append ( diags , moreDiags ... )
if ! moreDiags . HasErrors ( ) {
const errSummary = "Invalid validation error message"
switch {
case vv . ErrorMessage == "" :
diags = diags . Append ( & hcl . Diagnostic {
Severity : hcl . DiagError ,
Summary : errSummary ,
Detail : "An empty string is not a valid nor useful error message." ,
Subject : attr . Expr . Range ( ) . Ptr ( ) ,
} )
case ! looksLikeSentences ( vv . ErrorMessage ) :
// Because we're going to include this string verbatim as part
2020-11-04 07:13:45 -05:00
// of a bigger error message written in our usual style, we'll
// require the given error message to conform to that. We might
// relax this in future if e.g. we start presenting these error
// messages in a different way, or if Packer starts supporting
// producing error messages in other human languages, etc. For
// pragmatism we also allow sentences ending with exclamation
// points, but we don't mention it explicitly here because
// that's not really consistent with the Packer UI writing
// style.
2020-10-30 07:26:22 -04:00
diags = diags . Append ( & hcl . Diagnostic {
Severity : hcl . DiagError ,
Summary : errSummary ,
2020-11-04 07:13:45 -05:00
Detail : "Validation error message must be at least one full sentence starting with an uppercase letter ( if the alphabet permits it ) and ending with a period or question mark." ,
2020-10-30 07:26:22 -04:00
Subject : attr . Expr . Range ( ) . Ptr ( ) ,
} )
}
}
}
return vv , diags
}
// looksLikeSentence is a simple heuristic that encourages writing error
// messages that will be presentable when included as part of a larger error
// diagnostic whose other text is written in the UI writing style.
//
// This is intentionally not a very strong validation since we're assuming that
// authors want to write good messages and might just need a nudge about
// Packer's specific style, rather than that they are going to try to work
// around these rules to write a lower-quality message.
func looksLikeSentences ( s string ) bool {
2020-11-11 05:27:32 -05:00
s = strings . TrimSpace ( s )
2020-10-30 07:26:22 -04:00
if len ( s ) < 1 {
return false
}
runes := [ ] rune ( s ) // HCL guarantees that all strings are valid UTF-8
first := runes [ 0 ]
last := runes [ len ( runes ) - 1 ]
2020-11-04 07:13:45 -05:00
// If the first rune is a letter then it must be an uppercase letter. To
// sorts of nudge people into writting sentences. For alphabets that don't
// have the notion of 'upper', this does nothing.
2020-10-30 07:26:22 -04:00
if unicode . IsLetter ( first ) && ! unicode . IsUpper ( first ) {
return false
}
// The string must be at least one full sentence, which implies having
// sentence-ending punctuation.
return last == '.' || last == '?' || last == '!'
}
Hcl2 input variables, local variables and functions (#8588)
Mainly redefine or reused what Terraform did.
* allow to used `variables`, `variable` and `local` blocks
* import the following functions and their docs from Terraform: abs, abspath, basename, base64decode, base64encode, bcrypt, can, ceil, chomp, chunklist, cidrhost, cidrnetmask, cidrsubnet, cidrsubnets, coalesce, coalescelist, compact, concat, contains, convert, csvdecode, dirname, distinct, element, file, fileexists, fileset, flatten, floor, format, formatdate, formatlist, indent, index, join, jsondecode, jsonencode, keys, length, log, lookup, lower, max, md5, merge, min, parseint, pathexpand, pow, range, reverse, rsadecrypt, setintersection, setproduct, setunion, sha1, sha256, sha512, signum, slice, sort, split, strrev, substr, timestamp, timeadd, title, trim, trimprefix, trimspace, trimsuffix, try, upper, urlencode, uuidv4, uuidv5, values, yamldecode, yamlencode, zipmap.
2020-02-06 05:49:21 -05:00
// Prefix your environment variables with VarEnvPrefix so that Packer can see
// them.
const VarEnvPrefix = "PKR_VAR_"
2020-03-09 11:16:59 -04:00
func ( cfg * PackerConfig ) collectInputVariableValues ( env [ ] string , files [ ] * hcl . File , argv map [ string ] string ) hcl . Diagnostics {
Hcl2 input variables, local variables and functions (#8588)
Mainly redefine or reused what Terraform did.
* allow to used `variables`, `variable` and `local` blocks
* import the following functions and their docs from Terraform: abs, abspath, basename, base64decode, base64encode, bcrypt, can, ceil, chomp, chunklist, cidrhost, cidrnetmask, cidrsubnet, cidrsubnets, coalesce, coalescelist, compact, concat, contains, convert, csvdecode, dirname, distinct, element, file, fileexists, fileset, flatten, floor, format, formatdate, formatlist, indent, index, join, jsondecode, jsonencode, keys, length, log, lookup, lower, max, md5, merge, min, parseint, pathexpand, pow, range, reverse, rsadecrypt, setintersection, setproduct, setunion, sha1, sha256, sha512, signum, slice, sort, split, strrev, substr, timestamp, timeadd, title, trim, trimprefix, trimspace, trimsuffix, try, upper, urlencode, uuidv4, uuidv5, values, yamldecode, yamlencode, zipmap.
2020-02-06 05:49:21 -05:00
var diags hcl . Diagnostics
2020-03-09 11:16:59 -04:00
variables := cfg . InputVariables
Hcl2 input variables, local variables and functions (#8588)
Mainly redefine or reused what Terraform did.
* allow to used `variables`, `variable` and `local` blocks
* import the following functions and their docs from Terraform: abs, abspath, basename, base64decode, base64encode, bcrypt, can, ceil, chomp, chunklist, cidrhost, cidrnetmask, cidrsubnet, cidrsubnets, coalesce, coalescelist, compact, concat, contains, convert, csvdecode, dirname, distinct, element, file, fileexists, fileset, flatten, floor, format, formatdate, formatlist, indent, index, join, jsondecode, jsonencode, keys, length, log, lookup, lower, max, md5, merge, min, parseint, pathexpand, pow, range, reverse, rsadecrypt, setintersection, setproduct, setunion, sha1, sha256, sha512, signum, slice, sort, split, strrev, substr, timestamp, timeadd, title, trim, trimprefix, trimspace, trimsuffix, try, upper, urlencode, uuidv4, uuidv5, values, yamldecode, yamlencode, zipmap.
2020-02-06 05:49:21 -05:00
for _ , raw := range env {
if ! strings . HasPrefix ( raw , VarEnvPrefix ) {
continue
}
raw = raw [ len ( VarEnvPrefix ) : ] // trim the prefix
eq := strings . Index ( raw , "=" )
if eq == - 1 {
// Seems invalid, so we'll ignore it.
continue
}
name := raw [ : eq ]
value := raw [ eq + 1 : ]
variable , found := variables [ name ]
if ! found {
// this variable was not defined in the hcl files, let's skip it !
continue
}
fakeFilename := fmt . Sprintf ( "<value for var.%s from env>" , name )
2020-03-06 09:12:26 -05:00
expr , moreDiags := expressionFromVariableDefinition ( fakeFilename , value , variable . Type )
Hcl2 input variables, local variables and functions (#8588)
Mainly redefine or reused what Terraform did.
* allow to used `variables`, `variable` and `local` blocks
* import the following functions and their docs from Terraform: abs, abspath, basename, base64decode, base64encode, bcrypt, can, ceil, chomp, chunklist, cidrhost, cidrnetmask, cidrsubnet, cidrsubnets, coalesce, coalescelist, compact, concat, contains, convert, csvdecode, dirname, distinct, element, file, fileexists, fileset, flatten, floor, format, formatdate, formatlist, indent, index, join, jsondecode, jsonencode, keys, length, log, lookup, lower, max, md5, merge, min, parseint, pathexpand, pow, range, reverse, rsadecrypt, setintersection, setproduct, setunion, sha1, sha256, sha512, signum, slice, sort, split, strrev, substr, timestamp, timeadd, title, trim, trimprefix, trimspace, trimsuffix, try, upper, urlencode, uuidv4, uuidv5, values, yamldecode, yamlencode, zipmap.
2020-02-06 05:49:21 -05:00
diags = append ( diags , moreDiags ... )
if moreDiags . HasErrors ( ) {
continue
}
2020-03-03 05:15:56 -05:00
Hcl2 input variables, local variables and functions (#8588)
Mainly redefine or reused what Terraform did.
* allow to used `variables`, `variable` and `local` blocks
* import the following functions and their docs from Terraform: abs, abspath, basename, base64decode, base64encode, bcrypt, can, ceil, chomp, chunklist, cidrhost, cidrnetmask, cidrsubnet, cidrsubnets, coalesce, coalescelist, compact, concat, contains, convert, csvdecode, dirname, distinct, element, file, fileexists, fileset, flatten, floor, format, formatdate, formatlist, indent, index, join, jsondecode, jsonencode, keys, length, log, lookup, lower, max, md5, merge, min, parseint, pathexpand, pow, range, reverse, rsadecrypt, setintersection, setproduct, setunion, sha1, sha256, sha512, signum, slice, sort, split, strrev, substr, timestamp, timeadd, title, trim, trimprefix, trimspace, trimsuffix, try, upper, urlencode, uuidv4, uuidv5, values, yamldecode, yamlencode, zipmap.
2020-02-06 05:49:21 -05:00
val , valDiags := expr . Value ( nil )
diags = append ( diags , valDiags ... )
if variable . Type != cty . NilType {
var err error
val , err = convert . Convert ( val , variable . Type )
if err != nil {
diags = append ( diags , & hcl . Diagnostic {
Severity : hcl . DiagError ,
Summary : "Invalid value for variable" ,
Detail : fmt . Sprintf ( "The value for %s is not compatible with the variable's type constraint: %s." , name , err ) ,
Subject : expr . Range ( ) . Ptr ( ) ,
} )
val = cty . DynamicVal
}
}
2020-11-02 05:49:40 -05:00
variable . Values = append ( variable . Values , VariableAssignment {
From : "env" ,
Value : val ,
Expr : expr ,
} )
Hcl2 input variables, local variables and functions (#8588)
Mainly redefine or reused what Terraform did.
* allow to used `variables`, `variable` and `local` blocks
* import the following functions and their docs from Terraform: abs, abspath, basename, base64decode, base64encode, bcrypt, can, ceil, chomp, chunklist, cidrhost, cidrnetmask, cidrsubnet, cidrsubnets, coalesce, coalescelist, compact, concat, contains, convert, csvdecode, dirname, distinct, element, file, fileexists, fileset, flatten, floor, format, formatdate, formatlist, indent, index, join, jsondecode, jsonencode, keys, length, log, lookup, lower, max, md5, merge, min, parseint, pathexpand, pow, range, reverse, rsadecrypt, setintersection, setproduct, setunion, sha1, sha256, sha512, signum, slice, sort, split, strrev, substr, timestamp, timeadd, title, trim, trimprefix, trimspace, trimsuffix, try, upper, urlencode, uuidv4, uuidv5, values, yamldecode, yamlencode, zipmap.
2020-02-06 05:49:21 -05:00
}
// files will contain files found in the folder then files passed as
// arguments.
for _ , file := range files {
// Before we do our real decode, we'll probe to see if there are any
// blocks of type "variable" in this body, since it's a common mistake
// for new users to put variable declarations in pkrvars rather than
// variable value definitions, and otherwise our error message for that
// case is not so helpful.
{
content , _ , _ := file . Body . PartialContent ( & hcl . BodySchema {
Blocks : [ ] hcl . BlockHeaderSchema {
{
Type : "variable" ,
LabelNames : [ ] string { "name" } ,
} ,
} ,
} )
for _ , block := range content . Blocks {
name := block . Labels [ 0 ]
2020-10-30 10:38:29 -04:00
diags = append ( diags , & hcl . Diagnostic {
Hcl2 input variables, local variables and functions (#8588)
Mainly redefine or reused what Terraform did.
* allow to used `variables`, `variable` and `local` blocks
* import the following functions and their docs from Terraform: abs, abspath, basename, base64decode, base64encode, bcrypt, can, ceil, chomp, chunklist, cidrhost, cidrnetmask, cidrsubnet, cidrsubnets, coalesce, coalescelist, compact, concat, contains, convert, csvdecode, dirname, distinct, element, file, fileexists, fileset, flatten, floor, format, formatdate, formatlist, indent, index, join, jsondecode, jsonencode, keys, length, log, lookup, lower, max, md5, merge, min, parseint, pathexpand, pow, range, reverse, rsadecrypt, setintersection, setproduct, setunion, sha1, sha256, sha512, signum, slice, sort, split, strrev, substr, timestamp, timeadd, title, trim, trimprefix, trimspace, trimsuffix, try, upper, urlencode, uuidv4, uuidv5, values, yamldecode, yamlencode, zipmap.
2020-02-06 05:49:21 -05:00
Severity : hcl . DiagError ,
Summary : "Variable declaration in a .pkrvar file" ,
Detail : fmt . Sprintf ( "A .pkrvar file is used to assign " +
"values to variables that have already been declared " +
"in .pkr files, not to declare new variables. To " +
"declare variable %q, place this block in one of your" +
2020-03-12 08:40:25 -04:00
" .pkr files, such as variables.pkr.hcl\n\nTo set a " +
Hcl2 input variables, local variables and functions (#8588)
Mainly redefine or reused what Terraform did.
* allow to used `variables`, `variable` and `local` blocks
* import the following functions and their docs from Terraform: abs, abspath, basename, base64decode, base64encode, bcrypt, can, ceil, chomp, chunklist, cidrhost, cidrnetmask, cidrsubnet, cidrsubnets, coalesce, coalescelist, compact, concat, contains, convert, csvdecode, dirname, distinct, element, file, fileexists, fileset, flatten, floor, format, formatdate, formatlist, indent, index, join, jsondecode, jsonencode, keys, length, log, lookup, lower, max, md5, merge, min, parseint, pathexpand, pow, range, reverse, rsadecrypt, setintersection, setproduct, setunion, sha1, sha256, sha512, signum, slice, sort, split, strrev, substr, timestamp, timeadd, title, trim, trimprefix, trimspace, trimsuffix, try, upper, urlencode, uuidv4, uuidv5, values, yamldecode, yamlencode, zipmap.
2020-02-06 05:49:21 -05:00
"value for this variable in %s, use the definition " +
"syntax instead:\n %s = <value>" ,
name , block . TypeRange . Filename , name ) ,
Subject : & block . TypeRange ,
} )
}
if diags . HasErrors ( ) {
// If we already found problems then JustAttributes below will find
// the same problems with less-helpful messages, so we'll bail for
// now to let the user focus on the immediate problem.
return diags
}
}
attrs , moreDiags := file . Body . JustAttributes ( )
diags = append ( diags , moreDiags ... )
for name , attr := range attrs {
variable , found := variables [ name ]
if ! found {
2020-03-09 11:16:59 -04:00
sev := hcl . DiagWarning
if cfg . ValidationOptions . Strict {
sev = hcl . DiagError
}
diags = append ( diags , & hcl . Diagnostic {
Severity : sev ,
Summary : "Undefined variable" ,
Detail : fmt . Sprintf ( "A %q variable was set but was " +
"not found in known variables. To declare " +
2020-03-12 08:40:25 -04:00
"variable %q, place this block in one of your " +
2020-03-09 11:16:59 -04:00
".pkr files, such as variables.pkr.hcl" ,
name , name ) ,
Context : attr . Range . Ptr ( ) ,
} )
Hcl2 input variables, local variables and functions (#8588)
Mainly redefine or reused what Terraform did.
* allow to used `variables`, `variable` and `local` blocks
* import the following functions and their docs from Terraform: abs, abspath, basename, base64decode, base64encode, bcrypt, can, ceil, chomp, chunklist, cidrhost, cidrnetmask, cidrsubnet, cidrsubnets, coalesce, coalescelist, compact, concat, contains, convert, csvdecode, dirname, distinct, element, file, fileexists, fileset, flatten, floor, format, formatdate, formatlist, indent, index, join, jsondecode, jsonencode, keys, length, log, lookup, lower, max, md5, merge, min, parseint, pathexpand, pow, range, reverse, rsadecrypt, setintersection, setproduct, setunion, sha1, sha256, sha512, signum, slice, sort, split, strrev, substr, timestamp, timeadd, title, trim, trimprefix, trimspace, trimsuffix, try, upper, urlencode, uuidv4, uuidv5, values, yamldecode, yamlencode, zipmap.
2020-02-06 05:49:21 -05:00
continue
}
val , moreDiags := attr . Expr . Value ( nil )
diags = append ( diags , moreDiags ... )
if variable . Type != cty . NilType {
var err error
val , err = convert . Convert ( val , variable . Type )
if err != nil {
diags = append ( diags , & hcl . Diagnostic {
Severity : hcl . DiagError ,
Summary : "Invalid value for variable" ,
Detail : fmt . Sprintf ( "The value for %s is not compatible with the variable's type constraint: %s." , name , err ) ,
Subject : attr . Expr . Range ( ) . Ptr ( ) ,
} )
val = cty . DynamicVal
}
}
2020-11-02 05:49:40 -05:00
variable . Values = append ( variable . Values , VariableAssignment {
From : "varfile" ,
Value : val ,
Expr : attr . Expr ,
} )
Hcl2 input variables, local variables and functions (#8588)
Mainly redefine or reused what Terraform did.
* allow to used `variables`, `variable` and `local` blocks
* import the following functions and their docs from Terraform: abs, abspath, basename, base64decode, base64encode, bcrypt, can, ceil, chomp, chunklist, cidrhost, cidrnetmask, cidrsubnet, cidrsubnets, coalesce, coalescelist, compact, concat, contains, convert, csvdecode, dirname, distinct, element, file, fileexists, fileset, flatten, floor, format, formatdate, formatlist, indent, index, join, jsondecode, jsonencode, keys, length, log, lookup, lower, max, md5, merge, min, parseint, pathexpand, pow, range, reverse, rsadecrypt, setintersection, setproduct, setunion, sha1, sha256, sha512, signum, slice, sort, split, strrev, substr, timestamp, timeadd, title, trim, trimprefix, trimspace, trimsuffix, try, upper, urlencode, uuidv4, uuidv5, values, yamldecode, yamlencode, zipmap.
2020-02-06 05:49:21 -05:00
}
}
// Finally we process values given explicitly on the command line.
for name , value := range argv {
variable , found := variables [ name ]
if ! found {
diags = append ( diags , & hcl . Diagnostic {
2020-03-09 11:16:59 -04:00
Severity : hcl . DiagError ,
Summary : "Undefined -var variable" ,
Hcl2 input variables, local variables and functions (#8588)
Mainly redefine or reused what Terraform did.
* allow to used `variables`, `variable` and `local` blocks
* import the following functions and their docs from Terraform: abs, abspath, basename, base64decode, base64encode, bcrypt, can, ceil, chomp, chunklist, cidrhost, cidrnetmask, cidrsubnet, cidrsubnets, coalesce, coalescelist, compact, concat, contains, convert, csvdecode, dirname, distinct, element, file, fileexists, fileset, flatten, floor, format, formatdate, formatlist, indent, index, join, jsondecode, jsonencode, keys, length, log, lookup, lower, max, md5, merge, min, parseint, pathexpand, pow, range, reverse, rsadecrypt, setintersection, setproduct, setunion, sha1, sha256, sha512, signum, slice, sort, split, strrev, substr, timestamp, timeadd, title, trim, trimprefix, trimspace, trimsuffix, try, upper, urlencode, uuidv4, uuidv5, values, yamldecode, yamlencode, zipmap.
2020-02-06 05:49:21 -05:00
Detail : fmt . Sprintf ( "A %q variable was passed in the command " +
2020-03-12 08:40:25 -04:00
"line but was not found in known variables. " +
Hcl2 input variables, local variables and functions (#8588)
Mainly redefine or reused what Terraform did.
* allow to used `variables`, `variable` and `local` blocks
* import the following functions and their docs from Terraform: abs, abspath, basename, base64decode, base64encode, bcrypt, can, ceil, chomp, chunklist, cidrhost, cidrnetmask, cidrsubnet, cidrsubnets, coalesce, coalescelist, compact, concat, contains, convert, csvdecode, dirname, distinct, element, file, fileexists, fileset, flatten, floor, format, formatdate, formatlist, indent, index, join, jsondecode, jsonencode, keys, length, log, lookup, lower, max, md5, merge, min, parseint, pathexpand, pow, range, reverse, rsadecrypt, setintersection, setproduct, setunion, sha1, sha256, sha512, signum, slice, sort, split, strrev, substr, timestamp, timeadd, title, trim, trimprefix, trimspace, trimsuffix, try, upper, urlencode, uuidv4, uuidv5, values, yamldecode, yamlencode, zipmap.
2020-02-06 05:49:21 -05:00
"To declare variable %q, place this block in one of your" +
2020-03-12 08:40:25 -04:00
" .pkr files, such as variables.pkr.hcl" ,
Hcl2 input variables, local variables and functions (#8588)
Mainly redefine or reused what Terraform did.
* allow to used `variables`, `variable` and `local` blocks
* import the following functions and their docs from Terraform: abs, abspath, basename, base64decode, base64encode, bcrypt, can, ceil, chomp, chunklist, cidrhost, cidrnetmask, cidrsubnet, cidrsubnets, coalesce, coalescelist, compact, concat, contains, convert, csvdecode, dirname, distinct, element, file, fileexists, fileset, flatten, floor, format, formatdate, formatlist, indent, index, join, jsondecode, jsonencode, keys, length, log, lookup, lower, max, md5, merge, min, parseint, pathexpand, pow, range, reverse, rsadecrypt, setintersection, setproduct, setunion, sha1, sha256, sha512, signum, slice, sort, split, strrev, substr, timestamp, timeadd, title, trim, trimprefix, trimspace, trimsuffix, try, upper, urlencode, uuidv4, uuidv5, values, yamldecode, yamlencode, zipmap.
2020-02-06 05:49:21 -05:00
name , name ) ,
} )
continue
}
fakeFilename := fmt . Sprintf ( "<value for var.%s from arguments>" , name )
2020-03-06 09:12:26 -05:00
expr , moreDiags := expressionFromVariableDefinition ( fakeFilename , value , variable . Type )
Hcl2 input variables, local variables and functions (#8588)
Mainly redefine or reused what Terraform did.
* allow to used `variables`, `variable` and `local` blocks
* import the following functions and their docs from Terraform: abs, abspath, basename, base64decode, base64encode, bcrypt, can, ceil, chomp, chunklist, cidrhost, cidrnetmask, cidrsubnet, cidrsubnets, coalesce, coalescelist, compact, concat, contains, convert, csvdecode, dirname, distinct, element, file, fileexists, fileset, flatten, floor, format, formatdate, formatlist, indent, index, join, jsondecode, jsonencode, keys, length, log, lookup, lower, max, md5, merge, min, parseint, pathexpand, pow, range, reverse, rsadecrypt, setintersection, setproduct, setunion, sha1, sha256, sha512, signum, slice, sort, split, strrev, substr, timestamp, timeadd, title, trim, trimprefix, trimspace, trimsuffix, try, upper, urlencode, uuidv4, uuidv5, values, yamldecode, yamlencode, zipmap.
2020-02-06 05:49:21 -05:00
diags = append ( diags , moreDiags ... )
if moreDiags . HasErrors ( ) {
continue
}
2020-03-06 09:12:26 -05:00
Hcl2 input variables, local variables and functions (#8588)
Mainly redefine or reused what Terraform did.
* allow to used `variables`, `variable` and `local` blocks
* import the following functions and their docs from Terraform: abs, abspath, basename, base64decode, base64encode, bcrypt, can, ceil, chomp, chunklist, cidrhost, cidrnetmask, cidrsubnet, cidrsubnets, coalesce, coalescelist, compact, concat, contains, convert, csvdecode, dirname, distinct, element, file, fileexists, fileset, flatten, floor, format, formatdate, formatlist, indent, index, join, jsondecode, jsonencode, keys, length, log, lookup, lower, max, md5, merge, min, parseint, pathexpand, pow, range, reverse, rsadecrypt, setintersection, setproduct, setunion, sha1, sha256, sha512, signum, slice, sort, split, strrev, substr, timestamp, timeadd, title, trim, trimprefix, trimspace, trimsuffix, try, upper, urlencode, uuidv4, uuidv5, values, yamldecode, yamlencode, zipmap.
2020-02-06 05:49:21 -05:00
val , valDiags := expr . Value ( nil )
diags = append ( diags , valDiags ... )
if variable . Type != cty . NilType {
var err error
val , err = convert . Convert ( val , variable . Type )
if err != nil {
diags = append ( diags , & hcl . Diagnostic {
Severity : hcl . DiagError ,
Summary : "Invalid argument value for -var variable" ,
Detail : fmt . Sprintf ( "The received arg value for %s is not compatible with the variable's type constraint: %s." , name , err ) ,
Subject : expr . Range ( ) . Ptr ( ) ,
} )
val = cty . DynamicVal
}
}
2020-11-02 05:49:40 -05:00
variable . Values = append ( variable . Values , VariableAssignment {
From : "cmd" ,
Value : val ,
Expr : expr ,
} )
Hcl2 input variables, local variables and functions (#8588)
Mainly redefine or reused what Terraform did.
* allow to used `variables`, `variable` and `local` blocks
* import the following functions and their docs from Terraform: abs, abspath, basename, base64decode, base64encode, bcrypt, can, ceil, chomp, chunklist, cidrhost, cidrnetmask, cidrsubnet, cidrsubnets, coalesce, coalescelist, compact, concat, contains, convert, csvdecode, dirname, distinct, element, file, fileexists, fileset, flatten, floor, format, formatdate, formatlist, indent, index, join, jsondecode, jsonencode, keys, length, log, lookup, lower, max, md5, merge, min, parseint, pathexpand, pow, range, reverse, rsadecrypt, setintersection, setproduct, setunion, sha1, sha256, sha512, signum, slice, sort, split, strrev, substr, timestamp, timeadd, title, trim, trimprefix, trimspace, trimsuffix, try, upper, urlencode, uuidv4, uuidv5, values, yamldecode, yamlencode, zipmap.
2020-02-06 05:49:21 -05:00
}
return diags
}
2020-03-06 09:12:26 -05:00
// expressionFromVariableDefinition creates an hclsyntax.Expression that is capable of evaluating the specified value for a given cty.Type.
// The specified filename is to identify the source of where value originated from in the diagnostics report, if there is an error.
func expressionFromVariableDefinition ( filename string , value string , variableType cty . Type ) ( hclsyntax . Expression , hcl . Diagnostics ) {
switch variableType {
2020-09-02 10:26:50 -04:00
case cty . String , cty . Number , cty . NilType :
// when the type is nil (not set in a variable block) we default to
// interpreting everything as a string literal.
2020-03-06 09:12:26 -05:00
return & hclsyntax . LiteralValueExpr { Val : cty . StringVal ( value ) } , nil
default :
return hclsyntax . ParseExpression ( [ ] byte ( value ) , filename , hcl . Pos { Line : 1 , Column : 1 } )
}
}