diff --git a/mongodbatlas/framework/retry/retry_state.go b/mongodbatlas/framework/retry/retry_state.go new file mode 100644 index 0000000000..776e76055c --- /dev/null +++ b/mongodbatlas/framework/retry/retry_state.go @@ -0,0 +1,7 @@ +package retry + +const ( + RetryStrategyPendingState = "PENDING" + RetryStrategyCompletedState = "COMPLETED" + RetryStrategyErrorState = "ERROR" +) diff --git a/mongodbatlas/fw_resource_mongodbatlas_encryption_at_rest.go b/mongodbatlas/fw_resource_mongodbatlas_encryption_at_rest.go index 713bcad8e3..05f47777f2 100644 --- a/mongodbatlas/fw_resource_mongodbatlas_encryption_at_rest.go +++ b/mongodbatlas/fw_resource_mongodbatlas_encryption_at_rest.go @@ -2,11 +2,11 @@ package mongodbatlas import ( "context" + "errors" "fmt" "log" "net/http" "reflect" - "strings" "time" matlas "go.mongodb.org/atlas/mongodbatlas" @@ -20,8 +20,10 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/mongodb/terraform-provider-mongodbatlas/mongodbatlas/framework/conversion" + retrystrategy "github.com/mongodb/terraform-provider-mongodbatlas/mongodbatlas/framework/retry" validators "github.com/mongodb/terraform-provider-mongodbatlas/mongodbatlas/framework/validator" ) @@ -225,28 +227,23 @@ func (r *EncryptionAtRestRS) Create(ctx context.Context, req resource.CreateRequ encryptionAtRestReq.GoogleCloudKms = *newAtlasGcpKms(encryptionAtRestPlan.GoogleCloudKmsConfig) } - var encryptionResp *matlas.EncryptionAtRest + stateConf := &retry.StateChangeConf{ + Pending: []string{retrystrategy.RetryStrategyPendingState}, + Target: []string{retrystrategy.RetryStrategyCompletedState, retrystrategy.RetryStrategyErrorState}, + Refresh: resourceMongoDBAtlasEncryptionAtRestCreateRefreshFunc(ctx, projectID, conn, encryptionAtRestReq), + Timeout: 1 * time.Minute, + MinTimeout: 1 * time.Second, + Delay: 0, + } + + var encryptionResp interface{} var err error - for i := 0; i < 5; i++ { - encryptionResp, _, err = conn.EncryptionsAtRest.Create(ctx, encryptionAtRestReq) - if err != nil { - if strings.Contains(err.Error(), "CANNOT_ASSUME_ROLE") || strings.Contains(err.Error(), "INVALID_AWS_CREDENTIALS") || - strings.Contains(err.Error(), "CLOUD_PROVIDER_ACCESS_ROLE_NOT_AUTHORIZED") { - log.Printf("warning issue performing authorize EncryptionsAtRest not done try again: %s \n", err.Error()) - log.Println("retrying ") - time.Sleep(10 * time.Second) - encryptionAtRestReq.GroupID = projectID - continue - } - } - if err != nil { - resp.Diagnostics.AddError(fmt.Sprintf(errorCreateEncryptionAtRest, projectID), err.Error()) - return - } - break + if encryptionResp, err = stateConf.WaitForStateContext(ctx); err != nil { + resp.Diagnostics.AddError(fmt.Sprintf(errorCreateEncryptionAtRest, projectID), err.Error()) + return } - encryptionAtRestPlanNew := newTFEncryptionAtRestRSModel(ctx, projectID, encryptionResp, encryptionAtRestPlan) + encryptionAtRestPlanNew := newTFEncryptionAtRestRSModel(ctx, projectID, encryptionResp.(*matlas.EncryptionAtRest), encryptionAtRestPlan) resetDefaultsFromConfigOrState(ctx, encryptionAtRestPlan, encryptionAtRestPlanNew, encryptionAtRestConfig) // set state to fully populated data @@ -257,6 +254,25 @@ func (r *EncryptionAtRestRS) Create(ctx context.Context, req resource.CreateRequ } } +func resourceMongoDBAtlasEncryptionAtRestCreateRefreshFunc(ctx context.Context, projectID string, conn *matlas.Client, encryptionAtRestReq *matlas.EncryptionAtRest) retry.StateRefreshFunc { + return func() (interface{}, string, error) { + encryptionResp, _, err := conn.EncryptionsAtRest.Create(ctx, encryptionAtRestReq) + if err != nil { + if errors.Is(err, errors.New("CANNOT_ASSUME_ROLE")) || + errors.Is(err, errors.New("INVALID_AWS_CREDENTIALS")) || + errors.Is(err, errors.New("CLOUD_PROVIDER_ACCESS_ROLE_NOT_AUTHORIZED")) { + log.Printf("warning issue performing authorize EncryptionsAtRest not done try again: %s \n", err.Error()) + log.Println("retrying ") + + encryptionAtRestReq.GroupID = projectID + return encryptionResp, retrystrategy.RetryStrategyPendingState, nil + } + return encryptionResp, retrystrategy.RetryStrategyErrorState, err + } + return encryptionResp, retrystrategy.RetryStrategyCompletedState, nil + } +} + func (r *EncryptionAtRestRS) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { var encryptionAtRestState tfEncryptionAtRestRSModel var isImport bool