From d9a792c300d0c84bb816cc5cd8948cea78d33d52 Mon Sep 17 00:00:00 2001 From: Yago Carlos Fernandez Gou Date: Tue, 14 Oct 2025 16:20:41 +0200 Subject: [PATCH 01/14] Introduce waiters for Intake Runner, Intake and Intake User --- services/intake/wait/wait.go | 162 ++++++++++ services/intake/wait/wait_test.go | 515 ++++++++++++++++++++++++++++++ 2 files changed, 677 insertions(+) create mode 100644 services/intake/wait/wait.go create mode 100644 services/intake/wait/wait_test.go diff --git a/services/intake/wait/wait.go b/services/intake/wait/wait.go new file mode 100644 index 000000000..da275d812 --- /dev/null +++ b/services/intake/wait/wait.go @@ -0,0 +1,162 @@ +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" + "github.com/stackitcloud/stackit-sdk-go/services/intake" +) + +type APIClientInterface interface { + GetIntakeRunnerExecute(ctx context.Context, projectId, region, intakeRunnerId string) (*intake.IntakeRunnerResponse, error) + GetIntakeExecute(ctx context.Context, projectId, region, intakeId string) (*intake.IntakeResponse, error) + GetIntakeUserExecute(ctx context.Context, projectId, region, intakeId, intakeUserId string) (*intake.IntakeUserResponse, error) +} + +func CreateOrUpdateIntakeRunnerWaitHandler(ctx context.Context, a APIClientInterface, projectId, region, intakeRunnerId string) *wait.AsyncActionHandler[intake.IntakeRunnerResponse] { + handler := wait.New(func() (waitFinished bool, response *intake.IntakeRunnerResponse, err error) { + runner, err := a.GetIntakeRunnerExecute(ctx, projectId, region, intakeRunnerId) + 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 == nil || runner.State == nil { + return false, nil, fmt.Errorf("could not get ID or State from response for Intake Runner %s", intakeRunnerId) + } + + if *runner.Id == intakeRunnerId && *runner.State == intake.INTAKERUNNERRESPONSESTATE_ACTIVE { + return true, runner, nil + } + + // 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.SetTimeout(15 * time.Minute) + return handler +} + +func DeleteIntakeRunnerWaitHandler(ctx context.Context, a APIClientInterface, projectId, region, intakeRunnerId string) *wait.AsyncActionHandler[intake.IntakeRunnerResponse] { + handler := wait.New(func() (waitFinished bool, response *intake.IntakeRunnerResponse, err error) { + _, err = a.GetIntakeRunnerExecute(ctx, projectId, region, intakeRunnerId) + 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 + } + } + // An unexpected error occurred + return false, nil, err + }) + handler.SetTimeout(20 * time.Minute) + return handler +} + +func CreateOrUpdateIntakeWaitHandler(ctx context.Context, a APIClientInterface, projectId, region, intakeId string) *wait.AsyncActionHandler[intake.IntakeResponse] { + handler := wait.New(func() (waitFinished bool, response *intake.IntakeResponse, err error) { + ik, err := a.GetIntakeExecute(ctx, projectId, region, intakeId) + 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 == nil || ik.State == nil { + return false, nil, fmt.Errorf("could not get ID or State from response for Intake %s", intakeId) + } + + if *ik.Id == intakeId && *ik.State == intake.INTAKERESPONSESTATE_ACTIVE { + return true, ik, nil + } + + if *ik.Id == intakeId && *ik.State == intake.INTAKERESPONSESTATE_FAILED { + return true, ik, fmt.Errorf("create/update failed for Intake %s", intakeId) + } + + return false, nil, nil + }) + handler.SetTimeout(20 * time.Minute) + return handler +} + +func DeleteIntakeWaitHandler(ctx context.Context, a APIClientInterface, projectId, region, intakeId string) *wait.AsyncActionHandler[intake.IntakeResponse] { + handler := wait.New(func() (waitFinished bool, response *intake.IntakeResponse, err error) { + _, err = a.GetIntakeExecute(ctx, projectId, region, intakeId) + 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 + } + } + return false, nil, err + }) + handler.SetTimeout(10 * time.Minute) + return handler +} + +func CreateOrUpdateIntakeUserWaitHandler(ctx context.Context, a APIClientInterface, projectId, region, intakeId, intakeUserId string) *wait.AsyncActionHandler[intake.IntakeUserResponse] { + handler := wait.New(func() (waitFinished bool, response *intake.IntakeUserResponse, err error) { + user, err := a.GetIntakeUserExecute(ctx, projectId, region, intakeId, intakeUserId) + 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 == nil || user.State == nil { + return false, nil, fmt.Errorf("could not get ID or State from response for Intake User %s", intakeUserId) + } + + if *user.Id == intakeUserId && *user.State == intake.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 + }) + handler.SetTimeout(10 * time.Minute) + return handler +} + +func DeleteIntakeUserWaitHandler(ctx context.Context, a APIClientInterface, projectId, region, intakeId, intakeUserId string) *wait.AsyncActionHandler[intake.IntakeUserResponse] { + handler := wait.New(func() (waitFinished bool, response *intake.IntakeUserResponse, err error) { + _, err = a.GetIntakeUserExecute(ctx, projectId, region, intakeId, intakeUserId) + 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 + } + } + return false, nil, err + }) + handler.SetTimeout(10 * time.Minute) + return handler +} diff --git a/services/intake/wait/wait_test.go b/services/intake/wait/wait_test.go new file mode 100644 index 000000000..ef1b677b5 --- /dev/null +++ b/services/intake/wait/wait_test.go @@ -0,0 +1,515 @@ +package wait + +import ( + "context" + "net/http" + "testing" + "time" + + "github.com/google/go-cmp/cmp" + "github.com/google/uuid" + "github.com/stackitcloud/stackit-sdk-go/core/oapierror" + "github.com/stackitcloud/stackit-sdk-go/core/utils" + "github.com/stackitcloud/stackit-sdk-go/services/intake" +) + +// apiClientMocked is a mock of the API client +type apiClientMocked struct { + getRunnerFails bool + getIntakeFails bool + getUserFails bool + getErrorCode int + returnRunner bool + returnIntake bool + returnUser bool + intakeRunnerResponse *intake.IntakeRunnerResponse + intakeResponse *intake.IntakeResponse + intakeUserResponse *intake.IntakeUserResponse +} + +func (a *apiClientMocked) GetIntakeRunnerExecute(_ context.Context, _, _, _ string) (*intake.IntakeRunnerResponse, error) { + if a.getRunnerFails { + return nil, &oapierror.GenericOpenAPIError{ + StatusCode: a.getErrorCode, + } + } + if !a.returnRunner { + return nil, nil + } + return a.intakeRunnerResponse, nil +} + +func (a *apiClientMocked) GetIntakeExecute(_ context.Context, _, _, _ string) (*intake.IntakeResponse, error) { + if a.getIntakeFails { + return nil, &oapierror.GenericOpenAPIError{ + StatusCode: a.getErrorCode, + } + } + if !a.returnIntake { + return nil, nil + } + return a.intakeResponse, nil +} + +func (a *apiClientMocked) GetIntakeUserExecute(_ context.Context, _, _, _, _ string) (*intake.IntakeUserResponse, error) { + if a.getUserFails { + return nil, &oapierror.GenericOpenAPIError{ + StatusCode: a.getErrorCode, + } + } + if !a.returnUser { + return nil, nil + } + return a.intakeUserResponse, nil +} + +var ( + PROJECT_ID = uuid.NewString() + REGION = "eu01" + INTAKE_RUNNER_ID = uuid.NewString() + INTAKE_ID = uuid.NewString() + INTAKE_USER_ID = uuid.NewString() +) + +func TestCreateOrUpdateIntakeRunnerWaitHandler(t *testing.T) { + tests := []struct { + desc string + getFails bool + getErrorCode int + wantErr bool + wantResp bool + returnRunner bool + intakeRunnerResponse *intake.IntakeRunnerResponse + }{ + { + desc: "succeeded", + getFails: false, + wantErr: false, + wantResp: true, + returnRunner: true, + intakeRunnerResponse: &intake.IntakeRunnerResponse{ + Id: utils.Ptr(INTAKE_RUNNER_ID), + State: utils.Ptr(intake.INTAKERUNNERRESPONSESTATE_ACTIVE), + }, + }, + { + desc: "get fails", + getFails: true, + getErrorCode: http.StatusInternalServerError, + wantErr: true, + wantResp: false, + returnRunner: false, + }, + { + desc: "timeout", + getFails: false, + wantErr: true, + wantResp: false, + returnRunner: true, + intakeRunnerResponse: &intake.IntakeRunnerResponse{ + Id: utils.Ptr(INTAKE_RUNNER_ID), + State: utils.Ptr(intake.INTAKERUNNERRESPONSESTATE_RECONCILING), + }, + }, + { + desc: "nil response", + getFails: false, + wantErr: true, + wantResp: false, + returnRunner: false, + }, + { + desc: "nil id in response", + getFails: false, + wantErr: true, + wantResp: false, + returnRunner: true, + intakeRunnerResponse: &intake.IntakeRunnerResponse{ + State: utils.Ptr(intake.INTAKERUNNERRESPONSESTATE_RECONCILING), + }, + }, + { + desc: "nil state in response", + getFails: false, + wantErr: true, + wantResp: false, + returnRunner: true, + intakeRunnerResponse: &intake.IntakeRunnerResponse{ + Id: utils.Ptr(INTAKE_RUNNER_ID), + }, + }, + } + for _, tt := range tests { + t.Run(tt.desc, func(t *testing.T) { + apiClient := &apiClientMocked{ + getRunnerFails: tt.getFails, + getErrorCode: tt.getErrorCode, + returnRunner: tt.returnRunner, + intakeRunnerResponse: tt.intakeRunnerResponse, + } + + var wantResp *intake.IntakeRunnerResponse + if tt.wantResp { + wantResp = tt.intakeRunnerResponse + } + + handler := CreateOrUpdateIntakeRunnerWaitHandler(context.Background(), apiClient, PROJECT_ID, REGION, INTAKE_RUNNER_ID) + got, err := handler.SetTimeout(10 * time.Millisecond).WaitWithContext(context.Background()) + + if (err != nil) != tt.wantErr { + t.Fatalf("handler error = %v, wantErr %v", err, tt.wantErr) + } + if !cmp.Equal(got, wantResp) { + t.Fatalf("handler got = %v, want %v", got, wantResp) + } + }) + } +} + +func TestDeleteIntakeRunnerWaitHandler(t *testing.T) { + tests := []struct { + desc string + getFails bool + getErrorCode int + wantErr bool + returnRunner bool + }{ + { + desc: "succeeded", + getFails: true, + getErrorCode: http.StatusNotFound, + wantErr: false, + returnRunner: false, + }, + { + desc: "get fails", + getFails: true, + getErrorCode: http.StatusInternalServerError, + wantErr: true, + returnRunner: false, + }, + { + desc: "timeout", + getFails: false, + wantErr: true, + returnRunner: true, + }, + } + for _, tt := range tests { + t.Run(tt.desc, func(t *testing.T) { + apiClient := &apiClientMocked{ + getRunnerFails: tt.getFails, + getErrorCode: tt.getErrorCode, + returnRunner: tt.returnRunner, + intakeRunnerResponse: &intake.IntakeRunnerResponse{ // This is only used in the timeout case + Id: utils.Ptr(INTAKE_RUNNER_ID), + }, + } + handler := DeleteIntakeRunnerWaitHandler(context.Background(), apiClient, PROJECT_ID, REGION, INTAKE_RUNNER_ID) + _, err := handler.SetTimeout(10 * time.Millisecond).WaitWithContext(context.Background()) + + if (err != nil) != tt.wantErr { + t.Fatalf("handler error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestCreateOrUpdateIntakeWaitHandler(t *testing.T) { + tests := []struct { + desc string + getFails bool + getErrorCode int + wantErr bool + wantResp bool + returnIntake bool + intakeResponse *intake.IntakeResponse + }{ + { + desc: "succeeded", + getFails: false, + wantErr: false, + wantResp: true, + returnIntake: true, + intakeResponse: &intake.IntakeResponse{ + Id: utils.Ptr(INTAKE_ID), + State: utils.Ptr(intake.INTAKERESPONSESTATE_ACTIVE), + }, + }, + { + desc: "failed state", + getFails: false, + wantErr: true, + wantResp: true, + returnIntake: true, + intakeResponse: &intake.IntakeResponse{ + Id: utils.Ptr(INTAKE_ID), + State: utils.Ptr(intake.INTAKERESPONSESTATE_FAILED), + }, + }, + { + desc: "get fails", + getFails: true, + getErrorCode: http.StatusInternalServerError, + wantErr: true, + wantResp: false, + returnIntake: false, + }, + { + desc: "timeout", + getFails: false, + wantErr: true, + wantResp: false, + returnIntake: true, + intakeResponse: &intake.IntakeResponse{ + Id: utils.Ptr(INTAKE_ID), + State: utils.Ptr(intake.INTAKERESPONSESTATE_RECONCILING), + }, + }, + { + desc: "nil response", + getFails: false, + wantErr: true, + wantResp: false, + returnIntake: false, + }, + { + desc: "nil id in response", + getFails: false, + wantErr: true, + wantResp: false, + returnIntake: true, + intakeResponse: &intake.IntakeResponse{ + State: utils.Ptr(intake.INTAKERESPONSESTATE_RECONCILING), + }, + }, + { + desc: "nil state in response", + getFails: false, + wantErr: true, + wantResp: false, + returnIntake: true, + intakeResponse: &intake.IntakeResponse{ + Id: utils.Ptr(INTAKE_ID), + }, + }, + } + for _, tt := range tests { + t.Run(tt.desc, func(t *testing.T) { + apiClient := &apiClientMocked{ + getIntakeFails: tt.getFails, + getErrorCode: tt.getErrorCode, + returnIntake: tt.returnIntake, + intakeResponse: tt.intakeResponse, + } + + var wantResp *intake.IntakeResponse + if tt.wantResp { + wantResp = tt.intakeResponse + } + + handler := CreateOrUpdateIntakeWaitHandler(context.Background(), apiClient, PROJECT_ID, REGION, INTAKE_ID) + got, err := handler.SetTimeout(10 * time.Millisecond).WaitWithContext(context.Background()) + + if (err != nil) != tt.wantErr { + t.Fatalf("handler error = %v, wantErr %v", err, tt.wantErr) + } + if !cmp.Equal(got, wantResp) { + t.Fatalf("handler got = %v, want %v", got, wantResp) + } + }) + } +} + +func TestDeleteIntakeWaitHandler(t *testing.T) { + tests := []struct { + desc string + getFails bool + getErrorCode int + wantErr bool + returnIntake bool + }{ + { + desc: "succeeded", + getFails: true, + getErrorCode: http.StatusNotFound, + wantErr: false, + returnIntake: false, + }, + { + desc: "get fails", + getFails: true, + getErrorCode: http.StatusInternalServerError, + wantErr: true, + returnIntake: false, + }, + { + desc: "timeout", + getFails: false, + wantErr: true, + returnIntake: true, + }, + } + for _, tt := range tests { + t.Run(tt.desc, func(t *testing.T) { + apiClient := &apiClientMocked{ + getIntakeFails: tt.getFails, + getErrorCode: tt.getErrorCode, + returnIntake: tt.returnIntake, + intakeResponse: &intake.IntakeResponse{ + Id: utils.Ptr(INTAKE_ID), + }, + } + handler := DeleteIntakeWaitHandler(context.Background(), apiClient, PROJECT_ID, REGION, INTAKE_ID) + _, err := handler.SetTimeout(10 * time.Millisecond).WaitWithContext(context.Background()) + + if (err != nil) != tt.wantErr { + t.Fatalf("handler error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestCreateOrUpdateIntakeUserWaitHandler(t *testing.T) { + tests := []struct { + desc string + getFails bool + getErrorCode int + wantErr bool + wantResp bool + returnUser bool + intakeUserResponse *intake.IntakeUserResponse + }{ + { + desc: "succeeded", + getFails: false, + wantErr: false, + wantResp: true, + returnUser: true, + intakeUserResponse: &intake.IntakeUserResponse{ + Id: utils.Ptr(INTAKE_USER_ID), + State: utils.Ptr(intake.INTAKEUSERRESPONSESTATE_ACTIVE), + }, + }, + { + desc: "get fails", + getFails: true, + getErrorCode: http.StatusInternalServerError, + wantErr: true, + wantResp: false, + returnUser: false, + }, + { + desc: "timeout", + getFails: false, + wantErr: true, + wantResp: false, + returnUser: true, + intakeUserResponse: &intake.IntakeUserResponse{ + Id: utils.Ptr(INTAKE_USER_ID), + State: utils.Ptr(intake.INTAKEUSERRESPONSESTATE_RECONCILING), + }, + }, + { + desc: "nil response", + getFails: false, + wantErr: true, + wantResp: false, + returnUser: false, + }, + { + desc: "nil id in response", + getFails: false, + wantErr: true, + wantResp: false, + returnUser: true, + intakeUserResponse: &intake.IntakeUserResponse{ + State: utils.Ptr(intake.INTAKEUSERRESPONSESTATE_RECONCILING), + }, + }, + { + desc: "nil state in response", + getFails: false, + wantErr: true, + wantResp: false, + returnUser: true, + intakeUserResponse: &intake.IntakeUserResponse{ + Id: utils.Ptr(INTAKE_USER_ID), + }, + }, + } + for _, tt := range tests { + t.Run(tt.desc, func(t *testing.T) { + apiClient := &apiClientMocked{ + getUserFails: tt.getFails, + getErrorCode: tt.getErrorCode, + returnUser: tt.returnUser, + intakeUserResponse: tt.intakeUserResponse, + } + + var wantResp *intake.IntakeUserResponse + if tt.wantResp { + wantResp = tt.intakeUserResponse + } + + handler := CreateOrUpdateIntakeUserWaitHandler(context.Background(), apiClient, PROJECT_ID, REGION, INTAKE_ID, INTAKE_USER_ID) + got, err := handler.SetTimeout(10 * time.Millisecond).WaitWithContext(context.Background()) + + if (err != nil) != tt.wantErr { + t.Fatalf("handler error = %v, wantErr %v", err, tt.wantErr) + } + if !cmp.Equal(got, wantResp) { + t.Fatalf("handler got = %v, want %v", got, wantResp) + } + }) + } +} + +func TestDeleteIntakeUserWaitHandler(t *testing.T) { + tests := []struct { + desc string + getFails bool + getErrorCode int + wantErr bool + returnUser bool + }{ + { + desc: "succeeded", + getFails: true, + getErrorCode: http.StatusNotFound, + wantErr: false, + returnUser: false, + }, + { + desc: "get fails", + getFails: true, + getErrorCode: http.StatusInternalServerError, + wantErr: true, + returnUser: false, + }, + { + desc: "timeout", + getFails: false, + wantErr: true, + returnUser: true, + }, + } + for _, tt := range tests { + t.Run(tt.desc, func(t *testing.T) { + apiClient := &apiClientMocked{ + getUserFails: tt.getFails, + getErrorCode: tt.getErrorCode, + returnUser: tt.returnUser, + intakeUserResponse: &intake.IntakeUserResponse{ + Id: utils.Ptr(INTAKE_USER_ID), + }, + } + handler := DeleteIntakeUserWaitHandler(context.Background(), apiClient, PROJECT_ID, REGION, INTAKE_ID, INTAKE_USER_ID) + _, err := handler.SetTimeout(10 * time.Millisecond).WaitWithContext(context.Background()) + + if (err != nil) != tt.wantErr { + t.Fatalf("handler error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} From 0c18d79d8763b5a932a0776185bcd2f6ef546ccd Mon Sep 17 00:00:00 2001 From: Yago Carlos Fernandez Gou Date: Wed, 15 Oct 2025 18:07:47 +0200 Subject: [PATCH 02/14] Adjust timeouts for Intakes --- services/intake/wait/wait.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/services/intake/wait/wait.go b/services/intake/wait/wait.go index da275d812..1d76c3cd9 100644 --- a/services/intake/wait/wait.go +++ b/services/intake/wait/wait.go @@ -63,7 +63,7 @@ func DeleteIntakeRunnerWaitHandler(ctx context.Context, a APIClientInterface, pr // An unexpected error occurred return false, nil, err }) - handler.SetTimeout(20 * time.Minute) + handler.SetTimeout(15 * time.Minute) return handler } @@ -92,7 +92,7 @@ func CreateOrUpdateIntakeWaitHandler(ctx context.Context, a APIClientInterface, return false, nil, nil }) - handler.SetTimeout(20 * time.Minute) + handler.SetTimeout(10 * time.Minute) return handler } @@ -138,7 +138,7 @@ func CreateOrUpdateIntakeUserWaitHandler(ctx context.Context, a APIClientInterfa // it never becomes active. return false, nil, nil }) - handler.SetTimeout(10 * time.Minute) + handler.SetTimeout(5 * time.Minute) return handler } @@ -157,6 +157,6 @@ func DeleteIntakeUserWaitHandler(ctx context.Context, a APIClientInterface, proj } return false, nil, err }) - handler.SetTimeout(10 * time.Minute) + handler.SetTimeout(5 * time.Minute) return handler } From b05b779d39eed858bc0b5e56fd9e18544c45a9cb Mon Sep 17 00:00:00 2001 From: Yago Carlos Fernandez Gou Date: Thu, 16 Oct 2025 15:35:03 +0200 Subject: [PATCH 03/14] Include example using Intake SDK --- examples/intake/go.mod | 38 ++++++++++++++ examples/intake/go.sum | 70 ++++++++++++++++++++++++ examples/intake/intake.go | 108 ++++++++++++++++++++++++++++++++++++++ go.work | 3 +- 4 files changed, 218 insertions(+), 1 deletion(-) create mode 100644 examples/intake/go.mod create mode 100644 examples/intake/go.sum create mode 100644 examples/intake/intake.go diff --git a/examples/intake/go.mod b/examples/intake/go.mod new file mode 100644 index 000000000..f5c7988ca --- /dev/null +++ b/examples/intake/go.mod @@ -0,0 +1,38 @@ +module github.com/stackitcloud/stackit-sdk-go/examples/intake + +go 1.24.7 + +require ( + al.essio.dev/pkg/shellescape v1.5.1 // indirect + github.com/danieljoos/wincred v1.2.2 // indirect + github.com/fatih/color v1.18.0 // indirect + github.com/fsnotify/fsnotify v1.9.0 // indirect + github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/godbus/dbus/v5 v5.1.0 // indirect + github.com/golang-jwt/jwt/v5 v5.3.0 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/inhies/go-bytesize v0.0.0-20220417184213-4913239db9cf // indirect + github.com/lmittmann/tint v1.1.2 // indirect + github.com/mattn/go-colorable v0.1.14 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/pelletier/go-toml/v2 v2.2.4 // indirect + github.com/sagikazarmark/locafero v0.11.0 // indirect + github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect + github.com/spf13/afero v1.15.0 // indirect + github.com/spf13/cast v1.10.0 // indirect + github.com/spf13/cobra v1.10.1 // indirect + github.com/spf13/pflag v1.0.10 // indirect + github.com/spf13/viper v1.21.0 // indirect + github.com/stackitcloud/stackit-cli v0.44.1 // indirect + github.com/stackitcloud/stackit-sdk-go/core v0.17.3 // indirect + github.com/stackitcloud/stackit-sdk-go/services/iaas v0.31.0 // indirect + github.com/stackitcloud/stackit-sdk-go/services/intake v0.2.0 // indirect + github.com/subosito/gotenv v1.6.0 // indirect + github.com/zalando/go-keyring v0.2.6 // indirect + go.yaml.in/yaml/v3 v3.0.4 // indirect + golang.org/x/oauth2 v0.32.0 // indirect + golang.org/x/sys v0.37.0 // indirect + golang.org/x/term v0.36.0 // indirect + golang.org/x/text v0.30.0 // indirect +) diff --git a/examples/intake/go.sum b/examples/intake/go.sum new file mode 100644 index 000000000..e098a5f69 --- /dev/null +++ b/examples/intake/go.sum @@ -0,0 +1,70 @@ +al.essio.dev/pkg/shellescape v1.5.1 h1:86HrALUujYS/h+GtqoB26SBEdkWfmMI6FubjXlsXyho= +al.essio.dev/pkg/shellescape v1.5.1/go.mod h1:6sIqp7X2P6mThCQ7twERpZTuigpr6KbZWtls1U8I890= +github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= +github.com/danieljoos/wincred v1.2.2 h1:774zMFJrqaeYCK2W57BgAem/MLi6mtSE47MB6BOJ0i0= +github.com/danieljoos/wincred v1.2.2/go.mod h1:w7w4Utbrz8lqeMbDAK0lkNJUv5sAOkFi7nd/ogr0Uh8= +github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= +github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= +github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= +github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= +github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= +github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= +github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo= +github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/inhies/go-bytesize v0.0.0-20220417184213-4913239db9cf h1:FtEj8sfIcaaBfAKrE1Cwb61YDtYq9JxChK1c7AKce7s= +github.com/inhies/go-bytesize v0.0.0-20220417184213-4913239db9cf/go.mod h1:yrqSXGoD/4EKfF26AOGzscPOgTTJcyAwM2rpixWT+t4= +github.com/lmittmann/tint v1.1.2 h1:2CQzrL6rslrsyjqLDwD11bZ5OpLBPU+g3G/r5LSfS8w= +github.com/lmittmann/tint v1.1.2/go.mod h1:HIS3gSy7qNwGCj+5oRjAutErFBl4BzdQP6cJZ0NfMwE= +github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= +github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= +github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/sagikazarmark/locafero v0.11.0 h1:1iurJgmM9G3PA/I+wWYIOw/5SyBtxapeHDcg+AAIFXc= +github.com/sagikazarmark/locafero v0.11.0/go.mod h1:nVIGvgyzw595SUSUE6tvCp3YYTeHs15MvlmU87WwIik= +github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 h1:+jumHNA0Wrelhe64i8F6HNlS8pkoyMv5sreGx2Ry5Rw= +github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8/go.mod h1:3n1Cwaq1E1/1lhQhtRK2ts/ZwZEhjcQeJQ1RuC6Q/8U= +github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I= +github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg= +github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY= +github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo= +github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s= +github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0= +github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= +github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.21.0 h1:x5S+0EU27Lbphp4UKm1C+1oQO+rKx36vfCoaVebLFSU= +github.com/spf13/viper v1.21.0/go.mod h1:P0lhsswPGWD/1lZJ9ny3fYnVqxiegrlNrEmgLjbTCAY= +github.com/stackitcloud/stackit-cli v0.44.1 h1:3KiOEKt4OKMwpquB75zz52e5FjPLIvdKnmuHHvjwoVg= +github.com/stackitcloud/stackit-cli v0.44.1/go.mod h1:gU4khJV8vRH51xUpknMLnvBbN7YlwiRVWv3OWUHHE9E= +github.com/stackitcloud/stackit-sdk-go/core v0.17.3 h1:GsZGmRRc/3GJLmCUnsZswirr5wfLRrwavbnL/renOqg= +github.com/stackitcloud/stackit-sdk-go/core v0.17.3/go.mod h1:HBCXJGPgdRulplDzhrmwC+Dak9B/x0nzNtmOpu+1Ahg= +github.com/stackitcloud/stackit-sdk-go/services/iaas v0.31.0 h1:dnEjyapuv8WwRN5vE2z6+4/+ZqQTBx+bX27x2nOF7Jw= +github.com/stackitcloud/stackit-sdk-go/services/iaas v0.31.0/go.mod h1:854gnLR92NvAbJAA1xZEumrtNh1DoBP1FXTMvhwYA6w= +github.com/stackitcloud/stackit-sdk-go/services/intake v0.2.0 h1:p/zi4VPoCQWk7/2ubi3hxsqiaye41x/Pl3GXYbPkYOY= +github.com/stackitcloud/stackit-sdk-go/services/intake v0.2.0/go.mod h1:jOArPjNRkwv4487+9ab3dRG+lM09leu5FiRohbQs9Z4= +github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= +github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= +github.com/zalando/go-keyring v0.2.6 h1:r7Yc3+H+Ux0+M72zacZoItR3UDxeWfKTcabvkI8ua9s= +github.com/zalando/go-keyring v0.2.6/go.mod h1:2TCrxYrbUNYfNS/Kgy/LSrkSQzZ5UPVH85RwfczwvcI= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= +golang.org/x/oauth2 v0.32.0 h1:jsCblLleRMDrxMN29H3z/k1KliIvpLgCkE6R8FXXNgY= +golang.org/x/oauth2 v0.32.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ= +golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/term v0.36.0 h1:zMPR+aF8gfksFprF/Nc/rd1wRS1EI6nDBGyWAvDzx2Q= +golang.org/x/term v0.36.0/go.mod h1:Qu394IJq6V6dCBRgwqshf3mPF85AqzYEzofzRdZkWss= +golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k= +golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/examples/intake/intake.go b/examples/intake/intake.go new file mode 100644 index 000000000..dfae7d4f2 --- /dev/null +++ b/examples/intake/intake.go @@ -0,0 +1,108 @@ +package main + +import ( + "context" + "fmt" + "os" + + sdkConfig "github.com/stackitcloud/stackit-sdk-go/core/config" + "github.com/stackitcloud/stackit-sdk-go/core/utils" + "github.com/stackitcloud/stackit-sdk-go/services/intake" + "github.com/stackitcloud/stackit-sdk-go/services/intake/wait" +) + +func main() { + region := "REGION" // Region where the resources will be created + projectId := "PROJECT_ID" // Your STACKIT project ID + + dremioCatalogURI := "DREMIO_CATALOG_URI" // E.g., "https://my-dremio-catalog.data-platform.stackit.run/iceberg" + dremioTokenEndpoint := "DREMIO_TOKEN_ENDPOINT" // E.g., "https://my-dremio.data-platform.stackit.run/oauth/token" + dremioPAT := "DREMIO_PERSONAL_ACCESS_TOKEN" // Your Dremio Personal Access Token + catalogWarehouse := "CATALOG_WAREHOUSE" // Catalog warehouse where the data will be ingested + + intakeUserPassword := "s3cuRe_p@ssW0rd_f0r_1ntake!" // A secure password for the new intake user + + ctx := context.Background() + + intakeClient, err := intake.NewAPIClient( + sdkConfig.WithRegion(region), + ) + if err != nil { + fmt.Fprintf(os.Stderr, "Creating API client: %v\n", err) + os.Exit(1) + } + + // Create an Intake Runner + createRunnerPayload := intake.CreateIntakeRunnerPayload{ + DisplayName: utils.Ptr("my-example-runner"), + MaxMessageSizeKiB: utils.Ptr(int64(10)), + MaxMessagesPerHour: utils.Ptr(int64(1000)), + } + createRunnerResp, err := intakeClient.CreateIntakeRunner(ctx, projectId, region).CreateIntakeRunnerPayload(createRunnerPayload).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error creating Intake Runner: %v\n", err) + os.Exit(1) + } + intakeRunnerId := *createRunnerResp.Id + fmt.Printf("Triggered creation of Intake Runner with ID: %s. Waiting for it to become active...\n", intakeRunnerId) + + // Wait for the Intake Runner to become active + _, err = wait.CreateOrUpdateIntakeRunnerWaitHandler(ctx, intakeClient, projectId, region, intakeRunnerId).WaitWithContext(ctx) + if err != nil { + fmt.Fprintf(os.Stderr, "Error waiting for Intake Runner: %v\n", err) + os.Exit(1) + } + + // Create an Intake + dremioAuthType := intake.CatalogAuthType("dremio") // can also be set to "none" if the catalog is not authenticated + createIntakePayload := intake.CreateIntakePayload{ + DisplayName: utils.Ptr("my-example-intake"), + IntakeRunnerId: utils.Ptr(intakeRunnerId), + Catalog: &intake.IntakeCatalog{ + Uri: utils.Ptr(dremioCatalogURI), + Warehouse: utils.Ptr(catalogWarehouse), + Namespace: utils.Ptr("example_namespace"), + TableName: utils.Ptr("example_table"), + Auth: &intake.CatalogAuth{ + Type: &dremioAuthType, + Dremio: &intake.DremioAuth{ + TokenEndpoint: utils.Ptr(dremioTokenEndpoint), + PersonalAccessToken: utils.Ptr(dremioPAT), + }, + }, + }, + } + createIntakeResp, err := intakeClient.CreateIntake(ctx, projectId, region).CreateIntakePayload(createIntakePayload).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error creating Intake: %v\n", err) + os.Exit(1) + } + intakeId := *createIntakeResp.Id + fmt.Printf("Triggered creation of Intake with ID: %s. Waiting for it to become active...\n", intakeRunnerId) + + // Wait for the Intake to become active + _, err = wait.CreateOrUpdateIntakeWaitHandler(ctx, intakeClient, projectId, region, intakeId).WaitWithContext(ctx) + if err != nil { + fmt.Fprintf(os.Stderr, "Error waiting for Intake: %v\n", err) + os.Exit(1) + } + + createIntakeUserPayload := intake.CreateIntakeUserPayload{ + DisplayName: utils.Ptr("my-example-user"), + Password: utils.Ptr(intakeUserPassword), + } + createIntakeUserResp, err := intakeClient.CreateIntakeUser(ctx, projectId, region, intakeId).CreateIntakeUserPayload(createIntakeUserPayload).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error creating Intake User: %v\n", err) + os.Exit(1) + } + intakeUserId := *createIntakeUserResp.Id + fmt.Printf("Triggered creation of Intake User with ID: %s. Waiting for it to become active...\n", intakeRunnerId) + + // Wait for the Intake User to become active + _, err = wait.CreateOrUpdateIntakeUserWaitHandler(ctx, intakeClient, projectId, region, intakeId, intakeUserId).WaitWithContext(ctx) + if err != nil { + fmt.Fprintf(os.Stderr, "Error waiting for Intake User: %v\n", err) + os.Exit(1) + } +} diff --git a/go.work b/go.work index 478149caf..0b9a27186 100644 --- a/go.work +++ b/go.work @@ -1,4 +1,4 @@ -go 1.21 +go 1.24.7 use ( ./core @@ -10,6 +10,7 @@ use ( ./examples/dns ./examples/errorhandling ./examples/iaas + ./examples/intake ./examples/kms ./examples/loadbalancer ./examples/logme From be755a751af3dcd9f35789fdaa56ee665263fb1d Mon Sep 17 00:00:00 2001 From: Yago Carlos Fernandez Gou Date: Thu, 16 Oct 2025 15:42:33 +0200 Subject: [PATCH 04/14] Include root level CHANGELOG --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b6048369..839fa34fa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## Release (2025-10-16) +- `intake`: [v0.3.0](services/intake/CHANGELOG.md#v030) + - **Feature:** Add wait handlers for `Intake`, `IntakeRunner`, and `IntakeUser` resources. + - **Improvement:** Add usage examples for the `intake` service. + ## Release (2025-10-13) - `observability`: [v0.15.0](services/observability/CHANGELOG.md#v0150) - **Deprecation:** The `JaegerHttpTracesUrl` field is now deprecated in all relevant models and will be removed after 9th April 2026. Use the new `JaegerHttpUrl` field instead. From a038985e37718b1db45a8a192840f6f6ec773051 Mon Sep 17 00:00:00 2001 From: Yago Carlos Fernandez Gou Date: Thu, 16 Oct 2025 15:42:45 +0200 Subject: [PATCH 05/14] Include service level CHANGELOG --- services/intake/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/services/intake/CHANGELOG.md b/services/intake/CHANGELOG.md index 482590c6e..364cacac9 100644 --- a/services/intake/CHANGELOG.md +++ b/services/intake/CHANGELOG.md @@ -1,3 +1,7 @@ +## v0.3.0 +- **Feature:** Add wait handlers for `Intake`, `IntakeRunner`, and `IntakeUser` resources. +- **Improvement:** Add usage examples for the `intake` service. + ## v0.2.0 - **Feature:** Add response `IntakeRunnerResponse` to `UpdateIntakeRunnerExecute` request - **Feature:** Add response `IntakeUserResponse` to `UpdateIntakeUserExecute` request From 64dc074b1b4481db4a481eca37e9dda68a08a97e Mon Sep 17 00:00:00 2001 From: Yago Carlos Fernandez Gou Date: Thu, 16 Oct 2025 15:43:00 +0200 Subject: [PATCH 06/14] Bump Intake version --- services/intake/VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/intake/VERSION b/services/intake/VERSION index 1474d00f0..268b0334e 100644 --- a/services/intake/VERSION +++ b/services/intake/VERSION @@ -1 +1 @@ -v0.2.0 +v0.3.0 From 3ec43695f499d9ec513d4cf039af94d288ecc6ac Mon Sep 17 00:00:00 2001 From: Yago Carlos Fernandez Gou Date: Thu, 16 Oct 2025 15:43:43 +0200 Subject: [PATCH 07/14] Dependencies --- examples/intake/go.mod | 35 ++++------------------- examples/intake/go.sum | 63 +----------------------------------------- services/intake/go.mod | 1 + 3 files changed, 7 insertions(+), 92 deletions(-) diff --git a/examples/intake/go.mod b/examples/intake/go.mod index f5c7988ca..caef3c25c 100644 --- a/examples/intake/go.mod +++ b/examples/intake/go.mod @@ -3,36 +3,11 @@ module github.com/stackitcloud/stackit-sdk-go/examples/intake go 1.24.7 require ( - al.essio.dev/pkg/shellescape v1.5.1 // indirect - github.com/danieljoos/wincred v1.2.2 // indirect - github.com/fatih/color v1.18.0 // indirect - github.com/fsnotify/fsnotify v1.9.0 // indirect - github.com/go-viper/mapstructure/v2 v2.4.0 // indirect - github.com/godbus/dbus/v5 v5.1.0 // indirect + github.com/stackitcloud/stackit-sdk-go/core v0.17.3 + github.com/stackitcloud/stackit-sdk-go/services/intake v0.2.0 +) + +require ( github.com/golang-jwt/jwt/v5 v5.3.0 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/inhies/go-bytesize v0.0.0-20220417184213-4913239db9cf // indirect - github.com/lmittmann/tint v1.1.2 // indirect - github.com/mattn/go-colorable v0.1.14 // indirect - github.com/mattn/go-isatty v0.0.20 // indirect - github.com/pelletier/go-toml/v2 v2.2.4 // indirect - github.com/sagikazarmark/locafero v0.11.0 // indirect - github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect - github.com/spf13/afero v1.15.0 // indirect - github.com/spf13/cast v1.10.0 // indirect - github.com/spf13/cobra v1.10.1 // indirect - github.com/spf13/pflag v1.0.10 // indirect - github.com/spf13/viper v1.21.0 // indirect - github.com/stackitcloud/stackit-cli v0.44.1 // indirect - github.com/stackitcloud/stackit-sdk-go/core v0.17.3 // indirect - github.com/stackitcloud/stackit-sdk-go/services/iaas v0.31.0 // indirect - github.com/stackitcloud/stackit-sdk-go/services/intake v0.2.0 // indirect - github.com/subosito/gotenv v1.6.0 // indirect - github.com/zalando/go-keyring v0.2.6 // indirect - go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/oauth2 v0.32.0 // indirect - golang.org/x/sys v0.37.0 // indirect - golang.org/x/term v0.36.0 // indirect - golang.org/x/text v0.30.0 // indirect ) diff --git a/examples/intake/go.sum b/examples/intake/go.sum index e098a5f69..0e4800e16 100644 --- a/examples/intake/go.sum +++ b/examples/intake/go.sum @@ -1,70 +1,9 @@ -al.essio.dev/pkg/shellescape v1.5.1 h1:86HrALUujYS/h+GtqoB26SBEdkWfmMI6FubjXlsXyho= -al.essio.dev/pkg/shellescape v1.5.1/go.mod h1:6sIqp7X2P6mThCQ7twERpZTuigpr6KbZWtls1U8I890= -github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= -github.com/danieljoos/wincred v1.2.2 h1:774zMFJrqaeYCK2W57BgAem/MLi6mtSE47MB6BOJ0i0= -github.com/danieljoos/wincred v1.2.2/go.mod h1:w7w4Utbrz8lqeMbDAK0lkNJUv5sAOkFi7nd/ogr0Uh8= -github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= -github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= -github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= -github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= -github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= -github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= -github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= -github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo= github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= -github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/inhies/go-bytesize v0.0.0-20220417184213-4913239db9cf h1:FtEj8sfIcaaBfAKrE1Cwb61YDtYq9JxChK1c7AKce7s= -github.com/inhies/go-bytesize v0.0.0-20220417184213-4913239db9cf/go.mod h1:yrqSXGoD/4EKfF26AOGzscPOgTTJcyAwM2rpixWT+t4= -github.com/lmittmann/tint v1.1.2 h1:2CQzrL6rslrsyjqLDwD11bZ5OpLBPU+g3G/r5LSfS8w= -github.com/lmittmann/tint v1.1.2/go.mod h1:HIS3gSy7qNwGCj+5oRjAutErFBl4BzdQP6cJZ0NfMwE= -github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= -github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= -github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= -github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= -github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= -github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/sagikazarmark/locafero v0.11.0 h1:1iurJgmM9G3PA/I+wWYIOw/5SyBtxapeHDcg+AAIFXc= -github.com/sagikazarmark/locafero v0.11.0/go.mod h1:nVIGvgyzw595SUSUE6tvCp3YYTeHs15MvlmU87WwIik= -github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 h1:+jumHNA0Wrelhe64i8F6HNlS8pkoyMv5sreGx2Ry5Rw= -github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8/go.mod h1:3n1Cwaq1E1/1lhQhtRK2ts/ZwZEhjcQeJQ1RuC6Q/8U= -github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I= -github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg= -github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY= -github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo= -github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s= -github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0= -github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= -github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.21.0 h1:x5S+0EU27Lbphp4UKm1C+1oQO+rKx36vfCoaVebLFSU= -github.com/spf13/viper v1.21.0/go.mod h1:P0lhsswPGWD/1lZJ9ny3fYnVqxiegrlNrEmgLjbTCAY= -github.com/stackitcloud/stackit-cli v0.44.1 h1:3KiOEKt4OKMwpquB75zz52e5FjPLIvdKnmuHHvjwoVg= -github.com/stackitcloud/stackit-cli v0.44.1/go.mod h1:gU4khJV8vRH51xUpknMLnvBbN7YlwiRVWv3OWUHHE9E= github.com/stackitcloud/stackit-sdk-go/core v0.17.3 h1:GsZGmRRc/3GJLmCUnsZswirr5wfLRrwavbnL/renOqg= github.com/stackitcloud/stackit-sdk-go/core v0.17.3/go.mod h1:HBCXJGPgdRulplDzhrmwC+Dak9B/x0nzNtmOpu+1Ahg= -github.com/stackitcloud/stackit-sdk-go/services/iaas v0.31.0 h1:dnEjyapuv8WwRN5vE2z6+4/+ZqQTBx+bX27x2nOF7Jw= -github.com/stackitcloud/stackit-sdk-go/services/iaas v0.31.0/go.mod h1:854gnLR92NvAbJAA1xZEumrtNh1DoBP1FXTMvhwYA6w= github.com/stackitcloud/stackit-sdk-go/services/intake v0.2.0 h1:p/zi4VPoCQWk7/2ubi3hxsqiaye41x/Pl3GXYbPkYOY= github.com/stackitcloud/stackit-sdk-go/services/intake v0.2.0/go.mod h1:jOArPjNRkwv4487+9ab3dRG+lM09leu5FiRohbQs9Z4= -github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= -github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= -github.com/zalando/go-keyring v0.2.6 h1:r7Yc3+H+Ux0+M72zacZoItR3UDxeWfKTcabvkI8ua9s= -github.com/zalando/go-keyring v0.2.6/go.mod h1:2TCrxYrbUNYfNS/Kgy/LSrkSQzZ5UPVH85RwfczwvcI= -go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= -go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= -golang.org/x/oauth2 v0.32.0 h1:jsCblLleRMDrxMN29H3z/k1KliIvpLgCkE6R8FXXNgY= -golang.org/x/oauth2 v0.32.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ= -golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/term v0.36.0 h1:zMPR+aF8gfksFprF/Nc/rd1wRS1EI6nDBGyWAvDzx2Q= -golang.org/x/term v0.36.0/go.mod h1:Qu394IJq6V6dCBRgwqshf3mPF85AqzYEzofzRdZkWss= -golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k= -golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/services/intake/go.mod b/services/intake/go.mod index b4ef91bc5..6d177c71d 100644 --- a/services/intake/go.mod +++ b/services/intake/go.mod @@ -3,6 +3,7 @@ module github.com/stackitcloud/stackit-sdk-go/services/intake go 1.21 require ( + github.com/google/go-cmp v0.7.0 github.com/google/uuid v1.6.0 github.com/stackitcloud/stackit-sdk-go/core v0.17.3 ) From 4b1c13ad94b1216cb287c18dd8f0f5c5863b77f9 Mon Sep 17 00:00:00 2001 From: Yago Carlos Fernandez Gou Date: Fri, 17 Oct 2025 12:16:30 +0200 Subject: [PATCH 08/14] Address review: adjust Go version and region value --- examples/intake/go.mod | 2 +- examples/intake/intake.go | 2 +- go.work | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/intake/go.mod b/examples/intake/go.mod index caef3c25c..ea5af500e 100644 --- a/examples/intake/go.mod +++ b/examples/intake/go.mod @@ -1,6 +1,6 @@ module github.com/stackitcloud/stackit-sdk-go/examples/intake -go 1.24.7 +go 1.21 require ( github.com/stackitcloud/stackit-sdk-go/core v0.17.3 diff --git a/examples/intake/intake.go b/examples/intake/intake.go index dfae7d4f2..41788f812 100644 --- a/examples/intake/intake.go +++ b/examples/intake/intake.go @@ -12,7 +12,7 @@ import ( ) func main() { - region := "REGION" // Region where the resources will be created + region := "eu01" // Region where the resources will be created projectId := "PROJECT_ID" // Your STACKIT project ID dremioCatalogURI := "DREMIO_CATALOG_URI" // E.g., "https://my-dremio-catalog.data-platform.stackit.run/iceberg" diff --git a/go.work b/go.work index 0b9a27186..839083073 100644 --- a/go.work +++ b/go.work @@ -1,4 +1,4 @@ -go 1.24.7 +go 1.21 use ( ./core From 0a1f021180c6b95840c32f3449474367661e1f58 Mon Sep 17 00:00:00 2001 From: Devansh Thakur Date: Mon, 3 Nov 2025 16:59:03 +0100 Subject: [PATCH 09/14] removed example --- examples/intake/go.mod | 13 ----- examples/intake/go.sum | 9 ---- examples/intake/intake.go | 108 -------------------------------------- go.work | 1 - 4 files changed, 131 deletions(-) delete mode 100644 examples/intake/go.mod delete mode 100644 examples/intake/go.sum delete mode 100644 examples/intake/intake.go diff --git a/examples/intake/go.mod b/examples/intake/go.mod deleted file mode 100644 index ea5af500e..000000000 --- a/examples/intake/go.mod +++ /dev/null @@ -1,13 +0,0 @@ -module github.com/stackitcloud/stackit-sdk-go/examples/intake - -go 1.21 - -require ( - github.com/stackitcloud/stackit-sdk-go/core v0.17.3 - github.com/stackitcloud/stackit-sdk-go/services/intake v0.2.0 -) - -require ( - github.com/golang-jwt/jwt/v5 v5.3.0 // indirect - github.com/google/uuid v1.6.0 // indirect -) diff --git a/examples/intake/go.sum b/examples/intake/go.sum deleted file mode 100644 index 0e4800e16..000000000 --- a/examples/intake/go.sum +++ /dev/null @@ -1,9 +0,0 @@ -github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo= -github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE= -github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= -github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= -github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/stackitcloud/stackit-sdk-go/core v0.17.3 h1:GsZGmRRc/3GJLmCUnsZswirr5wfLRrwavbnL/renOqg= -github.com/stackitcloud/stackit-sdk-go/core v0.17.3/go.mod h1:HBCXJGPgdRulplDzhrmwC+Dak9B/x0nzNtmOpu+1Ahg= -github.com/stackitcloud/stackit-sdk-go/services/intake v0.2.0 h1:p/zi4VPoCQWk7/2ubi3hxsqiaye41x/Pl3GXYbPkYOY= -github.com/stackitcloud/stackit-sdk-go/services/intake v0.2.0/go.mod h1:jOArPjNRkwv4487+9ab3dRG+lM09leu5FiRohbQs9Z4= diff --git a/examples/intake/intake.go b/examples/intake/intake.go deleted file mode 100644 index 41788f812..000000000 --- a/examples/intake/intake.go +++ /dev/null @@ -1,108 +0,0 @@ -package main - -import ( - "context" - "fmt" - "os" - - sdkConfig "github.com/stackitcloud/stackit-sdk-go/core/config" - "github.com/stackitcloud/stackit-sdk-go/core/utils" - "github.com/stackitcloud/stackit-sdk-go/services/intake" - "github.com/stackitcloud/stackit-sdk-go/services/intake/wait" -) - -func main() { - region := "eu01" // Region where the resources will be created - projectId := "PROJECT_ID" // Your STACKIT project ID - - dremioCatalogURI := "DREMIO_CATALOG_URI" // E.g., "https://my-dremio-catalog.data-platform.stackit.run/iceberg" - dremioTokenEndpoint := "DREMIO_TOKEN_ENDPOINT" // E.g., "https://my-dremio.data-platform.stackit.run/oauth/token" - dremioPAT := "DREMIO_PERSONAL_ACCESS_TOKEN" // Your Dremio Personal Access Token - catalogWarehouse := "CATALOG_WAREHOUSE" // Catalog warehouse where the data will be ingested - - intakeUserPassword := "s3cuRe_p@ssW0rd_f0r_1ntake!" // A secure password for the new intake user - - ctx := context.Background() - - intakeClient, err := intake.NewAPIClient( - sdkConfig.WithRegion(region), - ) - if err != nil { - fmt.Fprintf(os.Stderr, "Creating API client: %v\n", err) - os.Exit(1) - } - - // Create an Intake Runner - createRunnerPayload := intake.CreateIntakeRunnerPayload{ - DisplayName: utils.Ptr("my-example-runner"), - MaxMessageSizeKiB: utils.Ptr(int64(10)), - MaxMessagesPerHour: utils.Ptr(int64(1000)), - } - createRunnerResp, err := intakeClient.CreateIntakeRunner(ctx, projectId, region).CreateIntakeRunnerPayload(createRunnerPayload).Execute() - if err != nil { - fmt.Fprintf(os.Stderr, "Error creating Intake Runner: %v\n", err) - os.Exit(1) - } - intakeRunnerId := *createRunnerResp.Id - fmt.Printf("Triggered creation of Intake Runner with ID: %s. Waiting for it to become active...\n", intakeRunnerId) - - // Wait for the Intake Runner to become active - _, err = wait.CreateOrUpdateIntakeRunnerWaitHandler(ctx, intakeClient, projectId, region, intakeRunnerId).WaitWithContext(ctx) - if err != nil { - fmt.Fprintf(os.Stderr, "Error waiting for Intake Runner: %v\n", err) - os.Exit(1) - } - - // Create an Intake - dremioAuthType := intake.CatalogAuthType("dremio") // can also be set to "none" if the catalog is not authenticated - createIntakePayload := intake.CreateIntakePayload{ - DisplayName: utils.Ptr("my-example-intake"), - IntakeRunnerId: utils.Ptr(intakeRunnerId), - Catalog: &intake.IntakeCatalog{ - Uri: utils.Ptr(dremioCatalogURI), - Warehouse: utils.Ptr(catalogWarehouse), - Namespace: utils.Ptr("example_namespace"), - TableName: utils.Ptr("example_table"), - Auth: &intake.CatalogAuth{ - Type: &dremioAuthType, - Dremio: &intake.DremioAuth{ - TokenEndpoint: utils.Ptr(dremioTokenEndpoint), - PersonalAccessToken: utils.Ptr(dremioPAT), - }, - }, - }, - } - createIntakeResp, err := intakeClient.CreateIntake(ctx, projectId, region).CreateIntakePayload(createIntakePayload).Execute() - if err != nil { - fmt.Fprintf(os.Stderr, "Error creating Intake: %v\n", err) - os.Exit(1) - } - intakeId := *createIntakeResp.Id - fmt.Printf("Triggered creation of Intake with ID: %s. Waiting for it to become active...\n", intakeRunnerId) - - // Wait for the Intake to become active - _, err = wait.CreateOrUpdateIntakeWaitHandler(ctx, intakeClient, projectId, region, intakeId).WaitWithContext(ctx) - if err != nil { - fmt.Fprintf(os.Stderr, "Error waiting for Intake: %v\n", err) - os.Exit(1) - } - - createIntakeUserPayload := intake.CreateIntakeUserPayload{ - DisplayName: utils.Ptr("my-example-user"), - Password: utils.Ptr(intakeUserPassword), - } - createIntakeUserResp, err := intakeClient.CreateIntakeUser(ctx, projectId, region, intakeId).CreateIntakeUserPayload(createIntakeUserPayload).Execute() - if err != nil { - fmt.Fprintf(os.Stderr, "Error creating Intake User: %v\n", err) - os.Exit(1) - } - intakeUserId := *createIntakeUserResp.Id - fmt.Printf("Triggered creation of Intake User with ID: %s. Waiting for it to become active...\n", intakeRunnerId) - - // Wait for the Intake User to become active - _, err = wait.CreateOrUpdateIntakeUserWaitHandler(ctx, intakeClient, projectId, region, intakeId, intakeUserId).WaitWithContext(ctx) - if err != nil { - fmt.Fprintf(os.Stderr, "Error waiting for Intake User: %v\n", err) - os.Exit(1) - } -} diff --git a/go.work b/go.work index 839083073..478149caf 100644 --- a/go.work +++ b/go.work @@ -10,7 +10,6 @@ use ( ./examples/dns ./examples/errorhandling ./examples/iaas - ./examples/intake ./examples/kms ./examples/loadbalancer ./examples/logme From 2637908eb2ba4ffeab4273fd159c0a45adb5783b Mon Sep 17 00:00:00 2001 From: Devansh <72165346+devanshcache@users.noreply.github.com> Date: Thu, 6 Nov 2025 21:04:19 +0100 Subject: [PATCH 10/14] Update services/intake/wait/wait_test.go MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Ruben Hönle --- services/intake/wait/wait_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/intake/wait/wait_test.go b/services/intake/wait/wait_test.go index ef1b677b5..83a6aef76 100644 --- a/services/intake/wait/wait_test.go +++ b/services/intake/wait/wait_test.go @@ -64,7 +64,7 @@ func (a *apiClientMocked) GetIntakeUserExecute(_ context.Context, _, _, _, _ str } var ( - PROJECT_ID = uuid.NewString() + projectId = uuid.NewString() REGION = "eu01" INTAKE_RUNNER_ID = uuid.NewString() INTAKE_ID = uuid.NewString() From 40841d8674a6a62adf53795115bdd59e94987352 Mon Sep 17 00:00:00 2001 From: Devansh Thakur Date: Thu, 6 Nov 2025 21:55:20 +0100 Subject: [PATCH 11/14] remove the empty line --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 45da4f77d..dc80f2645 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,3 @@ - ## Release (2025-xx-xx) - `core`: [v0.18.0](core/CHANGELOG.md#v0180) - **New:** Added duration utils From 0d818c145cab4adb0fbcfb38484ff08eb386e813 Mon Sep 17 00:00:00 2001 From: Devansh Thakur Date: Thu, 6 Nov 2025 21:59:43 +0100 Subject: [PATCH 12/14] use snake case for variables --- services/intake/wait/wait_test.go | 48 +++++++++++++++---------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/services/intake/wait/wait_test.go b/services/intake/wait/wait_test.go index 83a6aef76..bd6f5fcae 100644 --- a/services/intake/wait/wait_test.go +++ b/services/intake/wait/wait_test.go @@ -64,11 +64,11 @@ func (a *apiClientMocked) GetIntakeUserExecute(_ context.Context, _, _, _, _ str } var ( - projectId = uuid.NewString() - REGION = "eu01" - INTAKE_RUNNER_ID = uuid.NewString() - INTAKE_ID = uuid.NewString() - INTAKE_USER_ID = uuid.NewString() + projectId = uuid.NewString() + region = "eu01" + intakeRunnerId = uuid.NewString() + intakeId = uuid.NewString() + intakeUserId = uuid.NewString() ) func TestCreateOrUpdateIntakeRunnerWaitHandler(t *testing.T) { @@ -88,7 +88,7 @@ func TestCreateOrUpdateIntakeRunnerWaitHandler(t *testing.T) { wantResp: true, returnRunner: true, intakeRunnerResponse: &intake.IntakeRunnerResponse{ - Id: utils.Ptr(INTAKE_RUNNER_ID), + Id: utils.Ptr(intakeRunnerId), State: utils.Ptr(intake.INTAKERUNNERRESPONSESTATE_ACTIVE), }, }, @@ -107,7 +107,7 @@ func TestCreateOrUpdateIntakeRunnerWaitHandler(t *testing.T) { wantResp: false, returnRunner: true, intakeRunnerResponse: &intake.IntakeRunnerResponse{ - Id: utils.Ptr(INTAKE_RUNNER_ID), + Id: utils.Ptr(intakeRunnerId), State: utils.Ptr(intake.INTAKERUNNERRESPONSESTATE_RECONCILING), }, }, @@ -135,7 +135,7 @@ func TestCreateOrUpdateIntakeRunnerWaitHandler(t *testing.T) { wantResp: false, returnRunner: true, intakeRunnerResponse: &intake.IntakeRunnerResponse{ - Id: utils.Ptr(INTAKE_RUNNER_ID), + Id: utils.Ptr(intakeRunnerId), }, }, } @@ -153,7 +153,7 @@ func TestCreateOrUpdateIntakeRunnerWaitHandler(t *testing.T) { wantResp = tt.intakeRunnerResponse } - handler := CreateOrUpdateIntakeRunnerWaitHandler(context.Background(), apiClient, PROJECT_ID, REGION, INTAKE_RUNNER_ID) + handler := CreateOrUpdateIntakeRunnerWaitHandler(context.Background(), apiClient, projectId, region, intakeRunnerId) got, err := handler.SetTimeout(10 * time.Millisecond).WaitWithContext(context.Background()) if (err != nil) != tt.wantErr { @@ -202,10 +202,10 @@ func TestDeleteIntakeRunnerWaitHandler(t *testing.T) { getErrorCode: tt.getErrorCode, returnRunner: tt.returnRunner, intakeRunnerResponse: &intake.IntakeRunnerResponse{ // This is only used in the timeout case - Id: utils.Ptr(INTAKE_RUNNER_ID), + Id: utils.Ptr(intakeRunnerId), }, } - handler := DeleteIntakeRunnerWaitHandler(context.Background(), apiClient, PROJECT_ID, REGION, INTAKE_RUNNER_ID) + handler := DeleteIntakeRunnerWaitHandler(context.Background(), apiClient, projectId, region, intakeRunnerId) _, err := handler.SetTimeout(10 * time.Millisecond).WaitWithContext(context.Background()) if (err != nil) != tt.wantErr { @@ -232,7 +232,7 @@ func TestCreateOrUpdateIntakeWaitHandler(t *testing.T) { wantResp: true, returnIntake: true, intakeResponse: &intake.IntakeResponse{ - Id: utils.Ptr(INTAKE_ID), + Id: utils.Ptr(intakeId), State: utils.Ptr(intake.INTAKERESPONSESTATE_ACTIVE), }, }, @@ -243,7 +243,7 @@ func TestCreateOrUpdateIntakeWaitHandler(t *testing.T) { wantResp: true, returnIntake: true, intakeResponse: &intake.IntakeResponse{ - Id: utils.Ptr(INTAKE_ID), + Id: utils.Ptr(intakeId), State: utils.Ptr(intake.INTAKERESPONSESTATE_FAILED), }, }, @@ -262,7 +262,7 @@ func TestCreateOrUpdateIntakeWaitHandler(t *testing.T) { wantResp: false, returnIntake: true, intakeResponse: &intake.IntakeResponse{ - Id: utils.Ptr(INTAKE_ID), + Id: utils.Ptr(intakeId), State: utils.Ptr(intake.INTAKERESPONSESTATE_RECONCILING), }, }, @@ -290,7 +290,7 @@ func TestCreateOrUpdateIntakeWaitHandler(t *testing.T) { wantResp: false, returnIntake: true, intakeResponse: &intake.IntakeResponse{ - Id: utils.Ptr(INTAKE_ID), + Id: utils.Ptr(intakeId), }, }, } @@ -308,7 +308,7 @@ func TestCreateOrUpdateIntakeWaitHandler(t *testing.T) { wantResp = tt.intakeResponse } - handler := CreateOrUpdateIntakeWaitHandler(context.Background(), apiClient, PROJECT_ID, REGION, INTAKE_ID) + handler := CreateOrUpdateIntakeWaitHandler(context.Background(), apiClient, projectId, region, intakeId) got, err := handler.SetTimeout(10 * time.Millisecond).WaitWithContext(context.Background()) if (err != nil) != tt.wantErr { @@ -357,10 +357,10 @@ func TestDeleteIntakeWaitHandler(t *testing.T) { getErrorCode: tt.getErrorCode, returnIntake: tt.returnIntake, intakeResponse: &intake.IntakeResponse{ - Id: utils.Ptr(INTAKE_ID), + Id: utils.Ptr(intakeId), }, } - handler := DeleteIntakeWaitHandler(context.Background(), apiClient, PROJECT_ID, REGION, INTAKE_ID) + handler := DeleteIntakeWaitHandler(context.Background(), apiClient, projectId, region, intakeId) _, err := handler.SetTimeout(10 * time.Millisecond).WaitWithContext(context.Background()) if (err != nil) != tt.wantErr { @@ -387,7 +387,7 @@ func TestCreateOrUpdateIntakeUserWaitHandler(t *testing.T) { wantResp: true, returnUser: true, intakeUserResponse: &intake.IntakeUserResponse{ - Id: utils.Ptr(INTAKE_USER_ID), + Id: utils.Ptr(intakeUserId), State: utils.Ptr(intake.INTAKEUSERRESPONSESTATE_ACTIVE), }, }, @@ -406,7 +406,7 @@ func TestCreateOrUpdateIntakeUserWaitHandler(t *testing.T) { wantResp: false, returnUser: true, intakeUserResponse: &intake.IntakeUserResponse{ - Id: utils.Ptr(INTAKE_USER_ID), + Id: utils.Ptr(intakeUserId), State: utils.Ptr(intake.INTAKEUSERRESPONSESTATE_RECONCILING), }, }, @@ -434,7 +434,7 @@ func TestCreateOrUpdateIntakeUserWaitHandler(t *testing.T) { wantResp: false, returnUser: true, intakeUserResponse: &intake.IntakeUserResponse{ - Id: utils.Ptr(INTAKE_USER_ID), + Id: utils.Ptr(intakeUserId), }, }, } @@ -452,7 +452,7 @@ func TestCreateOrUpdateIntakeUserWaitHandler(t *testing.T) { wantResp = tt.intakeUserResponse } - handler := CreateOrUpdateIntakeUserWaitHandler(context.Background(), apiClient, PROJECT_ID, REGION, INTAKE_ID, INTAKE_USER_ID) + handler := CreateOrUpdateIntakeUserWaitHandler(context.Background(), apiClient, projectId, region, intakeId, intakeUserId) got, err := handler.SetTimeout(10 * time.Millisecond).WaitWithContext(context.Background()) if (err != nil) != tt.wantErr { @@ -501,10 +501,10 @@ func TestDeleteIntakeUserWaitHandler(t *testing.T) { getErrorCode: tt.getErrorCode, returnUser: tt.returnUser, intakeUserResponse: &intake.IntakeUserResponse{ - Id: utils.Ptr(INTAKE_USER_ID), + Id: utils.Ptr(intakeUserId), }, } - handler := DeleteIntakeUserWaitHandler(context.Background(), apiClient, PROJECT_ID, REGION, INTAKE_ID, INTAKE_USER_ID) + handler := DeleteIntakeUserWaitHandler(context.Background(), apiClient, projectId, region, intakeId, intakeUserId) _, err := handler.SetTimeout(10 * time.Millisecond).WaitWithContext(context.Background()) if (err != nil) != tt.wantErr { From 63ce414f8bac8a52e764b0c0eeac9c12a509eea4 Mon Sep 17 00:00:00 2001 From: Devansh Thakur Date: Thu, 6 Nov 2025 22:17:08 +0100 Subject: [PATCH 13/14] make region as const --- services/intake/wait/wait_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/services/intake/wait/wait_test.go b/services/intake/wait/wait_test.go index bd6f5fcae..347c055b1 100644 --- a/services/intake/wait/wait_test.go +++ b/services/intake/wait/wait_test.go @@ -63,9 +63,10 @@ func (a *apiClientMocked) GetIntakeUserExecute(_ context.Context, _, _, _, _ str return a.intakeUserResponse, nil } +const region = "eu01" + var ( projectId = uuid.NewString() - region = "eu01" intakeRunnerId = uuid.NewString() intakeId = uuid.NewString() intakeUserId = uuid.NewString() From 65769c3428006e4ea079f934fa9abe18204063fb Mon Sep 17 00:00:00 2001 From: Devansh Thakur Date: Fri, 7 Nov 2025 16:28:39 +0100 Subject: [PATCH 14/14] added intake service example with version v0.2.0 --- examples/intake/go.mod | 13 ++++++ examples/intake/go.sum | 10 +++++ examples/intake/intake.go | 86 +++++++++++++++++++++++++++++++++++++++ go.work | 1 + 4 files changed, 110 insertions(+) create mode 100644 examples/intake/go.mod create mode 100644 examples/intake/go.sum create mode 100644 examples/intake/intake.go diff --git a/examples/intake/go.mod b/examples/intake/go.mod new file mode 100644 index 000000000..ea5af500e --- /dev/null +++ b/examples/intake/go.mod @@ -0,0 +1,13 @@ +module github.com/stackitcloud/stackit-sdk-go/examples/intake + +go 1.21 + +require ( + github.com/stackitcloud/stackit-sdk-go/core v0.17.3 + github.com/stackitcloud/stackit-sdk-go/services/intake v0.2.0 +) + +require ( + github.com/golang-jwt/jwt/v5 v5.3.0 // indirect + github.com/google/uuid v1.6.0 // indirect +) diff --git a/examples/intake/go.sum b/examples/intake/go.sum new file mode 100644 index 000000000..b376b1380 --- /dev/null +++ b/examples/intake/go.sum @@ -0,0 +1,10 @@ +github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo= +github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/stackitcloud/stackit-sdk-go/core v0.17.3 h1:GsZGmRRc/3GJLmCUnsZswirr5wfLRrwavbnL/renOqg= +github.com/stackitcloud/stackit-sdk-go/core v0.17.3/go.mod h1:HBCXJGPgdRulplDzhrmwC+Dak9B/x0nzNtmOpu+1Ahg= +github.com/stackitcloud/stackit-sdk-go/services/intake v0.2.0 h1:p/zi4VPoCQWk7/2ubi3hxsqiaye41x/Pl3GXYbPkYOY= +github.com/stackitcloud/stackit-sdk-go/services/intake v0.2.0/go.mod h1:jOArPjNRkwv4487+9ab3dRG+lM09leu5FiRohbQs9Z4= diff --git a/examples/intake/intake.go b/examples/intake/intake.go new file mode 100644 index 000000000..dee1ffe74 --- /dev/null +++ b/examples/intake/intake.go @@ -0,0 +1,86 @@ +package main + +import ( + "context" + "fmt" + "os" + + sdkConfig "github.com/stackitcloud/stackit-sdk-go/core/config" + "github.com/stackitcloud/stackit-sdk-go/core/utils" + "github.com/stackitcloud/stackit-sdk-go/services/intake" +) + +func main() { + region := "eu01" // Region where the resources will be created + projectId := "PROJECT_ID" // Your STACKIT project ID + + dremioCatalogURI := "DREMIO_CATALOG_URI" // E.g., "https://my-dremio-catalog.data-platform.stackit.run/iceberg" + dremioTokenEndpoint := "DREMIO_TOKEN_ENDPOINT" // E.g., "https://my-dremio.data-platform.stackit.run/oauth/token" + dremioPAT := "DREMIO_PERSONAL_ACCESS_TOKEN" // Your Dremio Personal Access Token + catalogWarehouse := "CATALOG_WAREHOUSE" // Catalog warehouse where the data will be ingested + + intakeUserPassword := "s3cuRe_p@ssW0rd_f0r_1ntake!" // A secure password for the new intake user + + ctx := context.Background() + + intakeClient, err := intake.NewAPIClient( + sdkConfig.WithRegion(region), + ) + if err != nil { + fmt.Fprintf(os.Stderr, "Creating API client: %v\n", err) + os.Exit(1) + } + + // Create an Intake Runner + createRunnerPayload := intake.CreateIntakeRunnerPayload{ + DisplayName: utils.Ptr("my-example-runner"), + MaxMessageSizeKiB: utils.Ptr(int64(10)), + MaxMessagesPerHour: utils.Ptr(int64(1000)), + } + createRunnerResp, err := intakeClient.CreateIntakeRunner(ctx, projectId, region).CreateIntakeRunnerPayload(createRunnerPayload).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error creating Intake Runner: %v\n", err) + os.Exit(1) + } + intakeRunnerId := *createRunnerResp.Id + fmt.Printf("Triggered creation of Intake Runner with ID: %s. Waiting for it to become active...\n", intakeRunnerId) + + // Create an Intake + dremioAuthType := intake.CatalogAuthType("dremio") // can also be set to "none" if the catalog is not authenticated + createIntakePayload := intake.CreateIntakePayload{ + DisplayName: utils.Ptr("my-example-intake"), + IntakeRunnerId: utils.Ptr(intakeRunnerId), + Catalog: &intake.IntakeCatalog{ + Uri: utils.Ptr(dremioCatalogURI), + Warehouse: utils.Ptr(catalogWarehouse), + Namespace: utils.Ptr("example_namespace"), + TableName: utils.Ptr("example_table"), + Auth: &intake.CatalogAuth{ + Type: &dremioAuthType, + Dremio: &intake.DremioAuth{ + TokenEndpoint: utils.Ptr(dremioTokenEndpoint), + PersonalAccessToken: utils.Ptr(dremioPAT), + }, + }, + }, + } + createIntakeResp, err := intakeClient.CreateIntake(ctx, projectId, region).CreateIntakePayload(createIntakePayload).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error creating Intake: %v\n", err) + os.Exit(1) + } + intakeId := *createIntakeResp.Id + fmt.Printf("Triggered creation of Intake with ID: %s. Waiting for it to become active...\n", intakeRunnerId) + + createIntakeUserPayload := intake.CreateIntakeUserPayload{ + DisplayName: utils.Ptr("my-example-user"), + Password: utils.Ptr(intakeUserPassword), + } + createIntakeUserResp, err := intakeClient.CreateIntakeUser(ctx, projectId, region, intakeId).CreateIntakeUserPayload(createIntakeUserPayload).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error creating Intake User: %v\n", err) + os.Exit(1) + } + intakeUserId := *createIntakeUserResp.Id + fmt.Printf("Created Intake User with ID: %s\n", intakeUserId) +} diff --git a/go.work b/go.work index 478149caf..839083073 100644 --- a/go.work +++ b/go.work @@ -10,6 +10,7 @@ use ( ./examples/dns ./examples/errorhandling ./examples/iaas + ./examples/intake ./examples/kms ./examples/loadbalancer ./examples/logme