diff --git a/internal/services/iam/group_membership.go b/internal/services/iam/group_membership.go index cd730eb13d..fdbd436540 100644 --- a/internal/services/iam/group_membership.go +++ b/internal/services/iam/group_membership.go @@ -4,12 +4,14 @@ import ( "context" "fmt" "strings" + "time" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" iam "github.com/scaleway/scaleway-sdk-go/api/iam/v1alpha1" "github.com/scaleway/scaleway-sdk-go/scw" "github.com/scaleway/terraform-provider-scaleway/v2/internal/httperrors" + "github.com/scaleway/terraform-provider-scaleway/v2/internal/transport" "github.com/scaleway/terraform-provider-scaleway/v2/internal/types" ) @@ -53,11 +55,11 @@ func resourceIamGroupMembershipCreate(ctx context.Context, d *schema.ResourceDat userID := types.ExpandStringPtr(d.Get("user_id")) applicationID := types.ExpandStringPtr(d.Get("application_id")) - group, err := api.AddGroupMember(&iam.AddGroupMemberRequest{ + group, err := MakeGroupRequest(ctx, api, &iam.AddGroupMemberRequest{ GroupID: d.Get("group_id").(string), UserID: userID, ApplicationID: applicationID, - }, scw.WithContext(ctx)) + }) if err != nil { return diag.FromErr(err) } @@ -74,7 +76,7 @@ func resourceIamGroupMembershipRead(ctx context.Context, d *schema.ResourceData, if err != nil { return diag.FromErr(err) } - + // http GET request should not return a 409 error group, err := api.GetGroup(&iam.GetGroupRequest{ GroupID: groupID, }, scw.WithContext(ctx)) @@ -139,7 +141,7 @@ func resourceIamGroupMembershipDelete(ctx context.Context, d *schema.ResourceDat req.ApplicationID = &applicationID } - _, err = api.RemoveGroupMember(req, scw.WithContext(ctx)) + _, err = MakeGroupRequest(ctx, api, req) if err != nil { if httperrors.Is404(err) { d.SetId("") @@ -178,3 +180,24 @@ func ExpandGroupMembershipID(id string) (groupID string, userID string, applicat return } + +func MakeGroupRequest(ctx context.Context, api *iam.API, request any) (*iam.Group, error) { + retryInterval := 100 * time.Millisecond + + group, err := transport.RetryOnTransientStateError(func() (*iam.Group, error) { + switch req := request.(type) { + case *iam.AddGroupMemberRequest: + return api.AddGroupMember(req, scw.WithContext(ctx)) + case *iam.RemoveGroupMemberRequest: + return api.RemoveGroupMember(req, scw.WithContext(ctx)) + default: + return nil, fmt.Errorf("invalid request type: %T", req) + } + }, func() (string, error) { + time.Sleep(retryInterval) // lintignore: R018 + + return "", nil + }) + + return group, err +}