github.com/memsql/terraform@v0.7.0-rc2.0.20160706152241-21e2173e0a32/builtin/providers/openstack/resource_openstack_lb_member_v1.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/members"
    13  )
    14  
    15  func resourceLBMemberV1() *schema.Resource {
    16  	return &schema.Resource{
    17  		Create: resourceLBMemberV1Create,
    18  		Read:   resourceLBMemberV1Read,
    19  		Update: resourceLBMemberV1Update,
    20  		Delete: resourceLBMemberV1Delete,
    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  			"tenant_id": &schema.Schema{
    30  				Type:     schema.TypeString,
    31  				Optional: true,
    32  				ForceNew: true,
    33  			},
    34  			"pool_id": &schema.Schema{
    35  				Type:     schema.TypeString,
    36  				Required: true,
    37  				ForceNew: true,
    38  			},
    39  			"address": &schema.Schema{
    40  				Type:     schema.TypeString,
    41  				Required: true,
    42  				ForceNew: true,
    43  			},
    44  			"port": &schema.Schema{
    45  				Type:     schema.TypeInt,
    46  				Required: true,
    47  				ForceNew: true,
    48  			},
    49  			"weight": &schema.Schema{
    50  				Type:     schema.TypeInt,
    51  				Optional: true,
    52  				Computed: true,
    53  			},
    54  			"admin_state_up": &schema.Schema{
    55  				Type:     schema.TypeBool,
    56  				Optional: true,
    57  				ForceNew: false,
    58  				Computed: true,
    59  			},
    60  		},
    61  	}
    62  }
    63  
    64  func resourceLBMemberV1Create(d *schema.ResourceData, meta interface{}) error {
    65  	config := meta.(*Config)
    66  	networkingClient, err := config.networkingV2Client(d.Get("region").(string))
    67  	if err != nil {
    68  		return fmt.Errorf("Error creating OpenStack networking client: %s", err)
    69  	}
    70  
    71  	createOpts := members.CreateOpts{
    72  		TenantID:     d.Get("tenant_id").(string),
    73  		PoolID:       d.Get("pool_id").(string),
    74  		Address:      d.Get("address").(string),
    75  		ProtocolPort: d.Get("port").(int),
    76  	}
    77  
    78  	log.Printf("[DEBUG] OpenStack LB Member Create Options: %#v", createOpts)
    79  	m, err := members.Create(networkingClient, createOpts).Extract()
    80  	if err != nil {
    81  		return fmt.Errorf("Error creating OpenStack LB member: %s", err)
    82  	}
    83  	log.Printf("[INFO] LB member ID: %s", m.ID)
    84  
    85  	log.Printf("[DEBUG] Waiting for OpenStack LB member (%s) to become available.", m.ID)
    86  
    87  	stateConf := &resource.StateChangeConf{
    88  		Pending:    []string{"PENDING_CREATE"},
    89  		Target:     []string{"ACTIVE", "INACTIVE"},
    90  		Refresh:    waitForLBMemberActive(networkingClient, m.ID),
    91  		Timeout:    2 * time.Minute,
    92  		Delay:      5 * time.Second,
    93  		MinTimeout: 3 * time.Second,
    94  	}
    95  
    96  	_, err = stateConf.WaitForState()
    97  	if err != nil {
    98  		return err
    99  	}
   100  
   101  	d.SetId(m.ID)
   102  
   103  	// Due to the way Gophercloud is currently set up, AdminStateUp must be set post-create
   104  	updateOpts := members.UpdateOpts{
   105  		AdminStateUp: d.Get("admin_state_up").(bool),
   106  	}
   107  
   108  	log.Printf("[DEBUG] OpenStack LB Member Update Options: %#v", createOpts)
   109  	m, err = members.Update(networkingClient, m.ID, updateOpts).Extract()
   110  	if err != nil {
   111  		return fmt.Errorf("Error updating OpenStack LB member: %s", err)
   112  	}
   113  
   114  	return resourceLBMemberV1Read(d, meta)
   115  }
   116  
   117  func resourceLBMemberV1Read(d *schema.ResourceData, meta interface{}) error {
   118  	config := meta.(*Config)
   119  	networkingClient, err := config.networkingV2Client(d.Get("region").(string))
   120  	if err != nil {
   121  		return fmt.Errorf("Error creating OpenStack networking client: %s", err)
   122  	}
   123  
   124  	m, err := members.Get(networkingClient, d.Id()).Extract()
   125  	if err != nil {
   126  		return CheckDeleted(d, err, "LB member")
   127  	}
   128  
   129  	log.Printf("[DEBUG] Retreived OpenStack LB member %s: %+v", d.Id(), m)
   130  
   131  	d.Set("weight", m.Weight)
   132  	d.Set("admin_state_up", m.AdminStateUp)
   133  
   134  	return nil
   135  }
   136  
   137  func resourceLBMemberV1Update(d *schema.ResourceData, meta interface{}) error {
   138  	config := meta.(*Config)
   139  	networkingClient, err := config.networkingV2Client(d.Get("region").(string))
   140  	if err != nil {
   141  		return fmt.Errorf("Error creating OpenStack networking client: %s", err)
   142  	}
   143  
   144  	var updateOpts members.UpdateOpts
   145  	if d.HasChange("admin_state_up") {
   146  		asu := d.Get("admin_state_up").(bool)
   147  		updateOpts.AdminStateUp = asu
   148  	}
   149  
   150  	log.Printf("[DEBUG] Updating LB member %s with options: %+v", d.Id(), updateOpts)
   151  
   152  	_, err = members.Update(networkingClient, d.Id(), updateOpts).Extract()
   153  	if err != nil {
   154  		return fmt.Errorf("Error updating OpenStack LB member: %s", err)
   155  	}
   156  
   157  	return resourceLBMemberV1Read(d, meta)
   158  }
   159  
   160  func resourceLBMemberV1Delete(d *schema.ResourceData, meta interface{}) error {
   161  	config := meta.(*Config)
   162  	networkingClient, err := config.networkingV2Client(d.Get("region").(string))
   163  	if err != nil {
   164  		return fmt.Errorf("Error creating OpenStack networking client: %s", err)
   165  	}
   166  
   167  	err = members.Delete(networkingClient, d.Id()).ExtractErr()
   168  	if err != nil {
   169  		CheckDeleted(d, err, "LB member")
   170  	}
   171  
   172  	stateConf := &resource.StateChangeConf{
   173  		Pending:    []string{"ACTIVE", "PENDING_DELETE"},
   174  		Target:     []string{"DELETED"},
   175  		Refresh:    waitForLBMemberDelete(networkingClient, d.Id()),
   176  		Timeout:    2 * time.Minute,
   177  		Delay:      5 * time.Second,
   178  		MinTimeout: 3 * time.Second,
   179  	}
   180  
   181  	_, err = stateConf.WaitForState()
   182  	if err != nil {
   183  		return fmt.Errorf("Error deleting OpenStack LB member: %s", err)
   184  	}
   185  
   186  	d.SetId("")
   187  	return nil
   188  }
   189  
   190  func waitForLBMemberActive(networkingClient *gophercloud.ServiceClient, memberId string) resource.StateRefreshFunc {
   191  	return func() (interface{}, string, error) {
   192  		m, err := members.Get(networkingClient, memberId).Extract()
   193  		if err != nil {
   194  			return nil, "", err
   195  		}
   196  
   197  		log.Printf("[DEBUG] OpenStack LB member: %+v", m)
   198  		if m.Status == "ACTIVE" {
   199  			return m, "ACTIVE", nil
   200  		}
   201  
   202  		return m, m.Status, nil
   203  	}
   204  }
   205  
   206  func waitForLBMemberDelete(networkingClient *gophercloud.ServiceClient, memberId string) resource.StateRefreshFunc {
   207  	return func() (interface{}, string, error) {
   208  		log.Printf("[DEBUG] Attempting to delete OpenStack LB member %s", memberId)
   209  
   210  		m, err := members.Get(networkingClient, memberId).Extract()
   211  		if err != nil {
   212  			errCode, ok := err.(*gophercloud.UnexpectedResponseCodeError)
   213  			if !ok {
   214  				return m, "ACTIVE", err
   215  			}
   216  			if errCode.Actual == 404 {
   217  				log.Printf("[DEBUG] Successfully deleted OpenStack LB member %s", memberId)
   218  				return m, "DELETED", nil
   219  			}
   220  		}
   221  
   222  		log.Printf("[DEBUG] OpenStack LB member %s still active.", memberId)
   223  		return m, "ACTIVE", nil
   224  	}
   225  
   226  }