Skip to content
Merged
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
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,26 @@
## 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-02)
- **Bugfix:** `PartialUpdateInstanceWaitHandler` does not finish when update is succeeded
- **Deprecation:** Deprecated `InstanceStateSuccess`, `InstanceStateFailed`, `InstanceTypeCreate`, `InstanceTypeUpdate`, `InstanceTypeDelete` and will be removed after 2nd October 2025
- `mariadb`: [v0.21.2](services/mariadb/CHANGELOG.md#v0212-2025-04-02)
- **Bugfix:** `PartialUpdateInstanceWaitHandler` does not finish when update is succeeded
- **Deprecation:** Deprecated `InstanceStateSuccess`, `InstanceStateFailed`, `InstanceTypeCreate`, `InstanceTypeUpdate`, `InstanceTypeDelete` and will be removed after 2nd October 2025
- `opensearch`: [v0.20.2](services/opensearch/CHANGELOG.md#v0202-2025-04-02)
- **Bugfix:** `PartialUpdateInstanceWaitHandler` does not finish when update is succeeded
- **Deprecation:** Deprecated `InstanceStateSuccess`, `InstanceStateFailed`, `InstanceTypeCreate`, `InstanceTypeUpdate`, `InstanceTypeDelete` and will be removed after 2nd October 2025
- `redis`: [v0.21.2](services/redis/CHANGELOG.md#v0212-2025-04-02)
- **Bugfix:** `PartialUpdateInstanceWaitHandler` does not finish when update is succeeded
- **Deprecation:** Deprecated `InstanceStateSuccess`, `InstanceStateFailed`, `InstanceTypeCreate`, `InstanceTypeUpdate`, `InstanceTypeDelete` and will be removed after 2nd October 2025
- `rabbitmq`: [v0.21.2](services/rabbitmq/CHANGELOG.md#v0212-2025-04-02)
- **Bugfix:** `PartialUpdateInstanceWaitHandler` does not finish when update is succeeded
- **Deprecation:** Deprecated `InstanceStateSuccess`, `InstanceStateFailed`, `InstanceTypeCreate`, `InstanceTypeUpdate`, `InstanceTypeDelete` and will be removed after 2nd October 2025



## 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
4 changes: 4 additions & 0 deletions services/logme/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## v0.21.2 (2025-04-02)
- **Bugfix:** `PartialUpdateInstanceWaitHandler` does not finish when update is succeeded
- **Deprecation:** Deprecated `InstanceStateSuccess`, `InstanceStateFailed`, `InstanceTypeCreate`, `InstanceTypeUpdate`, `InstanceTypeDelete` and will be removed after 2nd October 2025

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

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

const (
InstanceStatusActive = "active"
InstanceStatusFailed = "failed"
InstanceStatusStopped = "stopped"
InstanceStatusCreating = "creating"
InstanceStatusDeleting = "deleting"
InstanceStatusUpdating = "updating"

// Deprecated: InstanceStateSuccess is deprecated and will be removed after 2nd October 2025.
InstanceStateSuccess = "succeeded"
InstanceStateFailed = "failed"
InstanceTypeCreate = "create"
InstanceTypeUpdate = "update"
InstanceTypeDelete = "delete"
// Deprecated: InstanceStateFailed is deprecated and will be removed after 2nd October 2025.
InstanceStateFailed = "failed"
// Deprecated: InstanceTypeCreate is deprecated and will be removed after 2nd October 2025.
InstanceTypeCreate = "create"
// Deprecated: InstanceTypeUpdate is deprecated and will be removed after 2nd October 2025.
InstanceTypeUpdate = "update"
// Deprecated: InstanceTypeDelete is deprecated and will be removed after 2nd October 2025.
InstanceTypeDelete = "delete"
)

// Interface needed for tests
Expand All @@ -37,14 +49,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.Status == nil {
return false, nil, fmt.Errorf("create failed for instance with id %s. The response is not valid: the status is missing", instanceId)
}
if *s.InstanceId == instanceId && *s.LastOperation.Type == InstanceTypeCreate && *s.LastOperation.State == InstanceStateSuccess {
switch *s.Status {
case 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)
case 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 +75,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.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 {
switch *s.Status {
case 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)
case 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,13 +99,13 @@ 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.LastOperation.Description == nil || s.Status == nil {
return false, nil, fmt.Errorf("delete failed for instance with id %s. The response is not valid: The status or last operation description are missing", instanceId)
}
if *s.LastOperation.Type != InstanceTypeDelete {
if *s.Status != InstanceStatusDeleting {
return false, nil, nil
}
if *s.LastOperation.State == InstanceStateSuccess {
if *s.Status == InstanceStatusActive {
if strings.Contains(*s.LastOperation.Description, "DeleteFailed") || strings.Contains(*s.LastOperation.Description, "failed") {
return true, nil, fmt.Errorf("instance was deleted successfully but has errors: %s", *s.LastOperation.Description)
}
Expand Down
59 changes: 20 additions & 39 deletions services/logme/wait/wait_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,26 +21,21 @@ type apiClientInstanceMocked struct {
resourceDescription string
}

var (
instanceTypeCreate = InstanceTypeCreate
instanceTypeUpdate = InstanceTypeUpdate
instanceTypeDelete = InstanceTypeDelete
)
const deleteOperation = "delete"

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 == deleteOperation && a.resourceState == InstanceStatusActive {
if a.deletionSucceedsWithErrors {
return &logme.Instance{
InstanceId: &a.resourceId,
Status: &a.resourceState,
LastOperation: &logme.InstanceLastOperation{
Description: &a.resourceDescription,
Type: a.resourceOperation,
State: &a.resourceState,
},
}, nil
}
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 @@ -126,21 +117,16 @@ func TestCreateInstanceWaitHandler(t *testing.T) {
instanceId := "foo-bar"

apiClient := &apiClientInstanceMocked{
getFails: tt.getFails,
resourceId: instanceId,
resourceOperation: &instanceTypeCreate,
resourceState: tt.resourceState,
getFails: tt.getFails,
resourceId: instanceId,
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 +156,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 @@ -200,21 +186,16 @@ func TestUpdateInstanceWaitHandler(t *testing.T) {
instanceId := "foo-bar"

apiClient := &apiClientInstanceMocked{
getFails: tt.getFails,
resourceId: instanceId,
resourceOperation: &instanceTypeUpdate,
resourceState: tt.resourceState,
getFails: tt.getFails,
resourceId: instanceId,
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 @@ -246,22 +227,22 @@ func TestDeleteInstanceWaitHandler(t *testing.T) {
desc: "delete_succeeded",
getFails: false,
deleteSucceeedsWithErrors: false,
resourceState: InstanceStateSuccess,
resourceState: InstanceStatusActive,
wantErr: false,
wantResp: true,
},
{
desc: "delete_failed",
getFails: false,
deleteSucceeedsWithErrors: false,
resourceState: InstanceStateFailed,
resourceState: InstanceStatusFailed,
wantErr: true,
wantResp: true,
},
{
desc: "delete_succeeds_with_errors",
getFails: false,
resourceState: InstanceStateSuccess,
resourceState: InstanceStatusActive,
deleteSucceeedsWithErrors: true,
resourceDescription: "Deleting resource: cf failed with error: DeleteFailed",
wantErr: true,
Expand All @@ -283,7 +264,7 @@ func TestDeleteInstanceWaitHandler(t *testing.T) {
getFails: tt.getFails,
deletionSucceedsWithErrors: tt.deleteSucceeedsWithErrors,
resourceId: instanceId,
resourceOperation: &instanceTypeDelete,
resourceOperation: utils.Ptr(deleteOperation),
resourceDescription: tt.resourceDescription,
resourceState: tt.resourceState,
}
Expand Down
4 changes: 4 additions & 0 deletions services/mariadb/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## v0.21.2 (2025-04-02)
- **Bugfix:** `PartialUpdateInstanceWaitHandler` does not finish when update is succeeded
- **Deprecation:** Deprecated `InstanceStateSuccess`, `InstanceStateFailed`, `InstanceTypeCreate`, `InstanceTypeUpdate`, `InstanceTypeDelete` and will be removed after 2nd October 2025

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

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

const (
InstanceStatusActive = "active"
InstanceStatusFailed = "failed"
InstanceStatusStopped = "stopped"
InstanceStatusCreating = "creating"
InstanceStatusDeleting = "deleting"
InstanceStatusUpdating = "updating"

// Deprecated: InstanceStateSuccess is deprecated and will be removed after 2nd October 2025.
InstanceStateSuccess = "succeeded"
InstanceStateFailed = "failed"
InstanceTypeCreate = "create"
InstanceTypeUpdate = "update"
InstanceTypeDelete = "delete"
// Deprecated: InstanceStateFailed is deprecated and will be removed after 2nd October 2025.
InstanceStateFailed = "failed"
// Deprecated: InstanceTypeCreate is deprecated and will be removed after 2nd October 2025.
InstanceTypeCreate = "create"
// Deprecated: InstanceTypeUpdate is deprecated and will be removed after 2nd October 2025.
InstanceTypeUpdate = "update"
// Deprecated: InstanceTypeDelete is deprecated and will be removed after 2nd October 2025.
InstanceTypeDelete = "delete"
)

// Interface needed for tests
Expand All @@ -37,14 +49,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.Status == nil {
return false, nil, fmt.Errorf("create failed for instance with id %s. The response is not valid: the status is missing", instanceId)
}
if *s.InstanceId == instanceId && *s.LastOperation.Type == InstanceTypeCreate && *s.LastOperation.State == InstanceStateSuccess {
switch *s.Status {
case 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)
case 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 +75,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.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 {
switch *s.Status {
case 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)
case 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,13 +99,13 @@ 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.LastOperation.Description == nil || s.Status == nil {
return false, nil, fmt.Errorf("delete failed for instance with id %s. The response is not valid: The status or last operation description are missing", instanceId)
}
if *s.LastOperation.Type != InstanceTypeDelete {
if *s.Status != InstanceStatusDeleting {
return false, nil, nil
}
if *s.LastOperation.State == InstanceStateSuccess {
if *s.Status == InstanceStatusActive {
if strings.Contains(*s.LastOperation.Description, "DeleteFailed") || strings.Contains(*s.LastOperation.Description, "failed") {
return true, nil, fmt.Errorf("instance was deleted successfully but has errors: %s", *s.LastOperation.Description)
}
Expand Down
Loading
Loading