Get rid of the list when parsing HCL maps for vars
When we parse a map from HCL, it's decoded into a list of maps because HCL allows declaring a key multiple times to implicitly add it to a list. Since there's no terraform variable configuration that supports this structure, we can always flatten a []map[string]interface{} value to a map[string]interface{} and remove any type rrors trying to apply that value.
This commit is contained in:
parent
3e3854ed65
commit
9fc50a76c3
|
@ -111,6 +111,10 @@ func loadKVFile(rawPath string) (map[string]interface{}, error) {
|
||||||
"Decoding errors are usually caused by an invalid format.",
|
"Decoding errors are usually caused by an invalid format.",
|
||||||
err)
|
err)
|
||||||
}
|
}
|
||||||
|
err = flattenMultiMaps(result)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
@ -185,10 +189,34 @@ func parseVarFlagAsHCL(input string) (string, interface{}, error) {
|
||||||
return "", nil, fmt.Errorf("Cannot parse value for variable %s (%q) as valid HCL. Only one value may be specified.", probablyName, input)
|
return "", nil, fmt.Errorf("Cannot parse value for variable %s (%q) as valid HCL. Only one value may be specified.", probablyName, input)
|
||||||
}
|
}
|
||||||
|
|
||||||
for k, v := range decoded {
|
err = flattenMultiMaps(decoded)
|
||||||
return k, v, nil
|
if err != nil {
|
||||||
|
return probablyName, "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Should be unreachable
|
var k string
|
||||||
return "", nil, fmt.Errorf("No value for variable: %s", input)
|
var v interface{}
|
||||||
|
for k, v = range decoded {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return k, v, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Variables don't support any type that can be configured via multiple
|
||||||
|
// declarations of the same HCL map, so any instances of
|
||||||
|
// []map[string]interface{} are either a single map that can be flattened, or
|
||||||
|
// are invalid config.
|
||||||
|
func flattenMultiMaps(m map[string]interface{}) error {
|
||||||
|
for k, v := range m {
|
||||||
|
switch v := v.(type) {
|
||||||
|
case []map[string]interface{}:
|
||||||
|
switch {
|
||||||
|
case len(v) > 1:
|
||||||
|
return fmt.Errorf("multiple map declarations not supported for variables")
|
||||||
|
case len(v) == 1:
|
||||||
|
m[k] = v[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,10 +2,11 @@ package command
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/davecgh/go-spew/spew"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestFlagStringKV_impl(t *testing.T) {
|
func TestFlagStringKV_impl(t *testing.T) {
|
||||||
|
@ -118,11 +119,9 @@ func TestFlagTypedKV(t *testing.T) {
|
||||||
{
|
{
|
||||||
`key={"hello" = "world", "foo" = "bar"}`,
|
`key={"hello" = "world", "foo" = "bar"}`,
|
||||||
map[string]interface{}{
|
map[string]interface{}{
|
||||||
"key": []map[string]interface{}{
|
"key": map[string]interface{}{
|
||||||
map[string]interface{}{
|
"hello": "world",
|
||||||
"hello": "world",
|
"foo": "bar",
|
||||||
"foo": "bar",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
false,
|
false,
|
||||||
|
@ -169,6 +168,10 @@ func TestFlagKVFile(t *testing.T) {
|
||||||
inputLibucl := `
|
inputLibucl := `
|
||||||
foo = "bar"
|
foo = "bar"
|
||||||
`
|
`
|
||||||
|
inputMap := `
|
||||||
|
foo = {
|
||||||
|
k = "v"
|
||||||
|
}`
|
||||||
|
|
||||||
inputJson := `{
|
inputJson := `{
|
||||||
"foo": "bar"}`
|
"foo": "bar"}`
|
||||||
|
@ -195,6 +198,16 @@ foo = "bar"
|
||||||
map[string]interface{}{"map.key": "foo"},
|
map[string]interface{}{"map.key": "foo"},
|
||||||
false,
|
false,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
inputMap,
|
||||||
|
map[string]interface{}{
|
||||||
|
"foo": map[string]interface{}{
|
||||||
|
"k": "v",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
path := testTempFile(t)
|
path := testTempFile(t)
|
||||||
|
|
Loading…
Reference in New Issue