Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,21 @@
## Release (2025-XX-YY)
- `cdn`: [v0.2.0](services/cdn/CHANGELOG.md#v020-2025-04-01)
- **API enhancement:** Provide waiter infrastructure
- `logme`: [v0.21.2](services/logme/CHANGELOG.md#v0212-2025-04-01)
- **Bugfix:** `PartialUpdateInstanceWaitHandler` does not finish when update is succeeded
- `mariadb`: [v0.21.2](services/mariadb/CHANGELOG.md#v0212-2025-04-01)
- **Bugfix:** `PartialUpdateInstanceWaitHandler` does not finish when update is succeeded
- `opensearch`: [v0.20.2](services/opensearch/CHANGELOG.md#v0202-2025-04-01)
- **Bugfix:** `PartialUpdateInstanceWaitHandler` does not finish when update is succeeded
- `redis`: [v0.21.2](services/redis/CHANGELOG.md#v0212-2025-04-01)
- **Bugfix:** `PartialUpdateInstanceWaitHandler` does not finish when update is succeeded
- `rabbitmq`: [v0.21.2](services/rabbitmq/CHANGELOG.md#v0212-2025-04-01)
- **Bugfix:** `PartialUpdateInstanceWaitHandler` does not finish when update is succeeded



## Release (2025-03-27)

- `alb`: [v0.2.1](services/alb/CHANGELOG.md#v021-2025-03-27)
- **Bugfix:** Removed ConfigureRegion() from API client
- `cdn`: [v0.1.1](services/cdn/CHANGELOG.md#v011-2025-03-27)
Expand Down
3 changes: 3 additions & 0 deletions services/logme/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
## v0.21.2 (2025-04-01)
- **Bugfix:** `PartialUpdateInstanceWaitHandler` does not finish when update is succeeded

## v0.21.1 (2025-03-19)
- **Internal:** Backwards compatible change to generated code

Expand Down
46 changes: 28 additions & 18 deletions services/logme/wait/wait.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@ import (
)

const (
InstanceStateSuccess = "succeeded"
InstanceStateFailed = "failed"
InstanceTypeCreate = "create"
InstanceTypeUpdate = "update"
InstanceTypeDelete = "delete"
InstanceStatusActive = "active"
InstanceStatusFailed = "failed"
InstanceStatusDeleting = "deleting"
InstanceStateSuccess = "succeeded"
InstanceTypeCreate = "create"
InstanceTypeUpdate = "update"
InstanceTypeDelete = "delete"
)

// Interface needed for tests
Expand All @@ -37,14 +39,18 @@ func CreateInstanceWaitHandler(ctx context.Context, a APIClientInstanceInterface
if err != nil {
return false, nil, err
}
if s.InstanceId == nil || s.LastOperation == nil || s.LastOperation.Type == nil || s.LastOperation.State == nil {
return false, nil, fmt.Errorf("create failed for instance with id %s. The response is not valid: the instance id, the last operation type or the state are missing", instanceId)
if s.InstanceId == nil || s.Status == nil {
return false, nil, fmt.Errorf("create failed for instance with id %s. The response is not valid: the instance id or the status are missing", instanceId)
}
if *s.InstanceId == instanceId && *s.LastOperation.Type == InstanceTypeCreate && *s.LastOperation.State == InstanceStateSuccess {
if *s.InstanceId == instanceId && *s.Status == InstanceStatusActive {
return true, s, nil
}
if *s.InstanceId == instanceId && *s.LastOperation.Type == InstanceTypeCreate && *s.LastOperation.State == InstanceStateFailed {
return true, s, fmt.Errorf("create failed for instance with id %s: %s", instanceId, *s.LastOperation.Description)
if *s.InstanceId == instanceId && *s.Status == InstanceStatusFailed {
var failedDescription string
if s.LastOperation != nil && s.LastOperation.Description != nil {
failedDescription = *s.LastOperation.Description
}
return true, s, fmt.Errorf("create failed for instance with id %s: %s", instanceId, failedDescription)
}
return false, nil, nil
})
Expand All @@ -59,14 +65,18 @@ func PartialUpdateInstanceWaitHandler(ctx context.Context, a APIClientInstanceIn
if err != nil {
return false, nil, err
}
if s.InstanceId == nil || s.LastOperation == nil || s.LastOperation.Type == nil || s.LastOperation.State == nil {
return false, nil, fmt.Errorf("update failed for instance with id %s. The response is not valid: the instance id, the last operation type or the state are missing", instanceId)
if s.InstanceId == nil || s.Status == nil {
return false, nil, fmt.Errorf("update failed for instance with id %s. The response is not valid: the instance id or the status are missing", instanceId)
}
if *s.InstanceId == instanceId && *s.LastOperation.Type == InstanceTypeUpdate && *s.LastOperation.State == InstanceStateSuccess {
if *s.InstanceId == instanceId && *s.Status == InstanceStatusActive {
return true, s, nil
}
if *s.InstanceId == instanceId && *s.LastOperation.Type == InstanceTypeUpdate && *s.LastOperation.State == InstanceStateFailed {
return true, s, fmt.Errorf("update failed for instance with id %s: %s", instanceId, *s.LastOperation.Description)
if *s.InstanceId == instanceId && *s.Status == InstanceStatusFailed {
var failedDescription string
if s.LastOperation != nil && s.LastOperation.Description != nil {
failedDescription = *s.LastOperation.Description
}
return true, s, fmt.Errorf("update failed for instance with id %s: %s", instanceId, failedDescription)
}
return false, nil, nil
})
Expand All @@ -79,10 +89,10 @@ func DeleteInstanceWaitHandler(ctx context.Context, a APIClientInstanceInterface
handler := wait.New(func() (waitFinished bool, response *struct{}, err error) {
s, err := a.GetInstanceExecute(ctx, projectId, instanceId)
if err == nil {
if s.LastOperation == nil || s.LastOperation.Type == nil || s.LastOperation.State == nil || s.LastOperation.Description == nil {
return false, nil, fmt.Errorf("delete failed for instance with id %s. The response is not valid: The last operation type, description or the state are missing", instanceId)
if s.LastOperation == nil || s.Status == nil || s.LastOperation.State == nil || s.LastOperation.Description == nil {
return false, nil, fmt.Errorf("delete failed for instance with id %s. The response is not valid: The status last operation type, description or the state are missing", instanceId)
}
if *s.LastOperation.Type != InstanceTypeDelete {
if *s.Status != InstanceStatusDeleting {
return false, nil, nil
}
if *s.LastOperation.State == InstanceStateSuccess {
Expand Down
43 changes: 13 additions & 30 deletions services/logme/wait/wait_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,17 @@ type apiClientInstanceMocked struct {
resourceDescription string
}

var (
instanceTypeCreate = InstanceTypeCreate
instanceTypeUpdate = InstanceTypeUpdate
instanceTypeDelete = InstanceTypeDelete
)

func (a *apiClientInstanceMocked) GetInstanceExecute(_ context.Context, _, _ string) (*logme.Instance, error) {
if a.getFails {
return nil, &oapierror.GenericOpenAPIError{
StatusCode: 500,
}
}
if *a.resourceOperation == InstanceTypeDelete && a.resourceState == InstanceStateSuccess {
if a.resourceOperation != nil && *a.resourceOperation == InstanceTypeDelete && a.resourceState == InstanceStateSuccess {
if a.deletionSucceedsWithErrors {
return &logme.Instance{
InstanceId: &a.resourceId,
Status: &a.resourceState,
LastOperation: &logme.InstanceLastOperation{
Description: &a.resourceDescription,
Type: a.resourceOperation,
Expand All @@ -51,11 +46,7 @@ func (a *apiClientInstanceMocked) GetInstanceExecute(_ context.Context, _, _ str

return &logme.Instance{
InstanceId: &a.resourceId,
LastOperation: &logme.InstanceLastOperation{
Description: &a.resourceDescription,
Type: a.resourceOperation,
State: &a.resourceState,
},
Status: utils.Ptr(a.resourceState),
}, nil
}

Expand Down Expand Up @@ -96,14 +87,14 @@ func TestCreateInstanceWaitHandler(t *testing.T) {
{
desc: "create_succeeded",
getFails: false,
resourceState: InstanceStateSuccess,
resourceState: InstanceStatusActive,
wantErr: false,
wantResp: true,
},
{
desc: "create_failed",
getFails: false,
resourceState: InstanceStateFailed,
resourceState: InstanceStatusFailed,
wantErr: true,
wantResp: true,
},
Expand All @@ -128,19 +119,15 @@ func TestCreateInstanceWaitHandler(t *testing.T) {
apiClient := &apiClientInstanceMocked{
getFails: tt.getFails,
resourceId: instanceId,
resourceOperation: &instanceTypeCreate,
resourceOperation: utils.Ptr(InstanceTypeCreate),
resourceState: tt.resourceState,
}

var wantRes *logme.Instance
if tt.wantResp {
wantRes = &logme.Instance{
InstanceId: &instanceId,
LastOperation: &logme.InstanceLastOperation{
Type: &instanceTypeCreate,
State: utils.Ptr(tt.resourceState),
Description: utils.Ptr(""),
},
Status: utils.Ptr(tt.resourceState),
}
}

Expand Down Expand Up @@ -170,14 +157,14 @@ func TestUpdateInstanceWaitHandler(t *testing.T) {
{
desc: "update_succeeded",
getFails: false,
resourceState: InstanceStateSuccess,
resourceState: InstanceStatusActive,
wantErr: false,
wantResp: true,
},
{
desc: "update_failed",
getFails: false,
resourceState: InstanceStateFailed,
resourceState: InstanceStatusFailed,
wantErr: true,
wantResp: true,
},
Expand All @@ -202,19 +189,15 @@ func TestUpdateInstanceWaitHandler(t *testing.T) {
apiClient := &apiClientInstanceMocked{
getFails: tt.getFails,
resourceId: instanceId,
resourceOperation: &instanceTypeUpdate,
resourceOperation: utils.Ptr(InstanceTypeUpdate),
resourceState: tt.resourceState,
}

var wantRes *logme.Instance
if tt.wantResp {
wantRes = &logme.Instance{
InstanceId: &instanceId,
LastOperation: &logme.InstanceLastOperation{
Type: &instanceTypeUpdate,
State: utils.Ptr(tt.resourceState),
Description: utils.Ptr(""),
},
Status: utils.Ptr(tt.resourceState),
}
}

Expand Down Expand Up @@ -254,7 +237,7 @@ func TestDeleteInstanceWaitHandler(t *testing.T) {
desc: "delete_failed",
getFails: false,
deleteSucceeedsWithErrors: false,
resourceState: InstanceStateFailed,
resourceState: InstanceStatusFailed,
wantErr: true,
wantResp: true,
},
Expand Down Expand Up @@ -283,7 +266,7 @@ func TestDeleteInstanceWaitHandler(t *testing.T) {
getFails: tt.getFails,
deletionSucceedsWithErrors: tt.deleteSucceeedsWithErrors,
resourceId: instanceId,
resourceOperation: &instanceTypeDelete,
resourceOperation: utils.Ptr(InstanceTypeDelete),
resourceDescription: tt.resourceDescription,
resourceState: tt.resourceState,
}
Expand Down
3 changes: 3 additions & 0 deletions services/mariadb/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
## v0.21.2 (2025-04-01)
- **Bugfix:** `PartialUpdateInstanceWaitHandler` does not finish when update is succeeded

## v0.21.1 (2025-03-19)
- **Internal:** Backwards compatible change to generated code

Expand Down
46 changes: 28 additions & 18 deletions services/mariadb/wait/wait.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@ import (
)

const (
InstanceStateSuccess = "succeeded"
InstanceStateFailed = "failed"
InstanceTypeCreate = "create"
InstanceTypeUpdate = "update"
InstanceTypeDelete = "delete"
InstanceStatusActive = "active"
InstanceStatusFailed = "failed"
InstanceStatusDeleting = "deleting"
InstanceStateSuccess = "succeeded"
InstanceTypeCreate = "create"
InstanceTypeUpdate = "update"
InstanceTypeDelete = "delete"
)

// Interface needed for tests
Expand All @@ -37,14 +39,18 @@ func CreateInstanceWaitHandler(ctx context.Context, a APIClientInstanceInterface
if err != nil {
return false, nil, err
}
if s.InstanceId == nil || s.LastOperation == nil || s.LastOperation.Type == nil || s.LastOperation.State == nil {
return false, nil, fmt.Errorf("create failed for instance with id %s. The response is not valid: the instance id, the last operation type or the state are missing", instanceId)
if s.InstanceId == nil || s.Status == nil {
return false, nil, fmt.Errorf("create failed for instance with id %s. The response is not valid: the instance id or the status are missing", instanceId)
}
if *s.InstanceId == instanceId && *s.LastOperation.Type == InstanceTypeCreate && *s.LastOperation.State == InstanceStateSuccess {
if *s.InstanceId == instanceId && *s.Status == InstanceStatusActive {
return true, s, nil
}
if *s.InstanceId == instanceId && *s.LastOperation.Type == InstanceTypeCreate && *s.LastOperation.State == InstanceStateFailed {
return true, s, fmt.Errorf("create failed for instance with id %s: %s", instanceId, *s.LastOperation.Description)
if *s.InstanceId == instanceId && *s.Status == InstanceStatusFailed {
var failedDescription string
if s.LastOperation != nil && s.LastOperation.Description != nil {
failedDescription = *s.LastOperation.Description
}
return true, s, fmt.Errorf("create failed for instance with id %s: %s", instanceId, failedDescription)
}
return false, nil, nil
})
Expand All @@ -59,14 +65,18 @@ func PartialUpdateInstanceWaitHandler(ctx context.Context, a APIClientInstanceIn
if err != nil {
return false, nil, err
}
if s.InstanceId == nil || s.LastOperation == nil || s.LastOperation.Type == nil || s.LastOperation.State == nil {
return false, nil, fmt.Errorf("update failed for instance with id %s. The response is not valid: the instance id, the last operation type or the state are missing", instanceId)
if s.InstanceId == nil || s.Status == nil {
return false, nil, fmt.Errorf("update failed for instance with id %s. The response is not valid: the instance id or the status are missing", instanceId)
}
if *s.InstanceId == instanceId && *s.LastOperation.Type == InstanceTypeUpdate && *s.LastOperation.State == InstanceStateSuccess {
if *s.InstanceId == instanceId && *s.Status == InstanceStatusActive {
return true, s, nil
}
if *s.InstanceId == instanceId && *s.LastOperation.Type == InstanceTypeUpdate && *s.LastOperation.State == InstanceStateFailed {
return true, s, fmt.Errorf("update failed for instance with id %s: %s", instanceId, *s.LastOperation.Description)
if *s.InstanceId == instanceId && *s.Status == InstanceStatusFailed {
var failedDescription string
if s.LastOperation != nil && s.LastOperation.Description != nil {
failedDescription = *s.LastOperation.Description
}
return true, s, fmt.Errorf("update failed for instance with id %s: %s", instanceId, failedDescription)
}
return false, nil, nil
})
Expand All @@ -79,10 +89,10 @@ func DeleteInstanceWaitHandler(ctx context.Context, a APIClientInstanceInterface
handler := wait.New(func() (waitFinished bool, response *struct{}, err error) {
s, err := a.GetInstanceExecute(ctx, projectId, instanceId)
if err == nil {
if s.LastOperation == nil || s.LastOperation.Type == nil || s.LastOperation.State == nil || s.LastOperation.Description == nil {
return false, nil, fmt.Errorf("delete failed for instance with id %s. The response is not valid: The last operation type, description or the state are missing", instanceId)
if s.LastOperation == nil || s.Status == nil || s.LastOperation.State == nil || s.LastOperation.Description == nil {
return false, nil, fmt.Errorf("delete failed for instance with id %s. The response is not valid: The status, last operation type, description or the state are missing", instanceId)
}
if *s.LastOperation.Type != InstanceTypeDelete {
if *s.Status != InstanceStatusDeleting {
return false, nil, nil
}
if *s.LastOperation.State == InstanceStateSuccess {
Expand Down
Loading
Loading