Skip to content

Commit

Permalink
More retries for CRM resources (project, org policies, folders)
Browse files Browse the repository at this point in the history
Signed-off-by: Modular Magician <[email protected]>
  • Loading branch information
emilymye authored and modular-magician committed Aug 5, 2019
1 parent 34f73a8 commit a3838ca
Show file tree
Hide file tree
Showing 6 changed files with 212 additions and 123 deletions.
37 changes: 12 additions & 25 deletions google-beta/data_source_google_folder.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ import (
"strings"

"github.com/hashicorp/terraform/helper/schema"

resourceManagerV2Beta1 "google.golang.org/api/cloudresourcemanager/v2beta1"
)

func dataSourceGoogleFolder() *schema.Resource {
Expand Down Expand Up @@ -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, 404 was handled in read().
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
}
Expand All @@ -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())
}
}
64 changes: 50 additions & 14 deletions google-beta/resource_google_folder.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"github.com/hashicorp/terraform/helper/schema"
resourceManagerV2Beta1 "google.golang.org/api/cloudresourcemanager/v2beta1"
"strings"
"time"
)

func resourceGoogleFolder() *schema.Resource {
Expand All @@ -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": {
Expand Down Expand Up @@ -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)
}
Expand Down Expand Up @@ -95,7 +107,7 @@ 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())
}
Expand All @@ -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)
}
Expand All @@ -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)
}
Expand All @@ -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
}

Expand All @@ -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
}
59 changes: 34 additions & 25 deletions google-beta/resource_google_folder_organization_policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package google

import (
"fmt"
"time"

"github.com/hashicorp/terraform/helper/schema"
"google.golang.org/api/cloudresourcemanager/v1"
Expand All @@ -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{
Expand Down Expand Up @@ -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))
}
Expand Down Expand Up @@ -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 {
Expand All @@ -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))
}
53 changes: 34 additions & 19 deletions google-beta/resource_google_organization_policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package google
import (
"fmt"
"strings"
"time"

"github.com/hashicorp/terraform/helper/schema"
"google.golang.org/api/cloudresourcemanager/v1"
Expand Down Expand Up @@ -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{
Expand Down Expand Up @@ -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))
}
Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -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
}

Expand Down
Loading

0 comments on commit a3838ca

Please sign in to comment.