github.com/tarrant/terraform@v0.3.8-0.20150402012457-f68c9eee638e/builtin/providers/openstack/resource_openstack_fw_firewall_v1.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 "github.com/rackspace/gophercloud" 11 "github.com/rackspace/gophercloud/openstack/networking/v2/extensions/fwaas/firewalls" 12 ) 13 14 func resourceFWFirewallV1() *schema.Resource { 15 return &schema.Resource{ 16 Create: resourceFWFirewallV1Create, 17 Read: resourceFWFirewallV1Read, 18 Update: resourceFWFirewallV1Update, 19 Delete: resourceFWFirewallV1Delete, 20 21 Schema: map[string]*schema.Schema{ 22 "region": &schema.Schema{ 23 Type: schema.TypeString, 24 Required: true, 25 ForceNew: true, 26 DefaultFunc: envDefaultFunc("OS_REGION_NAME"), 27 }, 28 "name": &schema.Schema{ 29 Type: schema.TypeString, 30 Optional: true, 31 }, 32 "description": &schema.Schema{ 33 Type: schema.TypeString, 34 Optional: true, 35 }, 36 "policy_id": &schema.Schema{ 37 Type: schema.TypeString, 38 Required: true, 39 }, 40 "admin_state_up": &schema.Schema{ 41 Type: schema.TypeBool, 42 Optional: true, 43 Default: true, 44 }, 45 "tenant_id": &schema.Schema{ 46 Type: schema.TypeString, 47 Optional: true, 48 ForceNew: true, 49 }, 50 }, 51 } 52 } 53 54 func resourceFWFirewallV1Create(d *schema.ResourceData, meta interface{}) error { 55 56 config := meta.(*Config) 57 networkingClient, err := config.networkingV2Client(d.Get("region").(string)) 58 if err != nil { 59 return fmt.Errorf("Error creating OpenStack networking client: %s", err) 60 } 61 62 adminStateUp := d.Get("admin_state_up").(bool) 63 64 firewallConfiguration := firewalls.CreateOpts{ 65 Name: d.Get("name").(string), 66 Description: d.Get("description").(string), 67 PolicyID: d.Get("policy_id").(string), 68 AdminStateUp: &adminStateUp, 69 TenantID: d.Get("tenant_id").(string), 70 } 71 72 log.Printf("[DEBUG] Create firewall: %#v", firewallConfiguration) 73 74 firewall, err := firewalls.Create(networkingClient, firewallConfiguration).Extract() 75 if err != nil { 76 return err 77 } 78 79 log.Printf("[DEBUG] Firewall created: %#v", firewall) 80 81 stateConf := &resource.StateChangeConf{ 82 Pending: []string{"PENDING_CREATE"}, 83 Target: "ACTIVE", 84 Refresh: waitForFirewallActive(networkingClient, firewall.ID), 85 Timeout: 30 * time.Second, 86 Delay: 0, 87 MinTimeout: 2 * time.Second, 88 } 89 90 _, err = stateConf.WaitForState() 91 92 d.SetId(firewall.ID) 93 94 return resourceFWFirewallV1Read(d, meta) 95 } 96 97 func resourceFWFirewallV1Read(d *schema.ResourceData, meta interface{}) error { 98 log.Printf("[DEBUG] Retrieve information about firewall: %s", d.Id()) 99 100 config := meta.(*Config) 101 networkingClient, err := config.networkingV2Client(d.Get("region").(string)) 102 if err != nil { 103 return fmt.Errorf("Error creating OpenStack networking client: %s", err) 104 } 105 106 firewall, err := firewalls.Get(networkingClient, d.Id()).Extract() 107 108 if err != nil { 109 return CheckDeleted(d, err, "LB pool") 110 } 111 112 d.Set("name", firewall.Name) 113 d.Set("description", firewall.Description) 114 d.Set("policy_id", firewall.PolicyID) 115 d.Set("admin_state_up", firewall.AdminStateUp) 116 d.Set("tenant_id", firewall.TenantID) 117 118 return nil 119 } 120 121 func resourceFWFirewallV1Update(d *schema.ResourceData, meta interface{}) error { 122 123 config := meta.(*Config) 124 networkingClient, err := config.networkingV2Client(d.Get("region").(string)) 125 if err != nil { 126 return fmt.Errorf("Error creating OpenStack networking client: %s", err) 127 } 128 129 opts := firewalls.UpdateOpts{} 130 131 if d.HasChange("name") { 132 opts.Name = d.Get("name").(string) 133 } 134 135 if d.HasChange("description") { 136 opts.Description = d.Get("description").(string) 137 } 138 139 if d.HasChange("policy_id") { 140 opts.PolicyID = d.Get("policy_id").(string) 141 } 142 143 if d.HasChange("admin_state_up") { 144 adminStateUp := d.Get("admin_state_up").(bool) 145 opts.AdminStateUp = &adminStateUp 146 } 147 148 log.Printf("[DEBUG] Updating firewall with id %s: %#v", d.Id(), opts) 149 150 stateConf := &resource.StateChangeConf{ 151 Pending: []string{"PENDING_CREATE", "PENDING_UPDATE"}, 152 Target: "ACTIVE", 153 Refresh: waitForFirewallActive(networkingClient, d.Id()), 154 Timeout: 30 * time.Second, 155 Delay: 0, 156 MinTimeout: 2 * time.Second, 157 } 158 159 _, err = stateConf.WaitForState() 160 161 err = firewalls.Update(networkingClient, d.Id(), opts).Err 162 if err != nil { 163 return err 164 } 165 166 return resourceFWFirewallV1Read(d, meta) 167 } 168 169 func resourceFWFirewallV1Delete(d *schema.ResourceData, meta interface{}) error { 170 log.Printf("[DEBUG] Destroy firewall: %s", d.Id()) 171 172 config := meta.(*Config) 173 networkingClient, err := config.networkingV2Client(d.Get("region").(string)) 174 if err != nil { 175 return fmt.Errorf("Error creating OpenStack networking client: %s", err) 176 } 177 178 stateConf := &resource.StateChangeConf{ 179 Pending: []string{"PENDING_CREATE", "PENDING_UPDATE"}, 180 Target: "ACTIVE", 181 Refresh: waitForFirewallActive(networkingClient, d.Id()), 182 Timeout: 30 * time.Second, 183 Delay: 0, 184 MinTimeout: 2 * time.Second, 185 } 186 187 _, err = stateConf.WaitForState() 188 189 err = firewalls.Delete(networkingClient, d.Id()).Err 190 191 if err != nil { 192 return err 193 } 194 195 stateConf = &resource.StateChangeConf{ 196 Pending: []string{"DELETING"}, 197 Target: "DELETED", 198 Refresh: waitForFirewallDeletion(networkingClient, d.Id()), 199 Timeout: 2 * time.Minute, 200 Delay: 0, 201 MinTimeout: 2 * time.Second, 202 } 203 204 _, err = stateConf.WaitForState() 205 206 return err 207 } 208 209 func waitForFirewallActive(networkingClient *gophercloud.ServiceClient, id string) resource.StateRefreshFunc { 210 211 return func() (interface{}, string, error) { 212 fw, err := firewalls.Get(networkingClient, id).Extract() 213 log.Printf("[DEBUG] Get firewall %s => %#v", id, fw) 214 215 if err != nil { 216 return nil, "", err 217 } 218 return fw, fw.Status, nil 219 } 220 } 221 222 func waitForFirewallDeletion(networkingClient *gophercloud.ServiceClient, id string) resource.StateRefreshFunc { 223 224 return func() (interface{}, string, error) { 225 fw, err := firewalls.Get(networkingClient, id).Extract() 226 log.Printf("[DEBUG] Get firewall %s => %#v", id, fw) 227 228 if err != nil { 229 httpStatus := err.(*gophercloud.UnexpectedResponseCodeError) 230 log.Printf("[DEBUG] Get firewall %s status is %d", id, httpStatus.Actual) 231 232 if httpStatus.Actual == 404 { 233 log.Printf("[DEBUG] Firewall %s is actually deleted", id) 234 return "", "DELETED", nil 235 } 236 return nil, "", fmt.Errorf("Unexpected status code %d", httpStatus.Actual) 237 } 238 239 log.Printf("[DEBUG] Firewall %s deletion is pending", id) 240 return fw, "DELETING", nil 241 } 242 }