diff --git a/google/error_retry_predicates.go b/google/error_retry_predicates.go index d02614392a9..73add242299 100644 --- a/google/error_retry_predicates.go +++ b/google/error_retry_predicates.go @@ -30,10 +30,3 @@ func pubsubTopicProjectNotReady(err error) (bool, string) { } return false, "" } - -func isSqlOperationInProgressError(err error) (bool, string) { - if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 409 { - return true, "Waiting for other concurrent Cloud SQL operations to finish" - } - return false, "" -} diff --git a/google/resource_sql_database_instance.go b/google/resource_sql_database_instance.go index aae49badee9..0732c9d8091 100644 --- a/google/resource_sql_database_instance.go +++ b/google/resource_sql_database_instance.go @@ -490,12 +490,11 @@ func resourceSqlDatabaseInstanceCreate(d *schema.ResourceData, meta interface{}) defer mutexKV.Unlock(instanceMutexKey(project, instance.MasterInstanceName)) } - var op *sqladmin.Operation - err = retryTimeDuration(func() (operr error) { - op, operr = config.clientSqlAdmin.Instances.Insert(project, instance).Do() - return operr - }, d.Timeout(schema.TimeoutCreate), isSqlOperationInProgressError) + op, err := config.clientSqlAdmin.Instances.Insert(project, instance).Do() if err != nil { + if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 409 { + return fmt.Errorf("Error, failed to create instance %s with error code 409: %s. This may be due to a name collision - SQL instance names cannot be reused within a week.", instance.Name, err) + } return fmt.Errorf("Error, failed to create instance %s: %s", instance.Name, err) } @@ -516,10 +515,10 @@ func resourceSqlDatabaseInstanceCreate(d *schema.ResourceData, meta interface{}) // Users in a replica instance are inherited from the master instance and should be left alone. if sqlDatabaseIsMaster(d) { var users *sqladmin.UsersListResponse - err = retryTimeDuration(func() error { + err = retryTime(func() error { users, err = config.clientSqlAdmin.Users.List(project, instance.Name).Do() return err - }, d.Timeout(schema.TimeoutRead), isSqlOperationInProgressError) + }, 5) if err != nil { return fmt.Errorf("Error, attempting to list users associated with instance %s: %s", instance.Name, err) } @@ -702,10 +701,13 @@ func resourceSqlDatabaseInstanceRead(d *schema.ResourceData, meta interface{}) e } var instance *sqladmin.DatabaseInstance - err = retryTimeDuration(func() (rerr error) { - instance, rerr = config.clientSqlAdmin.Instances.Get(project, d.Id()).Do() - return rerr - }, d.Timeout(schema.TimeoutRead), isSqlOperationInProgressError) + err = retry( + func() error { + instance, err = config.clientSqlAdmin.Instances.Get(project, d.Id()).Do() + return err + }, + ) + if err != nil { return handleNotFoundError(err, d, fmt.Sprintf("SQL Database Instance %q", d.Get("name").(string))) } @@ -779,11 +781,7 @@ func resourceSqlDatabaseInstanceUpdate(d *schema.ResourceData, meta interface{}) defer mutexKV.Unlock(instanceMutexKey(project, v.(string))) } - var op *sqladmin.Operation - err = retryTimeDuration(func() (rerr error) { - op, rerr = config.clientSqlAdmin.Instances.Update(project, d.Get("name").(string), instance).Do() - return rerr - }, d.Timeout(schema.TimeoutUpdate), isSqlOperationInProgressError) + op, err := config.clientSqlAdmin.Instances.Update(project, d.Get("name").(string), instance).Do() if err != nil { return fmt.Errorf("Error, failed to update instance settings for %s: %s", instance.Name, err) } @@ -812,10 +810,11 @@ func resourceSqlDatabaseInstanceDelete(d *schema.ResourceData, meta interface{}) } var op *sqladmin.Operation - err = retryTimeDuration(func() (rerr error) { - op, rerr = config.clientSqlAdmin.Instances.Delete(project, d.Get("name").(string)).Do() - return rerr + err = retryTimeDuration(func() error { + op, err = config.clientSqlAdmin.Instances.Delete(project, d.Get("name").(string)).Do() + return err }, d.Timeout(schema.TimeoutDelete)) + if err != nil { return fmt.Errorf("Error, failed to delete instance %s: %s", d.Get("name").(string), err) } diff --git a/google/validation.go b/google/validation.go index b10ceb778fe..f789992bd72 100644 --- a/google/validation.go +++ b/google/validation.go @@ -41,7 +41,7 @@ var ( ServiceAccountLinkRegexPrefix = "projects/" + ProjectRegexWildCard + "/serviceAccounts/" PossibleServiceAccountNames = []string{ - AppEngineServiceAccountNameRegex, + ServiceDefaultAccountNameRegex, ComputeServiceAccountNameRegex, CreatedServiceAccountNameRegex, } @@ -51,12 +51,16 @@ var ( // Format of service accounts created through the API CreatedServiceAccountNameRegex = fmt.Sprintf(RFC1035NameTemplate, 4, 28) + "@" + ProjectNameInDNSFormRegex + "\\.iam\\.gserviceaccount\\.com$" - ProjectNameInDNSFormRegex = "[-a-z0-9\\.]{1,63}" - // Format of default App Engine service accounts created by Google - AppEngineServiceAccountNameRegex = ProjectRegex + "@appspot.gserviceaccount.com" + // Format of service-created service account + // examples are: + // $PROJECTID@cloudbuild.gserviceaccount.com + // $PROJECTID@cloudservices.gserviceaccount.com + // $PROJECTID@appspot.gserviceaccount.com + ServiceDefaultAccountNameRegex = ProjectRegex + "@[a-z]+.gserviceaccount.com$" - ProjectNameRegex = "^[A-Za-z0-9-'\"\\s!]{4,30}$" + ProjectNameInDNSFormRegex = "[-a-z0-9\\.]{1,63}" + ProjectNameRegex = "^[A-Za-z0-9-'\"\\s!]{4,30}$" ) var rfc1918Networks = []string{