Skip to content

Commit

Permalink
Remove 0 counts from flatmap during MergeDiff
Browse files Browse the repository at this point in the history
When a InstanceState is merged with an InstanceDiff, any maps arrays or
sets that no longer exist are shown as empty with a count of 0. If these
are left in the flatmap structure, they will cause errors during
expansion because their existing in the map affects the counts for
parent structures.
  • Loading branch information
jbardin committed Jan 17, 2017
1 parent 6ac3968 commit 2820845
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 0 deletions.
20 changes: 20 additions & 0 deletions terraform/state.go
Expand Up @@ -9,6 +9,7 @@ import (
"io/ioutil"
"log"
"reflect"
"regexp"
"sort"
"strconv"
"strings"
Expand Down Expand Up @@ -1664,6 +1665,25 @@ func (s *InstanceState) MergeDiff(d *InstanceDiff) *InstanceState {
}
}

// Remove any now empty array, maps or sets because a parent structure
// won't include these entries in the count value.
isCount := regexp.MustCompile(`\.[%#]$`).MatchString
for k, v := range result.Attributes {
if isCount(k) && v == "0" {
delete(result.Attributes, k)

// Sanity check for invalid structures.
// If we removed the primary count key, there should have been no
// other keys left with this prefix.
base := k[:len(k)-2]
for k, _ := range result.Attributes {
if strings.HasPrefix(k, base) {
panic(fmt.Sprintf("empty structure %q has entry %q", base, k))
}
}
}
}

return result
}

Expand Down
50 changes: 50 additions & 0 deletions terraform/state_test.go
Expand Up @@ -1392,6 +1392,56 @@ func TestInstanceState_MergeDiff(t *testing.T) {
}
}

// Make sure we don't leave empty maps or arrays in the flatmapped Attributes,
// since those may affect the counts of a parent structure.
func TestInstanceState_MergeDiffRemoveCounts(t *testing.T) {
is := InstanceState{
ID: "foo",
Attributes: map[string]string{
"all.#": "3",
"all.1111": "x",
"all.1234.#": "1",
"all.1234.0": "a",
"all.5678.%": "1",
"all.5678.key": "val",
},
}

diff := &InstanceDiff{
Attributes: map[string]*ResourceAttrDiff{
"all.#": &ResourceAttrDiff{
Old: "3",
New: "1",
},
"all.1234.0": &ResourceAttrDiff{
NewRemoved: true,
},
"all.1234.#": &ResourceAttrDiff{
Old: "1",
New: "0",
},
"all.5678.key": &ResourceAttrDiff{
NewRemoved: true,
},
"all.5678.%": &ResourceAttrDiff{
Old: "1",
New: "0",
},
},
}

is2 := is.MergeDiff(diff)

expected := map[string]string{
"all.#": "1",
"all.1111": "x",
}

if !reflect.DeepEqual(expected, is2.Attributes) {
t.Fatalf("bad: %#v", is2.Attributes)
}
}

func TestInstanceState_MergeDiff_nil(t *testing.T) {
var is *InstanceState

Expand Down

0 comments on commit 2820845

Please sign in to comment.