Merge pull request #8620 from hashicorp/b-var-input

command: more resilient HCL check for inputs
This commit is contained in:
Mitchell Hashimoto 2016-09-02 10:02:23 -07:00 committed by GitHub
commit fad1ce9915
7 changed files with 81 additions and 30 deletions

View File

@ -129,6 +129,14 @@ func (v *FlagStringSlice) Set(raw string) error {
return nil return nil
} }
var (
// This regular expression is how we check if a value for a variable
// matches what we'd expect a rich HCL value to be. For example: {
// definitely signals a map. If a value DOESN'T match this, we return
// it as a raw string.
varFlagHCLRe = regexp.MustCompile(`^["\[\{]`)
)
// parseVarFlagAsHCL parses the value of a single variable as would have been specified // parseVarFlagAsHCL parses the value of a single variable as would have been specified
// on the command line via -var or in an environment variable named TF_VAR_x, where x is // on the command line via -var or in an environment variable named TF_VAR_x, where x is
// the name of the variable. In order to get around the restriction of HCL requiring a // the name of the variable. In order to get around the restriction of HCL requiring a
@ -143,13 +151,23 @@ func parseVarFlagAsHCL(input string) (string, interface{}, error) {
parsed, err := hcl.Parse(input) parsed, err := hcl.Parse(input)
if err != nil { if err != nil {
value := input[idx+1:]
// If it didn't parse as HCL, we check if it doesn't match our
// whitelist of TF-accepted HCL types for inputs. If not, then
// we let it through as a raw string.
trimmed := strings.TrimSpace(value)
if !varFlagHCLRe.MatchString(trimmed) {
return probablyName, value, nil
}
// This covers flags of the form `foo=bar` which is not valid HCL // This covers flags of the form `foo=bar` which is not valid HCL
// At this point, probablyName is actually the name, and the remainder // At this point, probablyName is actually the name, and the remainder
// of the expression after the equals sign is the value. // of the expression after the equals sign is the value.
if regexp.MustCompile(`Unknown token: \d+:\d+ IDENT`).Match([]byte(err.Error())) { if regexp.MustCompile(`Unknown token: \d+:\d+ IDENT`).Match([]byte(err.Error())) {
value := input[idx+1:]
return probablyName, value, nil return probablyName, value, nil
} }
return "", nil, fmt.Errorf("Cannot parse value for variable %s (%q) as valid HCL: %s", probablyName, input, err) return "", nil, fmt.Errorf("Cannot parse value for variable %s (%q) as valid HCL: %s", probablyName, input, err)
} }

View File

@ -47,6 +47,12 @@ func TestFlagStringKV(t *testing.T) {
nil, nil,
true, true,
}, },
{
"key=/path",
map[string]string{"key": "/path"},
false,
},
} }
for _, tc := range cases { for _, tc := range cases {
@ -127,6 +133,18 @@ func TestFlagTypedKV(t *testing.T) {
nil, nil,
true, true,
}, },
{
"key=/path",
map[string]interface{}{"key": "/path"},
false,
},
{
"key=1234.dkr.ecr.us-east-1.amazonaws.com/proj:abcdef",
map[string]interface{}{"key": "1234.dkr.ecr.us-east-1.amazonaws.com/proj:abcdef"},
false,
},
} }
for _, tc := range cases { for _, tc := range cases {

View File

@ -103,6 +103,16 @@ variable "ami" {
description = "the AMI to use" description = "the AMI to use"
} }
``` ```
This would be equivalent to the following json:
``` json
{
"variable": {
"ami": {
"description": "the AMI to use"
}
}
}
```
## Thanks ## Thanks

View File

@ -215,3 +215,4 @@ func (c *CommentGroup) Pos() token.Pos {
//------------------------------------------------------------------- //-------------------------------------------------------------------
func (o *ObjectKey) GoString() string { return fmt.Sprintf("*%#v", *o) } func (o *ObjectKey) GoString() string { return fmt.Sprintf("*%#v", *o) }
func (o *ObjectList) GoString() string { return fmt.Sprintf("*%#v", *o) }

View File

@ -224,6 +224,11 @@ func (s *Scanner) Scan() token.Token {
func (s *Scanner) scanComment(ch rune) { func (s *Scanner) scanComment(ch rune) {
// single line comments // single line comments
if ch == '#' || (ch == '/' && s.peek() != '*') { if ch == '#' || (ch == '/' && s.peek() != '*') {
if ch == '/' && s.peek() != '/' {
s.err("expected '/' for comment")
return
}
ch = s.next() ch = s.next()
for ch != '\n' && ch >= 0 && ch != eof { for ch != '\n' && ch >= 0 && ch != eof {
ch = s.next() ch = s.next()

View File

@ -296,7 +296,7 @@ func (s *Scanner) scanString() {
return return
} }
if ch == '"' && braces == 0 { if ch == '"' {
break break
} }

53
vendor/vendor.json vendored
View File

@ -1168,70 +1168,70 @@
"revision": "7e3c02b30806fa5779d3bdfc152ce4c6f40e7b38" "revision": "7e3c02b30806fa5779d3bdfc152ce4c6f40e7b38"
}, },
{ {
"checksumSHA1": "8E3sekKdBZ38W0UFwONoZb0txbE=", "checksumSHA1": "fa9G5tEr4oJJc3vtgn/B0NWZXfA=",
"path": "github.com/hashicorp/hcl", "path": "github.com/hashicorp/hcl",
"revision": "bc40da04e8303cb7406e9ed1a2b742d636c5d960", "revision": "99df0eb941dd8ddbc83d3f3605a34f6a686ac85e",
"revisionTime": "2016-08-22T16:37:30Z" "revisionTime": "2016-09-02T16:52:19Z"
}, },
{ {
"checksumSHA1": "IxyvRpCFeoJBGl2obLKJV7RCGjg=", "checksumSHA1": "67DfevLBglV52Y2eAuhFc/xQni0=",
"path": "github.com/hashicorp/hcl/hcl/ast", "path": "github.com/hashicorp/hcl/hcl/ast",
"revision": "d8c773c4cba11b11539e3d45f93daeaa5dcf1fa1", "revision": "99df0eb941dd8ddbc83d3f3605a34f6a686ac85e",
"revisionTime": "2016-07-11T23:17:52Z" "revisionTime": "2016-09-02T16:52:19Z"
}, },
{ {
"checksumSHA1": "5HVecyfmcTm6OTffEi6LGayQf5M=", "checksumSHA1": "5HVecyfmcTm6OTffEi6LGayQf5M=",
"path": "github.com/hashicorp/hcl/hcl/fmtcmd", "path": "github.com/hashicorp/hcl/hcl/fmtcmd",
"revision": "d8c773c4cba11b11539e3d45f93daeaa5dcf1fa1", "revision": "99df0eb941dd8ddbc83d3f3605a34f6a686ac85e",
"revisionTime": "2016-07-11T23:17:52Z" "revisionTime": "2016-09-02T16:52:19Z"
}, },
{ {
"checksumSHA1": "l2oQxBsZRwn6eZjf+whXr8c9+8c=", "checksumSHA1": "l2oQxBsZRwn6eZjf+whXr8c9+8c=",
"path": "github.com/hashicorp/hcl/hcl/parser", "path": "github.com/hashicorp/hcl/hcl/parser",
"revision": "d8c773c4cba11b11539e3d45f93daeaa5dcf1fa1", "revision": "99df0eb941dd8ddbc83d3f3605a34f6a686ac85e",
"revisionTime": "2016-07-11T23:17:52Z" "revisionTime": "2016-09-02T16:52:19Z"
}, },
{ {
"checksumSHA1": "CSmwxPOTz7GSpnWPF9aGkbVeR64=", "checksumSHA1": "CSmwxPOTz7GSpnWPF9aGkbVeR64=",
"path": "github.com/hashicorp/hcl/hcl/printer", "path": "github.com/hashicorp/hcl/hcl/printer",
"revision": "d8c773c4cba11b11539e3d45f93daeaa5dcf1fa1", "revision": "99df0eb941dd8ddbc83d3f3605a34f6a686ac85e",
"revisionTime": "2016-07-11T23:17:52Z" "revisionTime": "2016-09-02T16:52:19Z"
}, },
{ {
"checksumSHA1": "vjhDQVlgHhdxml1V8/cj0vOe+j8=", "checksumSHA1": "lgR7PSAZ0RtvAc9OCtCnNsF/x8g=",
"path": "github.com/hashicorp/hcl/hcl/scanner", "path": "github.com/hashicorp/hcl/hcl/scanner",
"revision": "d8c773c4cba11b11539e3d45f93daeaa5dcf1fa1", "revision": "99df0eb941dd8ddbc83d3f3605a34f6a686ac85e",
"revisionTime": "2016-07-11T23:17:52Z" "revisionTime": "2016-09-02T16:52:19Z"
}, },
{ {
"checksumSHA1": "JlZmnzqdmFFyb1+2afLyR3BOE/8=", "checksumSHA1": "JlZmnzqdmFFyb1+2afLyR3BOE/8=",
"path": "github.com/hashicorp/hcl/hcl/strconv", "path": "github.com/hashicorp/hcl/hcl/strconv",
"revision": "d8c773c4cba11b11539e3d45f93daeaa5dcf1fa1", "revision": "99df0eb941dd8ddbc83d3f3605a34f6a686ac85e",
"revisionTime": "2016-07-11T23:17:52Z" "revisionTime": "2016-09-02T16:52:19Z"
}, },
{ {
"checksumSHA1": "c6yprzj06ASwCo18TtbbNNBHljA=", "checksumSHA1": "c6yprzj06ASwCo18TtbbNNBHljA=",
"path": "github.com/hashicorp/hcl/hcl/token", "path": "github.com/hashicorp/hcl/hcl/token",
"revision": "d8c773c4cba11b11539e3d45f93daeaa5dcf1fa1", "revision": "99df0eb941dd8ddbc83d3f3605a34f6a686ac85e",
"revisionTime": "2016-07-11T23:17:52Z" "revisionTime": "2016-09-02T16:52:19Z"
}, },
{ {
"checksumSHA1": "jQ45CCc1ed/nlV7bbSnx6z72q1M=", "checksumSHA1": "jQ45CCc1ed/nlV7bbSnx6z72q1M=",
"path": "github.com/hashicorp/hcl/json/parser", "path": "github.com/hashicorp/hcl/json/parser",
"revision": "d8c773c4cba11b11539e3d45f93daeaa5dcf1fa1", "revision": "99df0eb941dd8ddbc83d3f3605a34f6a686ac85e",
"revisionTime": "2016-07-11T23:17:52Z" "revisionTime": "2016-09-02T16:52:19Z"
}, },
{ {
"checksumSHA1": "S1e0F9ZKSnqgOLfjDTYazRL28tA=", "checksumSHA1": "YdvFsNOMSWMLnY6fcliWQa0O5Fw=",
"path": "github.com/hashicorp/hcl/json/scanner", "path": "github.com/hashicorp/hcl/json/scanner",
"revision": "d8c773c4cba11b11539e3d45f93daeaa5dcf1fa1", "revision": "99df0eb941dd8ddbc83d3f3605a34f6a686ac85e",
"revisionTime": "2016-07-11T23:17:52Z" "revisionTime": "2016-09-02T16:52:19Z"
}, },
{ {
"checksumSHA1": "fNlXQCQEnb+B3k5UDL/r15xtSJY=", "checksumSHA1": "fNlXQCQEnb+B3k5UDL/r15xtSJY=",
"path": "github.com/hashicorp/hcl/json/token", "path": "github.com/hashicorp/hcl/json/token",
"revision": "d8c773c4cba11b11539e3d45f93daeaa5dcf1fa1", "revision": "99df0eb941dd8ddbc83d3f3605a34f6a686ac85e",
"revisionTime": "2016-07-11T23:17:52Z" "revisionTime": "2016-09-02T16:52:19Z"
}, },
{ {
"checksumSHA1": "OrnLOmhc0FcHYs02wtbu1siIsnM=", "checksumSHA1": "OrnLOmhc0FcHYs02wtbu1siIsnM=",
@ -1260,7 +1260,6 @@
}, },
{ {
"checksumSHA1": "jq2E42bB0kwKaerHXwJslUea4eM=", "checksumSHA1": "jq2E42bB0kwKaerHXwJslUea4eM=",
"origin": "github.com/hashicorp/terraform/vendor/github.com/henrikhodne/go-librato/librato",
"path": "github.com/henrikhodne/go-librato/librato", "path": "github.com/henrikhodne/go-librato/librato",
"revision": "6e9aa4b1a8a8b735ad14b4f1c9542ef183e82dc2", "revision": "6e9aa4b1a8a8b735ad14b4f1c9542ef183e82dc2",
"revisionTime": "2016-08-11T07:26:26Z" "revisionTime": "2016-08-11T07:26:26Z"