Merge pull request #9834 from hashicorp/azr-fix-hcl2_upgrade_random_generate

hcl2_upgrade: fix a case where the generated type is wrong
This commit is contained in:
Wilken Rivera 2020-08-27 13:03:34 -04:00 committed by GitHub
commit 67cd123d1c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 48 additions and 7 deletions

View File

@ -326,24 +326,65 @@ func jsonBodyToHCL2Body(out *hclwrite.Body, kvs map[string]interface{}) {
switch value := value.(type) {
case map[string]interface{}:
var first interface{}
for _, elem := range value {
first = elem
var mostComplexElem interface{}
for _, randomElem := range value {
// HACK: we take the most complex element of that map because
// in HCL2, map of objects can be bodies, for example:
// map containing object: source_ami_filter {} ( body )
// simple string/string map: tags = {} ) ( attribute )
//
// if we could not find an object in this map then it's most
// likely a plain map and so we guess it should be and
// attribute. Though now if value refers to something that is
// an object but only contains a string or a bool; we could
// generate a faulty object. For example a (somewhat invalid)
// source_ami_filter where only `most_recent` is set.
switch randomElem.(type) {
case string, int, float64, bool:
if mostComplexElem != nil {
continue
}
mostComplexElem = randomElem
default:
mostComplexElem = randomElem
}
}
switch first.(type) {
case string, int, float64:
switch mostComplexElem.(type) {
case string, int, float64, bool:
out.SetAttributeValue(k, hcl2shim.HCL2ValueFromConfigValue(value))
default:
nestedBlockBody := out.AppendNewBlock(k, nil).Body()
jsonBodyToHCL2Body(nestedBlockBody, value)
}
case map[string]string, map[string]int, map[string]float64:
out.SetAttributeValue(k, hcl2shim.HCL2ValueFromConfigValue(value))
case []interface{}:
if len(value) == 0 {
continue
}
switch value[0].(type) {
var mostComplexElem interface{}
for _, randomElem := range value {
// HACK: we take the most complex element of that slice because
// in hcl2 slices of plain types can be arrays, for example:
// simple string type: owners = ["0000000000"]
// object: launch_block_device_mappings {}
switch randomElem.(type) {
case string, int, float64, bool:
if mostComplexElem != nil {
continue
}
mostComplexElem = randomElem
default:
mostComplexElem = randomElem
}
}
switch mostComplexElem.(type) {
case map[string]interface{}:
// this is an object in a slice; so we unwrap it. We
// could try to remove any 's' suffix in the key, but
// this might not work everywhere.
for i := range value {
value := value[i].(map[string]interface{})
nestedBlockBody := out.AppendNewBlock(k, nil).Body()
@ -351,8 +392,8 @@ func jsonBodyToHCL2Body(out *hclwrite.Body, kvs map[string]interface{}) {
}
continue
default:
out.SetAttributeValue(k, hcl2shim.HCL2ValueFromConfigValue(value))
}
out.SetAttributeValue(k, hcl2shim.HCL2ValueFromConfigValue(value))
default:
out.SetAttributeValue(k, hcl2shim.HCL2ValueFromConfigValue(value))
}