terraform/builtin/providers/openstack/resource_openstack_fw_firew...

271 lines
6.8 KiB
Go
Raw Normal View History

2015-02-03 22:14:56 +01:00
package openstack
import (
"errors"
"fmt"
"log"
"time"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/helper/schema"
"github.com/rackspace/gophercloud"
"github.com/rackspace/gophercloud/openstack/networking/v2/extensions/fwaas/firewalls"
)
func resourceFWFirewallV1() *schema.Resource {
2015-02-03 22:14:56 +01:00
return &schema.Resource{
Create: resourceFWFirewallV1Create,
Read: resourceFWFirewallV1Read,
Update: resourceFWFirewallV1Update,
Delete: resourceFWFirewallV1Delete,
2015-02-03 22:14:56 +01:00
Schema: map[string]*schema.Schema{
"region": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
DefaultFunc: envDefaultFunc("OS_REGION_NAME"),
},
"name": &schema.Schema{
Type: schema.TypeString,
Optional: true,
},
"description": &schema.Schema{
Type: schema.TypeString,
Optional: true,
},
"policy_id": &schema.Schema{
Type: schema.TypeString,
Required: true,
},
"admin_state_up": &schema.Schema{
Type: schema.TypeBool,
Optional: true,
Default: true,
},
"tenant_id": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
2015-02-03 22:14:56 +01:00
},
}
}
func resourceFWFirewallV1Create(d *schema.ResourceData, meta interface{}) error {
2015-02-03 22:14:56 +01:00
config := meta.(*Config)
networkingClient, err := config.networkingV2Client(d.Get("region").(string))
if err != nil {
return fmt.Errorf("Error creating OpenStack networking client: %s", err)
}
adminStateUp := d.Get("admin_state_up").(bool)
firewallConfiguration := firewalls.CreateOpts{
Name: d.Get("name").(string),
Description: d.Get("description").(string),
PolicyID: d.Get("policy_id").(string),
AdminStateUp: &adminStateUp,
TenantID: d.Get("tenant_id").(string),
2015-02-03 22:14:56 +01:00
}
log.Printf("[DEBUG] Create firewall: %#v", firewallConfiguration)
firewall, err := firewalls.Create(networkingClient, firewallConfiguration).Extract()
if err != nil {
return err
}
log.Printf("[DEBUG] Firewall created: %#v", firewall)
stateConf := &resource.StateChangeConf{
Pending: []string{"PENDING_CREATE"},
Target: "ACTIVE",
Refresh: waitForFirewallActive(networkingClient, firewall.ID),
2015-02-03 22:14:56 +01:00
Timeout: 30 * time.Second,
Delay: 0,
MinTimeout: 2 * time.Second,
}
_, err = stateConf.WaitForState()
d.SetId(firewall.ID)
2015-02-03 22:14:56 +01:00
return nil
}
func resourceFWFirewallV1Read(d *schema.ResourceData, meta interface{}) error {
2015-02-03 22:14:56 +01:00
log.Printf("[DEBUG] Retrieve information about firewall: %s", d.Id())
config := meta.(*Config)
networkingClient, err := config.networkingV2Client(d.Get("region").(string))
if err != nil {
return fmt.Errorf("Error creating OpenStack networking client: %s", err)
}
firewall, err := firewalls.Get(networkingClient, d.Id()).Extract()
if err != nil {
httpError, ok := err.(*gophercloud.UnexpectedResponseCodeError)
2015-02-03 22:14:56 +01:00
if !ok {
return err
}
if httpError.Actual == 404 {
d.SetId("")
return nil
}
return err
}
if t, exists := d.GetOk("name"); exists && t != "" {
d.Set("name", firewall.Name)
} else {
d.Set("name", "")
}
if t, exists := d.GetOk("description"); exists && t != "" {
d.Set("description", firewall.Description)
} else {
d.Set("description", "")
}
if t, exists := d.GetOk("policy_id"); exists && t != "" {
d.Set("policy_id", firewall.PolicyID)
} else {
d.Set("policy_id", "")
}
if t, exists := d.GetOk("admin_state_up"); exists && t != "" {
d.Set("admin_state_up", firewall.AdminStateUp)
} else {
d.Set("admin_state_up", "")
}
if t, exists := d.GetOk("tenant_id"); exists && t != "" {
d.Set("tenant_id", firewall.TenantID)
} else {
d.Set("tenant_id", "")
}
2015-02-03 22:14:56 +01:00
return nil
}
func resourceFWFirewallV1Update(d *schema.ResourceData, meta interface{}) error {
2015-02-03 22:14:56 +01:00
config := meta.(*Config)
networkingClient, err := config.networkingV2Client(d.Get("region").(string))
if err != nil {
return fmt.Errorf("Error creating OpenStack networking client: %s", err)
}
opts := firewalls.UpdateOpts{}
if d.HasChange("name") {
opts.Name = d.Get("name").(string)
2015-02-03 22:14:56 +01:00
}
if d.HasChange("description") {
opts.Description = d.Get("description").(string)
2015-02-03 22:14:56 +01:00
}
if d.HasChange("policy_id") {
opts.PolicyID = d.Get("policy_id").(string)
}
if d.HasChange("admin_state_up") {
adminStateUp := d.Get("admin_state_up").(bool)
opts.AdminStateUp = &adminStateUp
2015-02-03 22:14:56 +01:00
}
log.Printf("[DEBUG] Updating firewall with id %s: %#v", d.Id(), opts)
2015-02-03 22:14:56 +01:00
stateConf := &resource.StateChangeConf{
Pending: []string{"PENDING_CREATE", "PENDING_UPDATE"},
2015-02-03 22:14:56 +01:00
Target: "ACTIVE",
Refresh: waitForFirewallActive(networkingClient, d.Id()),
2015-02-03 22:14:56 +01:00
Timeout: 30 * time.Second,
Delay: 0,
MinTimeout: 2 * time.Second,
}
_, err = stateConf.WaitForState()
return firewalls.Update(networkingClient, d.Id(), opts).Err
2015-02-03 22:14:56 +01:00
}
func resourceFWFirewallV1Delete(d *schema.ResourceData, meta interface{}) error {
2015-02-03 22:14:56 +01:00
log.Printf("[DEBUG] Destroy firewall: %s", d.Id())
config := meta.(*Config)
networkingClient, err := config.networkingV2Client(d.Get("region").(string))
if err != nil {
return fmt.Errorf("Error creating OpenStack networking client: %s", err)
}
stateConf := &resource.StateChangeConf{
Pending: []string{"PENDING_CREATE", "PENDING_UPDATE"},
Target: "ACTIVE",
Refresh: waitForFirewallActive(networkingClient, d.Id()),
Timeout: 30 * time.Second,
Delay: 0,
MinTimeout: 2 * time.Second,
}
_, err = stateConf.WaitForState()
2015-02-03 22:14:56 +01:00
err = firewalls.Delete(networkingClient, d.Id()).Err
if err != nil {
return err
}
stateConf = &resource.StateChangeConf{
2015-02-03 22:14:56 +01:00
Pending: []string{"DELETING"},
Target: "DELETED",
Refresh: waitForFirewallDeletion(networkingClient, d.Id()),
2015-02-03 22:14:56 +01:00
Timeout: 2 * time.Minute,
Delay: 0,
MinTimeout: 2 * time.Second,
}
_, err = stateConf.WaitForState()
return err
}
func waitForFirewallActive(networkingClient *gophercloud.ServiceClient, id string) resource.StateRefreshFunc {
2015-02-03 22:14:56 +01:00
return func() (interface{}, string, error) {
fw, err := firewalls.Get(networkingClient, id).Extract()
log.Printf("[DEBUG] Get firewall %s => %#v", id, fw)
if err != nil {
return nil, "", err
}
return fw, fw.Status, nil
}
}
func waitForFirewallDeletion(networkingClient *gophercloud.ServiceClient, id string) resource.StateRefreshFunc {
2015-02-03 22:14:56 +01:00
return func() (interface{}, string, error) {
fw, err := firewalls.Get(networkingClient, id).Extract()
log.Printf("[DEBUG] Get firewall %s => %#v", id, fw)
if err != nil {
httpStatus := err.(*gophercloud.UnexpectedResponseCodeError)
2015-02-03 22:14:56 +01:00
log.Printf("[DEBUG] Get firewall %s status is %d", id, httpStatus.Actual)
if httpStatus.Actual == 404 {
log.Printf("[DEBUG] Firewall %s is actually deleted", id)
return "", "DELETED", nil
}
return nil, "", errors.New(fmt.Sprintf("Unexpected status code %d", httpStatus.Actual))
}
log.Printf("[DEBUG] Firewall %s deletion is pending", id)
return fw, "DELETING", nil
}
}