Merge pull request #11757 from hashicorp/jbardin/GH-11588

Make sure to diff all nested schema.Set elements
This commit is contained in:
James Bardin 2017-02-07 17:05:32 -05:00 committed by GitHub
commit ced4c53324
2 changed files with 101 additions and 0 deletions

View File

@ -919,6 +919,7 @@ func (m schemaMap) diffSet(
diff *terraform.InstanceDiff, diff *terraform.InstanceDiff,
d *ResourceData, d *ResourceData,
all bool) error { all bool) error {
o, n, _, computedSet := d.diffChange(k) o, n, _, computedSet := d.diffChange(k)
if computedSet { if computedSet {
n = nil n = nil
@ -1003,6 +1004,7 @@ func (m schemaMap) diffSet(
for _, code := range list { for _, code := range list {
switch t := schema.Elem.(type) { switch t := schema.Elem.(type) {
case *Resource: case *Resource:
countDiff, cOk := diff.GetAttribute(k + ".#")
// This is a complex resource // This is a complex resource
for k2, schema := range t.Schema { for k2, schema := range t.Schema {
subK := fmt.Sprintf("%s.%s.%s", k, code, k2) subK := fmt.Sprintf("%s.%s.%s", k, code, k2)
@ -1010,7 +1012,17 @@ func (m schemaMap) diffSet(
if err != nil { if err != nil {
return err return err
} }
// If parent set is being removed
// remove all subfields which were missed by the diff func
// We process these separately because type-specific diff functions
// lack the context (hierarchy of fields)
subKeyIsCount := strings.HasSuffix(subK, ".#")
if cOk && countDiff.New == "0" && !subKeyIsCount {
m.markAsRemoved(subK, schema, diff)
}
} }
case *Schema: case *Schema:
// Copy the schema so that we can set Computed/ForceNew from // Copy the schema so that we can set Computed/ForceNew from
// the parent schema (the TypeSet). // the parent schema (the TypeSet).

View File

@ -2985,6 +2985,95 @@ func TestSchemaMap_Diff(t *testing.T) {
}, },
}, },
}, },
{
Name: "Removal of TypeSet should cause computed fields to be removed",
Schema: map[string]*Schema{
"type_set": &Schema{
Type: TypeSet,
Optional: true,
Elem: &Resource{
Schema: map[string]*Schema{
"name": &Schema{
Type: TypeString,
Optional: true,
},
"required": &Schema{
Type: TypeString,
Required: true,
},
"value": &Schema{
Type: TypeInt,
Optional: true,
},
"required_value": &Schema{
Type: TypeInt,
Required: true,
},
"computed_value": &Schema{
Type: TypeString,
Optional: true,
Computed: true,
},
},
},
Set: func(i interface{}) int {
if i != nil {
return 12345
}
return 0
},
},
},
State: &terraform.InstanceState{
Attributes: map[string]string{
"type_set.#": "1",
"type_set.12345.name": "Name",
"type_set.12345.required": "Required",
"type_set.12345.value": "0",
"type_set.12345.required_value": "5",
"type_set.12345.computed_value": "COMPUTED",
},
},
Config: map[string]interface{}{
"type_set": []interface{}{},
},
Diff: &terraform.InstanceDiff{
Attributes: map[string]*terraform.ResourceAttrDiff{
"type_set.#": &terraform.ResourceAttrDiff{
Old: "1",
New: "0",
NewRemoved: false,
},
"type_set.12345.name": &terraform.ResourceAttrDiff{
Old: "Name",
New: "",
NewRemoved: true,
},
"type_set.12345.required": &terraform.ResourceAttrDiff{
Old: "Required",
New: "",
NewRemoved: true,
},
"type_set.12345.value": &terraform.ResourceAttrDiff{
Old: "0",
New: "0",
NewRemoved: true,
},
"type_set.12345.required_value": &terraform.ResourceAttrDiff{
Old: "5",
New: "0",
NewRemoved: true,
},
"type_set.12345.computed_value": &terraform.ResourceAttrDiff{
NewRemoved: true,
},
},
},
},
} }
for i, tc := range cases { for i, tc := range cases {