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  }