github.com/ricardclau/terraform@v0.6.17-0.20160519222547-283e3ae6b5a9/builtin/providers/openstack/resource_openstack_networking_secgroup_rule_v2.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  
    11  	"github.com/rackspace/gophercloud"
    12  	"github.com/rackspace/gophercloud/openstack/networking/v2/extensions/security/rules"
    13  )
    14  
    15  func resourceNetworkingSecGroupRuleV2() *schema.Resource {
    16  	return &schema.Resource{
    17  		Create: resourceNetworkingSecGroupRuleV2Create,
    18  		Read:   resourceNetworkingSecGroupRuleV2Read,
    19  		Delete: resourceNetworkingSecGroupRuleV2Delete,
    20  
    21  		Schema: map[string]*schema.Schema{
    22  			"region": &schema.Schema{
    23  				Type:        schema.TypeString,
    24  				Required:    true,
    25  				ForceNew:    true,
    26  				DefaultFunc: schema.EnvDefaultFunc("OS_REGION_NAME", ""),
    27  			},
    28  			"direction": &schema.Schema{
    29  				Type:     schema.TypeString,
    30  				Required: true,
    31  				ForceNew: true,
    32  			},
    33  			"ethertype": &schema.Schema{
    34  				Type:     schema.TypeString,
    35  				Required: true,
    36  				ForceNew: true,
    37  			},
    38  			"port_range_min": &schema.Schema{
    39  				Type:     schema.TypeInt,
    40  				Optional: true,
    41  				ForceNew: true,
    42  				Computed: true,
    43  			},
    44  			"port_range_max": &schema.Schema{
    45  				Type:     schema.TypeInt,
    46  				Optional: true,
    47  				ForceNew: true,
    48  				Computed: true,
    49  			},
    50  			"protocol": &schema.Schema{
    51  				Type:     schema.TypeString,
    52  				Optional: true,
    53  				ForceNew: true,
    54  				Computed: true,
    55  			},
    56  			"remote_group_id": &schema.Schema{
    57  				Type:     schema.TypeString,
    58  				Optional: true,
    59  				ForceNew: true,
    60  				Computed: true,
    61  			},
    62  			"remote_ip_prefix": &schema.Schema{
    63  				Type:     schema.TypeString,
    64  				Optional: true,
    65  				ForceNew: true,
    66  				Computed: true,
    67  			},
    68  			"security_group_id": &schema.Schema{
    69  				Type:     schema.TypeString,
    70  				Required: true,
    71  				ForceNew: true,
    72  			},
    73  			"tenant_id": &schema.Schema{
    74  				Type:     schema.TypeString,
    75  				Optional: true,
    76  				ForceNew: true,
    77  				Computed: true,
    78  			},
    79  		},
    80  	}
    81  }
    82  
    83  func resourceNetworkingSecGroupRuleV2Create(d *schema.ResourceData, meta interface{}) error {
    84  
    85  	config := meta.(*Config)
    86  	networkingClient, err := config.networkingV2Client(d.Get("region").(string))
    87  	if err != nil {
    88  		return fmt.Errorf("Error creating OpenStack networking client: %s", err)
    89  	}
    90  
    91  	portRangeMin := d.Get("port_range_min").(int)
    92  	portRangeMax := d.Get("port_range_max").(int)
    93  	protocol := d.Get("protocol").(string)
    94  
    95  	if protocol == "" {
    96  		if portRangeMin != 0 || portRangeMax != 0 {
    97  			return fmt.Errorf("A protocol must be specified when using port_range_min and port_range_max")
    98  		}
    99  	}
   100  
   101  	opts := rules.CreateOpts{
   102  		Direction:      d.Get("direction").(string),
   103  		EtherType:      d.Get("ethertype").(string),
   104  		SecGroupID:     d.Get("security_group_id").(string),
   105  		PortRangeMin:   d.Get("port_range_min").(int),
   106  		PortRangeMax:   d.Get("port_range_max").(int),
   107  		Protocol:       d.Get("protocol").(string),
   108  		RemoteGroupID:  d.Get("remote_group_id").(string),
   109  		RemoteIPPrefix: d.Get("remote_ip_prefix").(string),
   110  		TenantID:       d.Get("tenant_id").(string),
   111  	}
   112  
   113  	log.Printf("[DEBUG] Create OpenStack Neutron security group: %#v", opts)
   114  
   115  	security_group_rule, err := rules.Create(networkingClient, opts).Extract()
   116  	if err != nil {
   117  		return err
   118  	}
   119  
   120  	log.Printf("[DEBUG] OpenStack Neutron Security Group Rule created: %#v", security_group_rule)
   121  
   122  	d.SetId(security_group_rule.ID)
   123  
   124  	return resourceNetworkingSecGroupRuleV2Read(d, meta)
   125  }
   126  
   127  func resourceNetworkingSecGroupRuleV2Read(d *schema.ResourceData, meta interface{}) error {
   128  	log.Printf("[DEBUG] Retrieve information about security group rule: %s", d.Id())
   129  
   130  	config := meta.(*Config)
   131  	networkingClient, err := config.networkingV2Client(d.Get("region").(string))
   132  	if err != nil {
   133  		return fmt.Errorf("Error creating OpenStack networking client: %s", err)
   134  	}
   135  
   136  	security_group_rule, err := rules.Get(networkingClient, d.Id()).Extract()
   137  
   138  	if err != nil {
   139  		return CheckDeleted(d, err, "OpenStack Security Group Rule")
   140  	}
   141  
   142  	d.Set("protocol", security_group_rule.Protocol)
   143  	d.Set("port_range_min", security_group_rule.PortRangeMin)
   144  	d.Set("port_range_max", security_group_rule.PortRangeMax)
   145  	d.Set("remote_group_id", security_group_rule.RemoteGroupID)
   146  	d.Set("remote_ip_prefix", security_group_rule.RemoteIPPrefix)
   147  	d.Set("tenant_id", security_group_rule.TenantID)
   148  	return nil
   149  }
   150  
   151  func resourceNetworkingSecGroupRuleV2Delete(d *schema.ResourceData, meta interface{}) error {
   152  	log.Printf("[DEBUG] Destroy security group rule: %s", d.Id())
   153  
   154  	config := meta.(*Config)
   155  	networkingClient, err := config.networkingV2Client(d.Get("region").(string))
   156  	if err != nil {
   157  		return fmt.Errorf("Error creating OpenStack networking client: %s", err)
   158  	}
   159  
   160  	stateConf := &resource.StateChangeConf{
   161  		Pending:    []string{"ACTIVE"},
   162  		Target:     []string{"DELETED"},
   163  		Refresh:    waitForSecGroupRuleDelete(networkingClient, d.Id()),
   164  		Timeout:    2 * time.Minute,
   165  		Delay:      5 * time.Second,
   166  		MinTimeout: 3 * time.Second,
   167  	}
   168  
   169  	_, err = stateConf.WaitForState()
   170  	if err != nil {
   171  		return fmt.Errorf("Error deleting OpenStack Neutron Security Group Rule: %s", err)
   172  	}
   173  
   174  	d.SetId("")
   175  	return err
   176  }
   177  
   178  func waitForSecGroupRuleDelete(networkingClient *gophercloud.ServiceClient, secGroupRuleId string) resource.StateRefreshFunc {
   179  	return func() (interface{}, string, error) {
   180  		log.Printf("[DEBUG] Attempting to delete OpenStack Security Group Rule %s.\n", secGroupRuleId)
   181  
   182  		r, err := rules.Get(networkingClient, secGroupRuleId).Extract()
   183  		if err != nil {
   184  			errCode, ok := err.(*gophercloud.UnexpectedResponseCodeError)
   185  			if !ok {
   186  				return r, "ACTIVE", err
   187  			}
   188  			if errCode.Actual == 404 {
   189  				log.Printf("[DEBUG] Successfully deleted OpenStack Neutron Security Group Rule %s", secGroupRuleId)
   190  				return r, "DELETED", nil
   191  			}
   192  		}
   193  
   194  		err = rules.Delete(networkingClient, secGroupRuleId).ExtractErr()
   195  		if err != nil {
   196  			errCode, ok := err.(*gophercloud.UnexpectedResponseCodeError)
   197  			if !ok {
   198  				return r, "ACTIVE", err
   199  			}
   200  			if errCode.Actual == 404 {
   201  				log.Printf("[DEBUG] Successfully deleted OpenStack Neutron Security Group Rule %s", secGroupRuleId)
   202  				return r, "DELETED", nil
   203  			}
   204  		}
   205  
   206  		log.Printf("[DEBUG] OpenStack Neutron Security Group Rule %s still active.\n", secGroupRuleId)
   207  		return r, "ACTIVE", nil
   208  	}
   209  }