diff --git a/internal/provider/resource_subaccount_entitlement.go b/internal/provider/resource_subaccount_entitlement.go index 8e74abeb..63e51f55 100644 --- a/internal/provider/resource_subaccount_entitlement.go +++ b/internal/provider/resource_subaccount_entitlement.go @@ -224,7 +224,7 @@ func (rs *subaccountEntitlementResource) createOrUpdate(ctx context.Context, req return callResult, entitlementCallRetrySucceeded, nil } - if err != nil && isRetriableError(err) { + if isRetriableError(err) { return callResult, entitlementCallRetryPending, nil } @@ -234,9 +234,9 @@ func (rs *subaccountEntitlementResource) createOrUpdate(ctx context.Context, req return callResult, entitlementCallRetryPending, err }, - Timeout: 5 * time.Minute, - Delay: 5 * time.Second, - MinTimeout: 5 * time.Second, + Timeout: 10 * time.Minute, + Delay: 10 * time.Second, + MinTimeout: 10 * time.Second, } _, err := RetryApiCallConf.WaitForStateContext(ctx) @@ -272,8 +272,8 @@ func (rs *subaccountEntitlementResource) createOrUpdate(ctx context.Context, req return *entitlement, entitlement.Assignment.EntityState, nil }, Timeout: 10 * time.Minute, - Delay: 5 * time.Second, - MinTimeout: 5 * time.Second, + Delay: 10 * time.Second, + MinTimeout: 10 * time.Second, } entitlement, err := createStateConf.WaitForStateContext(ctx) @@ -327,7 +327,7 @@ func (rs *subaccountEntitlementResource) Delete(ctx context.Context, req resourc return callResult, entitlementCallRetrySucceeded, nil } - if err != nil && isRetriableError(err) { + if isRetriableError(err) { return callResult, entitlementCallRetryPending, nil } @@ -337,9 +337,9 @@ func (rs *subaccountEntitlementResource) Delete(ctx context.Context, req resourc return callResult, entitlementCallRetryPending, err }, - Timeout: 5 * time.Minute, - Delay: 5 * time.Second, - MinTimeout: 5 * time.Second, + Timeout: 10 * time.Minute, + Delay: 10 * time.Second, + MinTimeout: 10 * time.Second, } _, err := RetryApiCallConf.WaitForStateContext(ctx) @@ -375,8 +375,8 @@ func (rs *subaccountEntitlementResource) Delete(ctx context.Context, req resourc return entitlement, cis_entitlements.StateProcessing, nil }, Timeout: 10 * time.Minute, - Delay: 5 * time.Second, - MinTimeout: 5 * time.Second, + Delay: 10 * time.Second, + MinTimeout: 10 * time.Second, } _, err = deleteStateConf.WaitForStateContext(ctx) @@ -429,8 +429,11 @@ func isRetriableError(err error) bool { if strings.Contains(err.Error(), "[Error: 30004/400]") { // Error code for a locking scenario - API call must be retried return true + } else if strings.Contains(err.Error(), "[Error: 11006/429]") { + // Error code when hitting a rate limit - API call must be retried + return true } else { - // No retry possible as errro code does not indicate a valid retry scenario + // No retry possible as error code does not indicate a valid retry scenario return false } diff --git a/internal/provider/resource_subaccount_service_instance.go b/internal/provider/resource_subaccount_service_instance.go index 8e854f99..e057ca3e 100644 --- a/internal/provider/resource_subaccount_service_instance.go +++ b/internal/provider/resource_subaccount_service_instance.go @@ -395,9 +395,14 @@ func (rs *subaccountServiceInstanceResource) Delete(ctx context.Context, req res Pending: []string{servicemanager.StateInProgress}, Target: []string{"DELETED"}, Refresh: func() (interface{}, string, error) { - subRes, comRes, err := rs.cli.Services.Instance.GetById(ctx, state.SubaccountId.ValueString(), state.Id.ValueString()) + subRes, cmdRes, err := rs.cli.Services.Instance.GetById(ctx, state.SubaccountId.ValueString(), state.Id.ValueString()) - if comRes.StatusCode == http.StatusNotFound { + if cmdRes.StatusCode == http.StatusTooManyRequests { + // Retry in case of rate limiting + return subRes, servicemanager.StateInProgress, nil + } + + if cmdRes.StatusCode == http.StatusNotFound { return subRes, "DELETED", nil } @@ -458,7 +463,12 @@ func (rs *subaccountServiceInstanceResource) CreateStateChange(ctx context.Conte Pending: []string{servicemanager.StateInProgress}, Target: []string{servicemanager.StateSucceeded}, Refresh: func() (interface{}, string, error) { - subRes, _, err := rs.cli.Services.Instance.GetById(ctx, state.SubaccountId.ValueString(), cliRes.Id) + subRes, cmdRes, err := rs.cli.Services.Instance.GetById(ctx, state.SubaccountId.ValueString(), cliRes.Id) + + if cmdRes.StatusCode == http.StatusTooManyRequests { + // Retry in case of rate limiting + return subRes, servicemanager.StateInProgress, nil + } if err != nil { return subRes, "", err @@ -496,7 +506,12 @@ func (rs *subaccountServiceInstanceResource) UpdateStateChange(ctx context.Conte Pending: []string{servicemanager.StateInProgress}, Target: []string{servicemanager.StateSucceeded}, Refresh: func() (interface{}, string, error) { - subRes, _, err := rs.cli.Services.Instance.GetById(ctx, state.SubaccountId.ValueString(), cliRes.Id) + subRes, cmdRes, err := rs.cli.Services.Instance.GetById(ctx, state.SubaccountId.ValueString(), cliRes.Id) + + if cmdRes.StatusCode == http.StatusTooManyRequests { + // Retry in case of rate limiting + return subRes, servicemanager.StateInProgress, nil + } if err != nil { return subRes, "", err diff --git a/internal/provider/resource_subaccount_subscription.go b/internal/provider/resource_subaccount_subscription.go index 0d6aa2d6..748e1360 100644 --- a/internal/provider/resource_subaccount_subscription.go +++ b/internal/provider/resource_subaccount_subscription.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "net/http" "strings" "github.com/hashicorp/terraform-plugin-framework-timeouts/resource/timeouts" @@ -323,7 +324,12 @@ func (rs *subaccountSubscriptionResource) CreateStateChange(ctx context.Context, Pending: []string{saas_manager_service.StateInProcess}, Target: []string{saas_manager_service.StateSubscribed}, Refresh: func() (interface{}, string, error) { - subRes, _, err := rs.cli.Accounts.Subscription.Get(ctx, plan.SubaccountId.ValueString(), plan.AppName.ValueString(), plan.PlanName.ValueString()) + subRes, cmdRes, err := rs.cli.Accounts.Subscription.Get(ctx, plan.SubaccountId.ValueString(), plan.AppName.ValueString(), plan.PlanName.ValueString()) + + if cmdRes.StatusCode == http.StatusTooManyRequests { + // Retry in case of rate limiting + return subRes, saas_manager_service.StateInProcess, nil + } if err != nil { return subRes, "", err @@ -357,7 +363,12 @@ func (rs *subaccountSubscriptionResource) DeleteStateChange(ctx context.Context, Pending: []string{saas_manager_service.StateInProcess}, Target: []string{saas_manager_service.StateNotSubscribed}, Refresh: func() (interface{}, string, error) { - subRes, _, err := rs.cli.Accounts.Subscription.Get(ctx, state.SubaccountId.ValueString(), state.AppName.ValueString(), state.PlanName.ValueString()) + subRes, cmdRes, err := rs.cli.Accounts.Subscription.Get(ctx, state.SubaccountId.ValueString(), state.AppName.ValueString(), state.PlanName.ValueString()) + + if cmdRes.StatusCode == http.StatusTooManyRequests { + // Retry in case of rate limiting + return subRes, saas_manager_service.StateInProcess, nil + } if err != nil { return subRes, subRes.State, err