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  }