diff --git a/Makefile b/Makefile index c1385cb4..3738d5a1 100644 --- a/Makefile +++ b/Makefile @@ -19,7 +19,7 @@ GOVERSION := 1.14 PROJECT := github.com/DeviaVir/terraform-provider-gsuite OWNER := $(notdir $(patsubst %/,%,$(dir $(PROJECT)))) NAME := $(notdir $(PROJECT)) -VERSION := 0.1.42 +VERSION := 0.1.44 EXTERNAL_TOOLS = \ github.com/golang/dep/cmd/dep diff --git a/gsuite/resource_group_settings.go b/gsuite/resource_group_settings.go index 104b758e..85f10b40 100644 --- a/gsuite/resource_group_settings.go +++ b/gsuite/resource_group_settings.go @@ -734,7 +734,7 @@ func resourceGroupSettingsRead(d *schema.ResourceData, meta interface{}) error { var err error var groupSetting *groupSettings.Groups - err = retry(func() error { + err = retryInvalid(func() error { groupSetting, err = config.groupSettings.Groups.Get(d.Get("email").(string)).Do() return err }, config.TimeoutMinutes) diff --git a/gsuite/utils.go b/gsuite/utils.go index 4da8909e..4d9d3b53 100644 --- a/gsuite/utils.go +++ b/gsuite/utils.go @@ -28,35 +28,48 @@ func handleNotFoundError(err error, d *schema.ResourceData, resource string) err } func retry(retryFunc func() error, minutes int) error { - return retryTime(retryFunc, minutes, false, false) + return retryTime(retryFunc, minutes, false, false, false) } func retryNotFound(retryFunc func() error, minutes int) error { - return retryTime(retryFunc, minutes, true, false) + return retryTime(retryFunc, minutes, true, false, false) +} + +func retryInvalid(retryFunc func() error, minutes int) error { + return retryTime(retryFunc, minutes, false, false, true) } func retryPassDuplicate(retryFunc func() error, minutes int) error { - return retryTime(retryFunc, minutes, true, true) + return retryTime(retryFunc, minutes, true, true, false) } -func retryTime(retryFunc func() error, minutes int, retryNotFound bool, retryPassDuplicate bool) error { +func retryTime(retryFunc func() error, minutes int, retryNotFound bool, retryPassDuplicate bool, retryInvalid bool) error { wait := 1 return resource.Retry(time.Duration(minutes)*time.Minute, func() *resource.RetryError { err := retryFunc() if err == nil { return nil } + rand.Seed(time.Now().UnixNano()) randomNumberMiliseconds := rand.Intn(1001) + + if gerr, ok := err.(*googleapi.Error); ok && (gerr.Code == 500 || gerr.Code == 502 || gerr.Code == 503) { + log.Printf("[DEBUG] Retrying server error code...") + time.Sleep(time.Duration(wait)*time.Second + time.Duration(randomNumberMiliseconds)) + wait = wait * 2 + return resource.RetryableError(gerr) + } + if retryPassDuplicate { - if gerr, ok := err.(*googleapi.Error); ok && (gerr.Errors[0].Reason == "quotaExceeded" || gerr.Code == 401 || gerr.Code == 429 || gerr.Code == 500 || gerr.Code == 502 || gerr.Code == 503) { + if gerr, ok := err.(*googleapi.Error); ok && (gerr.Errors[0].Reason == "quotaExceeded" || gerr.Code == 401 || gerr.Code == 429) { log.Printf("[DEBUG] Retrying quota/server error code...") time.Sleep(time.Duration(wait)*time.Second + time.Duration(randomNumberMiliseconds)) wait = wait * 2 return resource.RetryableError(gerr) } } else { - if gerr, ok := err.(*googleapi.Error); ok && (gerr.Errors[0].Reason == "quotaExceeded" || gerr.Code == 401 || gerr.Code == 409 || gerr.Code == 429 || gerr.Code == 500 || gerr.Code == 502 || gerr.Code == 503) { + if gerr, ok := err.(*googleapi.Error); ok && (gerr.Errors[0].Reason == "quotaExceeded" || gerr.Code == 401 || gerr.Code == 409 || gerr.Code == 429) { log.Printf("[DEBUG] Retrying quota/server error code...") time.Sleep(time.Duration(wait)*time.Second + time.Duration(randomNumberMiliseconds)) wait = wait * 2 @@ -72,6 +85,15 @@ func retryTime(retryFunc func() error, minutes int, retryNotFound bool, retryPas } } + if retryInvalid { + if gerr, ok := err.(*googleapi.Error); ok && (gerr.Errors[0].Reason == "invalid" || gerr.Code == 400) { + log.Printf("[DEBUG] Retrying invalid error code...") + time.Sleep(time.Duration(wait)*time.Second + time.Duration(randomNumberMiliseconds)) + wait = wait * 2 + return resource.RetryableError(gerr) + } + } + // Deal with the broken API if strings.Contains(fmt.Sprintf("%s", err), "Invalid Input: Bad request for \"") && strings.Contains(fmt.Sprintf("%s", err), "\"code\":400") { log.Printf("[DEBUG] Retrying invalid response from API") @@ -85,10 +107,6 @@ func retryTime(retryFunc func() error, minutes int, retryNotFound bool, retryPas log.Printf("[DEBUG] Retrying due to eventual consistency") return resource.RetryableError(err) } - if strings.Contains(fmt.Sprintf("%s", err), "Invalid Value, invalid") { - log.Printf("[DEBUG] G Suite API could be tripping up, retrying") - return resource.RetryableError(err) - } return resource.NonRetryableError(err) })