github.com/ns1/terraform@v0.7.10-0.20161109153551-8949419bef40/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(d.Get("region").(string))
    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(d.Get("region").(string))
   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  
   131  	return nil
   132  }
   133  
   134  func resourceFWFirewallV1Update(d *schema.ResourceData, meta interface{}) error {
   135  
   136  	config := meta.(*Config)
   137  	networkingClient, err := config.networkingV2Client(d.Get("region").(string))
   138  	if err != nil {
   139  		return fmt.Errorf("Error creating OpenStack networking client: %s", err)
   140  	}
   141  
   142  	opts := firewalls.UpdateOpts{}
   143  
   144  	if d.HasChange("name") {
   145  		opts.Name = d.Get("name").(string)
   146  	}
   147  
   148  	if d.HasChange("description") {
   149  		opts.Description = d.Get("description").(string)
   150  	}
   151  
   152  	if d.HasChange("policy_id") {
   153  		opts.PolicyID = d.Get("policy_id").(string)
   154  	}
   155  
   156  	if d.HasChange("admin_state_up") {
   157  		adminStateUp := d.Get("admin_state_up").(bool)
   158  		opts.AdminStateUp = &adminStateUp
   159  	}
   160  
   161  	log.Printf("[DEBUG] Updating firewall with id %s: %#v", d.Id(), opts)
   162  
   163  	stateConf := &resource.StateChangeConf{
   164  		Pending:    []string{"PENDING_CREATE", "PENDING_UPDATE"},
   165  		Target:     []string{"ACTIVE"},
   166  		Refresh:    waitForFirewallActive(networkingClient, d.Id()),
   167  		Timeout:    30 * time.Second,
   168  		Delay:      0,
   169  		MinTimeout: 2 * time.Second,
   170  	}
   171  
   172  	_, err = stateConf.WaitForState()
   173  
   174  	err = firewalls.Update(networkingClient, d.Id(), opts).Err
   175  	if err != nil {
   176  		return err
   177  	}
   178  
   179  	return resourceFWFirewallV1Read(d, meta)
   180  }
   181  
   182  func resourceFWFirewallV1Delete(d *schema.ResourceData, meta interface{}) error {
   183  	log.Printf("[DEBUG] Destroy firewall: %s", d.Id())
   184  
   185  	config := meta.(*Config)
   186  	networkingClient, err := config.networkingV2Client(d.Get("region").(string))
   187  	if err != nil {
   188  		return fmt.Errorf("Error creating OpenStack networking client: %s", err)
   189  	}
   190  
   191  	stateConf := &resource.StateChangeConf{
   192  		Pending:    []string{"PENDING_CREATE", "PENDING_UPDATE"},
   193  		Target:     []string{"ACTIVE"},
   194  		Refresh:    waitForFirewallActive(networkingClient, d.Id()),
   195  		Timeout:    30 * time.Second,
   196  		Delay:      0,
   197  		MinTimeout: 2 * time.Second,
   198  	}
   199  
   200  	_, err = stateConf.WaitForState()
   201  
   202  	err = firewalls.Delete(networkingClient, d.Id()).Err
   203  
   204  	if err != nil {
   205  		return err
   206  	}
   207  
   208  	stateConf = &resource.StateChangeConf{
   209  		Pending:    []string{"DELETING"},
   210  		Target:     []string{"DELETED"},
   211  		Refresh:    waitForFirewallDeletion(networkingClient, d.Id()),
   212  		Timeout:    2 * time.Minute,
   213  		Delay:      0,
   214  		MinTimeout: 2 * time.Second,
   215  	}
   216  
   217  	_, err = stateConf.WaitForState()
   218  
   219  	return err
   220  }
   221  
   222  func waitForFirewallActive(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  			return nil, "", err
   230  		}
   231  		return fw, fw.Status, nil
   232  	}
   233  }
   234  
   235  func waitForFirewallDeletion(networkingClient *gophercloud.ServiceClient, id string) resource.StateRefreshFunc {
   236  
   237  	return func() (interface{}, string, error) {
   238  		fw, err := firewalls.Get(networkingClient, id).Extract()
   239  		log.Printf("[DEBUG] Get firewall %s => %#v", id, fw)
   240  
   241  		if err != nil {
   242  			if _, ok := err.(gophercloud.ErrDefault404); ok {
   243  				log.Printf("[DEBUG] Firewall %s is actually deleted", id)
   244  				return "", "DELETED", nil
   245  			}
   246  			return nil, "", fmt.Errorf("Unexpected error: %s", err)
   247  		}
   248  
   249  		log.Printf("[DEBUG] Firewall %s deletion is pending", id)
   250  		return fw, "DELETING", nil
   251  	}
   252  }