github.com/jrperritt/terraform@v0.1.1-0.20170525065507-96f391dafc38/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 Update: resourceNetworkingSecGroupV2Update, 21 Delete: resourceNetworkingSecGroupV2Delete, 22 Importer: &schema.ResourceImporter{ 23 State: schema.ImportStatePassthrough, 24 }, 25 26 Timeouts: &schema.ResourceTimeout{ 27 Delete: schema.DefaultTimeout(10 * time.Minute), 28 }, 29 30 Schema: map[string]*schema.Schema{ 31 "region": &schema.Schema{ 32 Type: schema.TypeString, 33 Required: true, 34 ForceNew: true, 35 DefaultFunc: schema.EnvDefaultFunc("OS_REGION_NAME", ""), 36 }, 37 "name": &schema.Schema{ 38 Type: schema.TypeString, 39 Required: true, 40 }, 41 "description": &schema.Schema{ 42 Type: schema.TypeString, 43 Optional: true, 44 Computed: true, 45 }, 46 "tenant_id": &schema.Schema{ 47 Type: schema.TypeString, 48 Optional: true, 49 ForceNew: true, 50 Computed: true, 51 }, 52 "delete_default_rules": &schema.Schema{ 53 Type: schema.TypeBool, 54 Optional: true, 55 ForceNew: true, 56 }, 57 }, 58 } 59 } 60 61 func resourceNetworkingSecGroupV2Create(d *schema.ResourceData, meta interface{}) error { 62 63 config := meta.(*Config) 64 networkingClient, err := config.networkingV2Client(GetRegion(d)) 65 if err != nil { 66 return fmt.Errorf("Error creating OpenStack networking client: %s", err) 67 } 68 69 opts := groups.CreateOpts{ 70 Name: d.Get("name").(string), 71 Description: d.Get("description").(string), 72 TenantID: d.Get("tenant_id").(string), 73 } 74 75 log.Printf("[DEBUG] Create OpenStack Neutron Security Group: %#v", opts) 76 77 security_group, err := groups.Create(networkingClient, opts).Extract() 78 if err != nil { 79 return err 80 } 81 82 // Delete the default security group rules if it has been requested. 83 deleteDefaultRules := d.Get("delete_default_rules").(bool) 84 if deleteDefaultRules { 85 for _, rule := range security_group.Rules { 86 if err := rules.Delete(networkingClient, rule.ID).ExtractErr(); err != nil { 87 return fmt.Errorf( 88 "There was a problem deleting a default security group rule: %s", err) 89 } 90 } 91 } 92 93 log.Printf("[DEBUG] OpenStack Neutron Security Group created: %#v", security_group) 94 95 d.SetId(security_group.ID) 96 97 return resourceNetworkingSecGroupV2Read(d, meta) 98 } 99 100 func resourceNetworkingSecGroupV2Read(d *schema.ResourceData, meta interface{}) error { 101 log.Printf("[DEBUG] Retrieve information about security group: %s", d.Id()) 102 103 config := meta.(*Config) 104 networkingClient, err := config.networkingV2Client(GetRegion(d)) 105 if err != nil { 106 return fmt.Errorf("Error creating OpenStack networking client: %s", err) 107 } 108 109 security_group, err := groups.Get(networkingClient, d.Id()).Extract() 110 111 if err != nil { 112 return CheckDeleted(d, err, "OpenStack Neutron Security group") 113 } 114 115 d.Set("description", security_group.Description) 116 d.Set("tenant_id", security_group.TenantID) 117 d.Set("name", security_group.Name) 118 d.Set("region", GetRegion(d)) 119 120 return nil 121 } 122 123 func resourceNetworkingSecGroupV2Update(d *schema.ResourceData, meta interface{}) error { 124 config := meta.(*Config) 125 networkingClient, err := config.networkingV2Client(GetRegion(d)) 126 if err != nil { 127 return fmt.Errorf("Error creating OpenStack networking client: %s", err) 128 } 129 130 var update bool 131 var updateOpts groups.UpdateOpts 132 133 if d.HasChange("name") { 134 update = true 135 updateOpts.Name = d.Get("name").(string) 136 } 137 138 if d.HasChange("description") { 139 update = true 140 updateOpts.Name = d.Get("description").(string) 141 } 142 143 if update { 144 log.Printf("[DEBUG] Updating SecGroup %s with options: %#v", d.Id(), updateOpts) 145 _, err = groups.Update(networkingClient, d.Id(), updateOpts).Extract() 146 if err != nil { 147 return fmt.Errorf("Error updating OpenStack SecGroup: %s", err) 148 } 149 } 150 151 return resourceNetworkingSecGroupV2Read(d, meta) 152 } 153 154 func resourceNetworkingSecGroupV2Delete(d *schema.ResourceData, meta interface{}) error { 155 log.Printf("[DEBUG] Destroy security group: %s", d.Id()) 156 157 config := meta.(*Config) 158 networkingClient, err := config.networkingV2Client(GetRegion(d)) 159 if err != nil { 160 return fmt.Errorf("Error creating OpenStack networking client: %s", err) 161 } 162 163 stateConf := &resource.StateChangeConf{ 164 Pending: []string{"ACTIVE"}, 165 Target: []string{"DELETED"}, 166 Refresh: waitForSecGroupDelete(networkingClient, d.Id()), 167 Timeout: d.Timeout(schema.TimeoutDelete), 168 Delay: 5 * time.Second, 169 MinTimeout: 3 * time.Second, 170 } 171 172 _, err = stateConf.WaitForState() 173 if err != nil { 174 return fmt.Errorf("Error deleting OpenStack Neutron Security Group: %s", err) 175 } 176 177 d.SetId("") 178 return err 179 } 180 181 func waitForSecGroupDelete(networkingClient *gophercloud.ServiceClient, secGroupId string) resource.StateRefreshFunc { 182 return func() (interface{}, string, error) { 183 log.Printf("[DEBUG] Attempting to delete OpenStack Security Group %s.\n", secGroupId) 184 185 r, err := groups.Get(networkingClient, secGroupId).Extract() 186 if err != nil { 187 if _, ok := err.(gophercloud.ErrDefault404); ok { 188 log.Printf("[DEBUG] Successfully deleted OpenStack Neutron Security Group %s", secGroupId) 189 return r, "DELETED", nil 190 } 191 return r, "ACTIVE", err 192 } 193 194 err = groups.Delete(networkingClient, secGroupId).ExtractErr() 195 if err != nil { 196 if _, ok := err.(gophercloud.ErrDefault404); ok { 197 log.Printf("[DEBUG] Successfully deleted OpenStack Neutron Security Group %s", secGroupId) 198 return r, "DELETED", nil 199 } 200 if errCode, ok := err.(gophercloud.ErrUnexpectedResponseCode); ok { 201 if errCode.Actual == 409 { 202 return r, "ACTIVE", nil 203 } 204 } 205 return r, "ACTIVE", err 206 } 207 208 log.Printf("[DEBUG] OpenStack Neutron Security Group %s still active.\n", secGroupId) 209 return r, "ACTIVE", nil 210 } 211 }