provider/aws: Rework Beanstalk optional polling

expose a poll_interval for users to configure polling for updates
This commit is contained in:
clint shryock 2016-07-13 15:38:23 -06:00
parent 533e7aca34
commit de60481428
2 changed files with 71 additions and 53 deletions

View File

@ -137,7 +137,6 @@ func resourceAwsElasticBeanstalkEnvironment() *schema.Resource {
"poll_interval": &schema.Schema{ "poll_interval": &schema.Schema{
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Default: "10s",
ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) { ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) {
value := v.(string) value := v.(string)
duration, err := time.ParseDuration(value) duration, err := time.ParseDuration(value)
@ -261,9 +260,10 @@ func resourceAwsElasticBeanstalkEnvironmentCreate(d *schema.ResourceData, meta i
if err != nil { if err != nil {
return err return err
} }
pollInterval, err := time.ParseDuration(d.Get("poll_interval").(string)) pollInterval, err := time.ParseDuration(d.Get("poll_interval").(string))
if err != nil { if err != nil {
return err log.Printf("[WARN] Error parsing poll_interval, using default backoff")
} }
stateConf := &resource.StateChangeConf{ stateConf := &resource.StateChangeConf{
@ -272,7 +272,8 @@ func resourceAwsElasticBeanstalkEnvironmentCreate(d *schema.ResourceData, meta i
Refresh: environmentStateRefreshFunc(conn, d.Id()), Refresh: environmentStateRefreshFunc(conn, d.Id()),
Timeout: waitForReadyTimeOut, Timeout: waitForReadyTimeOut,
Delay: 10 * time.Second, Delay: 10 * time.Second,
MinTimeout: pollInterval, PollInterval: pollInterval,
MinTimeout: 3 * time.Second,
} }
_, err = stateConf.WaitForState() _, err = stateConf.WaitForState()
@ -295,19 +296,24 @@ func resourceAwsElasticBeanstalkEnvironmentUpdate(d *schema.ResourceData, meta i
envId := d.Id() envId := d.Id()
var hasChange bool
updateOpts := elasticbeanstalk.UpdateEnvironmentInput{ updateOpts := elasticbeanstalk.UpdateEnvironmentInput{
EnvironmentId: aws.String(envId), EnvironmentId: aws.String(envId),
} }
if d.HasChange("description") { if d.HasChange("description") {
hasChange = true
updateOpts.Description = aws.String(d.Get("description").(string)) updateOpts.Description = aws.String(d.Get("description").(string))
} }
if d.HasChange("solution_stack_name") { if d.HasChange("solution_stack_name") {
hasChange = true
updateOpts.SolutionStackName = aws.String(d.Get("solution_stack_name").(string)) updateOpts.SolutionStackName = aws.String(d.Get("solution_stack_name").(string))
} }
if d.HasChange("setting") { if d.HasChange("setting") {
hasChange = true
o, n := d.GetChange("setting") o, n := d.GetChange("setting")
if o == nil { if o == nil {
o = &schema.Set{F: optionSettingValueHash} o = &schema.Set{F: optionSettingValueHash}
@ -323,9 +329,11 @@ func resourceAwsElasticBeanstalkEnvironmentUpdate(d *schema.ResourceData, meta i
} }
if d.HasChange("template_name") { if d.HasChange("template_name") {
hasChange = true
updateOpts.TemplateName = aws.String(d.Get("template_name").(string)) updateOpts.TemplateName = aws.String(d.Get("template_name").(string))
} }
if hasChange {
// Get the current time to filter describeBeanstalkEvents messages // Get the current time to filter describeBeanstalkEvents messages
t := time.Now() t := time.Now()
log.Printf("[DEBUG] Elastic Beanstalk Environment update opts: %s", updateOpts) log.Printf("[DEBUG] Elastic Beanstalk Environment update opts: %s", updateOpts)
@ -340,7 +348,7 @@ func resourceAwsElasticBeanstalkEnvironmentUpdate(d *schema.ResourceData, meta i
} }
pollInterval, err := time.ParseDuration(d.Get("poll_interval").(string)) pollInterval, err := time.ParseDuration(d.Get("poll_interval").(string))
if err != nil { if err != nil {
return err log.Printf("[WARN] Error parsing poll_interval, using default backoff")
} }
stateConf := &resource.StateChangeConf{ stateConf := &resource.StateChangeConf{
@ -349,7 +357,8 @@ func resourceAwsElasticBeanstalkEnvironmentUpdate(d *schema.ResourceData, meta i
Refresh: environmentStateRefreshFunc(conn, d.Id()), Refresh: environmentStateRefreshFunc(conn, d.Id()),
Timeout: waitForReadyTimeOut, Timeout: waitForReadyTimeOut,
Delay: 10 * time.Second, Delay: 10 * time.Second,
MinTimeout: pollInterval, PollInterval: pollInterval,
MinTimeout: 3 * time.Second,
} }
_, err = stateConf.WaitForState() _, err = stateConf.WaitForState()
@ -363,6 +372,7 @@ func resourceAwsElasticBeanstalkEnvironmentUpdate(d *schema.ResourceData, meta i
if err != nil { if err != nil {
return err return err
} }
}
return resourceAwsElasticBeanstalkEnvironmentRead(d, meta) return resourceAwsElasticBeanstalkEnvironmentRead(d, meta)
} }
@ -590,7 +600,7 @@ func resourceAwsElasticBeanstalkEnvironmentDelete(d *schema.ResourceData, meta i
} }
pollInterval, err := time.ParseDuration(d.Get("poll_interval").(string)) pollInterval, err := time.ParseDuration(d.Get("poll_interval").(string))
if err != nil { if err != nil {
return err log.Printf("[WARN] Error parsing poll_interval, using default backoff")
} }
stateConf := &resource.StateChangeConf{ stateConf := &resource.StateChangeConf{
@ -599,7 +609,8 @@ func resourceAwsElasticBeanstalkEnvironmentDelete(d *schema.ResourceData, meta i
Refresh: environmentStateRefreshFunc(conn, d.Id()), Refresh: environmentStateRefreshFunc(conn, d.Id()),
Timeout: waitForReadyTimeOut, Timeout: waitForReadyTimeOut,
Delay: 10 * time.Second, Delay: 10 * time.Second,
MinTimeout: pollInterval, PollInterval: pollInterval,
MinTimeout: 3 * time.Second,
} }
_, err = stateConf.WaitForState() _, err = stateConf.WaitForState()

View File

@ -26,6 +26,7 @@ type StateChangeConf struct {
Target []string // Target state Target []string // Target state
Timeout time.Duration // The amount of time to wait before timeout Timeout time.Duration // The amount of time to wait before timeout
MinTimeout time.Duration // Smallest time to wait before refreshes MinTimeout time.Duration // Smallest time to wait before refreshes
PollInterval time.Duration // Override MinTimeout/backoff and only poll this often
NotFoundChecks int // Number of times to allow not found NotFoundChecks int // Number of times to allow not found
// This is to work around inconsistent APIs // This is to work around inconsistent APIs
@ -72,15 +73,21 @@ func (conf *StateChangeConf) WaitForState() (interface{}, error) {
time.Sleep(conf.Delay) time.Sleep(conf.Delay)
var err error var err error
var wait time.Duration
for tries := 0; ; tries++ { for tries := 0; ; tries++ {
// Wait between refreshes using an exponential backoff // Wait between refreshes using an exponential backoff
wait := time.Duration(math.Pow(2, float64(tries))) * // If a poll interval has been specified, choose that interval
if conf.PollInterval > 0 && conf.PollInterval < 180*time.Second {
wait = conf.PollInterval
} else {
wait = time.Duration(math.Pow(2, float64(tries))) *
100 * time.Millisecond 100 * time.Millisecond
if wait < conf.MinTimeout { if wait < conf.MinTimeout {
wait = conf.MinTimeout wait = conf.MinTimeout
} else if wait > 10*time.Second { } else if wait > 10*time.Second {
wait = 10 * time.Second wait = 10 * time.Second
} }
}
log.Printf("[TRACE] Waiting %s before next try", wait) log.Printf("[TRACE] Waiting %s before next try", wait)
time.Sleep(wait) time.Sleep(wait)