github.com/pmcatominey/terraform@v0.7.0-rc2.0.20160708105029-1401a52a5cc5/builtin/providers/openstack/resource_openstack_lb_loadbalancer_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/lbaas_v2/loadbalancers"
    13  )
    14  
    15  func resourceLoadBalancerV2() *schema.Resource {
    16  	return &schema.Resource{
    17  		Create: resourceLoadBalancerV2Create,
    18  		Read:   resourceLoadBalancerV2Read,
    19  		Update: resourceLoadBalancerV2Update,
    20  		Delete: resourceLoadBalancerV2Delete,
    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  
    30  			"name": &schema.Schema{
    31  				Type:     schema.TypeString,
    32  				Optional: true,
    33  			},
    34  
    35  			"description": &schema.Schema{
    36  				Type:     schema.TypeString,
    37  				Optional: true,
    38  			},
    39  
    40  			"vip_subnet_id": &schema.Schema{
    41  				Type:     schema.TypeString,
    42  				Required: true,
    43  				ForceNew: true,
    44  			},
    45  
    46  			"tenant_id": &schema.Schema{
    47  				Type:     schema.TypeString,
    48  				Optional: true,
    49  				Computed: true,
    50  				ForceNew: true,
    51  			},
    52  
    53  			"vip_address": &schema.Schema{
    54  				Type:     schema.TypeString,
    55  				Optional: true,
    56  				Computed: true,
    57  				ForceNew: true,
    58  			},
    59  
    60  			"admin_state_up": &schema.Schema{
    61  				Type:     schema.TypeBool,
    62  				Optional: true,
    63  			},
    64  
    65  			"flavor": &schema.Schema{
    66  				Type:     schema.TypeString,
    67  				Optional: true,
    68  				ForceNew: true,
    69  			},
    70  
    71  			"provider": &schema.Schema{
    72  				Type:     schema.TypeString,
    73  				Optional: true,
    74  				Computed: true,
    75  				ForceNew: true,
    76  			},
    77  		},
    78  	}
    79  }
    80  
    81  func resourceLoadBalancerV2Create(d *schema.ResourceData, meta interface{}) error {
    82  	config := meta.(*Config)
    83  	networkingClient, err := config.networkingV2Client(d.Get("region").(string))
    84  	if err != nil {
    85  		return fmt.Errorf("Error creating OpenStack networking client: %s", err)
    86  	}
    87  
    88  	adminStateUp := d.Get("admin_state_up").(bool)
    89  	createOpts := loadbalancers.CreateOpts{
    90  		Name:         d.Get("name").(string),
    91  		Description:  d.Get("description").(string),
    92  		VipSubnetID:  d.Get("vip_subnet_id").(string),
    93  		TenantID:     d.Get("tenant_id").(string),
    94  		VipAddress:   d.Get("vip_address").(string),
    95  		AdminStateUp: &adminStateUp,
    96  		Flavor:       d.Get("flavor").(string),
    97  		Provider:     d.Get("provider").(string),
    98  	}
    99  
   100  	log.Printf("[DEBUG] Create Options: %#v", createOpts)
   101  	lb, err := loadbalancers.Create(networkingClient, createOpts).Extract()
   102  	if err != nil {
   103  		return fmt.Errorf("Error creating OpenStack LoadBalancer: %s", err)
   104  	}
   105  	log.Printf("[INFO] LoadBalancer ID: %s", lb.ID)
   106  
   107  	log.Printf("[DEBUG] Waiting for Openstack LoadBalancer (%s) to become available.", lb.ID)
   108  
   109  	stateConf := &resource.StateChangeConf{
   110  		Pending:    []string{"PENDING_CREATE"},
   111  		Target:     []string{"ACTIVE"},
   112  		Refresh:    waitForLoadBalancerActive(networkingClient, lb.ID),
   113  		Timeout:    20 * time.Minute,
   114  		Delay:      5 * time.Second,
   115  		MinTimeout: 3 * time.Second,
   116  	}
   117  
   118  	_, err = stateConf.WaitForState()
   119  	if err != nil {
   120  		return err
   121  	}
   122  
   123  	d.SetId(lb.ID)
   124  
   125  	return resourceLoadBalancerV2Read(d, meta)
   126  }
   127  
   128  func resourceLoadBalancerV2Read(d *schema.ResourceData, meta interface{}) error {
   129  	config := meta.(*Config)
   130  	networkingClient, err := config.networkingV2Client(d.Get("region").(string))
   131  	if err != nil {
   132  		return fmt.Errorf("Error creating OpenStack networking client: %s", err)
   133  	}
   134  
   135  	lb, err := loadbalancers.Get(networkingClient, d.Id()).Extract()
   136  	if err != nil {
   137  		return CheckDeleted(d, err, "LoadBalancerV2")
   138  	}
   139  
   140  	log.Printf("[DEBUG] Retreived OpenStack LoadBalancerV2 %s: %+v", d.Id(), lb)
   141  
   142  	d.Set("name", lb.Name)
   143  	d.Set("description", lb.Description)
   144  	d.Set("vip_subnet_id", lb.VipSubnetID)
   145  	d.Set("tenant_id", lb.TenantID)
   146  	d.Set("vip_address", lb.VipAddress)
   147  	d.Set("admin_state_up", lb.AdminStateUp)
   148  	d.Set("flavor", lb.Flavor)
   149  	d.Set("provider", lb.Provider)
   150  
   151  	return nil
   152  }
   153  
   154  func resourceLoadBalancerV2Update(d *schema.ResourceData, meta interface{}) error {
   155  	config := meta.(*Config)
   156  	networkingClient, err := config.networkingV2Client(d.Get("region").(string))
   157  	if err != nil {
   158  		return fmt.Errorf("Error creating OpenStack networking client: %s", err)
   159  	}
   160  
   161  	var updateOpts loadbalancers.UpdateOpts
   162  	if d.HasChange("name") {
   163  		updateOpts.Name = d.Get("name").(string)
   164  	}
   165  	if d.HasChange("description") {
   166  		updateOpts.Description = d.Get("description").(string)
   167  	}
   168  	if d.HasChange("admin_state_up") {
   169  		asu := d.Get("admin_state_up").(bool)
   170  		updateOpts.AdminStateUp = &asu
   171  	}
   172  
   173  	log.Printf("[DEBUG] Updating OpenStack LBaaSV2 LoadBalancer %s with options: %+v", d.Id(), updateOpts)
   174  
   175  	_, err = loadbalancers.Update(networkingClient, d.Id(), updateOpts).Extract()
   176  	if err != nil {
   177  		return fmt.Errorf("Error updating OpenStack LBaaSV2 LoadBalancer: %s", err)
   178  	}
   179  
   180  	return resourceLoadBalancerV2Read(d, meta)
   181  }
   182  
   183  func resourceLoadBalancerV2Delete(d *schema.ResourceData, meta interface{}) error {
   184  	config := meta.(*Config)
   185  	networkingClient, err := config.networkingV2Client(d.Get("region").(string))
   186  	if err != nil {
   187  		return fmt.Errorf("Error creating OpenStack networking client: %s", err)
   188  	}
   189  
   190  	stateConf := &resource.StateChangeConf{
   191  		Pending:    []string{"ACTIVE", "PENDING_DELETE"},
   192  		Target:     []string{"DELETED"},
   193  		Refresh:    waitForLoadBalancerDelete(networkingClient, d.Id()),
   194  		Timeout:    2 * time.Minute,
   195  		Delay:      5 * time.Second,
   196  		MinTimeout: 3 * time.Second,
   197  	}
   198  
   199  	_, err = stateConf.WaitForState()
   200  	if err != nil {
   201  		return fmt.Errorf("Error deleting OpenStack LB Pool: %s", err)
   202  	}
   203  
   204  	d.SetId("")
   205  	return nil
   206  }
   207  
   208  func waitForLoadBalancerActive(networkingClient *gophercloud.ServiceClient, lbID string) resource.StateRefreshFunc {
   209  	return func() (interface{}, string, error) {
   210  		lb, err := loadbalancers.Get(networkingClient, lbID).Extract()
   211  		if err != nil {
   212  			return nil, "", err
   213  		}
   214  
   215  		log.Printf("[DEBUG] OpenStack LoadBalancer: %+v", lb)
   216  		if lb.ProvisioningStatus == "ACTIVE" {
   217  			return lb, "ACTIVE", nil
   218  		}
   219  
   220  		return lb, lb.ProvisioningStatus, nil
   221  	}
   222  }
   223  
   224  func waitForLoadBalancerDelete(networkingClient *gophercloud.ServiceClient, lbID string) resource.StateRefreshFunc {
   225  	return func() (interface{}, string, error) {
   226  		log.Printf("[DEBUG] Attempting to delete OpenStack LoadBalancerV2 %s", lbID)
   227  
   228  		lb, err := loadbalancers.Get(networkingClient, lbID).Extract()
   229  		if err != nil {
   230  			errCode, ok := err.(*gophercloud.UnexpectedResponseCodeError)
   231  			if !ok {
   232  				return lb, "ACTIVE", err
   233  			}
   234  			if errCode.Actual == 404 {
   235  				log.Printf("[DEBUG] Successfully deleted OpenStack LoadBalancerV2 %s", lbID)
   236  				return lb, "DELETED", nil
   237  			}
   238  		}
   239  
   240  		log.Printf("[DEBUG] Openstack LoadBalancerV2: %+v", lb)
   241  		err = loadbalancers.Delete(networkingClient, lbID).ExtractErr()
   242  		if err != nil {
   243  			errCode, ok := err.(*gophercloud.UnexpectedResponseCodeError)
   244  			if !ok {
   245  				return lb, "ACTIVE", err
   246  			}
   247  			if errCode.Actual == 404 {
   248  				log.Printf("[DEBUG] Successfully deleted OpenStack LoadBalancerV2 %s", lbID)
   249  				return lb, "DELETED", nil
   250  			}
   251  		}
   252  
   253  		log.Printf("[DEBUG] OpenStack LoadBalancerV2 %s still active.", lbID)
   254  		return lb, "ACTIVE", nil
   255  	}
   256  }