Merge pull request #20348 from hashicorp/jbardin/list-empty-strings
simple list diffs may also have missing elements
This commit is contained in:
commit
fabdd0db3e
|
@ -171,7 +171,7 @@ func testResourceUpdate(d *schema.ResourceData, meta interface{}) error {
|
|||
if errMsg != "" {
|
||||
return errors.New(errMsg)
|
||||
}
|
||||
return nil
|
||||
return testResourceRead(d, meta)
|
||||
}
|
||||
|
||||
func testResourceDelete(d *schema.ResourceData, meta interface{}) error {
|
||||
|
|
|
@ -30,6 +30,13 @@ func testResourceList() *schema.Resource {
|
|||
Optional: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
"sublist": {
|
||||
Type: schema.TypeList,
|
||||
Optional: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
},
|
||||
},
|
||||
"sublist_block": {
|
||||
Type: schema.TypeList,
|
||||
Optional: true,
|
||||
|
|
|
@ -218,3 +218,61 @@ resource "test_resource_list" "foo" {
|
|||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestResourceList_emptyStrings(t *testing.T) {
|
||||
resource.UnitTest(t, resource.TestCase{
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckResourceDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
resource.TestStep{
|
||||
Config: strings.TrimSpace(`
|
||||
resource "test_resource_list" "foo" {
|
||||
list_block {
|
||||
sublist = ["a", ""]
|
||||
}
|
||||
|
||||
list_block {
|
||||
sublist = [""]
|
||||
}
|
||||
|
||||
list_block {
|
||||
sublist = ["", "c", ""]
|
||||
}
|
||||
}
|
||||
`),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
resource.TestCheckResourceAttr("test_resource_list.foo", "list_block.0.sublist.0", "a"),
|
||||
resource.TestCheckResourceAttr("test_resource_list.foo", "list_block.0.sublist.1", ""),
|
||||
resource.TestCheckResourceAttr("test_resource_list.foo", "list_block.1.sublist.0", ""),
|
||||
resource.TestCheckResourceAttr("test_resource_list.foo", "list_block.2.sublist.0", ""),
|
||||
resource.TestCheckResourceAttr("test_resource_list.foo", "list_block.2.sublist.1", "c"),
|
||||
resource.TestCheckResourceAttr("test_resource_list.foo", "list_block.2.sublist.2", ""),
|
||||
),
|
||||
},
|
||||
resource.TestStep{
|
||||
Config: strings.TrimSpace(`
|
||||
resource "test_resource_list" "foo" {
|
||||
list_block {
|
||||
sublist = [""]
|
||||
}
|
||||
|
||||
list_block {
|
||||
sublist = []
|
||||
}
|
||||
|
||||
list_block {
|
||||
sublist = ["", "c"]
|
||||
}
|
||||
}
|
||||
`),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
resource.TestCheckResourceAttr("test_resource_list.foo", "list_block.0.sublist.#", "1"),
|
||||
resource.TestCheckResourceAttr("test_resource_list.foo", "list_block.0.sublist.0", ""),
|
||||
resource.TestCheckResourceAttr("test_resource_list.foo", "list_block.1.sublist.#", "0"),
|
||||
resource.TestCheckResourceAttr("test_resource_list.foo", "list_block.2.sublist.1", "c"),
|
||||
resource.TestCheckResourceAttr("test_resource_list.foo", "list_block.2.sublist.#", "2"),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
|
|
@ -624,7 +624,7 @@ func (d *InstanceDiff) applyBlockDiff(path []string, attrs map[string]string, sc
|
|||
if err != nil {
|
||||
// this shouldn't happen since we added these
|
||||
// ourself, but make note of it just in case.
|
||||
log.Printf("[ERROR] bas list index in %q: %s", k, err)
|
||||
log.Printf("[ERROR] bad list index in %q: %s", k, err)
|
||||
continue
|
||||
}
|
||||
if i >= length {
|
||||
|
@ -811,10 +811,61 @@ func (d *InstanceDiff) applyCollectionDiff(path []string, attrs map[string]strin
|
|||
}
|
||||
}
|
||||
|
||||
// Fill in the count value if it was missing for some reason:
|
||||
if result[name+"."+idx] == "" {
|
||||
result[name+"."+idx] = countFlatmapContainerValues(name+"."+idx, result)
|
||||
// Just like in nested list blocks, for simple lists we may need to fill in
|
||||
// missing empty strings.
|
||||
countKey := name + "." + idx
|
||||
count := result[countKey]
|
||||
length, _ := strconv.Atoi(count)
|
||||
|
||||
if count != "" && count != hcl2shim.UnknownVariableValue &&
|
||||
attrSchema.Type.Equals(cty.List(cty.String)) {
|
||||
// insert empty strings into missing indexes
|
||||
for i := 0; i < length; i++ {
|
||||
key := fmt.Sprintf("%s.%d", name, i)
|
||||
if _, ok := result[key]; !ok {
|
||||
result[key] = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// now check for truncation in any type of list
|
||||
if attrSchema.Type.IsListType() {
|
||||
for key := range result {
|
||||
if key == countKey {
|
||||
continue
|
||||
}
|
||||
|
||||
if len(key) <= len(name)+1 {
|
||||
// not sure what this is, but don't panic
|
||||
continue
|
||||
}
|
||||
|
||||
index := key[len(name)+1:]
|
||||
|
||||
// It is possible to have nested sets or maps, so look for another dot
|
||||
dot := strings.Index(index, ".")
|
||||
if dot > 0 {
|
||||
index = index[:dot]
|
||||
}
|
||||
|
||||
// This shouldn't have any more dots, since the element type is only string.
|
||||
num, err := strconv.Atoi(index)
|
||||
if err != nil {
|
||||
log.Printf("[ERROR] bad list index in %q: %s", currentKey, err)
|
||||
continue
|
||||
}
|
||||
|
||||
if num >= length {
|
||||
delete(result, key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fill in the count value if it was missing for some reason:
|
||||
if result[countKey] == "" {
|
||||
result[countKey] = countFlatmapContainerValues(countKey, result)
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue