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"
"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
}
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 {
// CmdValue, VarfileValue, EnvValue, DefaultValue are possible values of
// the variable; The first value set from these will be the one used. If
// none is set; an error will be returned if a user tries to use the
// Variable.
CmdValue cty . Value
VarfileValue cty . Value
EnvValue cty . Value
DefaultValue cty . Value
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-10-30 07:26:22 -04:00
Validations [ ] * VariableValidation
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-06-05 11:23:54 -04:00
return fmt . Sprintf ( "{Type:%s,CmdValue:%s,VarfileValue:%s,EnvValue:%s,DefaultValue:%s}" ,
v . Type . GoString ( ) ,
PrintableCtyValue ( v . CmdValue ) ,
PrintableCtyValue ( v . VarfileValue ) ,
PrintableCtyValue ( v . EnvValue ) ,
PrintableCtyValue ( v . DefaultValue ) ,
)
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
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 ) Value ( ) ( cty . Value , * hcl . Diagnostic ) {
for _ , value := range [ ] cty . Value {
v . CmdValue ,
v . VarfileValue ,
v . EnvValue ,
v . DefaultValue ,
} {
2020-03-09 12:25:56 -04:00
if value != cty . NilVal {
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 value , nil
2019-10-14 11:02:53 -04:00
}
}
2020-02-17 11:15:52 -05:00
2020-08-27 05:54:06 -04:00
return cty . UnknownVal ( v . Type ) , & 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 ,
2020-02-17 12:05:15 -05:00
Summary : fmt . Sprintf ( "Unset variable %q" , v . Name ) ,
2020-02-17 11:15:52 -05:00
Detail : "A used variable must be set or have a default value; see " +
2020-04-01 18:54:21 -04:00
"https://packer.io/docs/configuration/from-1.5/syntax for " +
2020-03-09 12:25:56 -04:00
"details." ,
2020-03-04 07:19:07 -05:00
Context : v . 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
}
}
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
}
2020-03-09 12:25:56 -04:00
func ( variables Variables ) Values ( ) ( map [ string ] cty . Value , 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
res := map [ string ] cty . Value { }
2020-03-09 12:25:56 -04:00
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
for k , v := range variables {
2020-03-09 12:25:56 -04:00
value , diag := v . Value ( )
if diag != nil {
diags = append ( diags , diag )
}
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
}
2020-03-09 12:25:56 -04:00
return res , 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-03-04 06:30:01 -05:00
Name : key ,
2020-02-21 06:12:30 -05:00
DefaultValue : value ,
Type : value . Type ( ) ,
2020-03-04 07:19:07 -05:00
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" ,
} ,
} ,
}
2020-02-21 06:12:30 -05:00
// decodeVariableBlock decodes a "variables" section the way packer 1 used to
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-10-30 07:26:22 -04:00
v . DefaultValue = defaultValue
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 {
v . Type = v . 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
// ErrorMessage is one or more full sentences, which would need to 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
// 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
// of a bigger error message written in our usual style in
// English, 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
// Terraform 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 Terraform UI
// writing style.
diags = diags . Append ( & hcl . Diagnostic {
Severity : hcl . DiagError ,
Summary : errSummary ,
Detail : "Validation error message must be at least one full English sentence starting with an uppercase letter and ending with a period or question mark." ,
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 {
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 ]
// If the first rune is a letter then it must be an uppercase letter.
// (This will only see the first rune in a multi-rune combining sequence,
// but the first rune is generally the letter if any are, and if not then
// we'll just ignore it because we're primarily expecting English messages
// right now anyway, for consistency with all of Terraform's other output.)
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
}
}
variable . EnvValue = val
}
// 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 ]
diags = diags . Append ( & hcl . Diagnostic {
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
}
}
variable . VarfileValue = val
}
}
// 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
}
}
variable . CmdValue = val
}
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 } )
}
}