From 42eacb35e17cfd44820df6a0d7abfe5c76f928f0 Mon Sep 17 00:00:00 2001 From: GokceGK Date: Wed, 6 May 2026 09:33:15 +0200 Subject: [PATCH 1/3] feat (intake): refactor wait handler to use helper struct relates to STACKITSDK-375 --- CHANGELOG.md | 2 + services/intake/CHANGELOG.md | 3 + services/intake/VERSION | 2 +- services/intake/v1betaapi/wait/wait.go | 188 +++++++++----------- services/intake/v1betaapi/wait/wait_test.go | 33 ++++ 5 files changed, 124 insertions(+), 104 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 13e639fe5..587a55fc5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -137,6 +137,8 @@ - **Dependencies:** Bump STACKIT SDK core module from `v0.25.0` to `v0.26.0` - [v0.9.0](services/intake/CHANGELOG.md#v090) - **Feature:** Added `_UNKNOWN_DEFAULT_OPEN_API` fallback value to all enums to handle unknown API values gracefully. + - [v0.9.1](services/intake/CHANGELOG.md#v091) + - `v1betaapi`: **Improvement**: Use new `WaiterHandler` struct in the Git WaitHandler - `kms`: - [v1.6.2](services/kms/CHANGELOG.md#v162) - **Dependencies:** Bump STACKIT SDK core module from `v0.24.0` to `v0.24.1` diff --git a/services/intake/CHANGELOG.md b/services/intake/CHANGELOG.md index 6067e030b..d8016c7bf 100644 --- a/services/intake/CHANGELOG.md +++ b/services/intake/CHANGELOG.md @@ -1,3 +1,6 @@ +## v0.9.1 +- `v1betaapi`: **Improvement**: Use new `WaiterHandler` struct in the Intake WaitHandler + ## v0.9.0 - **Feature:** Added `_UNKNOWN_DEFAULT_OPEN_API` fallback value to all enums to handle unknown API values gracefully. diff --git a/services/intake/VERSION b/services/intake/VERSION index 7965b36d6..7f7306b3c 100644 --- a/services/intake/VERSION +++ b/services/intake/VERSION @@ -1 +1 @@ -v0.9.0 \ No newline at end of file +v0.9.1 \ No newline at end of file diff --git a/services/intake/v1betaapi/wait/wait.go b/services/intake/v1betaapi/wait/wait.go index 5c1e0b9f3..e356a3c0f 100644 --- a/services/intake/v1betaapi/wait/wait.go +++ b/services/intake/v1betaapi/wait/wait.go @@ -3,11 +3,9 @@ package wait import ( "context" "errors" - "fmt" "net/http" "time" - "github.com/stackitcloud/stackit-sdk-go/core/oapierror" "github.com/stackitcloud/stackit-sdk-go/core/wait" intake "github.com/stackitcloud/stackit-sdk-go/services/intake/v1betaapi" ) @@ -27,133 +25,117 @@ const ( INTAKEUSERRESPONSESTATE_DELETING = "deleting" ) -func CreateOrUpdateIntakeRunnerWaitHandler(ctx context.Context, a intake.DefaultAPI, projectId, region, intakeRunnerId string) *wait.AsyncActionHandler[intake.IntakeRunnerResponse] { - handler := wait.New(func() (waitFinished bool, response *intake.IntakeRunnerResponse, err error) { - runner, err := a.GetIntakeRunner(ctx, projectId, region, intakeRunnerId).Execute() - if err != nil { - return false, nil, err - } - - if runner == nil { - return false, nil, fmt.Errorf("API returned a nil response for Intake Runner %s", intakeRunnerId) - } - - if runner.Id == intakeRunnerId && runner.State == INTAKERUNNERRESPONSESTATE_ACTIVE { - return true, runner, nil - } - +func CreateOrUpdateIntakeRunnerWaitHandler(ctx context.Context, client intake.DefaultAPI, projectId, region, intakeRunnerId string) *wait.AsyncActionHandler[intake.IntakeRunnerResponse] { + waitConfig := wait.WaiterHelper[intake.IntakeRunnerResponse, string]{ + FetchInstance: client.GetIntakeRunner(ctx, projectId, region, intakeRunnerId).Execute, + GetState: func(response *intake.IntakeRunnerResponse) (string, error) { + if response == nil { + return "", errors.New("empty response") + } + return response.State, nil + }, + ActiveState: []string{INTAKERUNNERRESPONSESTATE_ACTIVE}, + ErrorState: []string{}, // The API does not have a dedicated failure state for this resource, // so we rely on the timeout for cases where it never becomes active. - return false, nil, nil - }) + } + + handler := wait.New(waitConfig.Wait()) handler.SetTimeout(15 * time.Minute) return handler } -func DeleteIntakeRunnerWaitHandler(ctx context.Context, a intake.DefaultAPI, projectId, region, intakeRunnerId string) *wait.AsyncActionHandler[intake.IntakeRunnerResponse] { - handler := wait.New(func() (waitFinished bool, response *intake.IntakeRunnerResponse, err error) { - _, err = a.GetIntakeRunner(ctx, projectId, region, intakeRunnerId).Execute() - if err == nil { - // Resource still exists - return false, nil, nil - } - - var oapiError *oapierror.GenericOpenAPIError - if errors.As(err, &oapiError) { - if oapiError.StatusCode == http.StatusNotFound { - // Success: Resource is gone - return true, nil, nil +func DeleteIntakeRunnerWaitHandler(ctx context.Context, client intake.DefaultAPI, projectId, region, intakeRunnerId string) *wait.AsyncActionHandler[intake.IntakeRunnerResponse] { + waitConfig := wait.WaiterHelper[intake.IntakeRunnerResponse, string]{ + FetchInstance: client.GetIntakeRunner(ctx, projectId, region, intakeRunnerId).Execute, + GetState: func(response *intake.IntakeRunnerResponse) (string, error) { + if response == nil { + return "", errors.New("empty response") } - } - // An unexpected error occurred - return false, nil, err - }) + return response.State, nil + }, + ActiveState: []string{}, + ErrorState: []string{}, + DeleteHttpErrorStatusCodes: []int{http.StatusNotFound}, + } + + handler := wait.New(waitConfig.Wait()) handler.SetTimeout(15 * time.Minute) return handler } -func CreateOrUpdateIntakeWaitHandler(ctx context.Context, a intake.DefaultAPI, projectId, region, intakeId string) *wait.AsyncActionHandler[intake.IntakeResponse] { - handler := wait.New(func() (waitFinished bool, response *intake.IntakeResponse, err error) { - ik, err := a.GetIntake(ctx, projectId, region, intakeId).Execute() - if err != nil { - return false, nil, err - } - - if ik == nil { - return false, nil, fmt.Errorf("API returned a nil response for Intake %s", intakeId) - } - - if ik.Id == intakeId && ik.State == INTAKERESPONSESTATE_ACTIVE { - return true, ik, nil - } - - if ik.Id == intakeId && ik.State == INTAKERESPONSESTATE_FAILED { - return true, ik, fmt.Errorf("create/update failed for Intake %s", intakeId) - } +func CreateOrUpdateIntakeWaitHandler(ctx context.Context, client intake.DefaultAPI, projectId, region, intakeId string) *wait.AsyncActionHandler[intake.IntakeResponse] { + waitConfig := wait.WaiterHelper[intake.IntakeResponse, string]{ + FetchInstance: client.GetIntake(ctx, projectId, region, intakeId).Execute, + GetState: func(response *intake.IntakeResponse) (string, error) { + if response == nil { + return "", errors.New("empty response") + } + return response.State, nil + }, + ActiveState: []string{INTAKERUNNERRESPONSESTATE_ACTIVE}, + ErrorState: []string{INTAKERESPONSESTATE_FAILED}, + } - return false, nil, nil - }) + handler := wait.New(waitConfig.Wait()) handler.SetTimeout(10 * time.Minute) return handler } -func DeleteIntakeWaitHandler(ctx context.Context, a intake.DefaultAPI, projectId, region, intakeId string) *wait.AsyncActionHandler[intake.IntakeResponse] { - handler := wait.New(func() (waitFinished bool, response *intake.IntakeResponse, err error) { - _, err = a.GetIntake(ctx, projectId, region, intakeId).Execute() - if err == nil { - return false, nil, nil - } - - var oapiError *oapierror.GenericOpenAPIError - if errors.As(err, &oapiError) { - if oapiError.StatusCode == http.StatusNotFound { - return true, nil, nil +func DeleteIntakeWaitHandler(ctx context.Context, client intake.DefaultAPI, projectId, region, intakeId string) *wait.AsyncActionHandler[intake.IntakeResponse] { + waitConfig := wait.WaiterHelper[intake.IntakeResponse, string]{ + FetchInstance: client.GetIntake(ctx, projectId, region, intakeId).Execute, + GetState: func(response *intake.IntakeResponse) (string, error) { + if response == nil { + return "", errors.New("empty response") } - } - return false, nil, err - }) + return response.State, nil + }, + ActiveState: []string{}, + ErrorState: []string{}, + DeleteHttpErrorStatusCodes: []int{http.StatusNotFound}, + } + + handler := wait.New(waitConfig.Wait()) handler.SetTimeout(10 * time.Minute) return handler } -func CreateOrUpdateIntakeUserWaitHandler(ctx context.Context, a intake.DefaultAPI, projectId, region, intakeId, intakeUserId string) *wait.AsyncActionHandler[intake.IntakeUserResponse] { - handler := wait.New(func() (waitFinished bool, response *intake.IntakeUserResponse, err error) { - user, err := a.GetIntakeUser(ctx, projectId, region, intakeId, intakeUserId).Execute() - if err != nil { - return false, nil, err - } - - if user == nil { - return false, nil, fmt.Errorf("API returned a nil response for Intake User %s", intakeUserId) - } - - if user.Id == intakeUserId && user.State == INTAKEUSERRESPONSESTATE_ACTIVE { - return true, user, nil - } - - // The API does not have a dedicated failure state for this resource, we rely on the timeout for cases where - // it never becomes active. - return false, nil, nil - }) +func CreateOrUpdateIntakeUserWaitHandler(ctx context.Context, client intake.DefaultAPI, projectId, region, intakeId, intakeUserId string) *wait.AsyncActionHandler[intake.IntakeUserResponse] { + waitConfig := wait.WaiterHelper[intake.IntakeUserResponse, string]{ + FetchInstance: client.GetIntakeUser(ctx, projectId, region, intakeId, intakeUserId).Execute, + GetState: func(response *intake.IntakeUserResponse) (string, error) { + if response == nil { + return "", errors.New("empty response") + } + return response.State, nil + }, + ActiveState: []string{INTAKEUSERRESPONSESTATE_ACTIVE}, + ErrorState: []string{}, + // The API does not have a dedicated failure state for this resource, + // so we rely on the timeout for cases where it never becomes active. + } + + handler := wait.New(waitConfig.Wait()) handler.SetTimeout(5 * time.Minute) return handler } -func DeleteIntakeUserWaitHandler(ctx context.Context, a intake.DefaultAPI, projectId, region, intakeId, intakeUserId string) *wait.AsyncActionHandler[intake.IntakeUserResponse] { - handler := wait.New(func() (waitFinished bool, response *intake.IntakeUserResponse, err error) { - _, err = a.GetIntakeUser(ctx, projectId, region, intakeId, intakeUserId).Execute() - if err == nil { - return false, nil, nil - } - - var oapiError *oapierror.GenericOpenAPIError - if errors.As(err, &oapiError) { - if oapiError.StatusCode == http.StatusNotFound { - return true, nil, nil +func DeleteIntakeUserWaitHandler(ctx context.Context, client intake.DefaultAPI, projectId, region, intakeId, intakeUserId string) *wait.AsyncActionHandler[intake.IntakeUserResponse] { + waitConfig := wait.WaiterHelper[intake.IntakeUserResponse, string]{ + FetchInstance: client.GetIntakeUser(ctx, projectId, region, intakeId, intakeUserId).Execute, + GetState: func(response *intake.IntakeUserResponse) (string, error) { + if response == nil { + return "", errors.New("empty response") } - } - return false, nil, err - }) + return response.State, nil + }, + ActiveState: []string{}, + ErrorState: []string{}, + DeleteHttpErrorStatusCodes: []int{http.StatusNotFound}, + } + + handler := wait.New(waitConfig.Wait()) handler.SetTimeout(5 * time.Minute) return handler } diff --git a/services/intake/v1betaapi/wait/wait_test.go b/services/intake/v1betaapi/wait/wait_test.go index 3c15a551e..596d0458e 100644 --- a/services/intake/v1betaapi/wait/wait_test.go +++ b/services/intake/v1betaapi/wait/wait_test.go @@ -132,6 +132,17 @@ func TestCreateOrUpdateIntakeRunnerWaitHandler(t *testing.T) { State: INTAKERUNNERRESPONSESTATE_RECONCILING, }, }, + { + desc: "wrong state in response", + getFails: false, + wantErr: true, + wantResp: false, + returnRunner: true, + intakeRunnerResponse: &intake.IntakeRunnerResponse{ + Id: intakeRunnerId, + State: "wrong state", + }, + }, { desc: "nil state in response", getFails: false, @@ -292,6 +303,17 @@ func TestCreateOrUpdateIntakeWaitHandler(t *testing.T) { State: INTAKERESPONSESTATE_RECONCILING, }, }, + { + desc: "wrong state in response", + getFails: false, + wantErr: true, + wantResp: false, + returnIntake: true, + intakeResponse: &intake.IntakeResponse{ + Id: intakeId, + State: "wrong state", + }, + }, { desc: "nil state in response", getFails: false, @@ -441,6 +463,17 @@ func TestCreateOrUpdateIntakeUserWaitHandler(t *testing.T) { State: INTAKEUSERRESPONSESTATE_RECONCILING, }, }, + { + desc: "wrong state in response", + getFails: false, + wantErr: true, + wantResp: false, + returnUser: true, + intakeUserResponse: &intake.IntakeUserResponse{ + Id: intakeUserId, + State: "wrong state", + }, + }, { desc: "nil state in response", getFails: false, From eb9d9daf2d924338dd07ed20df7da549911aa702 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=B6kce=20G=C3=B6k=20Klingel?= <161626272+GokceGK@users.noreply.github.com> Date: Wed, 6 May 2026 16:01:32 +0200 Subject: [PATCH 2/3] Update services/intake/VERSION MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Ruben Hönle --- services/intake/VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/intake/VERSION b/services/intake/VERSION index 7f7306b3c..f78dc3652 100644 --- a/services/intake/VERSION +++ b/services/intake/VERSION @@ -1 +1 @@ -v0.9.1 \ No newline at end of file +v0.10.0 \ No newline at end of file From 6902f4c2da68e68e8a139fd38a7bc91944535640 Mon Sep 17 00:00:00 2001 From: GokceGK Date: Wed, 6 May 2026 16:04:34 +0200 Subject: [PATCH 3/3] feat(intake): update versions in the changelogs relates to STACKITSDK-375 --- CHANGELOG.md | 2 +- services/intake/CHANGELOG.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 587a55fc5..801485998 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -137,7 +137,7 @@ - **Dependencies:** Bump STACKIT SDK core module from `v0.25.0` to `v0.26.0` - [v0.9.0](services/intake/CHANGELOG.md#v090) - **Feature:** Added `_UNKNOWN_DEFAULT_OPEN_API` fallback value to all enums to handle unknown API values gracefully. - - [v0.9.1](services/intake/CHANGELOG.md#v091) + - [v0.10.0](services/intake/CHANGELOG.md#v0100) - `v1betaapi`: **Improvement**: Use new `WaiterHandler` struct in the Git WaitHandler - `kms`: - [v1.6.2](services/kms/CHANGELOG.md#v162) diff --git a/services/intake/CHANGELOG.md b/services/intake/CHANGELOG.md index d8016c7bf..3192502ed 100644 --- a/services/intake/CHANGELOG.md +++ b/services/intake/CHANGELOG.md @@ -1,4 +1,4 @@ -## v0.9.1 +## v0.10.0 - `v1betaapi`: **Improvement**: Use new `WaiterHandler` struct in the Intake WaitHandler ## v0.9.0