github.com/jrperritt/terraform@v0.1.1-0.20170525065507-96f391dafc38/builtin/providers/openstack/resource_openstack_networking_secgroup_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/gophercloud/gophercloud"
    12  	"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/groups"
    13  	"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/rules"
    14  )
    15  
    16  func resourceNetworkingSecGroupV2() *schema.Resource {
    17  	return &schema.Resource{
    18  		Create: resourceNetworkingSecGroupV2Create,
    19  		Read:   resourceNetworkingSecGroupV2Read,
    20  		Update: resourceNetworkingSecGroupV2Update,
    21  		Delete: resourceNetworkingSecGroupV2Delete,
    22  		Importer: &schema.ResourceImporter{
    23  			State: schema.ImportStatePassthrough,
    24  		},
    25  
    26  		Timeouts: &schema.ResourceTimeout{
    27  			Delete: schema.DefaultTimeout(10 * time.Minute),
    28  		},
    29  
    30  		Schema: map[string]*schema.Schema{
    31  			"region": &schema.Schema{
    32  				Type:        schema.TypeString,
    33  				Required:    true,
    34  				ForceNew:    true,
    35  				DefaultFunc: schema.EnvDefaultFunc("OS_REGION_NAME", ""),
    36  			},
    37  			"name": &schema.Schema{
    38  				Type:     schema.TypeString,
    39  				Required: true,
    40  			},
    41  			"description": &schema.Schema{
    42  				Type:     schema.TypeString,
    43  				Optional: true,
    44  				Computed: true,
    45  			},
    46  			"tenant_id": &schema.Schema{
    47  				Type:     schema.TypeString,
    48  				Optional: true,
    49  				ForceNew: true,
    50  				Computed: true,
    51  			},
    52  			"delete_default_rules": &schema.Schema{
    53  				Type:     schema.TypeBool,
    54  				Optional: true,
    55  				ForceNew: true,
    56  			},
    57  		},
    58  	}
    59  }
    60  
    61  func resourceNetworkingSecGroupV2Create(d *schema.ResourceData, meta interface{}) error {
    62  
    63  	config := meta.(*Config)
    64  	networkingClient, err := config.networkingV2Client(GetRegion(d))
    65  	if err != nil {
    66  		return fmt.Errorf("Error creating OpenStack networking client: %s", err)
    67  	}
    68  
    69  	opts := groups.CreateOpts{
    70  		Name:        d.Get("name").(string),
    71  		Description: d.Get("description").(string),
    72  		TenantID:    d.Get("tenant_id").(string),
    73  	}
    74  
    75  	log.Printf("[DEBUG] Create OpenStack Neutron Security Group: %#v", opts)
    76  
    77  	security_group, err := groups.Create(networkingClient, opts).Extract()
    78  	if err != nil {
    79  		return err
    80  	}
    81  
    82  	// Delete the default security group rules if it has been requested.
    83  	deleteDefaultRules := d.Get("delete_default_rules").(bool)
    84  	if deleteDefaultRules {
    85  		for _, rule := range security_group.Rules {
    86  			if err := rules.Delete(networkingClient, rule.ID).ExtractErr(); err != nil {
    87  				return fmt.Errorf(
    88  					"There was a problem deleting a default security group rule: %s", err)
    89  			}
    90  		}
    91  	}
    92  
    93  	log.Printf("[DEBUG] OpenStack Neutron Security Group created: %#v", security_group)
    94  
    95  	d.SetId(security_group.ID)
    96  
    97  	return resourceNetworkingSecGroupV2Read(d, meta)
    98  }
    99  
   100  func resourceNetworkingSecGroupV2Read(d *schema.ResourceData, meta interface{}) error {
   101  	log.Printf("[DEBUG] Retrieve information about security group: %s", d.Id())
   102  
   103  	config := meta.(*Config)
   104  	networkingClient, err := config.networkingV2Client(GetRegion(d))
   105  	if err != nil {
   106  		return fmt.Errorf("Error creating OpenStack networking client: %s", err)
   107  	}
   108  
   109  	security_group, err := groups.Get(networkingClient, d.Id()).Extract()
   110  
   111  	if err != nil {
   112  		return CheckDeleted(d, err, "OpenStack Neutron Security group")
   113  	}
   114  
   115  	d.Set("description", security_group.Description)
   116  	d.Set("tenant_id", security_group.TenantID)
   117  	d.Set("name", security_group.Name)
   118  	d.Set("region", GetRegion(d))
   119  
   120  	return nil
   121  }
   122  
   123  func resourceNetworkingSecGroupV2Update(d *schema.ResourceData, meta interface{}) error {
   124  	config := meta.(*Config)
   125  	networkingClient, err := config.networkingV2Client(GetRegion(d))
   126  	if err != nil {
   127  		return fmt.Errorf("Error creating OpenStack networking client: %s", err)
   128  	}
   129  
   130  	var update bool
   131  	var updateOpts groups.UpdateOpts
   132  
   133  	if d.HasChange("name") {
   134  		update = true
   135  		updateOpts.Name = d.Get("name").(string)
   136  	}
   137  
   138  	if d.HasChange("description") {
   139  		update = true
   140  		updateOpts.Name = d.Get("description").(string)
   141  	}
   142  
   143  	if update {
   144  		log.Printf("[DEBUG] Updating SecGroup %s with options: %#v", d.Id(), updateOpts)
   145  		_, err = groups.Update(networkingClient, d.Id(), updateOpts).Extract()
   146  		if err != nil {
   147  			return fmt.Errorf("Error updating OpenStack SecGroup: %s", err)
   148  		}
   149  	}
   150  
   151  	return resourceNetworkingSecGroupV2Read(d, meta)
   152  }
   153  
   154  func resourceNetworkingSecGroupV2Delete(d *schema.ResourceData, meta interface{}) error {
   155  	log.Printf("[DEBUG] Destroy security group: %s", d.Id())
   156  
   157  	config := meta.(*Config)
   158  	networkingClient, err := config.networkingV2Client(GetRegion(d))
   159  	if err != nil {
   160  		return fmt.Errorf("Error creating OpenStack networking client: %s", err)
   161  	}
   162  
   163  	stateConf := &resource.StateChangeConf{
   164  		Pending:    []string{"ACTIVE"},
   165  		Target:     []string{"DELETED"},
   166  		Refresh:    waitForSecGroupDelete(networkingClient, d.Id()),
   167  		Timeout:    d.Timeout(schema.TimeoutDelete),
   168  		Delay:      5 * time.Second,
   169  		MinTimeout: 3 * time.Second,
   170  	}
   171  
   172  	_, err = stateConf.WaitForState()
   173  	if err != nil {
   174  		return fmt.Errorf("Error deleting OpenStack Neutron Security Group: %s", err)
   175  	}
   176  
   177  	d.SetId("")
   178  	return err
   179  }
   180  
   181  func waitForSecGroupDelete(networkingClient *gophercloud.ServiceClient, secGroupId string) resource.StateRefreshFunc {
   182  	return func() (interface{}, string, error) {
   183  		log.Printf("[DEBUG] Attempting to delete OpenStack Security Group %s.\n", secGroupId)
   184  
   185  		r, err := groups.Get(networkingClient, secGroupId).Extract()
   186  		if err != nil {
   187  			if _, ok := err.(gophercloud.ErrDefault404); ok {
   188  				log.Printf("[DEBUG] Successfully deleted OpenStack Neutron Security Group %s", secGroupId)
   189  				return r, "DELETED", nil
   190  			}
   191  			return r, "ACTIVE", err
   192  		}
   193  
   194  		err = groups.Delete(networkingClient, secGroupId).ExtractErr()
   195  		if err != nil {
   196  			if _, ok := err.(gophercloud.ErrDefault404); ok {
   197  				log.Printf("[DEBUG] Successfully deleted OpenStack Neutron Security Group %s", secGroupId)
   198  				return r, "DELETED", nil
   199  			}
   200  			if errCode, ok := err.(gophercloud.ErrUnexpectedResponseCode); ok {
   201  				if errCode.Actual == 409 {
   202  					return r, "ACTIVE", nil
   203  				}
   204  			}
   205  			return r, "ACTIVE", err
   206  		}
   207  
   208  		log.Printf("[DEBUG] OpenStack Neutron Security Group %s still active.\n", secGroupId)
   209  		return r, "ACTIVE", nil
   210  	}
   211  }