github.com/mohanarpit/terraform@v0.6.16-0.20160909104007-291f29853544/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  		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  	updateOpts := members.UpdateOpts{
   108  		AdminStateUp: d.Get("admin_state_up").(bool),
   109  	}
   110  
   111  	log.Printf("[DEBUG] OpenStack LB Member Update Options: %#v", createOpts)
   112  	m, err = members.Update(networkingClient, m.ID, updateOpts).Extract()
   113  	if err != nil {
   114  		return fmt.Errorf("Error updating OpenStack LB member: %s", err)
   115  	}
   116  
   117  	return resourceLBMemberV1Read(d, meta)
   118  }
   119  
   120  func resourceLBMemberV1Read(d *schema.ResourceData, meta interface{}) error {
   121  	config := meta.(*Config)
   122  	networkingClient, err := config.networkingV2Client(d.Get("region").(string))
   123  	if err != nil {
   124  		return fmt.Errorf("Error creating OpenStack networking client: %s", err)
   125  	}
   126  
   127  	m, err := members.Get(networkingClient, d.Id()).Extract()
   128  	if err != nil {
   129  		return CheckDeleted(d, err, "LB member")
   130  	}
   131  
   132  	log.Printf("[DEBUG] Retreived OpenStack LB member %s: %+v", d.Id(), m)
   133  
   134  	d.Set("address", m.Address)
   135  	d.Set("pool_id", m.PoolID)
   136  	d.Set("port", m.ProtocolPort)
   137  	d.Set("weight", m.Weight)
   138  	d.Set("admin_state_up", m.AdminStateUp)
   139  
   140  	return nil
   141  }
   142  
   143  func resourceLBMemberV1Update(d *schema.ResourceData, meta interface{}) error {
   144  	config := meta.(*Config)
   145  	networkingClient, err := config.networkingV2Client(d.Get("region").(string))
   146  	if err != nil {
   147  		return fmt.Errorf("Error creating OpenStack networking client: %s", err)
   148  	}
   149  
   150  	var updateOpts members.UpdateOpts
   151  	if d.HasChange("admin_state_up") {
   152  		asu := d.Get("admin_state_up").(bool)
   153  		updateOpts.AdminStateUp = asu
   154  	}
   155  
   156  	log.Printf("[DEBUG] Updating LB member %s with options: %+v", d.Id(), updateOpts)
   157  
   158  	_, err = members.Update(networkingClient, d.Id(), updateOpts).Extract()
   159  	if err != nil {
   160  		return fmt.Errorf("Error updating OpenStack LB member: %s", err)
   161  	}
   162  
   163  	return resourceLBMemberV1Read(d, meta)
   164  }
   165  
   166  func resourceLBMemberV1Delete(d *schema.ResourceData, meta interface{}) error {
   167  	config := meta.(*Config)
   168  	networkingClient, err := config.networkingV2Client(d.Get("region").(string))
   169  	if err != nil {
   170  		return fmt.Errorf("Error creating OpenStack networking client: %s", err)
   171  	}
   172  
   173  	err = members.Delete(networkingClient, d.Id()).ExtractErr()
   174  	if err != nil {
   175  		CheckDeleted(d, err, "LB member")
   176  	}
   177  
   178  	stateConf := &resource.StateChangeConf{
   179  		Pending:    []string{"ACTIVE", "PENDING_DELETE"},
   180  		Target:     []string{"DELETED"},
   181  		Refresh:    waitForLBMemberDelete(networkingClient, d.Id()),
   182  		Timeout:    2 * time.Minute,
   183  		Delay:      5 * time.Second,
   184  		MinTimeout: 3 * time.Second,
   185  	}
   186  
   187  	_, err = stateConf.WaitForState()
   188  	if err != nil {
   189  		return fmt.Errorf("Error deleting OpenStack LB member: %s", err)
   190  	}
   191  
   192  	d.SetId("")
   193  	return nil
   194  }
   195  
   196  func waitForLBMemberActive(networkingClient *gophercloud.ServiceClient, memberId string) resource.StateRefreshFunc {
   197  	return func() (interface{}, string, error) {
   198  		m, err := members.Get(networkingClient, memberId).Extract()
   199  		if err != nil {
   200  			return nil, "", err
   201  		}
   202  
   203  		log.Printf("[DEBUG] OpenStack LB member: %+v", m)
   204  		if m.Status == "ACTIVE" {
   205  			return m, "ACTIVE", nil
   206  		}
   207  
   208  		return m, m.Status, nil
   209  	}
   210  }
   211  
   212  func waitForLBMemberDelete(networkingClient *gophercloud.ServiceClient, memberId string) resource.StateRefreshFunc {
   213  	return func() (interface{}, string, error) {
   214  		log.Printf("[DEBUG] Attempting to delete OpenStack LB member %s", memberId)
   215  
   216  		m, err := members.Get(networkingClient, memberId).Extract()
   217  		if err != nil {
   218  			errCode, ok := err.(*gophercloud.UnexpectedResponseCodeError)
   219  			if !ok {
   220  				return m, "ACTIVE", err
   221  			}
   222  			if errCode.Actual == 404 {
   223  				log.Printf("[DEBUG] Successfully deleted OpenStack LB member %s", memberId)
   224  				return m, "DELETED", nil
   225  			}
   226  		}
   227  
   228  		log.Printf("[DEBUG] OpenStack LB member %s still active.", memberId)
   229  		return m, "ACTIVE", nil
   230  	}
   231  
   232  }