Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,8 @@
- **Bugfix**: **Dependencies:** Bump STACKIT SDK core module from `v0.24.1` to `v0.25.0`
- [v1.8.3](services/mongodbflex/CHANGELOG.md#v183)
- **Dependencies:** Bump STACKIT SDK core module from `v0.25.0` to `v0.26.0`
- [v1.9.0](services/mongodbflex/CHANGELOG.md#v190)
- **Improvement:** Use new WaiterHelper for mongodbflex
- `objectstorage`:
- [v1.7.2](services/objectstorage/CHANGELOG.md#v172)
- **Dependencies:** Bump STACKIT SDK core module from `v0.24.0` to `v0.24.1`
Expand Down
3 changes: 3 additions & 0 deletions services/mongodbflex/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
## v1.9.0
- **Improvement:** Use new WaiterHelper for mongodbflex

## v1.8.3
- **Dependencies:** Bump STACKIT SDK core module from `v0.25.0` to `v0.26.0`

Expand Down
2 changes: 1 addition & 1 deletion services/mongodbflex/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v1.8.3
v1.9.0
180 changes: 80 additions & 100 deletions services/mongodbflex/v2api/wait/wait.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@ package wait

import (
"context"
"fmt"
"net/http"
"errors"
"sort"
"time"

"github.com/stackitcloud/stackit-sdk-go/core/oapierror"
"github.com/stackitcloud/stackit-sdk-go/core/wait"
mongodbflex "github.com/stackitcloud/stackit-sdk-go/services/mongodbflex/v2api"
)
Expand All @@ -27,29 +25,15 @@ const (

// CreateInstanceWaitHandler will wait for instance creation
func CreateInstanceWaitHandler(ctx context.Context, a mongodbflex.DefaultAPI, projectId, instanceId, region string) *wait.AsyncActionHandler[mongodbflex.InstanceResponse] {
handler := wait.New(func() (waitFinished bool, response *mongodbflex.InstanceResponse, err error) {
s, err := a.GetInstance(ctx, projectId, instanceId, region).Execute()
if err != nil {
return false, nil, err
}
if s == nil || s.Item == nil || s.Item.Id == nil || *s.Item.Id != instanceId || s.Item.Status == nil {
return false, nil, nil
}
switch *s.Item.Status {
default:
return true, s, fmt.Errorf("instance with id %s has unexpected status %s", instanceId, *s.Item.Status)
case "":
return false, nil, nil
case INSTANCESTATUS_PROCESSING:
return false, nil, nil
case INSTANCESTATUS_UNKNOWN:
return false, nil, nil
case INSTANCESTATUS_READY:
return true, s, nil
case INSTANCESTATUS_FAILED:
return true, s, fmt.Errorf("create failed for instance with id %s", instanceId)
}
})
waitConfig := wait.WaiterHelper[mongodbflex.InstanceResponse, string]{
FetchInstance: a.GetInstance(ctx, projectId, instanceId, region).Execute,
GetState: getStateInstance,
ActiveState: []string{INSTANCESTATUS_READY},
ErrorState: []string{INSTANCESTATUS_FAILED},
}

handler := wait.New(waitConfig.Wait())

handler.SetTimeout(45 * time.Minute)
handler.SetSleepBeforeWait(5 * time.Second)
return handler
Expand All @@ -61,74 +45,53 @@ func CloneInstanceWaitHandler(ctx context.Context, a mongodbflex.DefaultAPI, pro
}

func RestoreInstanceWaitHandler(ctx context.Context, a mongodbflex.DefaultAPI, projectId, instanceId, backupId, region string) *wait.AsyncActionHandler[mongodbflex.ListRestoreJobsResponse] {
handler := wait.New(func() (waitFinished bool, response *mongodbflex.ListRestoreJobsResponse, err error) {
s, err := a.ListRestoreJobs(ctx, projectId, instanceId, region).Execute()
if err != nil {
return false, nil, err
}
if s == nil || s.Items == nil {
return false, nil, nil
}

restoreJobsSlice := s.Items

// sort array by descending date
sort.Slice(restoreJobsSlice, func(i, j int) bool {
// swap elements to sort by descending order
return *restoreJobsSlice[i].Date > *restoreJobsSlice[j].Date
})

var status string
for _, restoreJob := range restoreJobsSlice {
if *restoreJob.BackupID == backupId {
status = *restoreJob.Status
break
waitConfig := wait.WaiterHelper[mongodbflex.ListRestoreJobsResponse, string]{
FetchInstance: a.ListRestoreJobs(ctx, projectId, instanceId, region).Execute,
GetState: func(response *mongodbflex.ListRestoreJobsResponse) (string, error) {
if response == nil {
return "", errors.New("response is nil")
}
}

switch status {
default:
return true, s, fmt.Errorf("restore job for backup with id %s has unexpected status %s", backupId, status)
case RestoreJobProcessing:
return false, nil, nil
case RestoreJobFinished:
return true, s, nil
case RestoreJobBroken:
return true, s, fmt.Errorf("restore job for backup with id %s is broken", backupId)
case RestoreJobKilled:
return true, s, fmt.Errorf("restore job for backup with id %s was killed", backupId)
}
})
if len(response.Items) == 0 {
return "", errors.New("response items is empty")
}
restoreJobsSlice := response.Items
// sort array by descending date
sort.Slice(restoreJobsSlice, func(i, j int) bool {
// swap elements to sort by descending order
return *restoreJobsSlice[i].Date > *restoreJobsSlice[j].Date
})

var status string
for _, restoreJob := range restoreJobsSlice {
if *restoreJob.BackupID == backupId {
status = *restoreJob.Status
break
}
}
return status, nil
},
ActiveState: []string{RestoreJobFinished},
ErrorState: []string{RestoreJobKilled, RestoreJobBroken},
}

handler := wait.New(waitConfig.Wait())

handler.SetTimeout(45 * time.Minute)
handler.SetSleepBeforeWait(5 * time.Second)
return handler
}

// UpdateInstanceWaitHandler will wait for instance update
func UpdateInstanceWaitHandler(ctx context.Context, a mongodbflex.DefaultAPI, projectId, instanceId, region string) *wait.AsyncActionHandler[mongodbflex.InstanceResponse] {
handler := wait.New(func() (waitFinished bool, response *mongodbflex.InstanceResponse, err error) {
s, err := a.GetInstance(ctx, projectId, instanceId, region).Execute()
if err != nil {
return false, nil, err
}
if s == nil || s.Item == nil || s.Item.Id == nil || *s.Item.Id != instanceId || s.Item.Status == nil {
return false, nil, nil
}
switch *s.Item.Status {
default:
return true, s, fmt.Errorf("instance with id %s has unexpected status %s", instanceId, *s.Item.Status)
case "":
return false, nil, nil
case INSTANCESTATUS_PROCESSING:
return false, nil, nil
case INSTANCESTATUS_UNKNOWN:
return false, nil, nil
case INSTANCESTATUS_READY:
return true, s, nil
case INSTANCESTATUS_FAILED:
return true, s, fmt.Errorf("update failed for instance with id %s", instanceId)
}
})
waitConfig := wait.WaiterHelper[mongodbflex.InstanceResponse, string]{
FetchInstance: a.GetInstance(ctx, projectId, instanceId, region).Execute,
GetState: getStateInstance,
ActiveState: []string{INSTANCESTATUS_READY},
ErrorState: []string{INSTANCESTATUS_FAILED},
}

handler := wait.New(waitConfig.Wait())

handler.SetTimeout(45 * time.Minute)
return handler
}
Expand All @@ -140,20 +103,37 @@ func PartialUpdateInstanceWaitHandler(ctx context.Context, a mongodbflex.Default

// DeleteInstanceWaitHandler will wait for instance deletion
func DeleteInstanceWaitHandler(ctx context.Context, a mongodbflex.DefaultAPI, projectId, instanceId, region string) *wait.AsyncActionHandler[struct{}] {
handler := wait.New(func() (waitFinished bool, response *struct{}, err error) {
_, err = a.GetInstance(ctx, projectId, instanceId, region).Execute()
if err == nil {
return false, nil, nil
}
oapiErr, ok := err.(*oapierror.GenericOpenAPIError) //nolint:errorlint //complaining that error.As should be used to catch wrapped errors, but this error should not be wrapped
if !ok {
return false, nil, fmt.Errorf("could not convert error to oapierror.GenericOpenAPIError")
}
if oapiErr.StatusCode != http.StatusNotFound {
return false, nil, err
}
return true, nil, nil
})
w := wait.WaiterHelper[mongodbflex.InstanceResponse, string]{
FetchInstance: a.GetInstance(ctx, projectId, instanceId, region).Execute,
GetState: getStateInstance,
ActiveState: []string{},
ErrorState: []string{},
}

// adapter for adhering to the wait helper type schema
genericCheck := w.Wait()
adaptedCheck := func() (waitFinished bool, response *struct{}, err error) {
finished, _, err := genericCheck()
return finished, nil, err
}

handler := wait.New(adaptedCheck)
handler.SetTimeout(15 * time.Minute)
return handler
}

func getStateInstance(response *mongodbflex.InstanceResponse) (string, error) {
if response == nil {
return "", errors.New("empty response")
}
if response.Item == nil {
return "", errors.New("empty items")
}
if response.Item.Id == nil {
return "", errors.New("empty item id")
}
if response.Item.Status == nil {
return "", errors.New("empty item status")
}
return *response.Item.Status, nil
}
Loading