diff --git a/Makefile b/Makefile index 31c4be82..563296c4 100644 --- a/Makefile +++ b/Makefile @@ -19,7 +19,7 @@ GOVERSION := 1.12 PROJECT := github.com/DeviaVir/terraform-provider-gsuite OWNER := $(notdir $(patsubst %/,%,$(dir $(PROJECT)))) NAME := $(notdir $(PROJECT)) -VERSION := 0.1.31 +VERSION := 0.1.32 EXTERNAL_TOOLS = \ github.com/golang/dep/cmd/dep diff --git a/gsuite/config.go b/gsuite/config.go index d34caa53..10887c15 100644 --- a/gsuite/config.go +++ b/gsuite/config.go @@ -35,6 +35,8 @@ type Config struct { CustomerId string + TimeoutMinutes int + OauthScopes []string directory *directory.Service diff --git a/gsuite/data_group.go b/gsuite/data_group.go index 2e01b7cb..aae7260d 100644 --- a/gsuite/data_group.go +++ b/gsuite/data_group.go @@ -67,7 +67,7 @@ func dataGroupRead(d *schema.ResourceData, meta interface{}) error { err = retry(func() error { group, err = config.directory.Groups.Get(d.Get("email").(string)).Do() return err - }) + }, config.TimeoutMinutes) if err != nil { return handleNotFoundError(err, d, fmt.Sprintf("Group %q", d.Get("name").(string))) diff --git a/gsuite/data_user.go b/gsuite/data_user.go index 51db7b17..33c3a325 100644 --- a/gsuite/data_user.go +++ b/gsuite/data_user.go @@ -237,7 +237,7 @@ func dataUserRead(d *schema.ResourceData, meta interface{}) error { err = retry(func() error { user, err = config.directory.Users.Get(d.Get("primary_email").(string)).Do() return err - }) + }, config.TimeoutMinutes) if err != nil { return handleNotFoundError(err, d, fmt.Sprintf("User %q", d.Id())) diff --git a/gsuite/provider.go b/gsuite/provider.go index 627479a1..8d160086 100644 --- a/gsuite/provider.go +++ b/gsuite/provider.go @@ -38,6 +38,11 @@ func Provider() *schema.Provider { Type: schema.TypeString, Optional: true, }, + "timeout_minutes": { + Type: schema.TypeInt, + Optional: true, + Default: 1, // 1 + (n*2) roof 16 = 1+2+4+8+16 = 31 seconds, 1 min should be "normal" operations + }, }, DataSourcesMap: map[string]*schema.Resource{ "gsuite_group": dataGroup(), @@ -103,12 +108,15 @@ func providerConfigure(d *schema.ResourceData, terraformVersion string) (interfa customerID = "my_customer" } + timeoutMinutes := d.Get("timeout_minutes").(int) + oauthScopes := oauthScopesFromConfigOrDefault(d.Get("oauth_scopes").(*schema.Set)) config := Config{ Credentials: credentials, ImpersonatedUserEmail: impersonatedUserEmail, OauthScopes: oauthScopes, CustomerId: customerID, + TimeoutMinutes: timeoutMinutes, } if err := config.loadAndValidate(terraformVersion); err != nil { diff --git a/gsuite/resource_domain.go b/gsuite/resource_domain.go index bfcf5801..7860e9e7 100644 --- a/gsuite/resource_domain.go +++ b/gsuite/resource_domain.go @@ -58,7 +58,7 @@ func resourceDomainCreate(d *schema.ResourceData, meta interface{}) error { err = retry(func() error { createdDomain, err = config.directory.Domains.Insert(customerId, domain).Do() return err - }) + }, config.TimeoutMinutes) if err != nil { return fmt.Errorf("[ERROR] Error creating domain: %s", err) @@ -91,7 +91,7 @@ func resourceDomainRead(d *schema.ResourceData, meta interface{}) error { err = retry(func() error { domain, err = config.directory.Domains.Get(customerId, domainName).Do() return err - }) + }, config.TimeoutMinutes) if err != nil { return handleNotFoundError(err, d, fmt.Sprintf("Domain %q", d.Get("domain_name").(string))) @@ -120,7 +120,7 @@ func resourceDomainDelete(d *schema.ResourceData, meta interface{}) error { err = retry(func() error { err = config.directory.Domains.Delete(customerId, domainName).Do() return err - }) + }, config.TimeoutMinutes) if err != nil { return fmt.Errorf("[ERROR] Error deleting domain: %s", err) diff --git a/gsuite/resource_group.go b/gsuite/resource_group.go index 4f003c29..2ef47a81 100644 --- a/gsuite/resource_group.go +++ b/gsuite/resource_group.go @@ -85,7 +85,7 @@ func resourceGroupCreate(d *schema.ResourceData, meta interface{}) error { err = retry(func() error { createdGroup, err = config.directory.Groups.Insert(group).Do() return err - }) + }, config.TimeoutMinutes) if err != nil { return fmt.Errorf("[ERROR] Error creating group: %s", err) @@ -101,7 +101,7 @@ func resourceGroupCreate(d *schema.ResourceData, meta interface{}) error { } _, err = config.directory.Groups.Aliases.Insert(d.Id(), alias).Do() return err - }) + }, config.TimeoutMinutes) } if err != nil { @@ -112,7 +112,7 @@ func resourceGroupCreate(d *schema.ResourceData, meta interface{}) error { err = retryNotFound(func() error { group, err = config.directory.Groups.Get(createdGroup.Id).Do() return err - }) + }, config.TimeoutMinutes) if err != nil { return fmt.Errorf("[ERROR] Taking too long to create this group: %s", err) @@ -165,7 +165,7 @@ func resourceGroupUpdate(d *schema.ResourceData, meta interface{}) error { err = retry(func() error { updatedGroup, err = config.directory.Groups.Patch(d.Id(), group).Do() return err - }) + }, config.TimeoutMinutes) if err != nil { return fmt.Errorf("[ERROR] Error updating group: %s", err) @@ -176,7 +176,7 @@ func resourceGroupUpdate(d *schema.ResourceData, meta interface{}) error { err = retry(func() error { aliasesResponse, err = config.directory.Groups.Aliases.List(d.Id()).Do() return err - }) + }, config.TimeoutMinutes) if err != nil { return fmt.Errorf("[ERROR] Could not list group aliases: %s", err) @@ -204,7 +204,7 @@ func resourceGroupUpdate(d *schema.ResourceData, meta interface{}) error { } _, err = config.directory.Groups.Aliases.Insert(d.Id(), alias).Do() return err - }) + }, config.TimeoutMinutes) } if err != nil { @@ -223,7 +223,7 @@ func resourceGroupRead(d *schema.ResourceData, meta interface{}) error { err = retry(func() error { group, err = config.directory.Groups.Get(d.Id()).Do() return err - }) + }, config.TimeoutMinutes) if err != nil { return handleNotFoundError(err, d, fmt.Sprintf("Group %q", d.Get("name").(string))) @@ -247,7 +247,7 @@ func resourceGroupDelete(d *schema.ResourceData, meta interface{}) error { err = retry(func() error { err = config.directory.Groups.Delete(d.Id()).Do() return err - }) + }, config.TimeoutMinutes) if err != nil { return fmt.Errorf("[ERROR] Error deleting group: %s", err) } diff --git a/gsuite/resource_group_member.go b/gsuite/resource_group_member.go index e6a91b0f..1f384023 100644 --- a/gsuite/resource_group_member.go +++ b/gsuite/resource_group_member.go @@ -90,7 +90,7 @@ func resourceGroupMemberCreate(d *schema.ResourceData, meta interface{}) error { err = retryPassDuplicate(func() error { createdGroupMember, err = config.directory.Members.Insert(group, groupMember).Do() return err - }) + }, config.TimeoutMinutes) if err != nil { if !strings.Contains(err.Error(), "Member already exists") { @@ -102,7 +102,7 @@ func resourceGroupMemberCreate(d *schema.ResourceData, meta interface{}) error { err = retry(func() error { existingGroupMembers, err = config.directory.Members.List(group).Do() return err - }) + }, config.TimeoutMinutes) if err != nil { return fmt.Errorf("[ERROR] Error listing existing group members: %s", err) } @@ -122,7 +122,7 @@ func resourceGroupMemberCreate(d *schema.ResourceData, meta interface{}) error { err = retry(func() error { _, err = config.directory.Members.Patch(group, locatedGroupMember.Id, groupMember).Do() return err - }) + }, config.TimeoutMinutes) if err != nil { return fmt.Errorf("[ERROR] Error updating existing group member: %s", err) @@ -138,7 +138,7 @@ func resourceGroupMemberCreate(d *schema.ResourceData, meta interface{}) error { err = retryNotFound(func() error { groupMember, err = config.directory.Members.Get(group, d.Id()).Do() return err - }) + }, config.TimeoutMinutes) if err != nil { return fmt.Errorf("[ERROR] Taking too long to create this group member: %s", err) @@ -172,7 +172,7 @@ func resourceGroupMemberUpdate(d *schema.ResourceData, meta interface{}) error { err = retry(func() error { updatedGroupMember, err = config.directory.Members.Patch(strings.ToLower(d.Get("group").(string)), d.Id(), groupMember).Do() return err - }) + }, config.TimeoutMinutes) if err != nil { return fmt.Errorf("[ERROR] Error updating group member: %s", err) @@ -190,7 +190,7 @@ func resourceGroupMemberRead(d *schema.ResourceData, meta interface{}) error { err = retry(func() error { groupMember, err = config.directory.Members.Get(strings.ToLower(d.Get("group").(string)), d.Id()).Do() return err - }) + }, config.TimeoutMinutes) if err != nil { return handleNotFoundError(err, d, fmt.Sprintf("Group member %q", d.Get("email").(string))) @@ -214,7 +214,7 @@ func resourceGroupMemberDelete(d *schema.ResourceData, meta interface{}) error { err = retry(func() error { err = config.directory.Members.Delete(strings.ToLower(d.Get("group").(string)), d.Id()).Do() return err - }) + }, config.TimeoutMinutes) if err != nil { return fmt.Errorf("[ERROR] Error deleting group member: %s", err) } diff --git a/gsuite/resource_group_members.go b/gsuite/resource_group_members.go index 43b1a533..957c52e4 100644 --- a/gsuite/resource_group_members.go +++ b/gsuite/resource_group_members.go @@ -203,13 +203,13 @@ func reconcileMembers(d *schema.ResourceData, cfgMembers, apiMembers []map[strin var updatedGroupMember *directory.Member var err error - err = retry(func() error { + err = retryNotFound(func() error { updatedGroupMember, err = config.directory.Members.Patch( strings.ToLower(d.Get("group_email").(string)), strings.ToLower(cfgMember["email"].(string)), groupMember).Do() return err - }) + }, config.TimeoutMinutes) if err != nil { return fmt.Errorf("[ERROR] Error updating groupMember: %s", err) @@ -245,7 +245,7 @@ func getAPIMembers(groupEmail string, config *Config) ([]*directory.Member, erro err = retry(func() error { membersResponse, err = config.directory.Members.List(groupEmail).PageToken(token).Do() return err - }) + }, config.TimeoutMinutes) if err != nil { return groupMembers, err @@ -277,7 +277,7 @@ func upsertMember(email, groupEmail, role string, config *Config) error { return nil } return err - }) + }, config.TimeoutMinutes) if isGroup == true { if role != "MEMBER" { @@ -297,7 +297,7 @@ func upsertMember(email, groupEmail, role string, config *Config) error { } return err - }) + }, config.TimeoutMinutes) // Based on the err return, either add as a new member, or update if isGroupMember == false { @@ -305,17 +305,17 @@ func upsertMember(email, groupEmail, role string, config *Config) error { err = retry(func() error { createdGroupMember, err = config.directory.Members.Insert(groupEmail, groupMember).Do() return err - }) + }, config.TimeoutMinutes) if err != nil { return fmt.Errorf("[ERROR] Error creating groupMember: %s, %s", err, email) } log.Printf("[INFO] Created groupMember: %s", createdGroupMember.Email) } else { var updatedGroupMember *directory.Member - err = retry(func() error { + err = retryNotFound(func() error { updatedGroupMember, err = config.directory.Members.Update(groupEmail, email, groupMember).Do() return err - }) + }, config.TimeoutMinutes) if err != nil { return fmt.Errorf("[ERROR] Error updating groupMember: %s, %s", err, email) } @@ -340,17 +340,17 @@ func upsertMember(email, groupEmail, role string, config *Config) error { return fmt.Errorf("[ERROR] Error adding groupMember %s, please make sure the user exists beforehand", email) } return err - }) + }, config.TimeoutMinutes) if err != nil { return createGroupMember(groupMember, groupEmail, config) } if hasMemberResponse.IsMember == true { var updatedGroupMember *directory.Member - err = retry(func() error { + err = retryNotFound(func() error { updatedGroupMember, err = config.directory.Members.Update(groupEmail, email, groupMember).Do() return err - }) + }, config.TimeoutMinutes) if err != nil { return fmt.Errorf("[ERROR] Error updating groupMember: %s, %s", err, email) } @@ -368,7 +368,7 @@ func createGroupMember(groupMember *directory.Member, groupEmail string, config err = retry(func() error { createdGroupMember, err = config.directory.Members.Insert(groupEmail, groupMember).Do() return err - }) + }, config.TimeoutMinutes) if err != nil { return fmt.Errorf("[ERROR] Error creating groupMember: %s, %s", err, groupMember.Email) } @@ -381,7 +381,7 @@ func deleteMember(email, groupEmail string, config *Config) (err error) { err = retry(func() error { err = config.directory.Members.Delete(groupEmail, email).Do() return err - }) + }, config.TimeoutMinutes) if err != nil { return fmt.Errorf("[ERROR] Error deleting member: %s", err) @@ -399,7 +399,7 @@ func resourceGroupMembersImporter(d *schema.ResourceData, meta interface{}) ([]* err = retry(func() error { group, err = config.directory.Groups.Get(strings.ToLower(d.Id())).Do() return err - }) + }, config.TimeoutMinutes) if err != nil { return nil, fmt.Errorf("[ERROR] Error fetching group. Make sure the group exists: %s ", err) diff --git a/gsuite/resource_group_settings.go b/gsuite/resource_group_settings.go index 2efd1ba2..645f30e0 100644 --- a/gsuite/resource_group_settings.go +++ b/gsuite/resource_group_settings.go @@ -603,7 +603,7 @@ func resourceGroupSettingsCreate(d *schema.ResourceData, meta interface{}) error err = retry(func() error { _, err = config.groupSettings.Groups.Update(d.Get("email").(string), groupSetting).Do() return err - }) + }, config.TimeoutMinutes) if err != nil { return fmt.Errorf("[ERROR] Something went wrong while updating group settings: %s", err) } @@ -1164,7 +1164,7 @@ func resourceGroupSettingsUpdate(d *schema.ResourceData, meta interface{}) error err = retry(func() error { _, err = config.groupSettings.Groups.Update(d.Get("email").(string), groupSetting).Do() return err - }) + }, config.TimeoutMinutes) if err != nil { return fmt.Errorf("[ERROR] Error updating group settings: %s", err) @@ -1181,7 +1181,7 @@ func resourceGroupSettingsRead(d *schema.ResourceData, meta interface{}) error { err = retry(func() error { groupSetting, err = config.groupSettings.Groups.Get(d.Get("email").(string)).Do() return err - }) + }, config.TimeoutMinutes) if err != nil { return handleNotFoundError(err, d, fmt.Sprintf("Group Settings for %q", d.Get("name").(string))) diff --git a/gsuite/resource_user.go b/gsuite/resource_user.go index de6ec680..3c1688bd 100644 --- a/gsuite/resource_user.go +++ b/gsuite/resource_user.go @@ -444,7 +444,7 @@ func resourceUserCreate(d *schema.ResourceData, meta interface{}) error { err = retry(func() error { createdUser, err = config.directory.Users.Insert(user).Do() return err - }) + }, config.TimeoutMinutes) if err != nil { return fmt.Errorf("Error creating user: %s", err) @@ -454,7 +454,7 @@ func resourceUserCreate(d *schema.ResourceData, meta interface{}) error { err = retryNotFound(func() error { user, err = config.directory.Users.Get(createdUser.Id).Do() return err - }) + }, config.TimeoutMinutes) if err != nil { return fmt.Errorf("[ERROR] Taking too long to create this user: %s", err) @@ -540,7 +540,7 @@ func userPosixCreate(d *schema.ResourceData, userID string, meta interface{}) er return errors.Wrap(e, e.Body) } return err - }) + }, config.TimeoutMinutes) if err != nil { return fmt.Errorf("Error updating user: %s", err) @@ -789,7 +789,7 @@ func resourceUserUpdate(d *schema.ResourceData, meta interface{}) error { return errors.Wrap(e, e.Body) } return err - }) + }, config.TimeoutMinutes) if err != nil { log.Printf("[WARN] Please note, a persistent 503 backend error can mean you need to change your posix values to be unique.") @@ -811,7 +811,7 @@ func resourceUserRead(d *schema.ResourceData, meta interface{}) error { return errors.New("Eventual consistency. Please try again") } return err - }) + }, config.TimeoutMinutes) if err != nil { return handleNotFoundError(err, d, fmt.Sprintf("User %q", d.Id())) @@ -866,7 +866,7 @@ func resourceUserDelete(d *schema.ResourceData, meta interface{}) error { err = retry(func() error { err = config.directory.Users.Delete(d.Id()).Do() return err - }) + }, config.TimeoutMinutes) if err != nil { return fmt.Errorf("Error deleting user: %s", err) } diff --git a/gsuite/resource_user_schema.go b/gsuite/resource_user_schema.go index 2ebd6b0b..aa5123e6 100644 --- a/gsuite/resource_user_schema.go +++ b/gsuite/resource_user_schema.go @@ -141,7 +141,7 @@ func resourceUserSchemaCreate(d *schema.ResourceData, meta interface{}) error { err = retry(func() error { created, err = config.directory.Schemas.Insert(myCustomerID, userSchema).Do() return err - }) + }, config.TimeoutMinutes) if err != nil { return fmt.Errorf("[ERROR] Error creating user schema: %s", err) @@ -162,7 +162,7 @@ func resourceUserSchemaRead(d *schema.ResourceData, meta interface{}) error { err = retry(func() error { read, err = config.directory.Schemas.Get(myCustomerID, d.Id()).Do() return err - }) + }, config.TimeoutMinutes) if err != nil { return handleNotFoundError(err, d, fmt.Sprintf("Schema %q", d.Get("schema_name").(string))) } @@ -212,7 +212,7 @@ func resourceUserSchemaUpdate(d *schema.ResourceData, meta interface{}) error { err = retry(func() error { updated, err = config.directory.Schemas.Update(myCustomerID, d.Id(), userSchema).Do() return err - }) + }, config.TimeoutMinutes) if err != nil { return fmt.Errorf("[ERROR] Error updating user schema: %s", err) @@ -226,7 +226,7 @@ func resourceUserSchemaDelete(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) return retry(func() error { return config.directory.Schemas.Delete(myCustomerID, d.Id()).Do() - }) + }, config.TimeoutMinutes) } func resourceUserSchemaImporter(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { diff --git a/gsuite/utils.go b/gsuite/utils.go index 6030c4c2..8f97fea4 100644 --- a/gsuite/utils.go +++ b/gsuite/utils.go @@ -26,16 +26,16 @@ func handleNotFoundError(err error, d *schema.ResourceData, resource string) err return fmt.Errorf("Error reading %s: %s", resource, err) } -func retry(retryFunc func() error) error { - return retryTime(retryFunc, 4, false, false) +func retry(retryFunc func() error, minutes int) error { + return retryTime(retryFunc, minutes, false, false) } -func retryNotFound(retryFunc func() error) error { - return retryTime(retryFunc, 4, true, false) +func retryNotFound(retryFunc func() error, minutes int) error { + return retryTime(retryFunc, minutes, true, false) } -func retryPassDuplicate(retryFunc func() error) error { - return retryTime(retryFunc, 4, true, true) +func retryPassDuplicate(retryFunc func() error, minutes int) error { + return retryTime(retryFunc, minutes, true, true) } func retryTime(retryFunc func() error, minutes int, retryNotFound bool, retryPassDuplicate bool) error {