From 0a2b5de67fa980b4224963235cd1a8fcbe3a4c51 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Thu, 1 Sep 2016 20:13:36 -0700 Subject: [PATCH 1/2] command: more resilient HCL check for inputs --- command/flag_kv.go | 20 +++++++++++++++++++- command/flag_kv_test.go | 21 +++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/command/flag_kv.go b/command/flag_kv.go index b39aa1cd8..f93eb8b81 100644 --- a/command/flag_kv.go +++ b/command/flag_kv.go @@ -129,6 +129,14 @@ func (v *FlagStringSlice) Set(raw string) error { 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 // 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 @@ -143,13 +151,23 @@ func parseVarFlagAsHCL(input string) (string, interface{}, error) { parsed, err := hcl.Parse(input) 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 // At this point, probablyName is actually the name, and the remainder // of the expression after the equals sign is the value. if regexp.MustCompile(`Unknown token: \d+:\d+ IDENT`).Match([]byte(err.Error())) { - value := input[idx+1:] return probablyName, value, nil } + return "", nil, fmt.Errorf("Cannot parse value for variable %s (%q) as valid HCL: %s", probablyName, input, err) } diff --git a/command/flag_kv_test.go b/command/flag_kv_test.go index 000915e61..dff174b47 100644 --- a/command/flag_kv_test.go +++ b/command/flag_kv_test.go @@ -47,6 +47,12 @@ func TestFlagStringKV(t *testing.T) { nil, true, }, + + { + "key=/path", + map[string]string{"key": "/path"}, + false, + }, } for _, tc := range cases { @@ -127,6 +133,21 @@ func TestFlagTypedKV(t *testing.T) { nil, true, }, + + /* + TODO: wait for HCL merge + { + "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 { From c84f699158258c7fb472c4d7aed089f8a3cab755 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 2 Sep 2016 09:58:05 -0700 Subject: [PATCH 2/2] update HCL vendor --- command/flag_kv_test.go | 13 ++--- vendor/github.com/hashicorp/hcl/README.md | 10 ++++ .../github.com/hashicorp/hcl/hcl/ast/ast.go | 3 +- .../hashicorp/hcl/hcl/scanner/scanner.go | 5 ++ .../hashicorp/hcl/json/scanner/scanner.go | 2 +- vendor/vendor.json | 53 +++++++++---------- 6 files changed, 49 insertions(+), 37 deletions(-) diff --git a/command/flag_kv_test.go b/command/flag_kv_test.go index dff174b47..7144ca8e8 100644 --- a/command/flag_kv_test.go +++ b/command/flag_kv_test.go @@ -134,14 +134,11 @@ func TestFlagTypedKV(t *testing.T) { true, }, - /* - TODO: wait for HCL merge - { - "key=/path", - map[string]interface{}{"key": "/path"}, - false, - }, - */ + { + "key=/path", + map[string]interface{}{"key": "/path"}, + false, + }, { "key=1234.dkr.ecr.us-east-1.amazonaws.com/proj:abcdef", diff --git a/vendor/github.com/hashicorp/hcl/README.md b/vendor/github.com/hashicorp/hcl/README.md index e292d5999..c8223326d 100644 --- a/vendor/github.com/hashicorp/hcl/README.md +++ b/vendor/github.com/hashicorp/hcl/README.md @@ -103,6 +103,16 @@ variable "ami" { description = "the AMI to use" } ``` +This would be equivalent to the following json: +``` json +{ + "variable": { + "ami": { + "description": "the AMI to use" + } + } +} +``` ## Thanks diff --git a/vendor/github.com/hashicorp/hcl/hcl/ast/ast.go b/vendor/github.com/hashicorp/hcl/hcl/ast/ast.go index 692ac24e2..ea3734f09 100644 --- a/vendor/github.com/hashicorp/hcl/hcl/ast/ast.go +++ b/vendor/github.com/hashicorp/hcl/hcl/ast/ast.go @@ -214,4 +214,5 @@ func (c *CommentGroup) Pos() token.Pos { // GoStringer //------------------------------------------------------------------- -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) } diff --git a/vendor/github.com/hashicorp/hcl/hcl/scanner/scanner.go b/vendor/github.com/hashicorp/hcl/hcl/scanner/scanner.go index b20416539..0735d95e0 100644 --- a/vendor/github.com/hashicorp/hcl/hcl/scanner/scanner.go +++ b/vendor/github.com/hashicorp/hcl/hcl/scanner/scanner.go @@ -224,6 +224,11 @@ func (s *Scanner) Scan() token.Token { func (s *Scanner) scanComment(ch rune) { // single line comments if ch == '#' || (ch == '/' && s.peek() != '*') { + if ch == '/' && s.peek() != '/' { + s.err("expected '/' for comment") + return + } + ch = s.next() for ch != '\n' && ch >= 0 && ch != eof { ch = s.next() diff --git a/vendor/github.com/hashicorp/hcl/json/scanner/scanner.go b/vendor/github.com/hashicorp/hcl/json/scanner/scanner.go index 477f71ff3..dd5c72bb3 100644 --- a/vendor/github.com/hashicorp/hcl/json/scanner/scanner.go +++ b/vendor/github.com/hashicorp/hcl/json/scanner/scanner.go @@ -296,7 +296,7 @@ func (s *Scanner) scanString() { return } - if ch == '"' && braces == 0 { + if ch == '"' { break } diff --git a/vendor/vendor.json b/vendor/vendor.json index 93971ec86..f11a6c710 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -1168,70 +1168,70 @@ "revision": "7e3c02b30806fa5779d3bdfc152ce4c6f40e7b38" }, { - "checksumSHA1": "8E3sekKdBZ38W0UFwONoZb0txbE=", + "checksumSHA1": "fa9G5tEr4oJJc3vtgn/B0NWZXfA=", "path": "github.com/hashicorp/hcl", - "revision": "bc40da04e8303cb7406e9ed1a2b742d636c5d960", - "revisionTime": "2016-08-22T16:37:30Z" + "revision": "99df0eb941dd8ddbc83d3f3605a34f6a686ac85e", + "revisionTime": "2016-09-02T16:52:19Z" }, { - "checksumSHA1": "IxyvRpCFeoJBGl2obLKJV7RCGjg=", + "checksumSHA1": "67DfevLBglV52Y2eAuhFc/xQni0=", "path": "github.com/hashicorp/hcl/hcl/ast", - "revision": "d8c773c4cba11b11539e3d45f93daeaa5dcf1fa1", - "revisionTime": "2016-07-11T23:17:52Z" + "revision": "99df0eb941dd8ddbc83d3f3605a34f6a686ac85e", + "revisionTime": "2016-09-02T16:52:19Z" }, { "checksumSHA1": "5HVecyfmcTm6OTffEi6LGayQf5M=", "path": "github.com/hashicorp/hcl/hcl/fmtcmd", - "revision": "d8c773c4cba11b11539e3d45f93daeaa5dcf1fa1", - "revisionTime": "2016-07-11T23:17:52Z" + "revision": "99df0eb941dd8ddbc83d3f3605a34f6a686ac85e", + "revisionTime": "2016-09-02T16:52:19Z" }, { "checksumSHA1": "l2oQxBsZRwn6eZjf+whXr8c9+8c=", "path": "github.com/hashicorp/hcl/hcl/parser", - "revision": "d8c773c4cba11b11539e3d45f93daeaa5dcf1fa1", - "revisionTime": "2016-07-11T23:17:52Z" + "revision": "99df0eb941dd8ddbc83d3f3605a34f6a686ac85e", + "revisionTime": "2016-09-02T16:52:19Z" }, { "checksumSHA1": "CSmwxPOTz7GSpnWPF9aGkbVeR64=", "path": "github.com/hashicorp/hcl/hcl/printer", - "revision": "d8c773c4cba11b11539e3d45f93daeaa5dcf1fa1", - "revisionTime": "2016-07-11T23:17:52Z" + "revision": "99df0eb941dd8ddbc83d3f3605a34f6a686ac85e", + "revisionTime": "2016-09-02T16:52:19Z" }, { - "checksumSHA1": "vjhDQVlgHhdxml1V8/cj0vOe+j8=", + "checksumSHA1": "lgR7PSAZ0RtvAc9OCtCnNsF/x8g=", "path": "github.com/hashicorp/hcl/hcl/scanner", - "revision": "d8c773c4cba11b11539e3d45f93daeaa5dcf1fa1", - "revisionTime": "2016-07-11T23:17:52Z" + "revision": "99df0eb941dd8ddbc83d3f3605a34f6a686ac85e", + "revisionTime": "2016-09-02T16:52:19Z" }, { "checksumSHA1": "JlZmnzqdmFFyb1+2afLyR3BOE/8=", "path": "github.com/hashicorp/hcl/hcl/strconv", - "revision": "d8c773c4cba11b11539e3d45f93daeaa5dcf1fa1", - "revisionTime": "2016-07-11T23:17:52Z" + "revision": "99df0eb941dd8ddbc83d3f3605a34f6a686ac85e", + "revisionTime": "2016-09-02T16:52:19Z" }, { "checksumSHA1": "c6yprzj06ASwCo18TtbbNNBHljA=", "path": "github.com/hashicorp/hcl/hcl/token", - "revision": "d8c773c4cba11b11539e3d45f93daeaa5dcf1fa1", - "revisionTime": "2016-07-11T23:17:52Z" + "revision": "99df0eb941dd8ddbc83d3f3605a34f6a686ac85e", + "revisionTime": "2016-09-02T16:52:19Z" }, { "checksumSHA1": "jQ45CCc1ed/nlV7bbSnx6z72q1M=", "path": "github.com/hashicorp/hcl/json/parser", - "revision": "d8c773c4cba11b11539e3d45f93daeaa5dcf1fa1", - "revisionTime": "2016-07-11T23:17:52Z" + "revision": "99df0eb941dd8ddbc83d3f3605a34f6a686ac85e", + "revisionTime": "2016-09-02T16:52:19Z" }, { - "checksumSHA1": "S1e0F9ZKSnqgOLfjDTYazRL28tA=", + "checksumSHA1": "YdvFsNOMSWMLnY6fcliWQa0O5Fw=", "path": "github.com/hashicorp/hcl/json/scanner", - "revision": "d8c773c4cba11b11539e3d45f93daeaa5dcf1fa1", - "revisionTime": "2016-07-11T23:17:52Z" + "revision": "99df0eb941dd8ddbc83d3f3605a34f6a686ac85e", + "revisionTime": "2016-09-02T16:52:19Z" }, { "checksumSHA1": "fNlXQCQEnb+B3k5UDL/r15xtSJY=", "path": "github.com/hashicorp/hcl/json/token", - "revision": "d8c773c4cba11b11539e3d45f93daeaa5dcf1fa1", - "revisionTime": "2016-07-11T23:17:52Z" + "revision": "99df0eb941dd8ddbc83d3f3605a34f6a686ac85e", + "revisionTime": "2016-09-02T16:52:19Z" }, { "checksumSHA1": "OrnLOmhc0FcHYs02wtbu1siIsnM=", @@ -1260,7 +1260,6 @@ }, { "checksumSHA1": "jq2E42bB0kwKaerHXwJslUea4eM=", - "origin": "github.com/hashicorp/terraform/vendor/github.com/henrikhodne/go-librato/librato", "path": "github.com/henrikhodne/go-librato/librato", "revision": "6e9aa4b1a8a8b735ad14b4f1c9542ef183e82dc2", "revisionTime": "2016-08-11T07:26:26Z"