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