Merge branch 'master' of github.com:hashicorp/terraform

* 'master' of github.com:hashicorp/terraform:
  Update CHANGELOG.md
  Update CHANGELOG.md
  core: honor "destroy" diffs for data resources
  provider/azurerm: `azurerm_network_interface` diffs didn't match during apply
  providers/google: Don't fail deleting disks that don't exist.
This commit is contained in:
clint shryock 2016-05-20 17:01:48 -05:00
commit d87fc5a55a
6 changed files with 73 additions and 22 deletions

View File

@ -44,7 +44,9 @@ BUG FIXES:
* provider/aws: fix Elastic Beanstalk `cname_prefix` continual plans [GH-6653]
* provider/aws: Make 'stage_name' required in api_gateway_deployment [Gh-6797]
* provider/azurerm: Fixes terraform crash when using SSH keys with `azurerm_virtual_machine` [GH-6766]
* provider/azurerm: Fix a bug causing 'diffs do not match' on `azurerm_network_interface` resources [GH-6790]
* provider/azurerm: Normalizes `availability_set_id` casing to avoid spurious diffs in `azurerm_virtual_machine` [GH-6768]
* provider/google: Fix a bug causing an error attempting to delete an already-deleted `google_compute_disk` [GH-6689]
* provider/openstack: Reassociate Floating IP on network changes [GH-6579]
* provider/vsphere: `gateway` and `ipv6_gateway` are now read from `vsphere_virtual_machine` resources [GH-6522]
* provider/vsphere: `ipv*_gateway` parameters won't force a new `vsphere_virtual_machine` [GH-6635]

View File

@ -337,7 +337,13 @@ func resourceArmNetworkInterfaceIpConfigurationHash(v interface{}) int {
m := v.(map[string]interface{})
buf.WriteString(fmt.Sprintf("%s-", m["name"].(string)))
buf.WriteString(fmt.Sprintf("%s-", m["subnet_id"].(string)))
if m["private_ip_address"] != nil {
buf.WriteString(fmt.Sprintf("%s-", m["private_ip_address"].(string)))
}
buf.WriteString(fmt.Sprintf("%s-", m["private_ip_address_allocation"].(string)))
if m["public_ip_address_id"] != nil {
buf.WriteString(fmt.Sprintf("%s-", m["public_ip_address_id"].(string)))
}
return hashcode.String(buf.String())
}

View File

