github.com/danp/terraform@v0.9.5-0.20170426144147-39d740081351/builtin/providers/openstack/resource_openstack_networking_secgroup_v2.go (about) 1 package openstack 2 3 import ( 4 "fmt" 5 "log" 6 "time" 7 8 "github.com/hashicorp/terraform/helper/resource" 9 "github.com/hashicorp/terraform/helper/schema" 10 11 "github.com/gophercloud/gophercloud" 12 "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/groups" 13 "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/rules" 14 ) 15 16 func resourceNetworkingSecGroupV2() *schema.Resource { 17 return &schema.Resource{ 18 Create: resourceNetworkingSecGroupV2Create, 19 Read: resourceNetworkingSecGroupV2Read, 20 Delete: resourceNetworkingSecGroupV2Delete, 21 Importer: &schema.ResourceImporter{ 22 State: schema.ImportStatePassthrough, 23 }, 24 25 Timeouts: &schema.ResourceTimeout{ 26 Delete: schema.DefaultTimeout(10 * time.Minute), 27 }, 28 29 Schema: map[string]*schema.Schema{ 30 "region": &schema.Schema{ 31 Type: schema.TypeString, 32 Required: true, 33 ForceNew: true, 34 DefaultFunc: schema.EnvDefaultFunc("OS_REGION_NAME", ""), 35 }, 36 "name": &schema.Schema{ 37 Type: schema.TypeString, 38 Required: true, 39 ForceNew: true, 40 }, 41 "description": &schema.Schema{ 42 Type: schema.TypeString, 43 Optional: true, 44 ForceNew: true, 45 Computed: true, 46 }, 47 "tenant_id": &schema.Schema{ 48 Type: schema.TypeString, 49 Optional: true, 50 ForceNew: true, 51 Computed: true, 52 }, 53 "delete_default_rules": &schema.Schema{ 54 Type: schema.TypeBool, 55 Optional: true, 56 ForceNew: true, 57 }, 58 }, 59 } 60 } 61 62 func resourceNetworkingSecGroupV2Create(d *schema.ResourceData, meta interface{}) error { 63 64 config := meta.(*Config) 65 networkingClient, err := config.networkingV2Client(GetRegion(d)) 66 if err != nil { 67 return fmt.Errorf("Error creating OpenStack networking client: %s", err) 68 } 69 70 opts := groups.CreateOpts{ 71 Name: d.Get("name").(string), 72 Description: d.Get("description").(string), 73 TenantID: d.Get("tenant_id").(string), 74 } 75 76 log.Printf("[DEBUG] Create OpenStack Neutron Security Group: %#v", opts) 77 78 security_group, err := groups.Create(networkingClient, opts).Extract() 79 if err != nil { 80 return err 81 } 82 83 // Delete the default security group rules if it has been requested. 84 deleteDefaultRules := d.Get("delete_default_rules").(bool) 85 if deleteDefaultRules { 86 for _, rule := range security_group.Rules { 87 if err := rules.Delete(networkingClient, rule.ID).ExtractErr(); err != nil { 88 return fmt.Errorf( 89 "There was a problem deleting a default security group rule: %s", err) 90 } 91 } 92 } 93 94 log.Printf("[DEBUG] OpenStack Neutron Security Group created: %#v", security_group) 95 96 d.SetId(security_group.ID) 97 98 return resourceNetworkingSecGroupV2Read(d, meta) 99 } 100 101 func resourceNetworkingSecGroupV2Read(d *schema.ResourceData, meta interface{}) error { 102 log.Printf("[DEBUG] Retrieve information about security group: %s", d.Id()) 103 104 config := meta.(*Config) 105 networkingClient, err := config.networkingV2Client(GetRegion(d)) 106 if err != nil { 107 return fmt.Errorf("Error creating OpenStack networking client: %s", err) 108 } 109 110 security_group, err := groups.Get(networkingClient, d.Id()).Extract() 111 112 if err != nil { 113 return CheckDeleted(d, err, "OpenStack Neutron Security group") 114 } 115 116 d.Set("description", security_group.Description) 117 d.Set("tenant_id", security_group.TenantID) 118 d.Set("name", security_group.Name) 119 d.Set("region", GetRegion(d)) 120 121 return nil 122 } 123 124 func resourceNetworkingSecGroupV2Delete(d *schema.ResourceData, meta interface{}) error { 125 log.Printf("[DEBUG] Destroy security group: %s", d.Id()) 126 127 config := meta.(*Config) 128 networkingClient, err := config.networkingV2Client(GetRegion(d)) 129 if err != nil { 130 return fmt.Errorf("Error creating OpenStack networking client: %s", err) 131 } 132 133 stateConf := &resource.StateChangeConf{ 134 Pending: []string{"ACTIVE"}, 135 Target: []string{"DELETED"}, 136 Refresh: waitForSecGroupDelete(networkingClient, d.Id()), 137 Timeout: d.Timeout(schema.TimeoutDelete), 138 Delay: 5 * time.Second, 139 MinTimeout: 3 * time.Second, 140 } 141 142 _, err = stateConf.WaitForState() 143 if err != nil { 144 return fmt.Errorf("Error deleting OpenStack Neutron Security Group: %s", err) 145 } 146 147 d.SetId("") 148 return err 149 } 150 151 func waitForSecGroupDelete(networkingClient *gophercloud.ServiceClient, secGroupId string) resource.StateRefreshFunc { 152 return func() (interface{}, string, error) { 153 log.Printf("[DEBUG] Attempting to delete OpenStack Security Group %s.\n", secGroupId) 154 155 r, err := groups.Get(networkingClient, secGroupId).Extract() 156 if err != nil { 157 if _, ok := err.(gophercloud.ErrDefault404); ok { 158 log.Printf("[DEBUG] Successfully deleted OpenStack Neutron Security Group %s", secGroupId) 159 return r, "DELETED", nil 160 } 161 return r, "ACTIVE", err 162 } 163 164 err = groups.Delete(networkingClient, secGroupId).ExtractErr() 165 if err != nil { 166 if _, ok := err.(gophercloud.ErrDefault404); ok { 167 log.Printf("[DEBUG] Successfully deleted OpenStack Neutron Security Group %s", secGroupId) 168 return r, "DELETED", nil 169 } 170 if errCode, ok := err.(gophercloud.ErrUnexpectedResponseCode); ok { 171 if errCode.Actual == 409 { 172 return r, "ACTIVE", nil 173 } 174 } 175 return r, "ACTIVE", err 176 } 177 178 log.Printf("[DEBUG] OpenStack Neutron Security Group %s still active.\n", secGroupId) 179 return r, "ACTIVE", nil 180 } 181 }