github.com/gabrielperezs/terraform@v0.7.0-rc2.0.20160715084931-f7da2612946f/builtin/providers/openstack/resource_openstack_lb_monitor_v1.go (about)

     1  package openstack
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"strconv"
     7  	"time"
     8  
     9  	"github.com/hashicorp/terraform/helper/resource"
    10  	"github.com/hashicorp/terraform/helper/schema"
    11  
    12  	"github.com/rackspace/gophercloud"
    13  	"github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/monitors"
    14  )
    15  
    16  func resourceLBMonitorV1() *schema.Resource {
    17  	return &schema.Resource{
    18  		Create: resourceLBMonitorV1Create,
    19  		Read:   resourceLBMonitorV1Read,
    20  		Update: resourceLBMonitorV1Update,
    21  		Delete: resourceLBMonitorV1Delete,
    22  		Importer: &schema.ResourceImporter{
    23  			State: schema.ImportStatePassthrough,
    24  		},
    25  
    26  		Schema: map[string]*schema.Schema{
    27  			"region": &schema.Schema{
    28  				Type:        schema.TypeString,
    29  				Required:    true,
    30  				ForceNew:    true,
    31  				DefaultFunc: schema.EnvDefaultFunc("OS_REGION_NAME", ""),
    32  			},
    33  			"tenant_id": &schema.Schema{
    34  				Type:     schema.TypeString,
    35  				Optional: true,
    36  				ForceNew: true,
    37  				Computed: true,
    38  			},
    39  			"type": &schema.Schema{
    40  				Type:     schema.TypeString,
    41  				Required: true,
    42  				ForceNew: true,
    43  			},
    44  			"delay": &schema.Schema{
    45  				Type:     schema.TypeInt,
    46  				Required: true,
    47  				ForceNew: false,
    48  			},
    49  			"timeout": &schema.Schema{
    50  				Type:     schema.TypeInt,
    51  				Required: true,
    52  				ForceNew: false,
    53  			},
    54  			"max_retries": &schema.Schema{
    55  				Type:     schema.TypeInt,
    56  				Required: true,
    57  				ForceNew: false,
    58  			},
    59  			"url_path": &schema.Schema{
    60  				Type:     schema.TypeString,
    61  				Optional: true,
    62  				ForceNew: false,
    63  			},
    64  			"http_method": &schema.Schema{
    65  				Type:     schema.TypeString,
    66  				Optional: true,
    67  				ForceNew: false,
    68  			},
    69  			"expected_codes": &schema.Schema{
    70  				Type:     schema.TypeString,
    71  				Optional: true,
    72  				ForceNew: false,
    73  			},
    74  			"admin_state_up": &schema.Schema{
    75  				Type:     schema.TypeString,
    76  				Optional: true,
    77  				ForceNew: false,
    78  				Computed: true,
    79  			},
    80  		},
    81  	}
    82  }
    83  
    84  func resourceLBMonitorV1Create(d *schema.ResourceData, meta interface{}) error {
    85  	config := meta.(*Config)
    86  	networkingClient, err := config.networkingV2Client(d.Get("region").(string))
    87  	if err != nil {
    88  		return fmt.Errorf("Error creating OpenStack networking client: %s", err)
    89  	}
    90  
    91  	createOpts := monitors.CreateOpts{
    92  		TenantID:      d.Get("tenant_id").(string),
    93  		Type:          d.Get("type").(string),
    94  		Delay:         d.Get("delay").(int),
    95  		Timeout:       d.Get("timeout").(int),
    96  		MaxRetries:    d.Get("max_retries").(int),
    97  		URLPath:       d.Get("url_path").(string),
    98  		ExpectedCodes: d.Get("expected_codes").(string),
    99  		HTTPMethod:    d.Get("http_method").(string),
   100  	}
   101  
   102  	asuRaw := d.Get("admin_state_up").(string)
   103  	if asuRaw != "" {
   104  		asu, err := strconv.ParseBool(asuRaw)
   105  		if err != nil {
   106  			return fmt.Errorf("admin_state_up, if provided, must be either 'true' or 'false'")
   107  		}
   108  		createOpts.AdminStateUp = &asu
   109  	}
   110  
   111  	log.Printf("[DEBUG] Create Options: %#v", createOpts)
   112  	m, err := monitors.Create(networkingClient, createOpts).Extract()
   113  	if err != nil {
   114  		return fmt.Errorf("Error creating OpenStack LB Monitor: %s", err)
   115  	}
   116  	log.Printf("[INFO] LB Monitor ID: %s", m.ID)
   117  
   118  	log.Printf("[DEBUG] Waiting for OpenStack LB Monitor (%s) to become available.", m.ID)
   119  
   120  	stateConf := &resource.StateChangeConf{
   121  		Pending:    []string{"PENDING_CREATE"},
   122  		Target:     []string{"ACTIVE"},
   123  		Refresh:    waitForLBMonitorActive(networkingClient, m.ID),
   124  		Timeout:    2 * time.Minute,
   125  		Delay:      5 * time.Second,
   126  		MinTimeout: 3 * time.Second,
   127  	}
   128  
   129  	_, err = stateConf.WaitForState()
   130  	if err != nil {
   131  		return err
   132  	}
   133  
   134  	d.SetId(m.ID)
   135  
   136  	return resourceLBMonitorV1Read(d, meta)
   137  }
   138  
   139  func resourceLBMonitorV1Read(d *schema.ResourceData, meta interface{}) error {
   140  	config := meta.(*Config)
   141  	networkingClient, err := config.networkingV2Client(d.Get("region").(string))
   142  	if err != nil {
   143  		return fmt.Errorf("Error creating OpenStack networking client: %s", err)
   144  	}
   145  
   146  	m, err := monitors.Get(networkingClient, d.Id()).Extract()
   147  	if err != nil {
   148  		return CheckDeleted(d, err, "LB monitor")
   149  	}
   150  
   151  	log.Printf("[DEBUG] Retreived OpenStack LB Monitor %s: %+v", d.Id(), m)
   152  
   153  	d.Set("type", m.Type)
   154  	d.Set("delay", m.Delay)
   155  	d.Set("timeout", m.Timeout)
   156  	d.Set("max_retries", m.MaxRetries)
   157  	d.Set("tenant_id", m.TenantID)
   158  	d.Set("url_path", m.URLPath)
   159  	d.Set("http_method", m.HTTPMethod)
   160  	d.Set("expected_codes", m.ExpectedCodes)
   161  	d.Set("admin_state_up", strconv.FormatBool(m.AdminStateUp))
   162  
   163  	return nil
   164  }
   165  
   166  func resourceLBMonitorV1Update(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  	updateOpts := monitors.UpdateOpts{
   174  		Delay:         d.Get("delay").(int),
   175  		Timeout:       d.Get("timeout").(int),
   176  		MaxRetries:    d.Get("max_retries").(int),
   177  		URLPath:       d.Get("url_path").(string),
   178  		HTTPMethod:    d.Get("http_method").(string),
   179  		ExpectedCodes: d.Get("expected_codes").(string),
   180  	}
   181  
   182  	if d.HasChange("admin_state_up") {
   183  		asuRaw := d.Get("admin_state_up").(string)
   184  		if asuRaw != "" {
   185  			asu, err := strconv.ParseBool(asuRaw)
   186  			if err != nil {
   187  				return fmt.Errorf("admin_state_up, if provided, must be either 'true' or 'false'")
   188  			}
   189  			updateOpts.AdminStateUp = &asu
   190  		}
   191  	}
   192  
   193  	log.Printf("[DEBUG] Updating OpenStack LB Monitor %s with options: %+v", d.Id(), updateOpts)
   194  
   195  	_, err = monitors.Update(networkingClient, d.Id(), updateOpts).Extract()
   196  	if err != nil {
   197  		return fmt.Errorf("Error updating OpenStack LB Monitor: %s", err)
   198  	}
   199  
   200  	return resourceLBMonitorV1Read(d, meta)
   201  }
   202  
   203  func resourceLBMonitorV1Delete(d *schema.ResourceData, meta interface{}) error {
   204  	config := meta.(*Config)
   205  	networkingClient, err := config.networkingV2Client(d.Get("region").(string))
   206  	if err != nil {
   207  		return fmt.Errorf("Error creating OpenStack networking client: %s", err)
   208  	}
   209  
   210  	stateConf := &resource.StateChangeConf{
   211  		Pending:    []string{"ACTIVE", "PENDING_DELETE"},
   212  		Target:     []string{"DELETED"},
   213  		Refresh:    waitForLBMonitorDelete(networkingClient, d.Id()),
   214  		Timeout:    2 * time.Minute,
   215  		Delay:      5 * time.Second,
   216  		MinTimeout: 3 * time.Second,
   217  	}
   218  
   219  	_, err = stateConf.WaitForState()
   220  	if err != nil {
   221  		return fmt.Errorf("Error deleting OpenStack LB Monitor: %s", err)
   222  	}
   223  
   224  	d.SetId("")
   225  	return nil
   226  }
   227  
   228  func waitForLBMonitorActive(networkingClient *gophercloud.ServiceClient, monitorId string) resource.StateRefreshFunc {
   229  	return func() (interface{}, string, error) {
   230  		m, err := monitors.Get(networkingClient, monitorId).Extract()
   231  		if err != nil {
   232  			return nil, "", err
   233  		}
   234  
   235  		// The monitor resource has no Status attribute, so a successful Get is the best we can do
   236  		log.Printf("[DEBUG] OpenStack LB Monitor: %+v", m)
   237  		return m, "ACTIVE", nil
   238  	}
   239  }
   240  
   241  func waitForLBMonitorDelete(networkingClient *gophercloud.ServiceClient, monitorId string) resource.StateRefreshFunc {
   242  	return func() (interface{}, string, error) {
   243  		log.Printf("[DEBUG] Attempting to delete OpenStack LB Monitor %s", monitorId)
   244  
   245  		m, err := monitors.Get(networkingClient, monitorId).Extract()
   246  		if err != nil {
   247  			errCode, ok := err.(*gophercloud.UnexpectedResponseCodeError)
   248  			if !ok {
   249  				return m, "ACTIVE", err
   250  			}
   251  			if errCode.Actual == 404 {
   252  				log.Printf("[DEBUG] Successfully deleted OpenStack LB Monitor %s", monitorId)
   253  				return m, "DELETED", nil
   254  			}
   255  			if errCode.Actual == 409 {
   256  				log.Printf("[DEBUG] OpenStack LB Monitor (%s) is waiting for Pool to delete.", monitorId)
   257  				return m, "PENDING", nil
   258  			}
   259  		}
   260  
   261  		log.Printf("[DEBUG] OpenStack LB Monitor: %+v", m)
   262  		err = monitors.Delete(networkingClient, monitorId).ExtractErr()
   263  		if err != nil {
   264  			errCode, ok := err.(*gophercloud.UnexpectedResponseCodeError)
   265  			if !ok {
   266  				return m, "ACTIVE", err
   267  			}
   268  			if errCode.Actual == 404 {
   269  				log.Printf("[DEBUG] Successfully deleted OpenStack LB Monitor %s", monitorId)
   270  				return m, "DELETED", nil
   271  			}
   272  			if errCode.Actual == 409 {
   273  				log.Printf("[DEBUG] OpenStack LB Monitor (%s) is waiting for Pool to delete.", monitorId)
   274  				return m, "PENDING", nil
   275  			}
   276  		}
   277  
   278  		log.Printf("[DEBUG] OpenStack LB Monitor %s still active.", monitorId)
   279  		return m, "ACTIVE", nil
   280  	}
   281  
   282  }