From c4c480bb928ebf1577d42bfc050e35c02d87ab2e Mon Sep 17 00:00:00 2001 From: Joe Topjian Date: Thu, 16 Jul 2015 03:26:41 +0000 Subject: [PATCH] provider/openstack: Safe SecGroup Delete This commit enables security groups to be deleted in a safe way by checking their state over a period of time. This fixes occurrences when the API says the instance is deleted but it is still in the process of being deleted by OpenStack and thus the security group returns an error saying that there are still instances attached to the group. --- .../resource_openstack_compute_secgroup_v2.go | 39 ++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/builtin/providers/openstack/resource_openstack_compute_secgroup_v2.go b/builtin/providers/openstack/resource_openstack_compute_secgroup_v2.go index 18812cb59eb2..3cc0cbf0cc64 100644 --- a/builtin/providers/openstack/resource_openstack_compute_secgroup_v2.go +++ b/builtin/providers/openstack/resource_openstack_compute_secgroup_v2.go @@ -4,8 +4,10 @@ import ( "bytes" "fmt" "log" + "time" "github.com/hashicorp/terraform/helper/hashcode" + "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/helper/schema" "github.com/rackspace/gophercloud" "github.com/rackspace/gophercloud/openstack/compute/v2/extensions/secgroups" @@ -210,10 +212,20 @@ func resourceComputeSecGroupV2Delete(d *schema.ResourceData, meta interface{}) e return fmt.Errorf("Error creating OpenStack compute client: %s", err) } - err = secgroups.Delete(computeClient, d.Id()).ExtractErr() + stateConf := &resource.StateChangeConf{ + Pending: []string{"ACTIVE"}, + Target: "DELETED", + Refresh: SecGroupV2StateRefreshFunc(computeClient, d), + Timeout: 10 * time.Minute, + Delay: 10 * time.Second, + MinTimeout: 3 * time.Second, + } + + _, err = stateConf.WaitForState() if err != nil { return fmt.Errorf("Error deleting OpenStack security group: %s", err) } + d.SetId("") return nil } @@ -292,3 +304,28 @@ func secgroupRuleV2Hash(v interface{}) int { return hashcode.String(buf.String()) } + +func SecGroupV2StateRefreshFunc(computeClient *gophercloud.ServiceClient, d *schema.ResourceData) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + log.Printf("[DEBUG] Attempting to delete Security Group %s.\n", d.Id()) + + err := secgroups.Delete(computeClient, d.Id()).ExtractErr() + if err != nil { + return nil, "", err + } + + s, err := secgroups.Get(computeClient, d.Id()).Extract() + if err != nil { + err = CheckDeleted(d, err, "Security Group") + if err != nil { + return s, "", err + } else { + log.Printf("[DEBUG] Successfully deleted Security Group %s", d.Id()) + return s, "DELETED", nil + } + } + + log.Printf("[DEBUG] Security Group %s still active.\n", d.Id()) + return s, "ACTIVE", nil + } +}