provider/template: validate vars are primitives

Closes #7160 by returning a proper error.
This commit is contained in:
Paul Hinze 2016-07-11 15:39:34 -05:00
parent dc313de5b4
commit b7e854fa8b
No known key found for this signature in database
GPG Key ID: B69DEDF2D55501C0
3 changed files with 71 additions and 5 deletions

View File

@ -6,6 +6,7 @@ import (
"fmt"
"os"
"path/filepath"
"strings"
"github.com/hashicorp/hil"
"github.com/hashicorp/hil/ast"
@ -49,10 +50,11 @@ func dataSourceFile() *schema.Resource {
ConflictsWith: []string{"template"},
},
"vars": &schema.Schema{
Type: schema.TypeMap,
Optional: true,
Default: make(map[string]interface{}),
Description: "variables to substitute",
Type: schema.TypeMap,
Optional: true,
Default: make(map[string]interface{}),
Description: "variables to substitute",
ValidateFunc: validateVarsAttribute,
},
"rendered": &schema.Schema{
Type: schema.TypeString,
@ -156,3 +158,22 @@ func validateTemplateAttribute(v interface{}, key string) (ws []string, es []err
return
}
func validateVarsAttribute(v interface{}, key string) (ws []string, es []error) {
// vars can only be primitives right now
var badVars []string
for k, v := range v.(map[string]interface{}) {
switch v.(type) {
case []interface{}:
badVars = append(badVars, fmt.Sprintf("%s (list)", k))
case map[string]interface{}:
badVars = append(badVars, fmt.Sprintf("%s (map)", k))
}
}
if len(badVars) > 0 {
es = append(es, fmt.Errorf(
"%s: cannot contain non-primitives; bad keys: %s",
key, strings.Join(badVars, ", ")))
}
return
}

View File

@ -71,6 +71,49 @@ func TestValidateTemplateAttribute(t *testing.T) {
}
}
func TestValidateVarsAttribute(t *testing.T) {
cases := map[string]struct {
Vars map[string]interface{}
ExpectErr string
}{
"lists are invalid": {
map[string]interface{}{
"list": []interface{}{},
},
`vars: cannot contain non-primitives`,
},
"maps are invalid": {
map[string]interface{}{
"map": map[string]interface{}{},
},
`vars: cannot contain non-primitives`,
},
"strings, integers, floats, and bools are AOK": {
map[string]interface{}{
"string": "foo",
"int": 1,
"bool": true,
"float": float64(1.0),
},
``,
},
}
for tn, tc := range cases {
_, es := validateVarsAttribute(tc.Vars, "vars")
if len(es) > 0 {
if tc.ExpectErr == "" {
t.Fatalf("%s: expected no err, got: %#v", tn, es)
}
if !strings.Contains(es[0].Error(), tc.ExpectErr) {
t.Fatalf("%s: expected\n%s\nto contain\n%s", tn, es[0], tc.ExpectErr)
}
} else if tc.ExpectErr != "" {
t.Fatalf("%s: expected err containing %q, got none!", tn, tc.ExpectErr)
}
}
}
// This test covers a panic due to config.Func formerly being a
// shared map, causing multiple template_file resources to try and
// accessing it parallel during their lang.Eval() runs.

View File

@ -31,7 +31,9 @@ The following arguments are supported:
from a file on disk using the [`file()` interpolation
function](/docs/configuration/interpolation.html#file_path_).
* `vars` - (Optional) Variables for interpolation within the template.
* `vars` - (Optional) Variables for interpolation within the template. Note
that variables must all be primitives. Direct references to lists or maps
will cause a validation error.
The following arguments are maintained for backwards compatibility and may be
removed in a future version: