From 0a2b5de67fa980b4224963235cd1a8fcbe3a4c51 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Thu, 1 Sep 2016 20:13:36 -0700 Subject: [PATCH] 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 {