@ -184,6 +184,12 @@ func resourceComputeDiskDelete(d *schema.ResourceData, meta interface{}) error {
op, err := config.clientCompute.Disks.Delete(
project, d.Get("zone").(string), d.Id()).Do()
if err != nil {
if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 404 {
log.Printf("[WARN] Removing Disk %q because it's gone", d.Get("name").(string))
// The resource doesn't exist anymore
d.SetId("")
return nil
}
return fmt.Errorf("Error deleting disk: %s", err)
}

View File

@ -126,7 +126,7 @@ func TestAccComputeInstance_IP(t *testing.T) {
})
}
func TestAccComputeInstance_disks(t *testing.T) {
func TestAccComputeInstance_disksWithoutAutodelete(t *testing.T) {
var instance compute.Instance
var instanceName = fmt.Sprintf("instance-test-%s", acctest.RandString(10))
var diskName = fmt.Sprintf("instance-testd-%s", acctest.RandString(10))
@ -137,7 +137,7 @@ func TestAccComputeInstance_disks(t *testing.T) {
CheckDestroy: testAccCheckComputeInstanceDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccComputeInstance_disks(diskName, instanceName),
Config: testAccComputeInstance_disks(diskName, instanceName, false),
Check: resource.ComposeTestCheckFunc(
testAccCheckComputeInstanceExists(
"google_compute_instance.foobar", &instance),
@ -149,6 +149,29 @@ func TestAccComputeInstance_disks(t *testing.T) {
})
}
func TestAccComputeInstance_disksWithAutodelete(t *testing.T) {
var instance compute.Instance
var instanceName = fmt.Sprintf("instance-test-%s", acctest.RandString(10))
var diskName = fmt.Sprintf("instance-testd-%s", acctest.RandString(10))
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckComputeInstanceDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccComputeInstance_disks(diskName, instanceName, true),
Check: resource.ComposeTestCheckFunc(
testAccCheckComputeInstanceExists(
"google_compute_instance.foobar", &instance),
testAccCheckComputeInstanceDisk(&instance, instanceName, true, true),
testAccCheckComputeInstanceDisk(&instance, diskName, true, false),
),
},
},
})
}
func TestAccComputeInstance_local_ssd(t *testing.T) {
var instance compute.Instance
var instanceName = fmt.Sprintf("instance-test-%s", acctest.RandString(10))
@ -702,7 +725,7 @@ func testAccComputeInstance_ip(ip, instance string) string {
}`, ip, instance)
}
func testAccComputeInstance_disks(disk, instance string) string {
func testAccComputeInstance_disks(disk, instance string, autodelete bool) string {
return fmt.Sprintf(`
resource "google_compute_disk" "foobar" {
name = "%s"
@ -722,7 +745,7 @@ func testAccComputeInstance_disks(disk, instance string) string {
disk {
disk = "${google_compute_disk.foobar.name}"
auto_delete = false
auto_delete = %v
}
network_interface {
@ -732,7 +755,7 @@ func testAccComputeInstance_disks(disk, instance string) string {
metadata {
foo = "bar"
}
}`, disk, instance)
}`, disk, instance, autodelete)
}
func testAccComputeInstance_local_ssd(instance string) string {

View File

@ -12,12 +12,14 @@ type EvalReadDataDiff struct {
OutputState **InstanceState
Config **ResourceConfig
Info *InstanceInfo
// Set Previous when re-evaluating diff during apply, to ensure that
// the "Destroy" flag is preserved.
Previous **InstanceDiff
}
func (n *EvalReadDataDiff) Eval(ctx EvalContext) (interface{}, error) {
// TODO: test
provider := *n.Provider
config := *n.Config
err := ctx.Hook(func(h Hook) (HookAction, error) {
return h.PreDiff(n.Info, nil)
@ -26,21 +28,32 @@ func (n *EvalReadDataDiff) Eval(ctx EvalContext) (interface{}, error) {
return nil, err
}
diff, err := provider.ReadDataDiff(n.Info, config)
if err != nil {
return nil, err
}
if diff == nil {
diff = new(InstanceDiff)
}
var diff *InstanceDiff
// id is always computed, because we're always "creating a new resource"
diff.init()
diff.Attributes["id"] = &ResourceAttrDiff{
Old: "",
NewComputed: true,
RequiresNew: true,
Type: DiffAttrOutput,
if n.Previous != nil && *n.Previous != nil && (*n.Previous).Destroy {
// If we're re-diffing for a diff that was already planning to
// destroy, then we'll just continue with that plan.
diff = &InstanceDiff{Destroy: true}
} else {
provider := *n.Provider
config := *n.Config
diff, err := provider.ReadDataDiff(n.Info, config)
if err != nil {
return nil, err
}
if diff == nil {
diff = new(InstanceDiff)
}
// id is always computed, because we're always "creating a new resource"
diff.init()
diff.Attributes["id"] = &ResourceAttrDiff{
Old: "",
NewComputed: true,
RequiresNew: true,
Type: DiffAttrOutput,
}
}
err = ctx.Hook(func(h Hook) (HookAction, error) {
@ -83,7 +96,7 @@ func (n *EvalReadDataApply) Eval(ctx EvalContext) (interface{}, error) {
// If the diff is for *destroying* this resource then we'll
// just drop its state and move on, since data resources don't
// support an actual "destroy" action.
if diff.Destroy {
if diff != nil && diff.Destroy {
if n.Output != nil {
*n.Output = nil
}

View File

@ -810,6 +810,7 @@ func (n *graphNodeExpandedResource) dataResourceEvalNodes(resource *Resource, in
&EvalReadDataDiff{
Info: info,
Config: &config,
Previous: &diff,
Provider: &provider,
Output: &diff,
},