github.com/vtorhonen/terraform@v0.9.0-beta2.0.20170307220345-5d894e4ffda7/builtin/providers/openstack/resource_openstack_lb_monitor_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/gophercloud/gophercloud"
    12  	"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/monitors"
    13  )
    14  
    15  func resourceMonitorV2() *schema.Resource {
    16  	return &schema.Resource{
    17  		Create: resourceMonitorV2Create,
    18  		Read:   resourceMonitorV2Read,
    19  		Update: resourceMonitorV2Update,
    20  		Delete: resourceMonitorV2Delete,
    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  			"pool_id": &schema.Schema{
    31  				Type:     schema.TypeString,
    32  				Required: true,
    33  				ForceNew: true,
    34  			},
    35  
    36  			"name": &schema.Schema{
    37  				Type:     schema.TypeString,
    38  				Optional: true,
    39  			},
    40  
    41  			"tenant_id": &schema.Schema{
    42  				Type:     schema.TypeString,
    43  				Optional: true,
    44  				Computed: true,
    45  				ForceNew: true,
    46  			},
    47  
    48  			"type": &schema.Schema{
    49  				Type:     schema.TypeString,
    50  				Required: true,
    51  				ForceNew: true,
    52  			},
    53  			"delay": &schema.Schema{
    54  				Type:     schema.TypeInt,
    55  				Required: true,
    56  			},
    57  			"timeout": &schema.Schema{
    58  				Type:     schema.TypeInt,
    59  				Required: true,
    60  			},
    61  			"max_retries": &schema.Schema{
    62  				Type:     schema.TypeInt,
    63  				Required: true,
    64  			},
    65  			"url_path": &schema.Schema{
    66  				Type:     schema.TypeString,
    67  				Optional: true,
    68  				Computed: true,
    69  			},
    70  			"http_method": &schema.Schema{
    71  				Type:     schema.TypeString,
    72  				Optional: true,
    73  				Computed: true,
    74  			},
    75  			"expected_codes": &schema.Schema{
    76  				Type:     schema.TypeString,
    77  				Optional: true,
    78  				Computed: true,
    79  			},
    80  			"admin_state_up": &schema.Schema{
    81  				Type:     schema.TypeBool,
    82  				Default:  true,
    83  				Optional: true,
    84  			},
    85  
    86  			"id": &schema.Schema{
    87  				Type:     schema.TypeString,
    88  				Optional: true,
    89  				Computed: true,
    90  			},
    91  		},
    92  	}
    93  }
    94  
    95  func resourceMonitorV2Create(d *schema.ResourceData, meta interface{}) error {
    96  	config := meta.(*Config)
    97  	networkingClient, err := config.networkingV2Client(GetRegion(d))
    98  	if err != nil {
    99  		return fmt.Errorf("Error creating OpenStack networking client: %s", err)
   100  	}
   101  
   102  	adminStateUp := d.Get("admin_state_up").(bool)
   103  	createOpts := monitors.CreateOpts{
   104  		PoolID:        d.Get("pool_id").(string),
   105  		TenantID:      d.Get("tenant_id").(string),
   106  		Type:          d.Get("type").(string),
   107  		Delay:         d.Get("delay").(int),
   108  		Timeout:       d.Get("timeout").(int),
   109  		MaxRetries:    d.Get("max_retries").(int),
   110  		URLPath:       d.Get("url_path").(string),
   111  		HTTPMethod:    d.Get("http_method").(string),
   112  		ExpectedCodes: d.Get("expected_codes").(string),
   113  		Name:          d.Get("name").(string),
   114  		AdminStateUp:  &adminStateUp,
   115  	}
   116  
   117  	log.Printf("[DEBUG] Create Options: %#v", createOpts)
   118  	monitor, err := monitors.Create(networkingClient, createOpts).Extract()
   119  	if err != nil {
   120  		return fmt.Errorf("Error creating OpenStack LBaaSV2 monitor: %s", err)
   121  	}
   122  	log.Printf("[INFO] monitor ID: %s", monitor.ID)
   123  
   124  	log.Printf("[DEBUG] Waiting for Openstack LBaaSV2 monitor (%s) to become available.", monitor.ID)
   125  
   126  	stateConf := &resource.StateChangeConf{
   127  		Pending:    []string{"PENDING_CREATE"},
   128  		Target:     []string{"ACTIVE"},
   129  		Refresh:    waitForMonitorActive(networkingClient, monitor.ID),
   130  		Timeout:    2 * time.Minute,
   131  		Delay:      5 * time.Second,
   132  		MinTimeout: 3 * time.Second,
   133  	}
   134  
   135  	_, err = stateConf.WaitForState()
   136  	if err != nil {
   137  		return err
   138  	}
   139  
   140  	d.SetId(monitor.ID)
   141  
   142  	return resourceMonitorV2Read(d, meta)
   143  }
   144  
   145  func resourceMonitorV2Read(d *schema.ResourceData, meta interface{}) error {
   146  	config := meta.(*Config)
   147  	networkingClient, err := config.networkingV2Client(GetRegion(d))
   148  	if err != nil {
   149  		return fmt.Errorf("Error creating OpenStack networking client: %s", err)
   150  	}
   151  
   152  	monitor, err := monitors.Get(networkingClient, d.Id()).Extract()
   153  	if err != nil {
   154  		return CheckDeleted(d, err, "LBV2 Monitor")
   155  	}
   156  
   157  	log.Printf("[DEBUG] Retrieved OpenStack LBaaSV2 Monitor %s: %+v", d.Id(), monitor)
   158  
   159  	d.Set("id", monitor.ID)
   160  	d.Set("tenant_id", monitor.TenantID)
   161  	d.Set("type", monitor.Type)
   162  	d.Set("delay", monitor.Delay)
   163  	d.Set("timeout", monitor.Timeout)
   164  	d.Set("max_retries", monitor.MaxRetries)
   165  	d.Set("url_path", monitor.URLPath)
   166  	d.Set("http_method", monitor.HTTPMethod)
   167  	d.Set("expected_codes", monitor.ExpectedCodes)
   168  	d.Set("admin_state_up", monitor.AdminStateUp)
   169  	d.Set("name", monitor.Name)
   170  
   171  	return nil
   172  }
   173  
   174  func resourceMonitorV2Update(d *schema.ResourceData, meta interface{}) error {
   175  	config := meta.(*Config)
   176  	networkingClient, err := config.networkingV2Client(GetRegion(d))
   177  	if err != nil {
   178  		return fmt.Errorf("Error creating OpenStack networking client: %s", err)
   179  	}
   180  
   181  	var updateOpts monitors.UpdateOpts
   182  	if d.HasChange("url_path") {
   183  		updateOpts.URLPath = d.Get("url_path").(string)
   184  	}
   185  	if d.HasChange("expected_codes") {
   186  		updateOpts.ExpectedCodes = d.Get("expected_codes").(string)
   187  	}
   188  	if d.HasChange("delay") {
   189  		updateOpts.Delay = d.Get("delay").(int)
   190  	}
   191  	if d.HasChange("timeout") {
   192  		updateOpts.Timeout = d.Get("timeout").(int)
   193  	}
   194  	if d.HasChange("max_retries") {
   195  		updateOpts.MaxRetries = d.Get("max_retries").(int)
   196  	}
   197  	if d.HasChange("admin_state_up") {
   198  		asu := d.Get("admin_state_up").(bool)
   199  		updateOpts.AdminStateUp = &asu
   200  	}
   201  	if d.HasChange("name") {
   202  		updateOpts.Name = d.Get("name").(string)
   203  	}
   204  	if d.HasChange("http_method") {
   205  		updateOpts.HTTPMethod = d.Get("http_method").(string)
   206  	}
   207  
   208  	log.Printf("[DEBUG] Updating OpenStack LBaaSV2 Monitor %s with options: %+v", d.Id(), updateOpts)
   209  
   210  	_, err = monitors.Update(networkingClient, d.Id(), updateOpts).Extract()
   211  	if err != nil {
   212  		return fmt.Errorf("Error updating OpenStack LBaaSV2 Monitor: %s", err)
   213  	}
   214  
   215  	return resourceMonitorV2Read(d, meta)
   216  }
   217  
   218  func resourceMonitorV2Delete(d *schema.ResourceData, meta interface{}) error {
   219  	config := meta.(*Config)
   220  	networkingClient, err := config.networkingV2Client(GetRegion(d))
   221  	if err != nil {
   222  		return fmt.Errorf("Error creating OpenStack networking client: %s", err)
   223  	}
   224  
   225  	stateConf := &resource.StateChangeConf{
   226  		Pending:    []string{"ACTIVE", "PENDING_DELETE"},
   227  		Target:     []string{"DELETED"},
   228  		Refresh:    waitForMonitorDelete(networkingClient, d.Id()),
   229  		Timeout:    2 * time.Minute,
   230  		Delay:      5 * time.Second,
   231  		MinTimeout: 3 * time.Second,
   232  	}
   233  
   234  	_, err = stateConf.WaitForState()
   235  	if err != nil {
   236  		return fmt.Errorf("Error deleting OpenStack LBaaSV2 Monitor: %s", err)
   237  	}
   238  
   239  	d.SetId("")
   240  	return nil
   241  }
   242  
   243  func waitForMonitorActive(networkingClient *gophercloud.ServiceClient, monitorID string) resource.StateRefreshFunc {
   244  	return func() (interface{}, string, error) {
   245  		monitor, err := monitors.Get(networkingClient, monitorID).Extract()
   246  		if err != nil {
   247  			return nil, "", err
   248  		}
   249  
   250  		log.Printf("[DEBUG] OpenStack LBaaSV2 Monitor: %+v", monitor)
   251  		return monitor, "ACTIVE", nil
   252  	}
   253  }
   254  
   255  func waitForMonitorDelete(networkingClient *gophercloud.ServiceClient, monitorID string) resource.StateRefreshFunc {
   256  	return func() (interface{}, string, error) {
   257  		log.Printf("[DEBUG] Attempting to delete OpenStack LBaaSV2 Monitor %s", monitorID)
   258  
   259  		monitor, err := monitors.Get(networkingClient, monitorID).Extract()
   260  		if err != nil {
   261  			if _, ok := err.(gophercloud.ErrDefault404); ok {
   262  				log.Printf("[DEBUG] Successfully deleted OpenStack LBaaSV2 Monitor %s", monitorID)
   263  				return monitor, "DELETED", nil
   264  			}
   265  			return monitor, "ACTIVE", err
   266  		}
   267  
   268  		log.Printf("[DEBUG] Openstack LBaaSV2 Monitor: %+v", monitor)
   269  		err = monitors.Delete(networkingClient, monitorID).ExtractErr()
   270  		if err != nil {
   271  			if _, ok := err.(gophercloud.ErrDefault404); ok {
   272  				log.Printf("[DEBUG] Successfully deleted OpenStack LBaaSV2 Monitor %s", monitorID)
   273  				return monitor, "DELETED", nil
   274  			}
   275  
   276  			if errCode, ok := err.(gophercloud.ErrUnexpectedResponseCode); ok {
   277  				if errCode.Actual == 409 {
   278  					log.Printf("[DEBUG] OpenStack LBaaSV2 Monitor (%s) is still in use.", monitorID)
   279  					return monitor, "ACTIVE", nil
   280  				}
   281  			}
   282  
   283  			return monitor, "ACTIVE", err
   284  		}
   285  
   286  		log.Printf("[DEBUG] OpenStack LBaaSV2 Monitor %s still active.", monitorID)
   287  		return monitor, "ACTIVE", nil
   288  	}
   289  }