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