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