github.com/memsql/terraform@v0.7.0-rc2.0.20160706152241-21e2173e0a32/builtin/providers/openstack/resource_openstack_networking_secgroup_rule_v2.go (about)

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