diff --git a/build/terraform b/build/terraform index d678d7b5ead6..72f6f7fa8cdf 160000 --- a/build/terraform +++ b/build/terraform @@ -1 +1 @@ -Subproject commit d678d7b5ead691d62174100cdd08c2501187a5a6 +Subproject commit 72f6f7fa8cdfec8a53e7f228eba2f2b094cdab12 diff --git a/build/terraform-beta b/build/terraform-beta index 34f73a899d56..647193c245ea 160000 --- a/build/terraform-beta +++ b/build/terraform-beta @@ -1 +1 @@ -Subproject commit 34f73a899d56d5d182644488b3089f87c5905cf5 +Subproject commit 647193c245ea540a411708bfe86ca1c19c583a97 diff --git a/third_party/terraform/data_sources/data_source_google_folder.go b/third_party/terraform/data_sources/data_source_google_folder.go index df634f99dc91..c782eb249021 100644 --- a/third_party/terraform/data_sources/data_source_google_folder.go +++ b/third_party/terraform/data_sources/data_source_google_folder.go @@ -5,8 +5,6 @@ import ( "strings" "github.com/hashicorp/terraform/helper/schema" - - resourceManagerV2Beta1 "google.golang.org/api/cloudresourcemanager/v2beta1" ) func dataSourceGoogleFolder() *schema.Resource { @@ -53,24 +51,17 @@ func dataSourceGoogleFolder() *schema.Resource { func dataSourceFolderRead(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) - folderName := d.Get("folder").(string) - - folder, err := config.clientResourceManagerV2Beta1.Folders.Get(canonicalFolderName(folderName)).Do() - - if err != nil { - return handleNotFoundError(err, d, fmt.Sprintf("Folder Not Found : %s", folderName)) + d.SetId(canonicalFolderName(d.Get("folder").(string))) + if err := resourceGoogleFolderRead(d, meta); err != nil { + return err + } + // If resource doesn't exist, read will not set ID and we should return error. + if d.Id() == "" { + return nil } - - d.SetId(GetResourceNameFromSelfLink(folder.Name)) - d.Set("name", folder.Name) - d.Set("parent", folder.Parent) - d.Set("display_name", folder.DisplayName) - d.Set("lifecycle_state", folder.LifecycleState) - d.Set("create_time", folder.CreateTime) if v, ok := d.GetOk("lookup_organization"); ok && v.(bool) { - organization, err := lookupOrganizationName(folder, config) - + organization, err := lookupOrganizationName(d.Id(), d, config) if err != nil { return err } @@ -89,20 +80,16 @@ func canonicalFolderName(ba string) string { return "folders/" + ba } -func lookupOrganizationName(folder *resourceManagerV2Beta1.Folder, config *Config) (string, error) { - parent := folder.Parent - +func lookupOrganizationName(parent string, d *schema.ResourceData, config *Config) (string, error) { if parent == "" || strings.HasPrefix(parent, "organizations/") { return parent, nil } else if strings.HasPrefix(parent, "folders/") { - parentFolder, err := config.clientResourceManagerV2Beta1.Folders.Get(parent).Do() - + parentFolder, err := getGoogleFolder(parent, d, config) if err != nil { return "", fmt.Errorf("Error getting parent folder '%s': %s", parent, err) } - - return lookupOrganizationName(parentFolder, config) + return lookupOrganizationName(parentFolder.Parent, d, config) } else { - return "", fmt.Errorf("Unknown parent type '%s' on folder '%s'", parent, folder.Name) + return "", fmt.Errorf("Unknown parent type '%s' on folder '%s'", parent, d.Id()) } } diff --git a/third_party/terraform/resources/resource_google_folder.go b/third_party/terraform/resources/resource_google_folder.go index d9079be4b0e7..398b285c151a 100644 --- a/third_party/terraform/resources/resource_google_folder.go +++ b/third_party/terraform/resources/resource_google_folder.go @@ -6,6 +6,7 @@ import ( "github.com/hashicorp/terraform/helper/schema" resourceManagerV2Beta1 "google.golang.org/api/cloudresourcemanager/v2beta1" "strings" + "time" ) func resourceGoogleFolder() *schema.Resource { @@ -19,6 +20,13 @@ func resourceGoogleFolder() *schema.Resource { State: resourceGoogleFolderImportState, }, + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(4 * time.Minute), + Update: schema.DefaultTimeout(4 * time.Minute), + Read: schema.DefaultTimeout(4 * time.Minute), + Delete: schema.DefaultTimeout(4 * time.Minute), + }, + Schema: map[string]*schema.Schema{ // Format is either folders/{folder_id} or organizations/{org_id}. "parent": { @@ -55,10 +63,14 @@ func resourceGoogleFolderCreate(d *schema.ResourceData, meta interface{}) error displayName := d.Get("display_name").(string) parent := d.Get("parent").(string) - op, err := config.clientResourceManagerV2Beta1.Folders.Create(&resourceManagerV2Beta1.Folder{ - DisplayName: displayName, - }).Parent(parent).Do() - + var op *resourceManagerV2Beta1.Operation + err := retryTimeDuration(func() error { + var reqErr error + op, reqErr = config.clientResourceManagerV2Beta1.Folders.Create(&resourceManagerV2Beta1.Folder{ + DisplayName: displayName, + }).Parent(parent).Do() + return reqErr + }, d.Timeout(schema.TimeoutCreate)) if err != nil { return fmt.Errorf("Error creating folder '%s' in '%s': %s", displayName, parent, err) } @@ -95,9 +107,9 @@ func resourceGoogleFolderCreate(d *schema.ResourceData, meta interface{}) error func resourceGoogleFolderRead(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) - folder, err := config.clientResourceManagerV2Beta1.Folders.Get(d.Id()).Do() + folder, err := getGoogleFolder(d.Id(), d, config) if err != nil { - return handleNotFoundError(err, d, d.Id()) + return handleNotFoundError(err, d, fmt.Sprintf("Folder Not Found : %s", d.Id())) } d.Set("name", folder.Name) @@ -115,10 +127,12 @@ func resourceGoogleFolderUpdate(d *schema.ResourceData, meta interface{}) error d.Partial(true) if d.HasChange("display_name") { - _, err := config.clientResourceManagerV2Beta1.Folders.Patch(d.Id(), &resourceManagerV2Beta1.Folder{ - DisplayName: displayName, - }).Do() - + err := retry(func() error { + _, reqErr := config.clientResourceManagerV2Beta1.Folders.Patch(d.Id(), &resourceManagerV2Beta1.Folder{ + DisplayName: displayName, + }).Do() + return reqErr + }) if err != nil { return fmt.Errorf("Error updating display_name to '%s': %s", displayName, err) } @@ -128,10 +142,15 @@ func resourceGoogleFolderUpdate(d *schema.ResourceData, meta interface{}) error if d.HasChange("parent") { newParent := d.Get("parent").(string) - op, err := config.clientResourceManagerV2Beta1.Folders.Move(d.Id(), &resourceManagerV2Beta1.MoveFolderRequest{ - DestinationParent: newParent, - }).Do() + var op *resourceManagerV2Beta1.Operation + err := retry(func() error { + var reqErr error + op, reqErr = config.clientResourceManagerV2Beta1.Folders.Move(d.Id(), &resourceManagerV2Beta1.MoveFolderRequest{ + DestinationParent: newParent, + }).Do() + return reqErr + }) if err != nil { return fmt.Errorf("Error moving folder '%s' to '%s': %s", displayName, newParent, err) } @@ -158,11 +177,13 @@ func resourceGoogleFolderDelete(d *schema.ResourceData, meta interface{}) error config := meta.(*Config) displayName := d.Get("display_name").(string) - _, err := config.clientResourceManagerV2Beta1.Folders.Delete(d.Id()).Do() + err := retryTimeDuration(func() error { + _, reqErr := config.clientResourceManagerV2Beta1.Folders.Delete(d.Id()).Do() + return reqErr + }, d.Timeout(schema.TimeoutDelete)) if err != nil { return fmt.Errorf("Error deleting folder '%s': %s", displayName, err) } - return nil } @@ -177,3 +198,18 @@ func resourceGoogleFolderImportState(d *schema.ResourceData, m interface{}) ([]* return []*schema.ResourceData{d}, nil } + +// Util to get a Folder resource from API. Note that folder described by name is not necessarily the +// ResourceData resource. +func getGoogleFolder(folderName string, d *schema.ResourceData, config *Config) (*resourceManagerV2Beta1.Folder, error) { + var folder *resourceManagerV2Beta1.Folder + err := retryTimeDuration(func() error { + var reqErr error + folder, reqErr = config.clientResourceManagerV2Beta1.Folders.Get(folderName).Do() + return reqErr + }, d.Timeout(schema.TimeoutRead)) + if err != nil { + return nil, err + } + return folder, nil +} diff --git a/third_party/terraform/resources/resource_google_folder_organization_policy.go b/third_party/terraform/resources/resource_google_folder_organization_policy.go index ebf367fdc0fe..b4ffa962e760 100644 --- a/third_party/terraform/resources/resource_google_folder_organization_policy.go +++ b/third_party/terraform/resources/resource_google_folder_organization_policy.go @@ -2,6 +2,7 @@ package google import ( "fmt" + "time" "github.com/hashicorp/terraform/helper/schema" "google.golang.org/api/cloudresourcemanager/v1" @@ -18,6 +19,13 @@ func resourceGoogleFolderOrganizationPolicy() *schema.Resource { State: resourceFolderOrgPolicyImporter, }, + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(4 * time.Minute), + Update: schema.DefaultTimeout(4 * time.Minute), + Read: schema.DefaultTimeout(4 * time.Minute), + Delete: schema.DefaultTimeout(4 * time.Minute), + }, + Schema: mergeSchemas( schemaOrganizationPolicy, map[string]*schema.Schema{ @@ -68,10 +76,13 @@ func resourceGoogleFolderOrganizationPolicyRead(d *schema.ResourceData, meta int config := meta.(*Config) folder := canonicalFolderId(d.Get("folder").(string)) - policy, err := config.clientResourceManager.Folders.GetOrgPolicy(folder, &cloudresourcemanager.GetOrgPolicyRequest{ - Constraint: canonicalOrgPolicyConstraint(d.Get("constraint").(string)), - }).Do() - + var policy *cloudresourcemanager.OrgPolicy + err := retryTimeDuration(func() (getErr error) { + policy, getErr = config.clientResourceManager.Folders.GetOrgPolicy(folder, &cloudresourcemanager.GetOrgPolicyRequest{ + Constraint: canonicalOrgPolicyConstraint(d.Get("constraint").(string)), + }).Do() + return getErr + }, d.Timeout(schema.TimeoutRead)) if err != nil { return handleNotFoundError(err, d, fmt.Sprintf("Organization policy for %s", folder)) } @@ -103,15 +114,12 @@ func resourceGoogleFolderOrganizationPolicyDelete(d *schema.ResourceData, meta i config := meta.(*Config) folder := canonicalFolderId(d.Get("folder").(string)) - _, err := config.clientResourceManager.Folders.ClearOrgPolicy(folder, &cloudresourcemanager.ClearOrgPolicyRequest{ - Constraint: canonicalOrgPolicyConstraint(d.Get("constraint").(string)), - }).Do() - - if err != nil { - return err - } - - return nil + return retryTimeDuration(func() (delErr error) { + _, delErr = config.clientResourceManager.Folders.ClearOrgPolicy(folder, &cloudresourcemanager.ClearOrgPolicyRequest{ + Constraint: canonicalOrgPolicyConstraint(d.Get("constraint").(string)), + }).Do() + return delErr + }, d.Timeout(schema.TimeoutDelete)) } func setFolderOrganizationPolicy(d *schema.ResourceData, meta interface{}) error { @@ -128,16 +136,17 @@ func setFolderOrganizationPolicy(d *schema.ResourceData, meta interface{}) error return err } - _, err = config.clientResourceManager.Folders.SetOrgPolicy(folder, &cloudresourcemanager.SetOrgPolicyRequest{ - Policy: &cloudresourcemanager.OrgPolicy{ - Constraint: canonicalOrgPolicyConstraint(d.Get("constraint").(string)), - BooleanPolicy: expandBooleanOrganizationPolicy(d.Get("boolean_policy").([]interface{})), - ListPolicy: listPolicy, - RestoreDefault: restoreDefault, - Version: int64(d.Get("version").(int)), - Etag: d.Get("etag").(string), - }, - }).Do() - - return err + return retryTimeDuration(func() (setErr error) { + _, setErr = config.clientResourceManager.Folders.SetOrgPolicy(folder, &cloudresourcemanager.SetOrgPolicyRequest{ + Policy: &cloudresourcemanager.OrgPolicy{ + Constraint: canonicalOrgPolicyConstraint(d.Get("constraint").(string)), + BooleanPolicy: expandBooleanOrganizationPolicy(d.Get("boolean_policy").([]interface{})), + ListPolicy: listPolicy, + RestoreDefault: restoreDefault, + Version: int64(d.Get("version").(int)), + Etag: d.Get("etag").(string), + }, + }).Do() + return setErr + }, d.Timeout(schema.TimeoutCreate)) } diff --git a/third_party/terraform/resources/resource_google_organization_policy.go b/third_party/terraform/resources/resource_google_organization_policy.go index 2c7f96e185e5..85cf77bf2a31 100644 --- a/third_party/terraform/resources/resource_google_organization_policy.go +++ b/third_party/terraform/resources/resource_google_organization_policy.go @@ -3,6 +3,7 @@ package google import ( "fmt" "strings" + "time" "github.com/hashicorp/terraform/helper/schema" "google.golang.org/api/cloudresourcemanager/v1" @@ -131,6 +132,13 @@ func resourceGoogleOrganizationPolicy() *schema.Resource { State: resourceGoogleOrganizationPolicyImportState, }, + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(4 * time.Minute), + Update: schema.DefaultTimeout(4 * time.Minute), + Read: schema.DefaultTimeout(4 * time.Minute), + Delete: schema.DefaultTimeout(4 * time.Minute), + }, + Schema: mergeSchemas( schemaOrganizationPolicy, map[string]*schema.Schema{ @@ -161,10 +169,13 @@ func resourceGoogleOrganizationPolicyRead(d *schema.ResourceData, meta interface config := meta.(*Config) org := "organizations/" + d.Get("org_id").(string) - policy, err := config.clientResourceManager.Organizations.GetOrgPolicy(org, &cloudresourcemanager.GetOrgPolicyRequest{ - Constraint: canonicalOrgPolicyConstraint(d.Get("constraint").(string)), - }).Do() - + var policy *cloudresourcemanager.OrgPolicy + err := retryTimeDuration(func() (readErr error) { + policy, readErr = config.clientResourceManager.Organizations.GetOrgPolicy(org, &cloudresourcemanager.GetOrgPolicyRequest{ + Constraint: canonicalOrgPolicyConstraint(d.Get("constraint").(string)), + }).Do() + return readErr + }, d.Timeout(schema.TimeoutRead)) if err != nil { return handleNotFoundError(err, d, fmt.Sprintf("Organization policy for %s", org)) } @@ -196,10 +207,12 @@ func resourceGoogleOrganizationPolicyDelete(d *schema.ResourceData, meta interfa config := meta.(*Config) org := "organizations/" + d.Get("org_id").(string) - _, err := config.clientResourceManager.Organizations.ClearOrgPolicy(org, &cloudresourcemanager.ClearOrgPolicyRequest{ - Constraint: canonicalOrgPolicyConstraint(d.Get("constraint").(string)), - }).Do() - + err := retryTimeDuration(func() error { + _, dErr := config.clientResourceManager.Organizations.ClearOrgPolicy(org, &cloudresourcemanager.ClearOrgPolicyRequest{ + Constraint: canonicalOrgPolicyConstraint(d.Get("constraint").(string)), + }).Do() + return dErr + }, d.Timeout(schema.TimeoutDelete)) if err != nil { return err } @@ -246,17 +259,19 @@ func setOrganizationPolicy(d *schema.ResourceData, meta interface{}) error { return err } - _, err = config.clientResourceManager.Organizations.SetOrgPolicy(org, &cloudresourcemanager.SetOrgPolicyRequest{ - Policy: &cloudresourcemanager.OrgPolicy{ - Constraint: canonicalOrgPolicyConstraint(d.Get("constraint").(string)), - BooleanPolicy: expandBooleanOrganizationPolicy(d.Get("boolean_policy").([]interface{})), - ListPolicy: listPolicy, - RestoreDefault: restoreDefault, - Version: int64(d.Get("version").(int)), - Etag: d.Get("etag").(string), - }, - }).Do() - + err = retryTimeDuration(func() (setErr error) { + _, setErr = config.clientResourceManager.Organizations.SetOrgPolicy(org, &cloudresourcemanager.SetOrgPolicyRequest{ + Policy: &cloudresourcemanager.OrgPolicy{ + Constraint: canonicalOrgPolicyConstraint(d.Get("constraint").(string)), + BooleanPolicy: expandBooleanOrganizationPolicy(d.Get("boolean_policy").([]interface{})), + ListPolicy: listPolicy, + RestoreDefault: restoreDefault, + Version: int64(d.Get("version").(int)), + Etag: d.Get("etag").(string), + }, + }).Do() + return setErr + }, d.Timeout(schema.TimeoutCreate)) return err } diff --git a/third_party/terraform/resources/resource_google_project.go b/third_party/terraform/resources/resource_google_project.go index 8a25b6e21907..bd70cf43baa1 100644 --- a/third_party/terraform/resources/resource_google_project.go +++ b/third_party/terraform/resources/resource_google_project.go @@ -3,7 +3,6 @@ package google import ( "fmt" "log" - "net/http" "regexp" "strconv" "strings" @@ -29,6 +28,14 @@ func resourceGoogleProject() *schema.Resource { Importer: &schema.ResourceImporter{ State: resourceProjectImportState, }, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(4 * time.Minute), + Update: schema.DefaultTimeout(4 * time.Minute), + Read: schema.DefaultTimeout(4 * time.Minute), + Delete: schema.DefaultTimeout(4 * time.Minute), + }, + MigrateState: resourceGoogleProjectMigrateState, Schema: map[string]*schema.Schema{ @@ -216,7 +223,11 @@ func resourceGoogleProjectCreate(d *schema.ResourceData, meta interface{}) error project.Labels = expandLabels(d) } - op, err := config.clientResourceManager.Projects.Create(project).Do() + var op *cloudresourcemanager.Operation + err = retryTimeDuration(func() (reqErr error) { + op, reqErr = config.clientResourceManager.Projects.Create(project).Do() + return reqErr + }, d.Timeout(schema.TimeoutCreate)) if err != nil { return fmt.Errorf("error creating project %s (%s): %s. "+ "If you received a 403 error, make sure you have the"+ @@ -273,8 +284,7 @@ func resourceGoogleProjectRead(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) pid := d.Id() - // Read the project - p, err := config.clientResourceManager.Projects.Get(pid).Do() + p, err := readGoogleProject(d, config) if err != nil { return handleNotFoundError(err, d, fmt.Sprintf("Project %q", pid)) } @@ -306,8 +316,12 @@ func resourceGoogleProjectRead(d *schema.ResourceData, meta interface{}) error { } } + var ba *cloudbilling.ProjectBillingInfo + err = retryTimeDuration(func() (reqErr error) { + ba, reqErr = config.clientBilling.Projects.GetBillingInfo(prefixedProject(pid)).Do() + return reqErr + }, d.Timeout(schema.TimeoutRead)) // Read the billing account - ba, err := config.clientBilling.Projects.GetBillingInfo(prefixedProject(pid)).Do() if err != nil && !isApiNotEnabledError(err) { return fmt.Errorf("Error reading billing account for project %q: %v", prefixedProject(pid), err) } else if isApiNotEnabledError(err) { @@ -374,9 +388,9 @@ func resourceGoogleProjectUpdate(d *schema.ResourceData, meta interface{}) error // Read the project // we need the project even though refresh has already been called // because the API doesn't support patch, so we need the actual object - p, err := config.clientResourceManager.Projects.Get(pid).Do() + p, err := readGoogleProject(d, config) if err != nil { - if v, ok := err.(*googleapi.Error); ok && v.Code == http.StatusNotFound { + if isGoogleApiErrorWithCode(err, 404) { return fmt.Errorf("Project %q does not exist.", pid) } return fmt.Errorf("Error checking project %q: %s", pid, err) @@ -388,10 +402,13 @@ func resourceGoogleProjectUpdate(d *schema.ResourceData, meta interface{}) error if ok := d.HasChange("name"); ok { p.Name = project_name // Do update on project - p, err = config.clientResourceManager.Projects.Update(p.ProjectId, p).Do() - if err != nil { + if err = retryTimeDuration(func() (updateErr error) { + p, updateErr = config.clientResourceManager.Projects.Update(p.ProjectId, p).Do() + return updateErr + }, d.Timeout(schema.TimeoutUpdate)); err != nil { return fmt.Errorf("Error updating project %q: %s", project_name, err) } + d.SetPartial("name") } @@ -402,8 +419,10 @@ func resourceGoogleProjectUpdate(d *schema.ResourceData, meta interface{}) error } // Do update on project - p, err = config.clientResourceManager.Projects.Update(p.ProjectId, p).Do() - if err != nil { + if err = retryTimeDuration(func() (updateErr error) { + p, updateErr = config.clientResourceManager.Projects.Update(p.ProjectId, p).Do() + return updateErr + }, d.Timeout(schema.TimeoutUpdate)); err != nil { return fmt.Errorf("Error updating project %q: %s", project_name, err) } d.SetPartial("org_id") @@ -423,8 +442,10 @@ func resourceGoogleProjectUpdate(d *schema.ResourceData, meta interface{}) error p.Labels = expandLabels(d) // Do Update on project - p, err = config.clientResourceManager.Projects.Update(p.ProjectId, p).Do() - if err != nil { + if err = retryTimeDuration(func() (updateErr error) { + p, updateErr = config.clientResourceManager.Projects.Update(p.ProjectId, p).Do() + return updateErr + }, d.Timeout(schema.TimeoutUpdate)); err != nil { return fmt.Errorf("Error updating project %q: %s", project_name, err) } d.SetPartial("labels") @@ -439,9 +460,11 @@ func resourceGoogleProjectDelete(d *schema.ResourceData, meta interface{}) error // Only delete projects if skip_delete isn't set if !d.Get("skip_delete").(bool) { pid := d.Id() - _, err := config.clientResourceManager.Projects.Delete(pid).Do() - if err != nil { - return fmt.Errorf("Error deleting project %q: %s", pid, err) + if err := retryTimeDuration(func() error { + _, delErr := config.clientResourceManager.Projects.Delete(pid).Do() + return delErr + }, d.Timeout(schema.TimeoutDelete)); err != nil { + return handleNotFoundError(err, d, fmt.Sprintf("Project %s", pid)) } } d.SetId("") @@ -542,3 +565,13 @@ func deleteComputeNetwork(project, network string, config *Config) error { } return nil } + +func readGoogleProject(d *schema.ResourceData, config *Config) (*cloudresourcemanager.Project, error) { + var p *cloudresourcemanager.Project + // Read the project + err := retryTimeDuration(func() (reqErr error) { + p, reqErr = config.clientResourceManager.Projects.Get(d.Id()).Do() + return reqErr + }, d.Timeout(schema.TimeoutRead)) + return p, err +} diff --git a/third_party/terraform/resources/resource_google_project_organization_policy.go b/third_party/terraform/resources/resource_google_project_organization_policy.go index f509782ab288..6d9b7c9d05fe 100644 --- a/third_party/terraform/resources/resource_google_project_organization_policy.go +++ b/third_party/terraform/resources/resource_google_project_organization_policy.go @@ -2,6 +2,7 @@ package google import ( "fmt" + "time" "github.com/hashicorp/terraform/helper/schema" "google.golang.org/api/cloudresourcemanager/v1" @@ -18,6 +19,13 @@ func resourceGoogleProjectOrganizationPolicy() *schema.Resource { State: resourceProjectOrgPolicyImporter, }, + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(4 * time.Minute), + Update: schema.DefaultTimeout(4 * time.Minute), + Read: schema.DefaultTimeout(4 * time.Minute), + Delete: schema.DefaultTimeout(4 * time.Minute), + }, + Schema: mergeSchemas( schemaOrganizationPolicy, map[string]*schema.Schema{ @@ -67,10 +75,13 @@ func resourceGoogleProjectOrganizationPolicyRead(d *schema.ResourceData, meta in config := meta.(*Config) project := prefixedProject(d.Get("project").(string)) - policy, err := config.clientResourceManager.Projects.GetOrgPolicy(project, &cloudresourcemanager.GetOrgPolicyRequest{ - Constraint: canonicalOrgPolicyConstraint(d.Get("constraint").(string)), - }).Do() - + var policy *cloudresourcemanager.OrgPolicy + err := retryTimeDuration(func() (readErr error) { + policy, readErr = config.clientResourceManager.Projects.GetOrgPolicy(project, &cloudresourcemanager.GetOrgPolicyRequest{ + Constraint: canonicalOrgPolicyConstraint(d.Get("constraint").(string)), + }).Do() + return readErr + }, d.Timeout(schema.TimeoutRead)) if err != nil { return handleNotFoundError(err, d, fmt.Sprintf("Organization policy for %s", project)) } @@ -102,15 +113,12 @@ func resourceGoogleProjectOrganizationPolicyDelete(d *schema.ResourceData, meta config := meta.(*Config) project := prefixedProject(d.Get("project").(string)) - _, err := config.clientResourceManager.Projects.ClearOrgPolicy(project, &cloudresourcemanager.ClearOrgPolicyRequest{ - Constraint: canonicalOrgPolicyConstraint(d.Get("constraint").(string)), - }).Do() - - if err != nil { + return retryTimeDuration(func() error { + _, err := config.clientResourceManager.Projects.ClearOrgPolicy(project, &cloudresourcemanager.ClearOrgPolicyRequest{ + Constraint: canonicalOrgPolicyConstraint(d.Get("constraint").(string)), + }).Do() return err - } - - return nil + }, d.Timeout(schema.TimeoutDelete)) } func setProjectOrganizationPolicy(d *schema.ResourceData, meta interface{}) error { @@ -127,16 +135,17 @@ func setProjectOrganizationPolicy(d *schema.ResourceData, meta interface{}) erro return err } - _, err = config.clientResourceManager.Projects.SetOrgPolicy(project, &cloudresourcemanager.SetOrgPolicyRequest{ - Policy: &cloudresourcemanager.OrgPolicy{ - Constraint: canonicalOrgPolicyConstraint(d.Get("constraint").(string)), - BooleanPolicy: expandBooleanOrganizationPolicy(d.Get("boolean_policy").([]interface{})), - ListPolicy: listPolicy, - RestoreDefault: restore_default, - Version: int64(d.Get("version").(int)), - Etag: d.Get("etag").(string), - }, - }).Do() - - return err + return retryTimeDuration(func() error { + _, err := config.clientResourceManager.Projects.SetOrgPolicy(project, &cloudresourcemanager.SetOrgPolicyRequest{ + Policy: &cloudresourcemanager.OrgPolicy{ + Constraint: canonicalOrgPolicyConstraint(d.Get("constraint").(string)), + BooleanPolicy: expandBooleanOrganizationPolicy(d.Get("boolean_policy").([]interface{})), + ListPolicy: listPolicy, + RestoreDefault: restore_default, + Version: int64(d.Get("version").(int)), + Etag: d.Get("etag").(string), + }, + }).Do() + return err + }, d.Timeout(schema.TimeoutCreate)) }