remove the partially-known ~ set sigil in diffs

The NewExtra values are stored outside the diff from plan, and the
original keys may not contain the ~ prefix. Adding the NewExtra back
into the diff with the mismatched key was causing an entire new set
element to be populated. Since this symbol isn't used to apply the diff
in helper/schema, we can simply strip them out.
This commit is contained in:
James Bardin 2019-02-27 12:19:25 -05:00
parent 08f0f60908
commit 47604c36c8
3 changed files with 70 additions and 0 deletions

View File

@ -1,9 +1,12 @@
package test package test
import ( import (
"bytes"
"fmt" "fmt"
"math/rand" "math/rand"
"strings"
"github.com/hashicorp/terraform/helper/hashcode"
"github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/schema"
) )
@ -39,10 +42,47 @@ func testResourceComputedSet() *schema.Resource {
}, },
Set: schema.HashString, Set: schema.HashString,
}, },
"rule": {
Type: schema.TypeSet,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"id": {
Type: schema.TypeString,
Computed: true,
},
"ip_protocol": {
Type: schema.TypeString,
Required: true,
ForceNew: false,
},
"cidr": {
Type: schema.TypeString,
Optional: true,
ForceNew: false,
StateFunc: func(v interface{}) string {
return strings.ToLower(v.(string))
},
},
},
},
},
}, },
} }
} }
func computeSecGroupV2RuleHash(v interface{}) int {
var buf bytes.Buffer
m := v.(map[string]interface{})
buf.WriteString(fmt.Sprintf("%s-", m["ip_protocol"].(string)))
buf.WriteString(fmt.Sprintf("%s-", strings.ToLower(m["cidr"].(string))))
return hashcode.String(buf.String())
}
func testResourceComputedSetCreate(d *schema.ResourceData, meta interface{}) error { func testResourceComputedSetCreate(d *schema.ResourceData, meta interface{}) error {
d.SetId(fmt.Sprintf("%x", rand.Int63())) d.SetId(fmt.Sprintf("%x", rand.Int63()))
return testResourceComputedSetRead(d, meta) return testResourceComputedSetRead(d, meta)

View File

@ -50,3 +50,22 @@ resource "test_resource_computed_set" "foo" {
}, },
}) })
} }
func TestResourceComputedSet_ruleTest(t *testing.T) {
resource.UnitTest(t, resource.TestCase{
Providers: testAccProviders,
CheckDestroy: testAccCheckResourceDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: strings.TrimSpace(`
resource "test_resource_computed_set" "foo" {
rule {
ip_protocol = "udp"
cidr = "0.0.0.0/0"
}
}
`),
},
},
})
}

View File

@ -747,6 +747,17 @@ func (s *GRPCProviderServer) ApplyResourceChange(_ context.Context, req *proto.A
} }
} }
// We need to fix any sets that may be using the "~" index prefix to
// indicate partially computed. The special sigil isn't really used except
// as a clue to visually indicate that the set isn't wholly known.
for k, d := range diff.Attributes {
if strings.Contains(k, ".~") {
delete(diff.Attributes, k)
k = strings.Replace(k, ".~", ".", -1)
diff.Attributes[k] = d
}
}
// add NewExtra Fields that may have been stored in the private data // add NewExtra Fields that may have been stored in the private data
if newExtra := private[newExtraKey]; newExtra != nil { if newExtra := private[newExtraKey]; newExtra != nil {
for k, v := range newExtra.(map[string]interface{}) { for k, v := range newExtra.(map[string]interface{}) {