Skip to content

Commit 3ffd5cf

Browse files
fix(sqlserverflex): add retries on Locked + TooEarly for user + database
STACKITTPR-785
1 parent ab24d7b commit 3ffd5cf

3 files changed

Lines changed: 26 additions & 4 deletions

File tree

‎stackit/internal/services/sqlserverflex/database/resource.go‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,9 @@ func (r *databaseResource) Create(ctx context.Context, req resource.CreateReques
202202

203203
ctx = core.InitProviderContext(ctx)
204204

205-
_, err = r.client.DefaultAPI.CreateDatabase(ctx, projectId, region, instanceId).CreateDatabasePayload(*payload).Execute()
205+
// Workaround: The database creation will be tried 5 times. In some cases the instance might be
206+
// in maintenance mode and the database API is temporarily unavailable. Usually this is only for 1-2 seconds.
207+
_, err = utils.RetryRequest(ctx, r.client.DefaultAPI.CreateDatabase(ctx, projectId, region, instanceId).CreateDatabasePayload(*payload).Execute, sqlserverflexUtils.RetryConfig)
206208
if err != nil {
207209
resp.Diagnostics.AddError("Error creating database", err.Error())
208210
return
@@ -314,7 +316,9 @@ func (r *databaseResource) Delete(ctx context.Context, req resource.DeleteReques
314316

315317
ctx = core.InitProviderContext(ctx)
316318

317-
err := r.client.DefaultAPI.DeleteDatabase(ctx, projectId, region, instanceId, name).Execute()
319+
// Workaround: The database deletion will be tried 5 times. In some cases the instance might be
320+
// in maintenance mode and the database API is temporarily unavailable. Usually this is only for 1-2 seconds.
321+
err := utils.RetryRequestWithoutResponse(ctx, r.client.DefaultAPI.DeleteDatabase(ctx, projectId, region, instanceId, name).Execute, sqlserverflexUtils.RetryConfig)
318322
if err != nil {
319323
if oapiErr, ok := errors.AsType[*oapierror.GenericOpenAPIError](err); ok && oapiErr.StatusCode == http.StatusNotFound {
320324
return

‎stackit/internal/services/sqlserverflex/user/resource.go‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,9 @@ func (r *userResource) Create(ctx context.Context, req resource.CreateRequest, r
263263
return
264264
}
265265
// Create new user
266-
userResp, err := r.client.DefaultAPI.CreateUser(ctx, projectId, region, instanceId).CreateUserPayload(*payload).Execute()
266+
// Workaround: The user creation will be tried 5 times. In some cases the instance might be
267+
// in maintenance mode and the user API is temporarily unavailable. Usually this is only for 1-2 seconds.
268+
userResp, err := utils.RetryRequest(ctx, r.client.DefaultAPI.CreateUser(ctx, projectId, region, instanceId).CreateUserPayload(*payload).Execute, sqlserverflexUtils.RetryConfig)
267269
if err != nil {
268270
core.LogAndAddError(ctx, &resp.Diagnostics, "Error creating user", fmt.Sprintf("Calling API: %v", err))
269271
return
@@ -389,7 +391,9 @@ func (r *userResource) Delete(ctx context.Context, req resource.DeleteRequest, r
389391
}
390392

391393
// Delete existing user
392-
err = r.client.DefaultAPI.DeleteUser(ctx, projectId, region, instanceId, userId).Execute()
394+
// Workaround: The user deletion will be tried 5 times. In some cases the instance might be
395+
// in maintenance mode and the user API is temporarily unavailable. Usually this is only for 1-2 seconds.
396+
err = utils.RetryRequestWithoutResponse(ctx, r.client.DefaultAPI.DeleteUser(ctx, projectId, region, instanceId, userId).Execute, sqlserverflexUtils.RetryConfig)
393397
if err != nil {
394398
if oapiErr, ok := errors.AsType[*oapierror.GenericOpenAPIError](err); ok && oapiErr.StatusCode == http.StatusNotFound {
395399
return

‎stackit/internal/services/sqlserverflex/utils/util.go‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package utils
33
import (
44
"context"
55
"fmt"
6+
"net/http"
7+
"time"
68

79
sqlserverflex "github.com/stackitcloud/stackit-sdk-go/services/sqlserverflex/v3api"
810

@@ -29,3 +31,15 @@ func ConfigureClient(ctx context.Context, providerData *core.ProviderData, diags
2931

3032
return apiClient
3133
}
34+
35+
var RetryConfig = utils.RetryConfig{
36+
Attempts: 5,
37+
Backoff: func(attempt int) time.Duration {
38+
// Wait for every attempt 5 seconds longer. 5s, 10s, 15s and so on
39+
return time.Duration(attempt*5) * time.Second
40+
},
41+
RetryStatusCodes: []int{
42+
http.StatusLocked,
43+
http.StatusTooEarly,
44+
},
45+
}

0 commit comments

Comments
 (0)