From d64ea5b6e0ef58b2e4b267d5c18eb1f6dca551d7 Mon Sep 17 00:00:00 2001 From: Jonas Schlecht Date: Wed, 15 Jul 2026 14:04:23 +0200 Subject: [PATCH] feat(postgresflex): migrate to V2 api Relates to STACKITCLI-374 --- go.mod | 2 +- go.sum | 4 +- .../postgresflex/backup/describe/describe.go | 11 +- .../backup/describe/describe_test.go | 16 +- internal/cmd/postgresflex/backup/list/list.go | 10 +- .../cmd/postgresflex/backup/list/list_test.go | 12 +- .../backup/update-schedule/update_schedule.go | 16 +- .../update-schedule/update_schedule_test.go | 19 +- .../cmd/postgresflex/instance/clone/clone.go | 29 +- .../postgresflex/instance/clone/clone_test.go | 189 ++++++------ .../postgresflex/instance/create/create.go | 75 +++-- .../instance/create/create_test.go | 281 +++++++++--------- .../postgresflex/instance/delete/delete.go | 24 +- .../instance/delete/delete_test.go | 89 +++--- .../instance/describe/describe.go | 12 +- .../instance/describe/describe_test.go | 12 +- .../cmd/postgresflex/instance/list/list.go | 8 +- .../postgresflex/instance/list/list_test.go | 8 +- .../postgresflex/instance/update/update.go | 33 +- .../instance/update/update_test.go | 257 ++++++++-------- internal/cmd/postgresflex/options/options.go | 39 +-- .../cmd/postgresflex/options/options_test.go | 127 ++++---- .../cmd/postgresflex/user/create/create.go | 12 +- .../postgresflex/user/create/create_test.go | 18 +- .../cmd/postgresflex/user/delete/delete.go | 8 +- .../postgresflex/user/delete/delete_test.go | 8 +- .../postgresflex/user/describe/describe.go | 6 +- .../user/describe/describe_test.go | 10 +- internal/cmd/postgresflex/user/list/list.go | 16 +- .../cmd/postgresflex/user/list/list_test.go | 10 +- .../user/reset-password/reset_password.go | 14 +- .../reset-password/reset_password_test.go | 8 +- .../cmd/postgresflex/user/update/update.go | 14 +- .../postgresflex/user/update/update_test.go | 13 +- .../services/postgresflex/client/client.go | 4 +- .../pkg/services/postgresflex/utils/utils.go | 39 ++- .../services/postgresflex/utils/utils_test.go | 210 +++++++------ 37 files changed, 819 insertions(+), 844 deletions(-) diff --git a/go.mod b/go.mod index 2353b9927..160310ab2 100644 --- a/go.mod +++ b/go.mod @@ -27,7 +27,7 @@ require ( github.com/stackitcloud/stackit-sdk-go/services/logs v0.5.2 github.com/stackitcloud/stackit-sdk-go/services/mongodbflex v1.12.0 github.com/stackitcloud/stackit-sdk-go/services/opensearch v1.1.0 - github.com/stackitcloud/stackit-sdk-go/services/postgresflex v1.3.5 + github.com/stackitcloud/stackit-sdk-go/services/postgresflex v1.11.0 github.com/stackitcloud/stackit-sdk-go/services/resourcemanager v0.24.0 github.com/stackitcloud/stackit-sdk-go/services/runcommand v1.4.3 github.com/stackitcloud/stackit-sdk-go/services/secretsmanager v0.18.1 diff --git a/go.sum b/go.sum index 5ec24b922..a00946832 100644 --- a/go.sum +++ b/go.sum @@ -626,8 +626,8 @@ github.com/stackitcloud/stackit-sdk-go/services/observability v0.24.0 h1:KhuWPXr github.com/stackitcloud/stackit-sdk-go/services/observability v0.24.0/go.mod h1:0fEZQHm729mBdvg4sNrAhM6KmHROHJSeS2FwCMRk46k= github.com/stackitcloud/stackit-sdk-go/services/opensearch v1.1.0 h1:hooc/E9Qabn8xno1NUd3uJQfUbW5KoY6mgURlnd776c= github.com/stackitcloud/stackit-sdk-go/services/opensearch v1.1.0/go.mod h1:L+NlfC1hilLOqlLLukCj/UDnxlnNrc/oMikcw3Ansyw= -github.com/stackitcloud/stackit-sdk-go/services/postgresflex v1.3.5 h1:H67e3KnHQx954yI8fuQmxXwRf/myqAdLg2KvxImp00g= -github.com/stackitcloud/stackit-sdk-go/services/postgresflex v1.3.5/go.mod h1:xmAWk9eom8wznvLuLfm0F4xyeiBX8LaggXsKFmos+dw= +github.com/stackitcloud/stackit-sdk-go/services/postgresflex v1.11.0 h1:cuI4NhuFhaZ3tTkBpUM7nt2odKFJkyCcphT/3gGb9CE= +github.com/stackitcloud/stackit-sdk-go/services/postgresflex v1.11.0/go.mod h1:yzlakB+f8ur4yAHR6lyCABO+HcEtZG3G2Faj6m5/uW8= github.com/stackitcloud/stackit-sdk-go/services/rabbitmq v1.1.0 h1:HRJwodJX4aOn/487zaqJIKw13yIj4T6dn7/kEHLxeTg= github.com/stackitcloud/stackit-sdk-go/services/rabbitmq v1.1.0/go.mod h1:TwfVVynB/+AKbccSOLk2qZpPL1tdK43BBAiACP6EtSg= github.com/stackitcloud/stackit-sdk-go/services/redis v1.1.0 h1:ckYMRXAGE2/vaxPeNGEuun9AGcFn/8xuu0ytfsiqfWU= diff --git a/internal/cmd/postgresflex/backup/describe/describe.go b/internal/cmd/postgresflex/backup/describe/describe.go index ee3e3753e..effe99ea0 100644 --- a/internal/cmd/postgresflex/backup/describe/describe.go +++ b/internal/cmd/postgresflex/backup/describe/describe.go @@ -8,7 +8,7 @@ import ( "github.com/stackitcloud/stackit-cli/internal/pkg/types" "github.com/spf13/cobra" - "github.com/stackitcloud/stackit-sdk-go/services/postgresflex" + postgresflex "github.com/stackitcloud/stackit-sdk-go/services/postgresflex/v2api" "github.com/stackitcloud/stackit-cli/internal/pkg/args" "github.com/stackitcloud/stackit-cli/internal/pkg/errors" @@ -73,7 +73,7 @@ func NewCmd(params *types.CmdParams) *cobra.Command { return fmt.Errorf("describe backup for PostgreSQL Flex instance: %w", err) } - return outputResult(params.Printer, model.OutputFormat, *resp.Item) + return outputResult(params.Printer, model.OutputFormat, resp.Item) }, } configureFlags(cmd) @@ -103,11 +103,14 @@ func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inpu } func buildRequest(ctx context.Context, model *inputModel, apiClient *postgresflex.APIClient) postgresflex.ApiGetBackupRequest { - req := apiClient.GetBackup(ctx, model.ProjectId, model.Region, model.InstanceId, model.BackupId) + req := apiClient.DefaultAPI.GetBackup(ctx, model.ProjectId, model.Region, model.InstanceId, model.BackupId) return req } -func outputResult(p *print.Printer, outputFormat string, backup postgresflex.Backup) error { +func outputResult(p *print.Printer, outputFormat string, backup *postgresflex.Backup) error { + if backup == nil { + return fmt.Errorf("backup is nil") + } if backup.StartTime == nil || *backup.StartTime == "" { return fmt.Errorf("start time not defined") } diff --git a/internal/cmd/postgresflex/backup/describe/describe_test.go b/internal/cmd/postgresflex/backup/describe/describe_test.go index 79588d715..ce3bebe11 100644 --- a/internal/cmd/postgresflex/backup/describe/describe_test.go +++ b/internal/cmd/postgresflex/backup/describe/describe_test.go @@ -8,7 +8,7 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" "github.com/google/uuid" - "github.com/stackitcloud/stackit-sdk-go/services/postgresflex" + postgresflex "github.com/stackitcloud/stackit-sdk-go/services/postgresflex/v2api" "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/testparams" @@ -18,7 +18,7 @@ import ( type testCtxKey struct{} var testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") -var testClient = &postgresflex.APIClient{} +var testClient = &postgresflex.APIClient{DefaultAPI: &postgresflex.DefaultAPIService{}} var testProjectId = uuid.NewString() var testInstanceId = uuid.NewString() var testBackupId = "backupID" @@ -63,7 +63,7 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { } func fixtureRequest(mods ...func(request *postgresflex.ApiGetBackupRequest)) postgresflex.ApiGetBackupRequest { - request := testClient.GetBackup(testCtx, testProjectId, testRegion, testInstanceId, testBackupId) + request := testClient.DefaultAPI.GetBackup(testCtx, testProjectId, testRegion, testInstanceId, testBackupId) for _, mod := range mods { mod(&request) } @@ -231,7 +231,7 @@ func TestBuildRequest(t *testing.T) { diff := cmp.Diff(request, tt.expectedRequest, cmp.AllowUnexported(tt.expectedRequest), - cmpopts.EquateComparable(testCtx), + cmpopts.EquateComparable(testCtx, postgresflex.DefaultAPIService{}), ) if diff != "" { t.Fatalf("Data does not match: %s", diff) @@ -243,7 +243,7 @@ func TestBuildRequest(t *testing.T) { func Test_outputResult(t *testing.T) { type args struct { outputFormat string - backup postgresflex.Backup + backup *postgresflex.Backup } tests := []struct { name string @@ -251,11 +251,11 @@ func Test_outputResult(t *testing.T) { wantErr bool }{ {"empty", args{}, true}, - {"standard", args{outputFormat: "", backup: postgresflex.Backup{StartTime: utils.Ptr(time.Now().Format(time.RFC3339))}}, false}, - {"complete", args{outputFormat: "", backup: postgresflex.Backup{ + {"standard", args{outputFormat: "", backup: &postgresflex.Backup{StartTime: utils.Ptr(time.Now().Format(time.RFC3339))}}, false}, + {"complete", args{outputFormat: "", backup: &postgresflex.Backup{ EndTime: utils.Ptr(time.Now().Format(time.RFC3339)), Id: utils.Ptr("id"), - Labels: &[]string{"foo", "bar", "baz"}, + Labels: []string{"foo", "bar", "baz"}, Name: utils.Ptr("name"), Options: &map[string]string{"test1": "test1", "test2": "test2"}, Size: utils.Ptr(int64(42)), diff --git a/internal/cmd/postgresflex/backup/list/list.go b/internal/cmd/postgresflex/backup/list/list.go index 004159b2b..27a400c0c 100644 --- a/internal/cmd/postgresflex/backup/list/list.go +++ b/internal/cmd/postgresflex/backup/list/list.go @@ -20,7 +20,7 @@ import ( "time" "github.com/spf13/cobra" - "github.com/stackitcloud/stackit-sdk-go/services/postgresflex" + postgresflex "github.com/stackitcloud/stackit-sdk-go/services/postgresflex/v2api" ) const ( @@ -68,7 +68,7 @@ func NewCmd(params *types.CmdParams) *cobra.Command { return err } - instanceLabel, err := postgresflexUtils.GetInstanceName(ctx, apiClient, model.ProjectId, model.Region, *model.InstanceId) + instanceLabel, err := postgresflexUtils.GetInstanceName(ctx, apiClient.DefaultAPI, model.ProjectId, model.Region, *model.InstanceId) if err != nil { params.Printer.Debug(print.ErrorLevel, "get instance name: %v", err) instanceLabel = *model.InstanceId @@ -80,11 +80,11 @@ func NewCmd(params *types.CmdParams) *cobra.Command { if err != nil { return fmt.Errorf("get backups for PostgreSQL Flex instance %q: %w", instanceLabel, err) } - if resp.Items == nil || len(*resp.Items) == 0 { + if len(resp.Items) == 0 { params.Printer.Outputf("No backups found for instance %q", instanceLabel) return nil } - backups := *resp.Items + backups := resp.Items // Truncate output if model.Limit != nil && len(backups) > int(*model.Limit) { @@ -129,7 +129,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command, _ []string) (*inputModel, } func buildRequest(ctx context.Context, model *inputModel, apiClient *postgresflex.APIClient) postgresflex.ApiListBackupsRequest { - req := apiClient.ListBackups(ctx, model.ProjectId, model.Region, *model.InstanceId) + req := apiClient.DefaultAPI.ListBackups(ctx, model.ProjectId, model.Region, *model.InstanceId) return req } diff --git a/internal/cmd/postgresflex/backup/list/list_test.go b/internal/cmd/postgresflex/backup/list/list_test.go index 1ac29b6dd..3da42ec44 100644 --- a/internal/cmd/postgresflex/backup/list/list_test.go +++ b/internal/cmd/postgresflex/backup/list/list_test.go @@ -11,7 +11,7 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" "github.com/google/uuid" - "github.com/stackitcloud/stackit-sdk-go/services/postgresflex" + postgresflex "github.com/stackitcloud/stackit-sdk-go/services/postgresflex/v2api" "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/utils" @@ -20,7 +20,7 @@ import ( type testCtxKey struct{} var testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") -var testClient = &postgresflex.APIClient{} +var testClient = &postgresflex.APIClient{DefaultAPI: &postgresflex.DefaultAPIService{}} var testProjectId = uuid.NewString() var testInstanceId = uuid.NewString() var testRegion = "eu01" @@ -55,7 +55,7 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { } func fixtureRequest(mods ...func(request *postgresflex.ApiListBackupsRequest)) postgresflex.ApiListBackupsRequest { - request := testClient.ListBackups(testCtx, testProjectId, testRegion, testInstanceId) + request := testClient.DefaultAPI.ListBackups(testCtx, testProjectId, testRegion, testInstanceId) for _, mod := range mods { mod(&request) } @@ -165,7 +165,7 @@ func TestBuildRequest(t *testing.T) { diff := cmp.Diff(request, tt.expectedRequest, cmp.AllowUnexported(tt.expectedRequest), - cmpopts.EquateComparable(testCtx), + cmpopts.EquateComparable(testCtx, postgresflex.DefaultAPIService{}), ) if diff != "" { t.Fatalf("Data does not match: %s", diff) @@ -190,7 +190,7 @@ func Test_outputResult(t *testing.T) { { EndTime: utils.Ptr(time.Now().Format(time.RFC3339)), Id: utils.Ptr("id"), - Labels: &[]string{"foo", "bar", "baz"}, + Labels: []string{"foo", "bar", "baz"}, Name: utils.Ptr("name"), Options: &map[string]string{"test1": "test1", "test2": "test2"}, Size: utils.Ptr(int64(42)), @@ -199,7 +199,7 @@ func Test_outputResult(t *testing.T) { { EndTime: utils.Ptr(time.Now().Format(time.RFC3339)), Id: utils.Ptr("id"), - Labels: &[]string{"foo", "bar", "baz"}, + Labels: []string{"foo", "bar", "baz"}, Name: utils.Ptr("name"), Options: &map[string]string{"test1": "test1", "test2": "test2"}, Size: utils.Ptr(int64(42)), diff --git a/internal/cmd/postgresflex/backup/update-schedule/update_schedule.go b/internal/cmd/postgresflex/backup/update-schedule/update_schedule.go index 447fe0864..8b200f83a 100644 --- a/internal/cmd/postgresflex/backup/update-schedule/update_schedule.go +++ b/internal/cmd/postgresflex/backup/update-schedule/update_schedule.go @@ -7,7 +7,7 @@ import ( "github.com/stackitcloud/stackit-cli/internal/pkg/types" "github.com/spf13/cobra" - "github.com/stackitcloud/stackit-sdk-go/services/postgresflex" + postgresflex "github.com/stackitcloud/stackit-sdk-go/services/postgresflex/v2api" "github.com/stackitcloud/stackit-cli/internal/pkg/args" cliErr "github.com/stackitcloud/stackit-cli/internal/pkg/errors" @@ -27,8 +27,8 @@ const ( type inputModel struct { *globalflags.GlobalFlagModel - InstanceId *string - BackupSchedule *string + InstanceId string + BackupSchedule string } func NewCmd(params *types.CmdParams) *cobra.Command { @@ -57,10 +57,10 @@ func NewCmd(params *types.CmdParams) *cobra.Command { return err } - instanceLabel, err := postgresflexUtils.GetInstanceName(ctx, apiClient, model.ProjectId, model.Region, *model.InstanceId) + instanceLabel, err := postgresflexUtils.GetInstanceName(ctx, apiClient.DefaultAPI, model.ProjectId, model.Region, model.InstanceId) if err != nil { params.Printer.Debug(print.ErrorLevel, "get instance name: %v", err) - instanceLabel = *model.InstanceId + instanceLabel = model.InstanceId } prompt := fmt.Sprintf("Are you sure you want to update backup schedule of instance %q?", instanceLabel) @@ -100,13 +100,13 @@ func parseInput(p *print.Printer, cmd *cobra.Command, _ []string) (*inputModel, return &inputModel{ GlobalFlagModel: globalFlags, - InstanceId: flags.FlagToStringPointer(p, cmd, instanceIdFlag), - BackupSchedule: flags.FlagToStringPointer(p, cmd, scheduleFlag), + InstanceId: flags.FlagToStringValue(p, cmd, instanceIdFlag), + BackupSchedule: flags.FlagToStringValue(p, cmd, scheduleFlag), }, nil } func buildRequest(ctx context.Context, model *inputModel, apiClient *postgresflex.APIClient) postgresflex.ApiUpdateBackupScheduleRequest { - req := apiClient.UpdateBackupSchedule(ctx, model.ProjectId, model.Region, *model.InstanceId) + req := apiClient.DefaultAPI.UpdateBackupSchedule(ctx, model.ProjectId, model.Region, model.InstanceId) req = req.UpdateBackupSchedulePayload(postgresflex.UpdateBackupSchedulePayload{ BackupSchedule: model.BackupSchedule, }) diff --git a/internal/cmd/postgresflex/backup/update-schedule/update_schedule_test.go b/internal/cmd/postgresflex/backup/update-schedule/update_schedule_test.go index 18ed95ae6..93ef49667 100644 --- a/internal/cmd/postgresflex/backup/update-schedule/update_schedule_test.go +++ b/internal/cmd/postgresflex/backup/update-schedule/update_schedule_test.go @@ -6,18 +6,17 @@ import ( "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/testutils" - "github.com/stackitcloud/stackit-cli/internal/pkg/utils" "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" "github.com/google/uuid" - "github.com/stackitcloud/stackit-sdk-go/services/postgresflex" + postgresflex "github.com/stackitcloud/stackit-sdk-go/services/postgresflex/v2api" ) type testCtxKey struct{} var testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") -var testClient = &postgresflex.APIClient{} +var testClient = &postgresflex.APIClient{DefaultAPI: &postgresflex.DefaultAPIService{}} var testProjectId = uuid.NewString() var testInstanceId = uuid.NewString() var testSchedule = "0 0 * * *" @@ -43,8 +42,8 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { Region: testRegion, Verbosity: globalflags.VerbosityDefault, }, - InstanceId: utils.Ptr(testInstanceId), - BackupSchedule: &testSchedule, + InstanceId: testInstanceId, + BackupSchedule: testSchedule, } for _, mod := range mods { mod(model) @@ -54,7 +53,7 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { func fixturePayload(mods ...func(payload *postgresflex.UpdateBackupSchedulePayload)) postgresflex.UpdateBackupSchedulePayload { payload := postgresflex.UpdateBackupSchedulePayload{ - BackupSchedule: utils.Ptr(testSchedule), + BackupSchedule: testSchedule, } for _, mod := range mods { mod(&payload) @@ -63,7 +62,7 @@ func fixturePayload(mods ...func(payload *postgresflex.UpdateBackupSchedulePaylo } func fixtureRequest(mods ...func(request *postgresflex.ApiUpdateBackupScheduleRequest)) postgresflex.ApiUpdateBackupScheduleRequest { - request := testClient.UpdateBackupSchedule(testCtx, testProjectId, testRegion, testInstanceId) + request := testClient.DefaultAPI.UpdateBackupSchedule(testCtx, testProjectId, testRegion, testInstanceId) request = request.UpdateBackupSchedulePayload(fixturePayload()) for _, mod := range mods { mod(&request) @@ -167,9 +166,9 @@ func TestBuildRequest(t *testing.T) { ProjectId: testProjectId, Region: testRegion, }, - InstanceId: utils.Ptr(testInstanceId), + InstanceId: testInstanceId, }, - expectedRequest: testClient.UpdateBackupSchedule(testCtx, testProjectId, testRegion, testInstanceId). + expectedRequest: testClient.DefaultAPI.UpdateBackupSchedule(testCtx, testProjectId, testRegion, testInstanceId). UpdateBackupSchedulePayload(postgresflex.UpdateBackupSchedulePayload{}), }, } @@ -180,7 +179,7 @@ func TestBuildRequest(t *testing.T) { diff := cmp.Diff(request, tt.expectedRequest, cmp.AllowUnexported(tt.expectedRequest), - cmpopts.EquateComparable(testCtx), + cmpopts.EquateComparable(testCtx, postgresflex.DefaultAPIService{}), ) if diff != "" { t.Fatalf("Data does not match: %s", diff) diff --git a/internal/cmd/postgresflex/instance/clone/clone.go b/internal/cmd/postgresflex/instance/clone/clone.go index facfdf105..b5bea934c 100644 --- a/internal/cmd/postgresflex/instance/clone/clone.go +++ b/internal/cmd/postgresflex/instance/clone/clone.go @@ -18,8 +18,8 @@ import ( "github.com/stackitcloud/stackit-cli/internal/pkg/utils" "github.com/spf13/cobra" - "github.com/stackitcloud/stackit-sdk-go/services/postgresflex" - "github.com/stackitcloud/stackit-sdk-go/services/postgresflex/wait" + postgresflex "github.com/stackitcloud/stackit-sdk-go/services/postgresflex/v2api" + wait "github.com/stackitcloud/stackit-sdk-go/services/postgresflex/v2api/wait" ) const ( @@ -72,7 +72,7 @@ func NewCmd(params *types.CmdParams) *cobra.Command { return err } - instanceLabel, err := postgresflexUtils.GetInstanceName(ctx, apiClient, model.ProjectId, model.Region, model.InstanceId) + instanceLabel, err := postgresflexUtils.GetInstanceName(ctx, apiClient.DefaultAPI, model.ProjectId, model.Region, model.InstanceId) if err != nil { params.Printer.Debug(print.ErrorLevel, "get instance name: %v", err) instanceLabel = model.InstanceId @@ -85,7 +85,7 @@ func NewCmd(params *types.CmdParams) *cobra.Command { } // Call API - req, err := buildRequest(ctx, model, apiClient) + req, err := buildRequest(ctx, model, apiClient.DefaultAPI) if err != nil { return err } @@ -98,7 +98,7 @@ func NewCmd(params *types.CmdParams) *cobra.Command { // Wait for async operation, if async mode not enabled if !model.Async { err := spinner.Run(params.Printer, "Cloning instance", func() error { - _, err = wait.CreateInstanceWaitHandler(ctx, apiClient, model.ProjectId, model.Region, instanceId).WaitWithContext(ctx) + _, err = wait.CreateInstanceWaitHandler(ctx, apiClient.DefaultAPI, model.ProjectId, model.Region, instanceId).WaitWithContext(ctx) return err }) if err != nil { @@ -151,18 +151,12 @@ func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inpu return &model, nil } -type PostgreSQLFlexClient interface { - CloneInstance(ctx context.Context, projectId, region, instanceId string) postgresflex.ApiCloneInstanceRequest - GetInstanceExecute(ctx context.Context, projectId, region, instanceId string) (*postgresflex.InstanceResponse, error) - ListStoragesExecute(ctx context.Context, projectId, region, flavorId string) (*postgresflex.ListStoragesResponse, error) -} - -func buildRequest(ctx context.Context, model *inputModel, apiClient PostgreSQLFlexClient) (postgresflex.ApiCloneInstanceRequest, error) { +func buildRequest(ctx context.Context, model *inputModel, apiClient postgresflex.DefaultAPI) (postgresflex.ApiCloneInstanceRequest, error) { req := apiClient.CloneInstance(ctx, model.ProjectId, model.Region, model.InstanceId) var storages *postgresflex.ListStoragesResponse if model.StorageClass != nil || model.StorageSize != nil { - currentInstance, err := apiClient.GetInstanceExecute(ctx, model.ProjectId, model.Region, model.InstanceId) + currentInstance, err := apiClient.GetInstance(ctx, model.ProjectId, model.Region, model.InstanceId).Execute() if err != nil { return req, fmt.Errorf("get PostgreSQL Flex instance: %w", err) } @@ -170,7 +164,7 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient PostgreSQLFl currentInstanceStorageClass := currentInstance.Item.Storage.Class currentInstanceStorageSize := currentInstance.Item.Storage.Size - storages, err = apiClient.ListStoragesExecute(ctx, model.ProjectId, model.Region, *validationFlavorId) + storages, err = apiClient.ListStorages(ctx, model.ProjectId, model.Region, *validationFlavorId).Execute() if err != nil { return req, fmt.Errorf("get PostgreSQL Flex storages: %w", err) } @@ -196,11 +190,10 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient PostgreSQLFl } func outputResult(p *print.Printer, outputFormat string, async bool, instanceLabel, instanceId string, resp *postgresflex.CloneInstanceResponse) error { - if resp == nil { - return fmt.Errorf("response not set") - } - return p.OutputResult(outputFormat, resp, func() error { + if resp == nil { + return fmt.Errorf("response not set") + } operationState := "Cloned" if async { operationState = "Triggered cloning of" diff --git a/internal/cmd/postgresflex/instance/clone/clone_test.go b/internal/cmd/postgresflex/instance/clone/clone_test.go index f123caf15..4e99f08e7 100644 --- a/internal/cmd/postgresflex/instance/clone/clone_test.go +++ b/internal/cmd/postgresflex/instance/clone/clone_test.go @@ -9,7 +9,7 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" "github.com/google/uuid" - "github.com/stackitcloud/stackit-sdk-go/services/postgresflex" + postgresflex "github.com/stackitcloud/stackit-sdk-go/services/postgresflex/v2api" "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/testparams" @@ -20,31 +20,30 @@ import ( type testCtxKey struct{} var testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") -var testClient = &postgresflex.APIClient{} +var testClient = &postgresflex.APIClient{DefaultAPI: &postgresflex.DefaultAPIService{}} -type postgresFlexClientMocked struct { +type mockSettings struct { listStoragesFails bool listStoragesResp *postgresflex.ListStoragesResponse getInstanceFails bool getInstanceResp *postgresflex.InstanceResponse } -func (c *postgresFlexClientMocked) CloneInstance(ctx context.Context, projectId, region, instanceId string) postgresflex.ApiCloneInstanceRequest { - return testClient.CloneInstance(ctx, projectId, region, instanceId) -} - -func (c *postgresFlexClientMocked) GetInstanceExecute(_ context.Context, _, _, _ string) (*postgresflex.InstanceResponse, error) { - if c.getInstanceFails { - return nil, fmt.Errorf("get instance failed") - } - return c.getInstanceResp, nil -} - -func (c *postgresFlexClientMocked) ListStoragesExecute(_ context.Context, _, _, _ string) (*postgresflex.ListStoragesResponse, error) { - if c.listStoragesFails { - return nil, fmt.Errorf("list storages failed") +func newAPIMockClient(c mockSettings) postgresflex.DefaultAPI { + return &postgresflex.DefaultAPIServiceMock{ + GetInstanceExecuteMock: utils.Ptr(func(_ postgresflex.ApiGetInstanceRequest) (*postgresflex.InstanceResponse, error) { + if c.getInstanceFails { + return nil, fmt.Errorf("get instance failed") + } + return c.getInstanceResp, nil + }), + ListStoragesExecuteMock: utils.Ptr(func(_ postgresflex.ApiListStoragesRequest) (*postgresflex.ListStoragesResponse, error) { + if c.listStoragesFails { + return nil, fmt.Errorf("list storages failed") + } + return c.listStoragesResp, nil + }), } - return c.listStoragesResp, nil } var testProjectId = uuid.NewString() @@ -138,7 +137,7 @@ func fixtureStandardInputModel(mods ...func(model *inputModel)) *inputModel { } func fixtureRequest(mods ...func(request *postgresflex.ApiCloneInstanceRequest)) postgresflex.ApiCloneInstanceRequest { - request := testClient.CloneInstance(testCtx, testProjectId, testRegion, testInstanceId) + request := testClient.DefaultAPI.CloneInstance(testCtx, testProjectId, testRegion, testInstanceId) request = request.CloneInstancePayload(fixturePayload()) for _, mod := range mods { mod(&request) @@ -316,14 +315,11 @@ func TestBuildRequest(t *testing.T) { recoveryTimestampString := testRecoveryTimestamp.Format(recoveryDateFormat) tests := []struct { - description string - model *inputModel - expectedRequest postgresflex.ApiCloneInstanceRequest - getInstanceFails bool - getInstanceResp *postgresflex.InstanceResponse - listStoragesFails bool - listStoragesResp *postgresflex.ListStoragesResponse - isValid bool + description string + model *inputModel + expectedRequest postgresflex.ApiCloneInstanceRequest + mockClientSettings mockSettings + isValid bool }{ { description: "base", @@ -337,25 +333,27 @@ func TestBuildRequest(t *testing.T) { model.StorageClass = utils.Ptr("class") }), isValid: true, - getInstanceResp: &postgresflex.InstanceResponse{ - Item: &postgresflex.Instance{ - Flavor: &postgresflex.Flavor{ - Id: utils.Ptr(testFlavorId), - }, - Storage: &postgresflex.Storage{ - Class: utils.Ptr(testStorageClass), - Size: utils.Ptr(testStorageSize), + mockClientSettings: mockSettings{ + getInstanceResp: &postgresflex.InstanceResponse{ + Item: &postgresflex.Instance{ + Flavor: &postgresflex.Flavor{ + Id: utils.Ptr(testFlavorId), + }, + Storage: &postgresflex.Storage{ + Class: utils.Ptr(testStorageClass), + Size: utils.Ptr(testStorageSize), + }, }, }, - }, - listStoragesResp: &postgresflex.ListStoragesResponse{ - StorageClasses: &[]string{"class"}, - StorageRange: &postgresflex.StorageRange{ - Min: utils.Ptr(int64(10)), - Max: utils.Ptr(int64(100)), + listStoragesResp: &postgresflex.ListStoragesResponse{ + StorageClasses: []string{"class"}, + StorageRange: &postgresflex.StorageRange{ + Min: utils.Ptr(int64(10)), + Max: utils.Ptr(int64(100)), + }, }, }, - expectedRequest: testClient.CloneInstance(testCtx, testProjectId, testRegion, testInstanceId). + expectedRequest: testClient.DefaultAPI.CloneInstance(testCtx, testProjectId, testRegion, testInstanceId). CloneInstancePayload(postgresflex.CloneInstancePayload{ Class: utils.Ptr("class"), Timestamp: utils.Ptr(recoveryTimestampString), @@ -368,25 +366,27 @@ func TestBuildRequest(t *testing.T) { model.StorageSize = utils.Ptr(int64(10)) }), isValid: true, - getInstanceResp: &postgresflex.InstanceResponse{ - Item: &postgresflex.Instance{ - Flavor: &postgresflex.Flavor{ - Id: utils.Ptr(testFlavorId), - }, - Storage: &postgresflex.Storage{ - Class: utils.Ptr(testStorageClass), - Size: utils.Ptr(testStorageSize), + mockClientSettings: mockSettings{ + getInstanceResp: &postgresflex.InstanceResponse{ + Item: &postgresflex.Instance{ + Flavor: &postgresflex.Flavor{ + Id: utils.Ptr(testFlavorId), + }, + Storage: &postgresflex.Storage{ + Class: utils.Ptr(testStorageClass), + Size: utils.Ptr(testStorageSize), + }, }, }, - }, - listStoragesResp: &postgresflex.ListStoragesResponse{ - StorageClasses: &[]string{"class"}, - StorageRange: &postgresflex.StorageRange{ - Min: utils.Ptr(int64(10)), - Max: utils.Ptr(int64(100)), + listStoragesResp: &postgresflex.ListStoragesResponse{ + StorageClasses: []string{"class"}, + StorageRange: &postgresflex.StorageRange{ + Min: utils.Ptr(int64(10)), + Max: utils.Ptr(int64(100)), + }, }, }, - expectedRequest: testClient.CloneInstance(testCtx, testProjectId, testRegion, testInstanceId). + expectedRequest: testClient.DefaultAPI.CloneInstance(testCtx, testProjectId, testRegion, testInstanceId). CloneInstancePayload(postgresflex.CloneInstancePayload{ Class: utils.Ptr("class"), Size: utils.Ptr(int64(10)), @@ -401,8 +401,10 @@ func TestBuildRequest(t *testing.T) { model.RecoveryDate = utils.Ptr(recoveryTimestampString) }, ), - getInstanceFails: true, - isValid: false, + mockClientSettings: mockSettings{ + getInstanceFails: true, + }, + isValid: false, }, { description: "invalid storage class", @@ -411,22 +413,24 @@ func TestBuildRequest(t *testing.T) { model.StorageClass = utils.Ptr("non-existing-class") }, ), - getInstanceResp: &postgresflex.InstanceResponse{ - Item: &postgresflex.Instance{ - Flavor: &postgresflex.Flavor{ - Id: utils.Ptr(testFlavorId), - }, - Storage: &postgresflex.Storage{ - Class: utils.Ptr(testStorageClass), - Size: utils.Ptr(testStorageSize), + mockClientSettings: mockSettings{ + getInstanceResp: &postgresflex.InstanceResponse{ + Item: &postgresflex.Instance{ + Flavor: &postgresflex.Flavor{ + Id: utils.Ptr(testFlavorId), + }, + Storage: &postgresflex.Storage{ + Class: utils.Ptr(testStorageClass), + Size: utils.Ptr(testStorageSize), + }, }, }, - }, - listStoragesResp: &postgresflex.ListStoragesResponse{ - StorageClasses: &[]string{"class"}, - StorageRange: &postgresflex.StorageRange{ - Min: utils.Ptr(int64(10)), - Max: utils.Ptr(int64(100)), + listStoragesResp: &postgresflex.ListStoragesResponse{ + StorageClasses: []string{"class"}, + StorageRange: &postgresflex.StorageRange{ + Min: utils.Ptr(int64(10)), + Max: utils.Ptr(int64(100)), + }, }, }, isValid: false, @@ -438,22 +442,24 @@ func TestBuildRequest(t *testing.T) { model.StorageSize = utils.Ptr(int64(9)) }, ), - getInstanceResp: &postgresflex.InstanceResponse{ - Item: &postgresflex.Instance{ - Flavor: &postgresflex.Flavor{ - Id: utils.Ptr(testFlavorId), - }, - Storage: &postgresflex.Storage{ - Class: utils.Ptr(testStorageClass), - Size: utils.Ptr(testStorageSize), + mockClientSettings: mockSettings{ + getInstanceResp: &postgresflex.InstanceResponse{ + Item: &postgresflex.Instance{ + Flavor: &postgresflex.Flavor{ + Id: utils.Ptr(testFlavorId), + }, + Storage: &postgresflex.Storage{ + Class: utils.Ptr(testStorageClass), + Size: utils.Ptr(testStorageSize), + }, }, }, - }, - listStoragesResp: &postgresflex.ListStoragesResponse{ - StorageClasses: &[]string{"class"}, - StorageRange: &postgresflex.StorageRange{ - Min: utils.Ptr(int64(10)), - Max: utils.Ptr(int64(100)), + listStoragesResp: &postgresflex.ListStoragesResponse{ + StorageClasses: []string{"class"}, + StorageRange: &postgresflex.StorageRange{ + Min: utils.Ptr(int64(10)), + Max: utils.Ptr(int64(100)), + }, }, }, isValid: false, @@ -462,13 +468,7 @@ func TestBuildRequest(t *testing.T) { for _, tt := range tests { t.Run(tt.description, func(t *testing.T) { - client := &postgresFlexClientMocked{ - getInstanceFails: tt.getInstanceFails, - getInstanceResp: tt.getInstanceResp, - listStoragesFails: tt.listStoragesFails, - listStoragesResp: tt.listStoragesResp, - } - request, err := buildRequest(testCtx, tt.model, client) + request, err := buildRequest(testCtx, tt.model, newAPIMockClient(tt.mockClientSettings)) if err != nil { if !tt.isValid { return @@ -479,6 +479,7 @@ func TestBuildRequest(t *testing.T) { diff := cmp.Diff(request, tt.expectedRequest, cmp.AllowUnexported(tt.expectedRequest), cmpopts.EquateComparable(testCtx), + cmpopts.IgnoreFields(tt.expectedRequest, "ApiService"), ) if diff != "" { t.Fatalf("Data does not match: %s", diff) diff --git a/internal/cmd/postgresflex/instance/create/create.go b/internal/cmd/postgresflex/instance/create/create.go index d3530b87e..5537cc370 100644 --- a/internal/cmd/postgresflex/instance/create/create.go +++ b/internal/cmd/postgresflex/instance/create/create.go @@ -20,8 +20,8 @@ import ( "github.com/stackitcloud/stackit-cli/internal/pkg/utils" "github.com/spf13/cobra" - "github.com/stackitcloud/stackit-sdk-go/services/postgresflex" - "github.com/stackitcloud/stackit-sdk-go/services/postgresflex/wait" + postgresflex "github.com/stackitcloud/stackit-sdk-go/services/postgresflex/v2api" + wait "github.com/stackitcloud/stackit-sdk-go/services/postgresflex/v2api/wait" ) const ( @@ -53,16 +53,16 @@ var ( type inputModel struct { *globalflags.GlobalFlagModel - InstanceName *string - ACL *[]string - BackupSchedule *string + InstanceName string + ACL []string + BackupSchedule string FlavorId *string CPU *int64 RAM *int64 StorageClass *string StorageSize *int64 - Version *string - Type *string + Version string + Type string } func NewCmd(params *types.CmdParams) *cobra.Command { @@ -109,16 +109,16 @@ func NewCmd(params *types.CmdParams) *cobra.Command { } // Fill in version, if needed - if model.Version == nil { - version, err := postgresflexUtils.GetLatestPostgreSQLVersion(ctx, apiClient, model.ProjectId, model.Region) + if model.Version == "" { + version, err := postgresflexUtils.GetLatestPostgreSQLVersion(ctx, apiClient.DefaultAPI, model.ProjectId, model.Region) if err != nil { return fmt.Errorf("get latest PostgreSQL version: %w", err) } - model.Version = &version + model.Version = version } // Call API - req, err := buildRequest(ctx, model, apiClient) + req, err := buildRequest(ctx, model, apiClient.DefaultAPI) if err != nil { return err } @@ -131,7 +131,7 @@ func NewCmd(params *types.CmdParams) *cobra.Command { // Wait for async operation, if async mode not enabled if !model.Async { err := spinner.Run(params.Printer, "Creating instance", func() error { - _, err = wait.CreateInstanceWaitHandler(ctx, apiClient, model.ProjectId, model.Region, instanceId).WaitWithContext(ctx) + _, err = wait.CreateInstanceWaitHandler(ctx, apiClient.DefaultAPI, model.ProjectId, model.Region, instanceId).WaitWithContext(ctx) return err }) if err != nil { @@ -187,41 +187,35 @@ func parseInput(p *print.Printer, cmd *cobra.Command, _ []string) (*inputModel, model := inputModel{ GlobalFlagModel: globalFlags, - InstanceName: flags.FlagToStringPointer(p, cmd, instanceNameFlag), - ACL: flags.FlagToStringSlicePointer(p, cmd, aclFlag), - BackupSchedule: utils.Ptr(flags.FlagWithDefaultToStringValue(p, cmd, backupScheduleFlag)), + InstanceName: flags.FlagToStringValue(p, cmd, instanceNameFlag), + ACL: flags.FlagToStringSliceValue(p, cmd, aclFlag), + BackupSchedule: flags.FlagWithDefaultToStringValue(p, cmd, backupScheduleFlag), FlavorId: flavorId, CPU: cpu, RAM: ram, StorageClass: utils.Ptr(flags.FlagWithDefaultToStringValue(p, cmd, storageClassFlag)), StorageSize: &storageSize, - Version: flags.FlagToStringPointer(p, cmd, versionFlag), - Type: typeFlag.Ptr(), + Version: flags.FlagToStringValue(p, cmd, versionFlag), + Type: typeFlag.Get(), } p.DebugInputModel(model) return &model, nil } -type PostgreSQLFlexClient interface { - CreateInstance(ctx context.Context, projectId, region string) postgresflex.ApiCreateInstanceRequest - ListFlavorsExecute(ctx context.Context, projectId, region string) (*postgresflex.ListFlavorsResponse, error) - ListStoragesExecute(ctx context.Context, projectId, region, flavorId string) (*postgresflex.ListStoragesResponse, error) -} - -func buildRequest(ctx context.Context, model *inputModel, apiClient PostgreSQLFlexClient) (postgresflex.ApiCreateInstanceRequest, error) { +func buildRequest(ctx context.Context, model *inputModel, apiClient postgresflex.DefaultAPI) (postgresflex.ApiCreateInstanceRequest, error) { req := apiClient.CreateInstance(ctx, model.ProjectId, model.Region) - var flavorId *string + var flavorId string var err error - flavors, err := apiClient.ListFlavorsExecute(ctx, model.ProjectId, model.Region) + flavors, err := apiClient.ListFlavors(ctx, model.ProjectId, model.Region).Execute() if err != nil { return req, fmt.Errorf("get PostgreSQL Flex flavors: %w", err) } if model.FlavorId == nil { - flavorId, err = postgresflexUtils.LoadFlavorId(*model.CPU, *model.RAM, flavors.Flavors) + foundFlavorId, err := postgresflexUtils.LoadFlavorId(*model.CPU, *model.RAM, flavors.Flavors) if err != nil { var dsaInvalidPlanError *cliErr.DSAInvalidPlanError if !errors.As(err, &dsaInvalidPlanError) { @@ -229,51 +223,52 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient PostgreSQLFl } return req, err } + flavorId = *foundFlavorId } else { err := postgresflexUtils.ValidateFlavorId(*model.FlavorId, flavors.Flavors) if err != nil { return req, err } - flavorId = model.FlavorId + flavorId = *model.FlavorId } - storages, err := apiClient.ListStoragesExecute(ctx, model.ProjectId, model.Region, *flavorId) + storages, err := apiClient.ListStorages(ctx, model.ProjectId, model.Region, flavorId).Execute() if err != nil { return req, fmt.Errorf("get PostgreSQL Flex storages: %w", err) } - err = postgresflexUtils.ValidateStorage(model.StorageClass, model.StorageSize, storages, *flavorId) + err = postgresflexUtils.ValidateStorage(model.StorageClass, model.StorageSize, storages, flavorId) if err != nil { return req, err } - replicas, err := postgresflexUtils.GetInstanceReplicas(*model.Type) + replicas, err := postgresflexUtils.GetInstanceReplicas(model.Type) if err != nil { return req, fmt.Errorf("get PostgreSQL Flex instance type: %w", err) } req = req.CreateInstancePayload(postgresflex.CreateInstancePayload{ Name: model.InstanceName, - Acl: &postgresflex.ACL{Items: model.ACL}, + Acl: postgresflex.ACL{Items: model.ACL}, BackupSchedule: model.BackupSchedule, FlavorId: flavorId, - Replicas: &replicas, - Storage: &postgresflex.Storage{ + Replicas: replicas, + Storage: postgresflex.Storage{ Class: model.StorageClass, Size: model.StorageSize, }, Version: model.Version, - Options: utils.Ptr(map[string]string{ - "type": *model.Type, - }), + Options: map[string]string{ + "type": model.Type, + }, }) return req, nil } func outputResult(p *print.Printer, outputFormat string, async bool, projectLabel, instanceId string, resp *postgresflex.CreateInstanceResponse) error { - if resp == nil { - return fmt.Errorf("no response passed") - } return p.OutputResult(outputFormat, resp, func() error { + if resp == nil { + return fmt.Errorf("no response passed") + } operationState := "Created" if async { operationState = "Triggered creation of" diff --git a/internal/cmd/postgresflex/instance/create/create_test.go b/internal/cmd/postgresflex/instance/create/create_test.go index 54f1b3087..d0f86d364 100644 --- a/internal/cmd/postgresflex/instance/create/create_test.go +++ b/internal/cmd/postgresflex/instance/create/create_test.go @@ -8,7 +8,7 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" "github.com/google/uuid" - "github.com/stackitcloud/stackit-sdk-go/services/postgresflex" + postgresflex "github.com/stackitcloud/stackit-sdk-go/services/postgresflex/v2api" "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/testparams" @@ -19,32 +19,31 @@ import ( type testCtxKey struct{} var testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") -var testClient = &postgresflex.APIClient{} +var testClient = &postgresflex.APIClient{DefaultAPI: &postgresflex.DefaultAPIService{}} var testRegion = "eu01" -type postgresFlexClientMocked struct { +type mockSettings struct { listFlavorsFails bool listFlavorsResp *postgresflex.ListFlavorsResponse listStoragesFails bool listStoragesResp *postgresflex.ListStoragesResponse } -func (c *postgresFlexClientMocked) CreateInstance(ctx context.Context, projectId, region string) postgresflex.ApiCreateInstanceRequest { - return testClient.CreateInstance(ctx, projectId, region) -} - -func (c *postgresFlexClientMocked) ListStoragesExecute(_ context.Context, _, _, _ string) (*postgresflex.ListStoragesResponse, error) { - if c.listFlavorsFails { - return nil, fmt.Errorf("list storages failed") - } - return c.listStoragesResp, nil -} - -func (c *postgresFlexClientMocked) ListFlavorsExecute(_ context.Context, _, _ string) (*postgresflex.ListFlavorsResponse, error) { - if c.listFlavorsFails { - return nil, fmt.Errorf("list flavors failed") +func newAPIClientMock(c mockSettings) postgresflex.DefaultAPI { + return postgresflex.DefaultAPIServiceMock{ + ListStoragesExecuteMock: utils.Ptr(func(_ postgresflex.ApiListStoragesRequest) (*postgresflex.ListStoragesResponse, error) { + if c.listStoragesFails { + return nil, fmt.Errorf("list storages failed") + } + return c.listStoragesResp, nil + }), + ListFlavorsExecuteMock: utils.Ptr(func(_ postgresflex.ApiListFlavorsRequest) (*postgresflex.ListFlavorsResponse, error) { + if c.listFlavorsFails { + return nil, fmt.Errorf("list flavors failed") + } + return c.listFlavorsResp, nil + }), } - return c.listFlavorsResp, nil } var testProjectId = uuid.NewString() @@ -76,14 +75,14 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { Region: testRegion, Verbosity: globalflags.VerbosityDefault, }, - InstanceName: utils.Ptr("example-name"), - ACL: utils.Ptr([]string{"0.0.0.0/0"}), - BackupSchedule: utils.Ptr("0 0 * * *"), + InstanceName: "example-name", + ACL: []string{"0.0.0.0/0"}, + BackupSchedule: "0 0 * * *", FlavorId: utils.Ptr(testFlavorId), StorageClass: utils.Ptr("premium-perf4-stackit"), StorageSize: utils.Ptr(int64(10)), - Version: utils.Ptr("6.0"), - Type: utils.Ptr("Replica"), + Version: "6.0", + Type: "Replica", } for _, mod := range mods { mod(model) @@ -92,7 +91,7 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { } func fixtureRequest(mods ...func(request *postgresflex.ApiCreateInstanceRequest)) postgresflex.ApiCreateInstanceRequest { - request := testClient.CreateInstance(testCtx, testProjectId, testRegion) + request := testClient.DefaultAPI.CreateInstance(testCtx, testProjectId, testRegion) request = request.CreateInstancePayload(fixturePayload()) for _, mod := range mods { mod(&request) @@ -102,19 +101,19 @@ func fixtureRequest(mods ...func(request *postgresflex.ApiCreateInstanceRequest) func fixturePayload(mods ...func(payload *postgresflex.CreateInstancePayload)) postgresflex.CreateInstancePayload { payload := postgresflex.CreateInstancePayload{ - Name: utils.Ptr("example-name"), - Acl: &postgresflex.ACL{Items: utils.Ptr([]string{"0.0.0.0/0"})}, - BackupSchedule: utils.Ptr("0 0 * * *"), - FlavorId: utils.Ptr(testFlavorId), - Replicas: utils.Ptr(int64(3)), - Storage: &postgresflex.Storage{ + Name: "example-name", + Acl: postgresflex.ACL{Items: []string{"0.0.0.0/0"}}, + BackupSchedule: "0 0 * * *", + FlavorId: testFlavorId, + Replicas: int32(3), + Storage: postgresflex.Storage{ Class: utils.Ptr("premium-perf4-stackit"), Size: utils.Ptr(int64(10)), }, - Version: utils.Ptr("6.0"), - Options: utils.Ptr(map[string]string{ + Version: "6.0", + Options: map[string]string{ "type": "Replica", - }), + }, } for _, mod := range mods { mod(&payload) @@ -215,7 +214,7 @@ func TestParseInput(t *testing.T) { }), isValid: true, expectedModel: fixtureInputModel(func(model *inputModel) { - model.Version = nil + model.Version = "" }), }, { @@ -224,9 +223,8 @@ func TestParseInput(t *testing.T) { aclValues: []string{"198.51.100.14/24", "198.51.100.14/32"}, isValid: true, expectedModel: fixtureInputModel(func(model *inputModel) { - model.ACL = utils.Ptr( - append(*model.ACL, "198.51.100.14/24", "198.51.100.14/32"), - ) + model.ACL = + append(model.ACL, "198.51.100.14/24", "198.51.100.14/32") }), }, { @@ -235,9 +233,8 @@ func TestParseInput(t *testing.T) { aclValues: []string{"198.51.100.14/24,198.51.100.14/32"}, isValid: true, expectedModel: fixtureInputModel(func(model *inputModel) { - model.ACL = utils.Ptr( - append(*model.ACL, "198.51.100.14/24", "198.51.100.14/32"), - ) + model.ACL = + append(model.ACL, "198.51.100.14/24", "198.51.100.14/32") }), }, { @@ -261,34 +258,33 @@ func TestParseInput(t *testing.T) { func TestBuildRequest(t *testing.T) { tests := []struct { - description string - model *inputModel - expectedRequest postgresflex.ApiCreateInstanceRequest - listFlavorsFails bool - listFlavorsResp *postgresflex.ListFlavorsResponse - listStoragesFails bool - listStoragesResp *postgresflex.ListStoragesResponse - isValid bool + description string + model *inputModel + expectedRequest postgresflex.ApiCreateInstanceRequest + mockClientSettings mockSettings + isValid bool }{ { description: "base with flavor ID", model: fixtureInputModel(), isValid: true, expectedRequest: fixtureRequest(), - listFlavorsResp: &postgresflex.ListFlavorsResponse{ - Flavors: &[]postgresflex.Flavor{ - { - Id: utils.Ptr(testFlavorId), - Cpu: utils.Ptr(int64(2)), - Memory: utils.Ptr(int64(4)), + mockClientSettings: mockSettings{ + listFlavorsResp: &postgresflex.ListFlavorsResponse{ + Flavors: []postgresflex.Flavor{ + { + Id: utils.Ptr(testFlavorId), + Cpu: utils.Ptr(int64(2)), + Memory: utils.Ptr(int64(4)), + }, }, }, - }, - listStoragesResp: &postgresflex.ListStoragesResponse{ - StorageClasses: &[]string{"premium-perf4-stackit"}, - StorageRange: &postgresflex.StorageRange{ - Min: utils.Ptr(int64(10)), - Max: utils.Ptr(int64(100)), + listStoragesResp: &postgresflex.ListStoragesResponse{ + StorageClasses: []string{"premium-perf4-stackit"}, + StorageRange: &postgresflex.StorageRange{ + Min: utils.Ptr(int64(10)), + Max: utils.Ptr(int64(100)), + }, }, }, }, @@ -303,50 +299,54 @@ func TestBuildRequest(t *testing.T) { ), isValid: true, expectedRequest: fixtureRequest(), - listFlavorsResp: &postgresflex.ListFlavorsResponse{ - Flavors: &[]postgresflex.Flavor{ - { - Id: utils.Ptr(testFlavorId), - Cpu: utils.Ptr(int64(2)), - Memory: utils.Ptr(int64(4)), - }, - { - Id: utils.Ptr("other-flavor"), - Cpu: utils.Ptr(int64(1)), - Memory: utils.Ptr(int64(8)), + mockClientSettings: mockSettings{ + listFlavorsResp: &postgresflex.ListFlavorsResponse{ + Flavors: []postgresflex.Flavor{ + { + Id: utils.Ptr(testFlavorId), + Cpu: utils.Ptr(int64(2)), + Memory: utils.Ptr(int64(4)), + }, + { + Id: utils.Ptr("other-flavor"), + Cpu: utils.Ptr(int64(1)), + Memory: utils.Ptr(int64(8)), + }, }, }, - }, - listStoragesResp: &postgresflex.ListStoragesResponse{ - StorageClasses: &[]string{"premium-perf4-stackit"}, - StorageRange: &postgresflex.StorageRange{ - Min: utils.Ptr(int64(10)), - Max: utils.Ptr(int64(100)), + listStoragesResp: &postgresflex.ListStoragesResponse{ + StorageClasses: []string{"premium-perf4-stackit"}, + StorageRange: &postgresflex.StorageRange{ + Min: utils.Ptr(int64(10)), + Max: utils.Ptr(int64(100)), + }, }, }, }, { description: "single instance type", - model: fixtureInputModel(func(model *inputModel) { model.Type = utils.Ptr("Single") }), + model: fixtureInputModel(func(model *inputModel) { model.Type = "Single" }), isValid: true, expectedRequest: fixtureRequest().CreateInstancePayload(fixturePayload(func(payload *postgresflex.CreateInstancePayload) { - payload.Options = utils.Ptr(map[string]string{"type": "Single"}) - payload.Replicas = utils.Ptr(int64(1)) + payload.Options = map[string]string{"type": "Single"} + payload.Replicas = int32(1) })), - listFlavorsResp: &postgresflex.ListFlavorsResponse{ - Flavors: &[]postgresflex.Flavor{ - { - Id: utils.Ptr(testFlavorId), - Cpu: utils.Ptr(int64(2)), - Memory: utils.Ptr(int64(4)), + mockClientSettings: mockSettings{ + listFlavorsResp: &postgresflex.ListFlavorsResponse{ + Flavors: []postgresflex.Flavor{ + { + Id: utils.Ptr(testFlavorId), + Cpu: utils.Ptr(int64(2)), + Memory: utils.Ptr(int64(4)), + }, }, }, - }, - listStoragesResp: &postgresflex.ListStoragesResponse{ - StorageClasses: &[]string{"premium-perf4-stackit"}, - StorageRange: &postgresflex.StorageRange{ - Min: utils.Ptr(int64(10)), - Max: utils.Ptr(int64(100)), + listStoragesResp: &postgresflex.ListStoragesResponse{ + StorageClasses: []string{"premium-perf4-stackit"}, + StorageRange: &postgresflex.StorageRange{ + Min: utils.Ptr(int64(10)), + Max: utils.Ptr(int64(100)), + }, }, }, }, @@ -359,8 +359,10 @@ func TestBuildRequest(t *testing.T) { model.RAM = utils.Ptr(int64(4)) }, ), - listFlavorsFails: true, - isValid: false, + mockClientSettings: mockSettings{ + listFlavorsFails: true, + }, + isValid: false, }, { description: "flavor id not found", @@ -371,17 +373,19 @@ func TestBuildRequest(t *testing.T) { model.RAM = utils.Ptr(int64(9)) }, ), - listFlavorsResp: &postgresflex.ListFlavorsResponse{ - Flavors: &[]postgresflex.Flavor{ - { - Id: utils.Ptr(testFlavorId), - Cpu: utils.Ptr(int64(2)), - Memory: utils.Ptr(int64(4)), - }, - { - Id: utils.Ptr("other-flavor"), - Cpu: utils.Ptr(int64(1)), - Memory: utils.Ptr(int64(8)), + mockClientSettings: mockSettings{ + listFlavorsResp: &postgresflex.ListFlavorsResponse{ + Flavors: []postgresflex.Flavor{ + { + Id: utils.Ptr(testFlavorId), + Cpu: utils.Ptr(int64(2)), + Memory: utils.Ptr(int64(4)), + }, + { + Id: utils.Ptr("other-flavor"), + Cpu: utils.Ptr(int64(1)), + Memory: utils.Ptr(int64(8)), + }, }, }, }, @@ -396,8 +400,10 @@ func TestBuildRequest(t *testing.T) { model.RAM = utils.Ptr(int64(4)) }, ), - listFlavorsFails: true, - isValid: false, + mockClientSettings: mockSettings{ + listFlavorsFails: true, + }, + isValid: false, }, { description: "invalid storage class", @@ -406,20 +412,22 @@ func TestBuildRequest(t *testing.T) { model.StorageClass = utils.Ptr("non-existing-class") }, ), - listFlavorsResp: &postgresflex.ListFlavorsResponse{ - Flavors: &[]postgresflex.Flavor{ - { - Id: utils.Ptr(testFlavorId), - Cpu: utils.Ptr(int64(2)), - Memory: utils.Ptr(int64(4)), + mockClientSettings: mockSettings{ + listFlavorsResp: &postgresflex.ListFlavorsResponse{ + Flavors: []postgresflex.Flavor{ + { + Id: utils.Ptr(testFlavorId), + Cpu: utils.Ptr(int64(2)), + Memory: utils.Ptr(int64(4)), + }, }, }, - }, - listStoragesResp: &postgresflex.ListStoragesResponse{ - StorageClasses: &[]string{"premium-perf4-stackit"}, - StorageRange: &postgresflex.StorageRange{ - Min: utils.Ptr(int64(10)), - Max: utils.Ptr(int64(100)), + listStoragesResp: &postgresflex.ListStoragesResponse{ + StorageClasses: []string{"premium-perf4-stackit"}, + StorageRange: &postgresflex.StorageRange{ + Min: utils.Ptr(int64(10)), + Max: utils.Ptr(int64(100)), + }, }, }, isValid: false, @@ -431,20 +439,22 @@ func TestBuildRequest(t *testing.T) { model.StorageSize = utils.Ptr(int64(9)) }, ), - listFlavorsResp: &postgresflex.ListFlavorsResponse{ - Flavors: &[]postgresflex.Flavor{ - { - Id: utils.Ptr(testFlavorId), - Cpu: utils.Ptr(int64(2)), - Memory: utils.Ptr(int64(4)), + mockClientSettings: mockSettings{ + listFlavorsResp: &postgresflex.ListFlavorsResponse{ + Flavors: []postgresflex.Flavor{ + { + Id: utils.Ptr(testFlavorId), + Cpu: utils.Ptr(int64(2)), + Memory: utils.Ptr(int64(4)), + }, }, }, - }, - listStoragesResp: &postgresflex.ListStoragesResponse{ - StorageClasses: &[]string{"premium-perf4-stackit"}, - StorageRange: &postgresflex.StorageRange{ - Min: utils.Ptr(int64(10)), - Max: utils.Ptr(int64(100)), + listStoragesResp: &postgresflex.ListStoragesResponse{ + StorageClasses: []string{"premium-perf4-stackit"}, + StorageRange: &postgresflex.StorageRange{ + Min: utils.Ptr(int64(10)), + Max: utils.Ptr(int64(100)), + }, }, }, isValid: false, @@ -453,13 +463,7 @@ func TestBuildRequest(t *testing.T) { for _, tt := range tests { t.Run(tt.description, func(t *testing.T) { - client := &postgresFlexClientMocked{ - listFlavorsFails: tt.listFlavorsFails, - listFlavorsResp: tt.listFlavorsResp, - listStoragesFails: tt.listStoragesFails, - listStoragesResp: tt.listStoragesResp, - } - request, err := buildRequest(testCtx, tt.model, client) + request, err := buildRequest(testCtx, tt.model, newAPIClientMock(tt.mockClientSettings)) if err != nil { if !tt.isValid { return @@ -470,6 +474,7 @@ func TestBuildRequest(t *testing.T) { diff := cmp.Diff(request, tt.expectedRequest, cmp.AllowUnexported(tt.expectedRequest), cmpopts.EquateComparable(testCtx), + cmpopts.IgnoreFields(tt.expectedRequest, "ApiService"), ) if diff != "" { t.Fatalf("Data does not match: %s", diff) diff --git a/internal/cmd/postgresflex/instance/delete/delete.go b/internal/cmd/postgresflex/instance/delete/delete.go index 3a8aa4cfe..c26787a42 100644 --- a/internal/cmd/postgresflex/instance/delete/delete.go +++ b/internal/cmd/postgresflex/instance/delete/delete.go @@ -18,8 +18,8 @@ import ( "github.com/stackitcloud/stackit-cli/internal/pkg/utils" "github.com/spf13/cobra" - "github.com/stackitcloud/stackit-sdk-go/services/postgresflex" - "github.com/stackitcloud/stackit-sdk-go/services/postgresflex/wait" + postgresflex "github.com/stackitcloud/stackit-sdk-go/services/postgresflex/v2api" + wait "github.com/stackitcloud/stackit-sdk-go/services/postgresflex/v2api/wait" ) const ( @@ -65,7 +65,7 @@ func NewCmd(params *types.CmdParams) *cobra.Command { return err } - instanceLabel, err := postgresflexUtils.GetInstanceName(ctx, apiClient, model.ProjectId, model.Region, model.InstanceId) + instanceLabel, err := postgresflexUtils.GetInstanceName(ctx, apiClient.DefaultAPI, model.ProjectId, model.Region, model.InstanceId) if err != nil { params.Printer.Debug(print.ErrorLevel, "get instance name: %v", err) instanceLabel = model.InstanceId @@ -77,7 +77,7 @@ func NewCmd(params *types.CmdParams) *cobra.Command { return err } - toDelete, toForceDelete, err := getNextOperations(ctx, model, apiClient) + toDelete, toForceDelete, err := getNextOperations(ctx, model, apiClient.DefaultAPI) if err != nil { return err } @@ -93,7 +93,7 @@ func NewCmd(params *types.CmdParams) *cobra.Command { // Wait for async operation, if async mode not enabled if !model.Async { err := spinner.Run(params.Printer, "Deleting instance", func() error { - _, err = wait.DeleteInstanceWaitHandler(ctx, apiClient, model.ProjectId, model.Region, model.InstanceId).WaitWithContext(ctx) + _, err = wait.DeleteInstanceWaitHandler(ctx, apiClient.DefaultAPI, model.ProjectId, model.Region, model.InstanceId).WaitWithContext(ctx) return err }) if err != nil { @@ -113,7 +113,7 @@ func NewCmd(params *types.CmdParams) *cobra.Command { // Wait for async operation, if async mode not enabled if !model.Async { err := spinner.Run(params.Printer, "Forcing deletion of instance", func() error { - _, err = wait.ForceDeleteInstanceWaitHandler(ctx, apiClient, model.ProjectId, model.Region, model.InstanceId).WaitWithContext(ctx) + _, err = wait.ForceDeleteInstanceWaitHandler(ctx, apiClient.DefaultAPI, model.ProjectId, model.Region, model.InstanceId).WaitWithContext(ctx) return err }) if err != nil { @@ -163,22 +163,16 @@ func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inpu } func buildDeleteRequest(ctx context.Context, model *inputModel, apiClient *postgresflex.APIClient) postgresflex.ApiDeleteInstanceRequest { - req := apiClient.DeleteInstance(ctx, model.ProjectId, model.Region, model.InstanceId) + req := apiClient.DefaultAPI.DeleteInstance(ctx, model.ProjectId, model.Region, model.InstanceId) return req } func buildForceDeleteRequest(ctx context.Context, model *inputModel, apiClient *postgresflex.APIClient) postgresflex.ApiForceDeleteInstanceRequest { - req := apiClient.ForceDeleteInstance(ctx, model.ProjectId, model.Region, model.InstanceId) + req := apiClient.DefaultAPI.ForceDeleteInstance(ctx, model.ProjectId, model.Region, model.InstanceId) return req } -type PostgreSQLFlexClient interface { - GetInstanceExecute(ctx context.Context, projectId, region, instanceId string) (*postgresflex.InstanceResponse, error) - ListVersionsExecute(ctx context.Context, projectId, region string) (*postgresflex.ListVersionsResponse, error) - GetUserExecute(ctx context.Context, projectId, region, instanceId, userId string) (*postgresflex.GetUserResponse, error) -} - -func getNextOperations(ctx context.Context, model *inputModel, apiClient PostgreSQLFlexClient) (toDelete, toForceDelete bool, err error) { +func getNextOperations(ctx context.Context, model *inputModel, apiClient postgresflex.DefaultAPI) (toDelete, toForceDelete bool, err error) { instanceStatus, err := postgresflexUtils.GetInstanceStatus(ctx, apiClient, model.ProjectId, model.Region, model.InstanceId) if err != nil { return false, false, fmt.Errorf("get PostgreSQL Flex instance status: %w", err) diff --git a/internal/cmd/postgresflex/instance/delete/delete_test.go b/internal/cmd/postgresflex/instance/delete/delete_test.go index fdbe26f4c..ffdd8c3b9 100644 --- a/internal/cmd/postgresflex/instance/delete/delete_test.go +++ b/internal/cmd/postgresflex/instance/delete/delete_test.go @@ -12,37 +12,32 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" "github.com/google/uuid" - "github.com/stackitcloud/stackit-sdk-go/services/postgresflex" - "github.com/stackitcloud/stackit-sdk-go/services/postgresflex/wait" + postgresflex "github.com/stackitcloud/stackit-sdk-go/services/postgresflex/v2api" + wait "github.com/stackitcloud/stackit-sdk-go/services/postgresflex/v2api/wait" ) type testCtxKey struct{} var testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") -var testClient = &postgresflex.APIClient{} +var testClient = &postgresflex.APIClient{DefaultAPI: &postgresflex.DefaultAPIService{}} var testProjectId = uuid.NewString() var testInstanceId = uuid.NewString() var testRegion = "eu01" -type postgresFlexClientMocked struct { +type mockSettings struct { getInstanceFails bool getInstanceResp *postgresflex.InstanceResponse } -func (c *postgresFlexClientMocked) GetInstanceExecute(_ context.Context, _, _, _ string) (*postgresflex.InstanceResponse, error) { - if c.getInstanceFails { - return nil, fmt.Errorf("get instance failed") +func newAPIMockClient(c mockSettings) postgresflex.DefaultAPI { + return postgresflex.DefaultAPIServiceMock{ + GetInstanceExecuteMock: utils.Ptr(func(_ postgresflex.ApiGetInstanceRequest) (*postgresflex.InstanceResponse, error) { + if c.getInstanceFails { + return nil, fmt.Errorf("get instance failed") + } + return c.getInstanceResp, nil + }), } - return c.getInstanceResp, nil -} - -func (c *postgresFlexClientMocked) ListVersionsExecute(_ context.Context, _, _ string) (*postgresflex.ListVersionsResponse, error) { - // Not used in testing - return nil, nil -} -func (c *postgresFlexClientMocked) GetUserExecute(_ context.Context, _, _, _, _ string) (*postgresflex.GetUserResponse, error) { - // Not used in testing - return nil, nil } func fixtureArgValues(mods ...func(argValues []string)) []string { @@ -82,7 +77,7 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { } func fixtureDeleteRequest(mods ...func(request *postgresflex.ApiDeleteInstanceRequest)) postgresflex.ApiDeleteInstanceRequest { - request := testClient.DeleteInstance(testCtx, testProjectId, testRegion, testInstanceId) + request := testClient.DefaultAPI.DeleteInstance(testCtx, testProjectId, testRegion, testInstanceId) for _, mod := range mods { mod(&request) } @@ -90,7 +85,7 @@ func fixtureDeleteRequest(mods ...func(request *postgresflex.ApiDeleteInstanceRe } func fixtureForceDeleteRequest(mods ...func(request *postgresflex.ApiForceDeleteInstanceRequest)) postgresflex.ApiForceDeleteInstanceRequest { - request := testClient.ForceDeleteInstance(testCtx, testProjectId, testRegion, testInstanceId) + request := testClient.DefaultAPI.ForceDeleteInstance(testCtx, testProjectId, testRegion, testInstanceId) for _, mod := range mods { mod(&request) } @@ -194,7 +189,7 @@ func TestBuildDeleteRequest(t *testing.T) { diff := cmp.Diff(request, tt.expectedRequest, cmp.AllowUnexported(tt.expectedRequest), - cmpopts.EquateComparable(testCtx), + cmpopts.EquateComparable(testCtx, postgresflex.DefaultAPIService{}), ) if diff != "" { t.Fatalf("Data does not match: %s", diff) @@ -222,7 +217,7 @@ func TestBuildForceDeleteRequest(t *testing.T) { diff := cmp.Diff(request, tt.expectedRequest, cmp.AllowUnexported(tt.expectedRequest), - cmpopts.EquateComparable(testCtx), + cmpopts.EquateComparable(testCtx, postgresflex.DefaultAPIService{}), ) if diff != "" { t.Fatalf("Data does not match: %s", diff) @@ -237,8 +232,7 @@ func TestCheckIfInstanceIsDeleted(t *testing.T) { model *inputModel expectedToDelete bool expectedToForceDelete bool - getInstanceResponse *postgresflex.InstanceResponse - getInstanceFails bool + mockClientSettings mockSettings isValid bool }{ { @@ -246,9 +240,11 @@ func TestCheckIfInstanceIsDeleted(t *testing.T) { model: fixtureInputModel(), expectedToDelete: true, expectedToForceDelete: false, - getInstanceResponse: &postgresflex.InstanceResponse{ - Item: &postgresflex.Instance{ - Status: utils.Ptr(wait.InstanceStateSuccess), + mockClientSettings: mockSettings{ + getInstanceResp: &postgresflex.InstanceResponse{ + Item: &postgresflex.Instance{ + Status: utils.Ptr(wait.InstanceStateSuccess), + }, }, }, isValid: true, @@ -260,9 +256,11 @@ func TestCheckIfInstanceIsDeleted(t *testing.T) { }), expectedToDelete: true, expectedToForceDelete: true, - getInstanceResponse: &postgresflex.InstanceResponse{ - Item: &postgresflex.Instance{ - Status: utils.Ptr(wait.InstanceStateSuccess), + mockClientSettings: mockSettings{ + getInstanceResp: &postgresflex.InstanceResponse{ + Item: &postgresflex.Instance{ + Status: utils.Ptr(wait.InstanceStateSuccess), + }, }, }, isValid: true, @@ -274,9 +272,11 @@ func TestCheckIfInstanceIsDeleted(t *testing.T) { }), expectedToDelete: false, expectedToForceDelete: true, - getInstanceResponse: &postgresflex.InstanceResponse{ - Item: &postgresflex.Instance{ - Status: utils.Ptr(wait.InstanceStateDeleted), + mockClientSettings: mockSettings{ + getInstanceResp: &postgresflex.InstanceResponse{ + Item: &postgresflex.Instance{ + Status: utils.Ptr(wait.InstanceStateDeleted), + }, }, }, isValid: true, @@ -284,29 +284,28 @@ func TestCheckIfInstanceIsDeleted(t *testing.T) { { description: "delete instance state Deleted", model: fixtureInputModel(), - getInstanceResponse: &postgresflex.InstanceResponse{ - Item: &postgresflex.Instance{ - Status: utils.Ptr(wait.InstanceStateDeleted), + mockClientSettings: mockSettings{ + getInstanceResp: &postgresflex.InstanceResponse{ + Item: &postgresflex.Instance{ + Status: utils.Ptr(wait.InstanceStateDeleted), + }, }, }, isValid: false, }, { - description: "delete instance get instance fails", - model: fixtureInputModel(), - getInstanceFails: true, - isValid: false, + description: "delete instance get instance fails", + model: fixtureInputModel(), + mockClientSettings: mockSettings{ + getInstanceFails: true, + }, + isValid: false, }, } for _, tt := range tests { t.Run(tt.description, func(t *testing.T) { - client := &postgresFlexClientMocked{ - getInstanceResp: tt.getInstanceResponse, - getInstanceFails: tt.getInstanceFails, - } - - toDelete, toForceDelete, err := getNextOperations(testCtx, tt.model, client) + toDelete, toForceDelete, err := getNextOperations(testCtx, tt.model, newAPIMockClient(tt.mockClientSettings)) if err != nil { if !tt.isValid { return diff --git a/internal/cmd/postgresflex/instance/describe/describe.go b/internal/cmd/postgresflex/instance/describe/describe.go index c97762a76..8a3b277c4 100644 --- a/internal/cmd/postgresflex/instance/describe/describe.go +++ b/internal/cmd/postgresflex/instance/describe/describe.go @@ -20,7 +20,7 @@ import ( "github.com/stackitcloud/stackit-cli/internal/pkg/utils" "github.com/spf13/cobra" - "github.com/stackitcloud/stackit-sdk-go/services/postgresflex" + postgresflex "github.com/stackitcloud/stackit-sdk-go/services/postgresflex/v2api" ) const ( @@ -89,18 +89,18 @@ func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inpu } func buildRequest(ctx context.Context, model *inputModel, apiClient *postgresflex.APIClient) postgresflex.ApiGetInstanceRequest { - req := apiClient.GetInstance(ctx, model.ProjectId, model.Region, model.InstanceId) + req := apiClient.DefaultAPI.GetInstance(ctx, model.ProjectId, model.Region, model.InstanceId) return req } func outputResult(p *print.Printer, outputFormat string, instance *postgresflex.Instance) error { - if instance == nil { - return fmt.Errorf("no response passed") - } return p.OutputResult(outputFormat, instance, func() error { + if instance == nil { + return fmt.Errorf("no response passed") + } acls := "" if instance.HasAcl() && instance.Acl.HasItems() { - acls = utils.JoinStringPtr(instance.Acl.Items, ",") + acls = utils.JoinStringPtr(&instance.Acl.Items, ",") } instanceType, err := postgresflexUtils.GetInstanceType(utils.PtrValue(instance.Replicas)) diff --git a/internal/cmd/postgresflex/instance/describe/describe_test.go b/internal/cmd/postgresflex/instance/describe/describe_test.go index 026940b76..487343136 100644 --- a/internal/cmd/postgresflex/instance/describe/describe_test.go +++ b/internal/cmd/postgresflex/instance/describe/describe_test.go @@ -7,7 +7,7 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" "github.com/google/uuid" - "github.com/stackitcloud/stackit-sdk-go/services/postgresflex" + postgresflex "github.com/stackitcloud/stackit-sdk-go/services/postgresflex/v2api" "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/testparams" @@ -17,7 +17,7 @@ import ( type testCtxKey struct{} var testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") -var testClient = &postgresflex.APIClient{} +var testClient = &postgresflex.APIClient{DefaultAPI: &postgresflex.DefaultAPIService{}} var testProjectId = uuid.NewString() var testInstanceId = uuid.NewString() var testRegion = "eu01" @@ -59,7 +59,7 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { } func fixtureRequest(mods ...func(request *postgresflex.ApiGetInstanceRequest)) postgresflex.ApiGetInstanceRequest { - request := testClient.GetInstance(testCtx, testProjectId, testRegion, testInstanceId) + request := testClient.DefaultAPI.GetInstance(testCtx, testProjectId, testRegion, testInstanceId) for _, mod := range mods { mod(&request) } @@ -163,7 +163,7 @@ func TestBuildRequest(t *testing.T) { diff := cmp.Diff(request, tt.expectedRequest, cmp.AllowUnexported(tt.expectedRequest), - cmpopts.EquateComparable(testCtx), + cmpopts.EquateComparable(testCtx, postgresflex.DefaultAPIService{}), ) if diff != "" { t.Fatalf("Data does not match: %s", diff) @@ -191,7 +191,7 @@ func Test_outputResult(t *testing.T) { outputFormat: "", instance: &postgresflex.Instance{ Acl: &postgresflex.ACL{ - Items: &[]string{}, + Items: []string{}, }, BackupSchedule: new(string), Flavor: &postgresflex.Flavor{ @@ -203,7 +203,7 @@ func Test_outputResult(t *testing.T) { Id: new(string), Name: new(string), Options: &map[string]string{}, - Replicas: new(int64), + Replicas: new(int32), Status: new(string), Storage: &postgresflex.Storage{ Class: new(string), diff --git a/internal/cmd/postgresflex/instance/list/list.go b/internal/cmd/postgresflex/instance/list/list.go index 9f1b0f690..fe8e06423 100644 --- a/internal/cmd/postgresflex/instance/list/list.go +++ b/internal/cmd/postgresflex/instance/list/list.go @@ -7,7 +7,7 @@ import ( "github.com/stackitcloud/stackit-cli/internal/pkg/types" "github.com/spf13/cobra" - "github.com/stackitcloud/stackit-sdk-go/services/postgresflex" + postgresflex "github.com/stackitcloud/stackit-sdk-go/services/postgresflex/v2api" "golang.org/x/text/cases" "golang.org/x/text/language" @@ -68,7 +68,7 @@ func NewCmd(params *types.CmdParams) *cobra.Command { if err != nil { return fmt.Errorf("get PostgreSQL Flex instances: %w", err) } - if resp.Items == nil || len(*resp.Items) == 0 { + if len(resp.Items) == 0 { projectLabel, err := projectname.GetProjectName(ctx, params.Printer, params.CliVersion, cmd) if err != nil { params.Printer.Debug(print.ErrorLevel, "get project name: %v", err) @@ -77,7 +77,7 @@ func NewCmd(params *types.CmdParams) *cobra.Command { params.Printer.Info("No instances found for project %q\n", projectLabel) return nil } - instances := *resp.Items + instances := resp.Items // Truncate output if model.Limit != nil && len(instances) > int(*model.Limit) { @@ -120,7 +120,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command, _ []string) (*inputModel, } func buildRequest(ctx context.Context, model *inputModel, apiClient *postgresflex.APIClient) postgresflex.ApiListInstancesRequest { - req := apiClient.ListInstances(ctx, model.ProjectId, model.Region) + req := apiClient.DefaultAPI.ListInstances(ctx, model.ProjectId, model.Region) return req } diff --git a/internal/cmd/postgresflex/instance/list/list_test.go b/internal/cmd/postgresflex/instance/list/list_test.go index 87d9d9111..1a7c68ccb 100644 --- a/internal/cmd/postgresflex/instance/list/list_test.go +++ b/internal/cmd/postgresflex/instance/list/list_test.go @@ -7,7 +7,7 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" "github.com/google/uuid" - "github.com/stackitcloud/stackit-sdk-go/services/postgresflex" + postgresflex "github.com/stackitcloud/stackit-sdk-go/services/postgresflex/v2api" "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/testparams" @@ -18,7 +18,7 @@ import ( type testCtxKey struct{} var testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") -var testClient = &postgresflex.APIClient{} +var testClient = &postgresflex.APIClient{DefaultAPI: &postgresflex.DefaultAPIService{}} var testProjectId = uuid.NewString() var testRegion = "eu01" @@ -50,7 +50,7 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { } func fixtureRequest(mods ...func(request *postgresflex.ApiListInstancesRequest)) postgresflex.ApiListInstancesRequest { - request := testClient.ListInstances(testCtx, testProjectId, testRegion) + request := testClient.DefaultAPI.ListInstances(testCtx, testProjectId, testRegion) for _, mod := range mods { mod(&request) } @@ -139,7 +139,7 @@ func TestBuildRequest(t *testing.T) { diff := cmp.Diff(request, tt.expectedRequest, cmp.AllowUnexported(tt.expectedRequest), - cmpopts.EquateComparable(testCtx), + cmpopts.EquateComparable(testCtx, postgresflex.DefaultAPIService{}), ) if diff != "" { t.Fatalf("Data does not match: %s", diff) diff --git a/internal/cmd/postgresflex/instance/update/update.go b/internal/cmd/postgresflex/instance/update/update.go index fc2bc8986..aaeedd410 100644 --- a/internal/cmd/postgresflex/instance/update/update.go +++ b/internal/cmd/postgresflex/instance/update/update.go @@ -19,8 +19,8 @@ import ( "github.com/stackitcloud/stackit-cli/internal/pkg/utils" "github.com/spf13/cobra" - "github.com/stackitcloud/stackit-sdk-go/services/postgresflex" - "github.com/stackitcloud/stackit-sdk-go/services/postgresflex/wait" + postgresflex "github.com/stackitcloud/stackit-sdk-go/services/postgresflex/v2api" + wait "github.com/stackitcloud/stackit-sdk-go/services/postgresflex/v2api/wait" ) const ( @@ -48,7 +48,7 @@ type inputModel struct { InstanceId string InstanceName *string - ACL *[]string + ACL []string BackupSchedule *string FlavorId *string CPU *int64 @@ -87,7 +87,7 @@ func NewCmd(params *types.CmdParams) *cobra.Command { return err } - instanceLabel, err := postgresflexUtils.GetInstanceName(ctx, apiClient, model.ProjectId, model.Region, model.InstanceId) + instanceLabel, err := postgresflexUtils.GetInstanceName(ctx, apiClient.DefaultAPI, model.ProjectId, model.Region, model.InstanceId) if err != nil { params.Printer.Debug(print.ErrorLevel, "get instance name: %v", err) instanceLabel = model.InstanceId @@ -100,7 +100,7 @@ func NewCmd(params *types.CmdParams) *cobra.Command { } // Call API - req, err := buildRequest(ctx, model, apiClient) + req, err := buildRequest(ctx, model, apiClient.DefaultAPI) if err != nil { return err } @@ -113,7 +113,7 @@ func NewCmd(params *types.CmdParams) *cobra.Command { // Wait for async operation, if async mode not enabled if !model.Async { err := spinner.Run(params.Printer, "Updating instance", func() error { - _, err = wait.PartialUpdateInstanceWaitHandler(ctx, apiClient, model.ProjectId, model.Region, instanceId).WaitWithContext(ctx) + _, err = wait.PartialUpdateInstanceWaitHandler(ctx, apiClient.DefaultAPI, model.ProjectId, model.Region, instanceId).WaitWithContext(ctx) return err }) if err != nil { @@ -153,7 +153,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inpu flavorId := flags.FlagToStringPointer(p, cmd, flavorIdFlag) cpu := flags.FlagToInt64Pointer(p, cmd, cpuFlag) ram := flags.FlagToInt64Pointer(p, cmd, ramFlag) - acl := flags.FlagToStringSlicePointer(p, cmd, aclFlag) + acl := flags.FlagToStringSliceValue(p, cmd, aclFlag) backupSchedule := flags.FlagToStringPointer(p, cmd, backupScheduleFlag) storageClass := flags.FlagToStringPointer(p, cmd, storageClassFlag) storageSize := flags.FlagToInt64Pointer(p, cmd, storageSizeFlag) @@ -191,20 +191,13 @@ func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inpu return &model, nil } -type PostgreSQLFlexClient interface { - PartialUpdateInstance(ctx context.Context, projectId, region, instanceId string) postgresflex.ApiPartialUpdateInstanceRequest - GetInstanceExecute(ctx context.Context, projectId, region, instanceId string) (*postgresflex.InstanceResponse, error) - ListFlavorsExecute(ctx context.Context, projectId, region string) (*postgresflex.ListFlavorsResponse, error) - ListStoragesExecute(ctx context.Context, projectId, region, flavorId string) (*postgresflex.ListStoragesResponse, error) -} - -func buildRequest(ctx context.Context, model *inputModel, apiClient PostgreSQLFlexClient) (postgresflex.ApiPartialUpdateInstanceRequest, error) { +func buildRequest(ctx context.Context, model *inputModel, apiClient postgresflex.DefaultAPI) (postgresflex.ApiPartialUpdateInstanceRequest, error) { req := apiClient.PartialUpdateInstance(ctx, model.ProjectId, model.Region, model.InstanceId) var flavorId *string var err error - flavors, err := apiClient.ListFlavorsExecute(ctx, model.ProjectId, model.Region) + flavors, err := apiClient.ListFlavors(ctx, model.ProjectId, model.Region).Execute() if err != nil { return req, fmt.Errorf("get PostgreSQL Flex flavors: %w", err) } @@ -213,7 +206,7 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient PostgreSQLFl ram := model.RAM cpu := model.CPU if model.RAM == nil || model.CPU == nil { - currentInstance, err := apiClient.GetInstanceExecute(ctx, model.ProjectId, model.Region, model.InstanceId) + currentInstance, err := apiClient.GetInstance(ctx, model.ProjectId, model.Region, model.InstanceId).Execute() if err != nil { return req, fmt.Errorf("get PostgreSQL Flex instance: %w", err) } @@ -244,13 +237,13 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient PostgreSQLFl if model.StorageClass != nil || model.StorageSize != nil { validationFlavorId := flavorId if validationFlavorId == nil { - currentInstance, err := apiClient.GetInstanceExecute(ctx, model.ProjectId, model.Region, model.InstanceId) + currentInstance, err := apiClient.GetInstance(ctx, model.ProjectId, model.Region, model.InstanceId).Execute() if err != nil { return req, fmt.Errorf("get PostgreSQL Flex instance: %w", err) } validationFlavorId = currentInstance.Item.Flavor.Id } - storages, err = apiClient.ListStoragesExecute(ctx, model.ProjectId, model.Region, *validationFlavorId) + storages, err = apiClient.ListStorages(ctx, model.ProjectId, model.Region, *validationFlavorId).Execute() if err != nil { return req, fmt.Errorf("get PostgreSQL Flex storages: %w", err) } @@ -273,7 +266,7 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient PostgreSQLFl } } - var replicas *int64 + var replicas *int32 var payloadOptions *map[string]string if model.Type != nil { replicasInt, err := postgresflexUtils.GetInstanceReplicas(*model.Type) diff --git a/internal/cmd/postgresflex/instance/update/update_test.go b/internal/cmd/postgresflex/instance/update/update_test.go index 401348b92..1cb0b5aff 100644 --- a/internal/cmd/postgresflex/instance/update/update_test.go +++ b/internal/cmd/postgresflex/instance/update/update_test.go @@ -8,7 +8,7 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" "github.com/google/uuid" - "github.com/stackitcloud/stackit-sdk-go/services/postgresflex" + postgresflex "github.com/stackitcloud/stackit-sdk-go/services/postgresflex/v2api" "github.com/stackitcloud/stackit-cli/internal/pkg/testparams" @@ -19,41 +19,38 @@ import ( type testCtxKey struct{} var testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") -var testClient = &postgresflex.APIClient{} +var testClient = &postgresflex.APIClient{DefaultAPI: &postgresflex.DefaultAPIService{}} var testRegion = "eu01" -type postgresFlexClientMocked struct { - listFlavorsFails bool - listFlavorsResp *postgresflex.ListFlavorsResponse - listStoragesFails bool - listStoragesResp *postgresflex.ListStoragesResponse - getInstanceFails bool - getInstanceResp *postgresflex.InstanceResponse +type mockSettings struct { + listFlavorsFails bool + listFlavorsResp *postgresflex.ListFlavorsResponse + listStoragesResp *postgresflex.ListStoragesResponse + getInstanceFails bool + getInstanceResp *postgresflex.InstanceResponse } -func (c *postgresFlexClientMocked) PartialUpdateInstance(ctx context.Context, projectId, region, instanceId string) postgresflex.ApiPartialUpdateInstanceRequest { - return testClient.PartialUpdateInstance(ctx, projectId, region, instanceId) -} - -func (c *postgresFlexClientMocked) GetInstanceExecute(_ context.Context, _, _, _ string) (*postgresflex.InstanceResponse, error) { - if c.getInstanceFails { - return nil, fmt.Errorf("get instance failed") - } - return c.getInstanceResp, nil -} - -func (c *postgresFlexClientMocked) ListStoragesExecute(_ context.Context, _, _, _ string) (*postgresflex.ListStoragesResponse, error) { - if c.listFlavorsFails { - return nil, fmt.Errorf("list storages failed") - } - return c.listStoragesResp, nil -} - -func (c *postgresFlexClientMocked) ListFlavorsExecute(_ context.Context, _, _ string) (*postgresflex.ListFlavorsResponse, error) { - if c.listFlavorsFails { - return nil, fmt.Errorf("list flavors failed") +func newAPIClientMock(c mockSettings) postgresflex.DefaultAPI { + return postgresflex.DefaultAPIServiceMock{ + GetInstanceExecuteMock: utils.Ptr(func(_ postgresflex.ApiGetInstanceRequest) (*postgresflex.InstanceResponse, error) { + if c.getInstanceFails { + return nil, fmt.Errorf("get instance failed") + } + return c.getInstanceResp, nil + }), + ListStoragesExecuteMock: utils.Ptr(func(_ postgresflex.ApiListStoragesRequest) (*postgresflex.ListStoragesResponse, error) { + if c.listFlavorsFails { + return nil, fmt.Errorf("list storages failed") + } + return c.listStoragesResp, nil + }), + ListFlavorsExecuteMock: utils.Ptr(func(_ postgresflex.ApiListFlavorsRequest) (*postgresflex.ListFlavorsResponse, error) { + if c.listFlavorsFails { + return nil, fmt.Errorf("list flavors failed") + } + return c.listFlavorsResp, nil + }), } - return c.listFlavorsResp, nil } var testProjectId = uuid.NewString() @@ -125,7 +122,7 @@ func fixtureStandardInputModel(mods ...func(model *inputModel)) *inputModel { InstanceId: testInstanceId, FlavorId: utils.Ptr(testFlavorId), InstanceName: utils.Ptr("example-name"), - ACL: utils.Ptr([]string{"0.0.0.0/0"}), + ACL: []string{"0.0.0.0/0"}, BackupSchedule: utils.Ptr("0 0 * * *"), StorageClass: utils.Ptr("class"), StorageSize: utils.Ptr(int64(10)), @@ -139,7 +136,7 @@ func fixtureStandardInputModel(mods ...func(model *inputModel)) *inputModel { } func fixtureRequest(mods ...func(request *postgresflex.ApiPartialUpdateInstanceRequest)) postgresflex.ApiPartialUpdateInstanceRequest { - request := testClient.PartialUpdateInstance(testCtx, testProjectId, testRegion, testInstanceId) + request := testClient.DefaultAPI.PartialUpdateInstance(testCtx, testProjectId, testRegion, testInstanceId) request = request.PartialUpdateInstancePayload(postgresflex.PartialUpdateInstancePayload{}) for _, mod := range mods { mod(&request) @@ -276,7 +273,7 @@ func TestParseInput(t *testing.T) { aclValues: []string{"198.51.100.14/24", "198.51.100.14/32"}, isValid: true, expectedModel: fixtureRequiredInputModel(func(model *inputModel) { - model.ACL = utils.Ptr([]string{"198.51.100.14/24", "198.51.100.14/32"}) + model.ACL = []string{"198.51.100.14/24", "198.51.100.14/32"} }), }, } @@ -348,16 +345,11 @@ func TestParseInput(t *testing.T) { func TestBuildRequest(t *testing.T) { tests := []struct { - description string - model *inputModel - expectedRequest postgresflex.ApiPartialUpdateInstanceRequest - getInstanceFails bool - getInstanceResp *postgresflex.InstanceResponse - listFlavorsFails bool - listFlavorsResp *postgresflex.ListFlavorsResponse - listStoragesFails bool - listStoragesResp *postgresflex.ListStoragesResponse - isValid bool + description string + model *inputModel + expectedRequest postgresflex.ApiPartialUpdateInstanceRequest + mockClientSettings mockSettings + isValid bool }{ { description: "no values", @@ -371,16 +363,18 @@ func TestBuildRequest(t *testing.T) { model.FlavorId = utils.Ptr(testFlavorId) }), isValid: true, - listFlavorsResp: &postgresflex.ListFlavorsResponse{ - Flavors: &[]postgresflex.Flavor{ - { - Id: utils.Ptr(testFlavorId), - Cpu: utils.Ptr(int64(2)), - Memory: utils.Ptr(int64(4)), + mockClientSettings: mockSettings{ + listFlavorsResp: &postgresflex.ListFlavorsResponse{ + Flavors: []postgresflex.Flavor{ + { + Id: utils.Ptr(testFlavorId), + Cpu: utils.Ptr(int64(2)), + Memory: utils.Ptr(int64(4)), + }, }, }, }, - expectedRequest: testClient.PartialUpdateInstance(testCtx, testProjectId, testRegion, testInstanceId). + expectedRequest: testClient.DefaultAPI.PartialUpdateInstance(testCtx, testProjectId, testRegion, testInstanceId). PartialUpdateInstancePayload(postgresflex.PartialUpdateInstancePayload{ FlavorId: utils.Ptr(testFlavorId), }), @@ -392,16 +386,18 @@ func TestBuildRequest(t *testing.T) { model.RAM = utils.Ptr(int64(4)) }), isValid: true, - listFlavorsResp: &postgresflex.ListFlavorsResponse{ - Flavors: &[]postgresflex.Flavor{ - { - Id: utils.Ptr(testFlavorId), - Cpu: utils.Ptr(int64(2)), - Memory: utils.Ptr(int64(4)), + mockClientSettings: mockSettings{ + listFlavorsResp: &postgresflex.ListFlavorsResponse{ + Flavors: []postgresflex.Flavor{ + { + Id: utils.Ptr(testFlavorId), + Cpu: utils.Ptr(int64(2)), + Memory: utils.Ptr(int64(4)), + }, }, }, }, - expectedRequest: testClient.PartialUpdateInstance(testCtx, testProjectId, testRegion, testInstanceId). + expectedRequest: testClient.DefaultAPI.PartialUpdateInstance(testCtx, testProjectId, testRegion, testInstanceId). PartialUpdateInstancePayload(postgresflex.PartialUpdateInstancePayload{ FlavorId: utils.Ptr(testFlavorId), }), @@ -412,21 +408,23 @@ func TestBuildRequest(t *testing.T) { model.StorageClass = utils.Ptr("class") }), isValid: true, - getInstanceResp: &postgresflex.InstanceResponse{ - Item: &postgresflex.Instance{ - Flavor: &postgresflex.Flavor{ - Id: utils.Ptr(testFlavorId), + mockClientSettings: mockSettings{ + getInstanceResp: &postgresflex.InstanceResponse{ + Item: &postgresflex.Instance{ + Flavor: &postgresflex.Flavor{ + Id: utils.Ptr(testFlavorId), + }, }, }, - }, - listStoragesResp: &postgresflex.ListStoragesResponse{ - StorageClasses: &[]string{"class"}, - StorageRange: &postgresflex.StorageRange{ - Min: utils.Ptr(int64(10)), - Max: utils.Ptr(int64(100)), + listStoragesResp: &postgresflex.ListStoragesResponse{ + StorageClasses: []string{"class"}, + StorageRange: &postgresflex.StorageRange{ + Min: utils.Ptr(int64(10)), + Max: utils.Ptr(int64(100)), + }, }, }, - expectedRequest: testClient.PartialUpdateInstance(testCtx, testProjectId, testRegion, testInstanceId). + expectedRequest: testClient.DefaultAPI.PartialUpdateInstance(testCtx, testProjectId, testRegion, testInstanceId). PartialUpdateInstancePayload(postgresflex.PartialUpdateInstancePayload{ Storage: &postgresflex.StorageUpdate{ Class: utils.Ptr("class"), @@ -440,21 +438,23 @@ func TestBuildRequest(t *testing.T) { model.StorageSize = utils.Ptr(int64(10)) }), isValid: true, - getInstanceResp: &postgresflex.InstanceResponse{ - Item: &postgresflex.Instance{ - Flavor: &postgresflex.Flavor{ - Id: utils.Ptr(testFlavorId), + mockClientSettings: mockSettings{ + getInstanceResp: &postgresflex.InstanceResponse{ + Item: &postgresflex.Instance{ + Flavor: &postgresflex.Flavor{ + Id: utils.Ptr(testFlavorId), + }, }, }, - }, - listStoragesResp: &postgresflex.ListStoragesResponse{ - StorageClasses: &[]string{"class"}, - StorageRange: &postgresflex.StorageRange{ - Min: utils.Ptr(int64(10)), - Max: utils.Ptr(int64(100)), + listStoragesResp: &postgresflex.ListStoragesResponse{ + StorageClasses: []string{"class"}, + StorageRange: &postgresflex.StorageRange{ + Min: utils.Ptr(int64(10)), + Max: utils.Ptr(int64(100)), + }, }, }, - expectedRequest: testClient.PartialUpdateInstance(testCtx, testProjectId, testRegion, testInstanceId). + expectedRequest: testClient.DefaultAPI.PartialUpdateInstance(testCtx, testProjectId, testRegion, testInstanceId). PartialUpdateInstancePayload(postgresflex.PartialUpdateInstancePayload{ Storage: &postgresflex.StorageUpdate{ Class: utils.Ptr("class"), @@ -470,8 +470,10 @@ func TestBuildRequest(t *testing.T) { model.RAM = utils.Ptr(int64(4)) }, ), - listFlavorsFails: true, - isValid: false, + mockClientSettings: mockSettings{ + listFlavorsFails: true, + }, + isValid: false, }, { description: "flavor id not found", @@ -481,17 +483,19 @@ func TestBuildRequest(t *testing.T) { model.RAM = utils.Ptr(int64(9)) }, ), - listFlavorsResp: &postgresflex.ListFlavorsResponse{ - Flavors: &[]postgresflex.Flavor{ - { - Id: utils.Ptr(testFlavorId), - Cpu: utils.Ptr(int64(2)), - Memory: utils.Ptr(int64(4)), - }, - { - Id: utils.Ptr("other-flavor"), - Cpu: utils.Ptr(int64(1)), - Memory: utils.Ptr(int64(8)), + mockClientSettings: mockSettings{ + listFlavorsResp: &postgresflex.ListFlavorsResponse{ + Flavors: []postgresflex.Flavor{ + { + Id: utils.Ptr(testFlavorId), + Cpu: utils.Ptr(int64(2)), + Memory: utils.Ptr(int64(4)), + }, + { + Id: utils.Ptr("other-flavor"), + Cpu: utils.Ptr(int64(1)), + Memory: utils.Ptr(int64(8)), + }, }, }, }, @@ -504,8 +508,10 @@ func TestBuildRequest(t *testing.T) { model.StorageClass = utils.Ptr("class") }, ), - getInstanceFails: true, - isValid: false, + mockClientSettings: mockSettings{ + getInstanceFails: true, + }, + isValid: false, }, { description: "get storages fails", @@ -516,8 +522,10 @@ func TestBuildRequest(t *testing.T) { model.RAM = utils.Ptr(int64(4)) }, ), - listFlavorsFails: true, - isValid: false, + mockClientSettings: mockSettings{ + listFlavorsFails: true, + }, + isValid: false, }, { description: "invalid storage class", @@ -526,18 +534,20 @@ func TestBuildRequest(t *testing.T) { model.StorageClass = utils.Ptr("non-existing-class") }, ), - getInstanceResp: &postgresflex.InstanceResponse{ - Item: &postgresflex.Instance{ - Flavor: &postgresflex.Flavor{ - Id: utils.Ptr(testFlavorId), + mockClientSettings: mockSettings{ + getInstanceResp: &postgresflex.InstanceResponse{ + Item: &postgresflex.Instance{ + Flavor: &postgresflex.Flavor{ + Id: utils.Ptr(testFlavorId), + }, }, }, - }, - listStoragesResp: &postgresflex.ListStoragesResponse{ - StorageClasses: &[]string{"class"}, - StorageRange: &postgresflex.StorageRange{ - Min: utils.Ptr(int64(10)), - Max: utils.Ptr(int64(100)), + listStoragesResp: &postgresflex.ListStoragesResponse{ + StorageClasses: []string{"class"}, + StorageRange: &postgresflex.StorageRange{ + Min: utils.Ptr(int64(10)), + Max: utils.Ptr(int64(100)), + }, }, }, isValid: false, @@ -549,18 +559,20 @@ func TestBuildRequest(t *testing.T) { model.StorageSize = utils.Ptr(int64(9)) }, ), - getInstanceResp: &postgresflex.InstanceResponse{ - Item: &postgresflex.Instance{ - Flavor: &postgresflex.Flavor{ - Id: utils.Ptr(testFlavorId), + mockClientSettings: mockSettings{ + getInstanceResp: &postgresflex.InstanceResponse{ + Item: &postgresflex.Instance{ + Flavor: &postgresflex.Flavor{ + Id: utils.Ptr(testFlavorId), + }, }, }, - }, - listStoragesResp: &postgresflex.ListStoragesResponse{ - StorageClasses: &[]string{"class"}, - StorageRange: &postgresflex.StorageRange{ - Min: utils.Ptr(int64(10)), - Max: utils.Ptr(int64(100)), + listStoragesResp: &postgresflex.ListStoragesResponse{ + StorageClasses: []string{"class"}, + StorageRange: &postgresflex.StorageRange{ + Min: utils.Ptr(int64(10)), + Max: utils.Ptr(int64(100)), + }, }, }, isValid: false, @@ -569,15 +581,7 @@ func TestBuildRequest(t *testing.T) { for _, tt := range tests { t.Run(tt.description, func(t *testing.T) { - client := &postgresFlexClientMocked{ - getInstanceFails: tt.getInstanceFails, - getInstanceResp: tt.getInstanceResp, - listFlavorsFails: tt.listFlavorsFails, - listFlavorsResp: tt.listFlavorsResp, - listStoragesFails: tt.listStoragesFails, - listStoragesResp: tt.listStoragesResp, - } - request, err := buildRequest(testCtx, tt.model, client) + request, err := buildRequest(testCtx, tt.model, newAPIClientMock(tt.mockClientSettings)) if err != nil { if !tt.isValid { return @@ -588,6 +592,7 @@ func TestBuildRequest(t *testing.T) { diff := cmp.Diff(request, tt.expectedRequest, cmp.AllowUnexported(tt.expectedRequest), cmpopts.EquateComparable(testCtx), + cmpopts.IgnoreFields(tt.expectedRequest, "ApiService"), ) if diff != "" { t.Fatalf("Data does not match: %s", diff) diff --git a/internal/cmd/postgresflex/options/options.go b/internal/cmd/postgresflex/options/options.go index e569b331e..9dd92b25b 100644 --- a/internal/cmd/postgresflex/options/options.go +++ b/internal/cmd/postgresflex/options/options.go @@ -7,7 +7,7 @@ import ( "github.com/stackitcloud/stackit-cli/internal/pkg/types" "github.com/spf13/cobra" - "github.com/stackitcloud/stackit-sdk-go/services/postgresflex" + postgresflex "github.com/stackitcloud/stackit-sdk-go/services/postgresflex/v2api" "github.com/stackitcloud/stackit-cli/internal/pkg/args" cliErr "github.com/stackitcloud/stackit-cli/internal/pkg/errors" @@ -37,9 +37,9 @@ type inputModel struct { } type options struct { - Flavors *[]postgresflex.Flavor `json:"flavors,omitempty"` - Versions *[]string `json:"versions,omitempty"` - Storages *flavorStorages `json:"flavorStorages,omitempty"` + Flavors []postgresflex.Flavor `json:"flavors,omitempty"` + Versions []string `json:"versions,omitempty"` + Storages *flavorStorages `json:"flavorStorages,omitempty"` } type flavorStorages struct { @@ -78,7 +78,7 @@ func NewCmd(params *types.CmdParams) *cobra.Command { } // Call API - err = buildAndExecuteRequest(ctx, params.Printer, model, apiClient) + err = buildAndExecuteRequest(ctx, params.Printer, model, apiClient.DefaultAPI) if err != nil { return fmt.Errorf("get PostgreSQL Flex options: %w", err) } @@ -132,32 +132,26 @@ func parseInput(p *print.Printer, cmd *cobra.Command, _ []string) (*inputModel, return &model, nil } -type postgresFlexOptionsClient interface { - ListFlavorsExecute(ctx context.Context, projectId, region string) (*postgresflex.ListFlavorsResponse, error) - ListVersionsExecute(ctx context.Context, projectId, region string) (*postgresflex.ListVersionsResponse, error) - ListStoragesExecute(ctx context.Context, projectId, region, flavorId string) (*postgresflex.ListStoragesResponse, error) -} - -func buildAndExecuteRequest(ctx context.Context, p *print.Printer, model *inputModel, apiClient postgresFlexOptionsClient) error { +func buildAndExecuteRequest(ctx context.Context, p *print.Printer, model *inputModel, apiClient postgresflex.DefaultAPI) error { var flavors *postgresflex.ListFlavorsResponse var versions *postgresflex.ListVersionsResponse var storages *postgresflex.ListStoragesResponse var err error if model.Flavors { - flavors, err = apiClient.ListFlavorsExecute(ctx, model.ProjectId, model.Region) + flavors, err = apiClient.ListFlavors(ctx, model.ProjectId, model.Region).Execute() if err != nil { return fmt.Errorf("get PostgreSQL Flex flavors: %w", err) } } if model.Versions { - versions, err = apiClient.ListVersionsExecute(ctx, model.ProjectId, model.Region) + versions, err = apiClient.ListVersions(ctx, model.ProjectId, model.Region).Execute() if err != nil { return fmt.Errorf("get PostgreSQL Flex versions: %w", err) } } if model.Storages { - storages, err = apiClient.ListStoragesExecute(ctx, model.ProjectId, model.Region, *model.FlavorId) + storages, err = apiClient.ListStorages(ctx, model.ProjectId, model.Region, *model.FlavorId).Execute() if err != nil { return fmt.Errorf("get PostgreSQL Flex storages: %w", err) } @@ -186,13 +180,13 @@ func outputResult(p *print.Printer, model inputModel, flavors *postgresflex.List return p.OutputResult(model.OutputFormat, options, func() error { content := []tables.Table{} - if model.Flavors && len(*options.Flavors) != 0 { - content = append(content, buildFlavorsTable(*options.Flavors)) + if model.Flavors && len(options.Flavors) != 0 { + content = append(content, buildFlavorsTable(options.Flavors)) } - if model.Versions && len(*options.Versions) != 0 { - content = append(content, buildVersionsTable(*options.Versions)) + if model.Versions && len(options.Versions) != 0 { + content = append(content, buildVersionsTable(options.Versions)) } - if model.Storages && options.Storages.Storages != nil && len(*options.Storages.Storages.StorageClasses) > 0 { + if model.Storages && options.Storages.Storages != nil && len(options.Storages.Storages.StorageClasses) > 0 { content = append(content, buildStoragesTable(*options.Storages.Storages)) } @@ -233,12 +227,11 @@ func buildVersionsTable(versions []string) tables.Table { } func buildStoragesTable(storagesResp postgresflex.ListStoragesResponse) tables.Table { - storages := *storagesResp.StorageClasses table := tables.NewTable() table.SetTitle("Storages") table.SetHeader("MINIMUM", "MAXIMUM", "STORAGE CLASS") - for i := range storages { - sc := storages[i] + for i := range storagesResp.StorageClasses { + sc := storagesResp.StorageClasses[i] table.AddRow( utils.PtrString(storagesResp.StorageRange.Min), utils.PtrString(storagesResp.StorageRange.Max), diff --git a/internal/cmd/postgresflex/options/options_test.go b/internal/cmd/postgresflex/options/options_test.go index b42f3bfe0..f2798225f 100644 --- a/internal/cmd/postgresflex/options/options_test.go +++ b/internal/cmd/postgresflex/options/options_test.go @@ -6,7 +6,7 @@ import ( "testing" "github.com/google/uuid" - "github.com/stackitcloud/stackit-sdk-go/services/postgresflex" + postgresflex "github.com/stackitcloud/stackit-sdk-go/services/postgresflex/v2api" "github.com/stackitcloud/stackit-cli/internal/pkg/testparams" @@ -20,7 +20,7 @@ type testCtxKey struct{} var testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") var testProjectId = uuid.NewString() -type postgresFlexClientMocked struct { +type mockSettings struct { listFlavorsFails bool listVersionsFails bool listStoragesFails bool @@ -30,38 +30,40 @@ type postgresFlexClientMocked struct { listStoragesCalled bool } -func (c *postgresFlexClientMocked) ListFlavorsExecute(_ context.Context, _, _ string) (*postgresflex.ListFlavorsResponse, error) { - c.listFlavorsCalled = true - if c.listFlavorsFails { - return nil, fmt.Errorf("list flavors failed") - } - return utils.Ptr(postgresflex.ListFlavorsResponse{ - Flavors: utils.Ptr([]postgresflex.Flavor{}), - }), nil -} - -func (c *postgresFlexClientMocked) ListVersionsExecute(_ context.Context, _, _ string) (*postgresflex.ListVersionsResponse, error) { - c.listVersionsCalled = true - if c.listVersionsFails { - return nil, fmt.Errorf("list versions failed") - } - return utils.Ptr(postgresflex.ListVersionsResponse{ - Versions: utils.Ptr([]string{}), - }), nil -} - -func (c *postgresFlexClientMocked) ListStoragesExecute(_ context.Context, _, _, _ string) (*postgresflex.ListStoragesResponse, error) { - c.listStoragesCalled = true - if c.listStoragesFails { - return nil, fmt.Errorf("list storages failed") +func newAPIClientMock(c *mockSettings) postgresflex.DefaultAPI { + return postgresflex.DefaultAPIServiceMock{ + ListFlavorsExecuteMock: utils.Ptr(func(_ postgresflex.ApiListFlavorsRequest) (*postgresflex.ListFlavorsResponse, error) { + c.listFlavorsCalled = true + if c.listFlavorsFails { + return nil, fmt.Errorf("list flavors failed") + } + return utils.Ptr(postgresflex.ListFlavorsResponse{ + Flavors: []postgresflex.Flavor{}, + }), nil + }), + ListVersionsExecuteMock: utils.Ptr(func(_ postgresflex.ApiListVersionsRequest) (*postgresflex.ListVersionsResponse, error) { + c.listVersionsCalled = true + if c.listVersionsFails { + return nil, fmt.Errorf("list versions failed") + } + return utils.Ptr(postgresflex.ListVersionsResponse{ + Versions: []string{}, + }), nil + }), + ListStoragesExecuteMock: utils.Ptr(func(_ postgresflex.ApiListStoragesRequest) (*postgresflex.ListStoragesResponse, error) { + c.listStoragesCalled = true + if c.listStoragesFails { + return nil, fmt.Errorf("list storages failed") + } + return utils.Ptr(postgresflex.ListStoragesResponse{ + StorageClasses: []string{}, + StorageRange: &postgresflex.StorageRange{ + Min: utils.Ptr(int64(10)), + Max: utils.Ptr(int64(100)), + }, + }), nil + }), } - return utils.Ptr(postgresflex.ListStoragesResponse{ - StorageClasses: utils.Ptr([]string{}), - StorageRange: &postgresflex.StorageRange{ - Min: utils.Ptr(int64(10)), - Max: utils.Ptr(int64(100)), - }, - }), nil } func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]string { @@ -187,9 +189,7 @@ func TestBuildAndExecuteRequest(t *testing.T) { description string model *inputModel isValid bool - listFlavorsFails bool - listVersionsFails bool - listStoragesFails bool + mockClientSettings mockSettings expectListFlavorsCalled bool expectListVersionsCalled bool expectListStoragesCalled bool @@ -232,28 +232,34 @@ func TestBuildAndExecuteRequest(t *testing.T) { expectListStoragesCalled: true, }, { - description: "list flavors fails", - model: fixtureInputModelAllTrue(), - isValid: false, - listFlavorsFails: true, + description: "list flavors fails", + model: fixtureInputModelAllTrue(), + isValid: false, + mockClientSettings: mockSettings{ + listFlavorsFails: true, + }, expectListFlavorsCalled: true, expectListVersionsCalled: false, expectListStoragesCalled: false, }, { - description: "list versions fails", - model: fixtureInputModelAllTrue(), - isValid: false, - listVersionsFails: true, + description: "list versions fails", + model: fixtureInputModelAllTrue(), + isValid: false, + mockClientSettings: mockSettings{ + listVersionsFails: true, + }, expectListFlavorsCalled: true, expectListVersionsCalled: true, expectListStoragesCalled: false, }, { - description: "list storages fails", - model: fixtureInputModelAllTrue(), - isValid: false, - listStoragesFails: true, + description: "list storages fails", + model: fixtureInputModelAllTrue(), + isValid: false, + mockClientSettings: mockSettings{ + listStoragesFails: true, + }, expectListFlavorsCalled: true, expectListVersionsCalled: true, expectListStoragesCalled: true, @@ -263,12 +269,7 @@ func TestBuildAndExecuteRequest(t *testing.T) { for _, tt := range tests { t.Run(tt.description, func(t *testing.T) { params := testparams.NewTestParams() - client := &postgresFlexClientMocked{ - listFlavorsFails: tt.listFlavorsFails, - listVersionsFails: tt.listVersionsFails, - listStoragesFails: tt.listStoragesFails, - } - + client := newAPIClientMock(&tt.mockClientSettings) err := buildAndExecuteRequest(testCtx, params.Printer, tt.model, client) if err != nil && tt.isValid { t.Fatalf("error building and executing request: %v", err) @@ -280,14 +281,14 @@ func TestBuildAndExecuteRequest(t *testing.T) { return } - if tt.expectListFlavorsCalled != client.listFlavorsCalled { - t.Fatalf("expected listFlavorsCalled to be %v, got %v", tt.expectListFlavorsCalled, client.listFlavorsCalled) + if tt.expectListFlavorsCalled != tt.mockClientSettings.listFlavorsCalled { + t.Fatalf("expected listFlavorsCalled to be %v, got %v", tt.expectListFlavorsCalled, tt.mockClientSettings.listFlavorsCalled) } - if tt.expectListVersionsCalled != client.listVersionsCalled { - t.Fatalf("expected listVersionsCalled to be %v, got %v", tt.expectListVersionsCalled, client.listVersionsCalled) + if tt.expectListVersionsCalled != tt.mockClientSettings.listVersionsCalled { + t.Fatalf("expected listVersionsCalled to be %v, got %v", tt.expectListVersionsCalled, tt.mockClientSettings.listVersionsCalled) } - if tt.expectListStoragesCalled != client.listStoragesCalled { - t.Fatalf("expected listStoragesCalled to be %v, got %v", tt.expectListStoragesCalled, client.listStoragesCalled) + if tt.expectListStoragesCalled != tt.mockClientSettings.listStoragesCalled { + t.Fatalf("expected listStoragesCalled to be %v, got %v", tt.expectListStoragesCalled, tt.mockClientSettings.listStoragesCalled) } }) } @@ -317,13 +318,13 @@ func Test_outputResult(t *testing.T) { args{ model: inputModel{GlobalFlagModel: &globalflags.GlobalFlagModel{}, Flavors: false, Versions: false, Storages: false, FlavorId: new(string)}, flavors: &postgresflex.ListFlavorsResponse{ - Flavors: &[]postgresflex.Flavor{}, + Flavors: []postgresflex.Flavor{}, }, versions: &postgresflex.ListVersionsResponse{ - Versions: &[]string{}, + Versions: []string{}, }, storages: &postgresflex.ListStoragesResponse{ - StorageClasses: &[]string{}, + StorageClasses: []string{}, StorageRange: &postgresflex.StorageRange{}, }, }, diff --git a/internal/cmd/postgresflex/user/create/create.go b/internal/cmd/postgresflex/user/create/create.go index c4742e2a0..3ea952b06 100644 --- a/internal/cmd/postgresflex/user/create/create.go +++ b/internal/cmd/postgresflex/user/create/create.go @@ -7,7 +7,7 @@ import ( "github.com/stackitcloud/stackit-cli/internal/pkg/types" "github.com/spf13/cobra" - "github.com/stackitcloud/stackit-sdk-go/services/postgresflex" + postgresflex "github.com/stackitcloud/stackit-sdk-go/services/postgresflex/v2api" "github.com/stackitcloud/stackit-cli/internal/pkg/args" "github.com/stackitcloud/stackit-cli/internal/pkg/errors" @@ -40,7 +40,7 @@ type inputModel struct { InstanceId string Username *string - Roles *[]string + Roles []string } func NewCmd(params *types.CmdParams) *cobra.Command { @@ -75,7 +75,7 @@ func NewCmd(params *types.CmdParams) *cobra.Command { return err } - instanceLabel, err := postgresflexUtils.GetInstanceName(ctx, apiClient, model.ProjectId, model.Region, model.InstanceId) + instanceLabel, err := postgresflexUtils.GetInstanceName(ctx, apiClient.DefaultAPI, model.ProjectId, model.Region, model.InstanceId) if err != nil { params.Printer.Debug(print.ErrorLevel, "get instance name: %v", err) instanceLabel = model.InstanceId @@ -121,7 +121,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command, _ []string) (*inputModel, GlobalFlagModel: globalFlags, InstanceId: flags.FlagToStringValue(p, cmd, instanceIdFlag), Username: flags.FlagToStringPointer(p, cmd, usernameFlag), - Roles: roleFlag.Ptr(), + Roles: roleFlag.Get(), } p.DebugInputModel(model) @@ -129,7 +129,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command, _ []string) (*inputModel, } func buildRequest(ctx context.Context, model *inputModel, apiClient *postgresflex.APIClient) postgresflex.ApiCreateUserRequest { - req := apiClient.CreateUser(ctx, model.ProjectId, model.Region, model.InstanceId) + req := apiClient.DefaultAPI.CreateUser(ctx, model.ProjectId, model.Region, model.InstanceId) req = req.CreateUserPayload(postgresflex.CreateUserPayload{ Username: model.Username, Roles: model.Roles, @@ -147,7 +147,7 @@ func outputResult(p *print.Printer, outputFormat, instanceLabel string, resp *po p.Outputf("Created user for instance %q. User ID: %s\n\n", instanceLabel, utils.PtrString(user.Id)) p.Outputf("Username: %s\n", utils.PtrString(user.Username)) p.Outputf("Password: %s\n", utils.PtrString(user.Password)) - p.Outputf("Roles: %v\n", utils.PtrString(user.Roles)) + p.Outputf("Roles: %v\n", user.Roles) p.Outputf("Host: %s\n", utils.PtrString(user.Host)) p.Outputf("Port: %s\n", utils.PtrString(user.Port)) p.Outputf("URI: %s\n", utils.PtrString(user.Uri)) diff --git a/internal/cmd/postgresflex/user/create/create_test.go b/internal/cmd/postgresflex/user/create/create_test.go index 2c9e50a7c..82bf6cec8 100644 --- a/internal/cmd/postgresflex/user/create/create_test.go +++ b/internal/cmd/postgresflex/user/create/create_test.go @@ -7,7 +7,7 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" "github.com/google/uuid" - "github.com/stackitcloud/stackit-sdk-go/services/postgresflex" + postgresflex "github.com/stackitcloud/stackit-sdk-go/services/postgresflex/v2api" "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/testparams" @@ -18,7 +18,7 @@ import ( type testCtxKey struct{} var testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") -var testClient = &postgresflex.APIClient{} +var testClient = &postgresflex.APIClient{DefaultAPI: &postgresflex.DefaultAPIService{}} var testProjectId = uuid.NewString() var testInstanceId = uuid.NewString() var testRegion = "eu01" @@ -46,7 +46,7 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { }, InstanceId: testInstanceId, Username: utils.Ptr("johndoe"), - Roles: utils.Ptr([]string{"login"}), + Roles: []string{"login"}, } for _, mod := range mods { mod(model) @@ -55,10 +55,10 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { } func fixtureRequest(mods ...func(request *postgresflex.ApiCreateUserRequest)) postgresflex.ApiCreateUserRequest { - request := testClient.CreateUser(testCtx, testProjectId, testRegion, testInstanceId) + request := testClient.DefaultAPI.CreateUser(testCtx, testProjectId, testRegion, testInstanceId) request = request.CreateUserPayload(postgresflex.CreateUserPayload{ Username: utils.Ptr("johndoe"), - Roles: utils.Ptr([]string{"login"}), + Roles: []string{"login"}, }) for _, mod := range mods { @@ -136,7 +136,7 @@ func TestParseInput(t *testing.T) { }), isValid: true, expectedModel: fixtureInputModel(func(model *inputModel) { - model.Roles = &rolesDefault + model.Roles = rolesDefault }), }, { @@ -172,7 +172,7 @@ func TestBuildRequest(t *testing.T) { model.Username = nil }), expectedRequest: fixtureRequest().CreateUserPayload(postgresflex.CreateUserPayload{ - Roles: utils.Ptr([]string{"login"}), + Roles: []string{"login"}, }), }, } @@ -183,7 +183,7 @@ func TestBuildRequest(t *testing.T) { diff := cmp.Diff(request, tt.expectedRequest, cmp.AllowUnexported(tt.expectedRequest), - cmpopts.EquateComparable(testCtx), + cmpopts.EquateComparable(testCtx, postgresflex.DefaultAPIService{}), ) if diff != "" { t.Fatalf("Data does not match: %s", diff) @@ -212,7 +212,7 @@ func Test_outputResult(t *testing.T) { Id: new(string), Password: new(string), Port: new(int64), - Roles: &[]string{}, + Roles: []string{}, Uri: new(string), Username: new(string), }, diff --git a/internal/cmd/postgresflex/user/delete/delete.go b/internal/cmd/postgresflex/user/delete/delete.go index d3646805a..f6667191c 100644 --- a/internal/cmd/postgresflex/user/delete/delete.go +++ b/internal/cmd/postgresflex/user/delete/delete.go @@ -16,7 +16,7 @@ import ( postgresflexUtils "github.com/stackitcloud/stackit-cli/internal/pkg/services/postgresflex/utils" "github.com/spf13/cobra" - "github.com/stackitcloud/stackit-sdk-go/services/postgresflex" + postgresflex "github.com/stackitcloud/stackit-sdk-go/services/postgresflex/v2api" ) const ( @@ -60,13 +60,13 @@ func NewCmd(params *types.CmdParams) *cobra.Command { return err } - instanceLabel, err := postgresflexUtils.GetInstanceName(ctx, apiClient, model.ProjectId, model.Region, model.InstanceId) + instanceLabel, err := postgresflexUtils.GetInstanceName(ctx, apiClient.DefaultAPI, model.ProjectId, model.Region, model.InstanceId) if err != nil { params.Printer.Debug(print.ErrorLevel, "get instance name: %v", err) instanceLabel = model.InstanceId } - userLabel, err := postgresflexUtils.GetUserName(ctx, apiClient, model.ProjectId, model.Region, model.InstanceId, model.UserId) + userLabel, err := postgresflexUtils.GetUserName(ctx, apiClient.DefaultAPI, model.ProjectId, model.Region, model.InstanceId, model.UserId) if err != nil { params.Printer.Debug(print.ErrorLevel, "get user name: %v", err) userLabel = model.UserId @@ -119,6 +119,6 @@ func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inpu } func buildRequest(ctx context.Context, model *inputModel, apiClient *postgresflex.APIClient) postgresflex.ApiDeleteUserRequest { - req := apiClient.DeleteUser(ctx, model.ProjectId, model.Region, model.InstanceId, model.UserId) + req := apiClient.DefaultAPI.DeleteUser(ctx, model.ProjectId, model.Region, model.InstanceId, model.UserId) return req } diff --git a/internal/cmd/postgresflex/user/delete/delete_test.go b/internal/cmd/postgresflex/user/delete/delete_test.go index a3ff66105..a91291466 100644 --- a/internal/cmd/postgresflex/user/delete/delete_test.go +++ b/internal/cmd/postgresflex/user/delete/delete_test.go @@ -10,13 +10,13 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" "github.com/google/uuid" - "github.com/stackitcloud/stackit-sdk-go/services/postgresflex" + postgresflex "github.com/stackitcloud/stackit-sdk-go/services/postgresflex/v2api" ) type testCtxKey struct{} var testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") -var testClient = &postgresflex.APIClient{} +var testClient = &postgresflex.APIClient{DefaultAPI: &postgresflex.DefaultAPIService{}} var testProjectId = uuid.NewString() var testInstanceId = uuid.NewString() var testUserId = "12345" @@ -61,7 +61,7 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { } func fixtureRequest(mods ...func(request *postgresflex.ApiDeleteUserRequest)) postgresflex.ApiDeleteUserRequest { - request := testClient.DeleteUser(testCtx, testProjectId, testRegion, testInstanceId, testUserId) + request := testClient.DefaultAPI.DeleteUser(testCtx, testProjectId, testRegion, testInstanceId, testUserId) for _, mod := range mods { mod(&request) } @@ -183,7 +183,7 @@ func TestBuildRequest(t *testing.T) { diff := cmp.Diff(request, tt.expectedRequest, cmp.AllowUnexported(tt.expectedRequest), - cmpopts.EquateComparable(testCtx), + cmpopts.EquateComparable(testCtx, postgresflex.DefaultAPIService{}), ) if diff != "" { t.Fatalf("Data does not match: %s", diff) diff --git a/internal/cmd/postgresflex/user/describe/describe.go b/internal/cmd/postgresflex/user/describe/describe.go index da2dac16a..17a68f2e0 100644 --- a/internal/cmd/postgresflex/user/describe/describe.go +++ b/internal/cmd/postgresflex/user/describe/describe.go @@ -7,7 +7,7 @@ import ( "github.com/stackitcloud/stackit-cli/internal/pkg/types" "github.com/spf13/cobra" - "github.com/stackitcloud/stackit-sdk-go/services/postgresflex" + postgresflex "github.com/stackitcloud/stackit-sdk-go/services/postgresflex/v2api" "github.com/stackitcloud/stackit-cli/internal/pkg/args" "github.com/stackitcloud/stackit-cli/internal/pkg/errors" @@ -105,7 +105,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inpu } func buildRequest(ctx context.Context, model *inputModel, apiClient *postgresflex.APIClient) postgresflex.ApiGetUserRequest { - req := apiClient.GetUser(ctx, model.ProjectId, model.Region, model.InstanceId, model.UserId) + req := apiClient.DefaultAPI.GetUser(ctx, model.ProjectId, model.Region, model.InstanceId, model.UserId) return req } @@ -116,7 +116,7 @@ func outputResult(p *print.Printer, outputFormat string, user postgresflex.UserR table.AddSeparator() table.AddRow("USERNAME", utils.PtrString(user.Username)) table.AddSeparator() - table.AddRow("ROLES", utils.PtrString(user.Roles)) + table.AddRow("ROLES", user.Roles) table.AddSeparator() table.AddRow("HOST", utils.PtrString(user.Host)) table.AddSeparator() diff --git a/internal/cmd/postgresflex/user/describe/describe_test.go b/internal/cmd/postgresflex/user/describe/describe_test.go index 3bb99678e..e5f64a31f 100644 --- a/internal/cmd/postgresflex/user/describe/describe_test.go +++ b/internal/cmd/postgresflex/user/describe/describe_test.go @@ -7,7 +7,7 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" "github.com/google/uuid" - "github.com/stackitcloud/stackit-sdk-go/services/postgresflex" + postgresflex "github.com/stackitcloud/stackit-sdk-go/services/postgresflex/v2api" "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/testparams" @@ -17,7 +17,7 @@ import ( type testCtxKey struct{} var testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") -var testClient = &postgresflex.APIClient{} +var testClient = &postgresflex.APIClient{DefaultAPI: &postgresflex.DefaultAPIService{}} var testProjectId = uuid.NewString() var testInstanceId = uuid.NewString() var testUserId = "12345" @@ -62,7 +62,7 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { } func fixtureRequest(mods ...func(request *postgresflex.ApiGetUserRequest)) postgresflex.ApiGetUserRequest { - request := testClient.GetUser(testCtx, testProjectId, testRegion, testInstanceId, testUserId) + request := testClient.DefaultAPI.GetUser(testCtx, testProjectId, testRegion, testInstanceId, testUserId) for _, mod := range mods { mod(&request) } @@ -184,7 +184,7 @@ func TestBuildRequest(t *testing.T) { diff := cmp.Diff(request, tt.expectedRequest, cmp.AllowUnexported(tt.expectedRequest), - cmpopts.EquateComparable(testCtx), + cmpopts.EquateComparable(testCtx, postgresflex.DefaultAPIService{}), ) if diff != "" { t.Fatalf("Data does not match: %s", diff) @@ -209,7 +209,7 @@ func Test_outputResult(t *testing.T) { Host: new(string), Id: new(string), Port: new(int64), - Roles: &[]string{}, + Roles: []string{}, Username: new(string), }}, false}, } diff --git a/internal/cmd/postgresflex/user/list/list.go b/internal/cmd/postgresflex/user/list/list.go index d0c9dbd36..0e3244062 100644 --- a/internal/cmd/postgresflex/user/list/list.go +++ b/internal/cmd/postgresflex/user/list/list.go @@ -7,7 +7,7 @@ import ( "github.com/stackitcloud/stackit-cli/internal/pkg/types" "github.com/spf13/cobra" - "github.com/stackitcloud/stackit-sdk-go/services/postgresflex" + postgresflex "github.com/stackitcloud/stackit-sdk-go/services/postgresflex/v2api" "github.com/stackitcloud/stackit-cli/internal/pkg/args" "github.com/stackitcloud/stackit-cli/internal/pkg/errors" @@ -29,7 +29,7 @@ const ( type inputModel struct { *globalflags.GlobalFlagModel - InstanceId *string + InstanceId string Limit *int64 } @@ -69,16 +69,16 @@ func NewCmd(params *types.CmdParams) *cobra.Command { if err != nil { return fmt.Errorf("get PostgreSQL Flex users: %w", err) } - if resp.Items == nil || len(*resp.Items) == 0 { - instanceLabel, err := postgresflexUtils.GetInstanceName(ctx, apiClient, model.ProjectId, model.Region, *model.InstanceId) + if len(resp.Items) == 0 { + instanceLabel, err := postgresflexUtils.GetInstanceName(ctx, apiClient.DefaultAPI, model.ProjectId, model.Region, model.InstanceId) if err != nil { params.Printer.Debug(print.ErrorLevel, "get instance name: %v", err) - instanceLabel = *model.InstanceId + instanceLabel = model.InstanceId } params.Printer.Info("No users found for instance %q\n", instanceLabel) return nil } - users := *resp.Items + users := resp.Items // Truncate output if model.Limit != nil && len(users) > int(*model.Limit) { @@ -117,7 +117,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command, _ []string) (*inputModel, model := inputModel{ GlobalFlagModel: globalFlags, - InstanceId: flags.FlagToStringPointer(p, cmd, instanceIdFlag), + InstanceId: flags.FlagToStringValue(p, cmd, instanceIdFlag), Limit: flags.FlagToInt64Pointer(p, cmd, limitFlag), } @@ -126,7 +126,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command, _ []string) (*inputModel, } func buildRequest(ctx context.Context, model *inputModel, apiClient *postgresflex.APIClient) postgresflex.ApiListUsersRequest { - req := apiClient.ListUsers(ctx, model.ProjectId, model.Region, *model.InstanceId) + req := apiClient.DefaultAPI.ListUsers(ctx, model.ProjectId, model.Region, model.InstanceId) return req } diff --git a/internal/cmd/postgresflex/user/list/list_test.go b/internal/cmd/postgresflex/user/list/list_test.go index caa4a46f8..58c82f4e2 100644 --- a/internal/cmd/postgresflex/user/list/list_test.go +++ b/internal/cmd/postgresflex/user/list/list_test.go @@ -7,7 +7,7 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" "github.com/google/uuid" - "github.com/stackitcloud/stackit-sdk-go/services/postgresflex" + postgresflex "github.com/stackitcloud/stackit-sdk-go/services/postgresflex/v2api" "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/testparams" @@ -18,7 +18,7 @@ import ( type testCtxKey struct{} var testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") -var testClient = &postgresflex.APIClient{} +var testClient = &postgresflex.APIClient{DefaultAPI: &postgresflex.DefaultAPIService{}} var testProjectId = uuid.NewString() var testInstanceId = uuid.NewString() var testRegion = "eu01" @@ -43,7 +43,7 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { Region: testRegion, Verbosity: globalflags.VerbosityDefault, }, - InstanceId: utils.Ptr(testInstanceId), + InstanceId: testInstanceId, Limit: utils.Ptr(int64(10)), } for _, mod := range mods { @@ -53,7 +53,7 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { } func fixtureRequest(mods ...func(request *postgresflex.ApiListUsersRequest)) postgresflex.ApiListUsersRequest { - request := testClient.ListUsers(testCtx, testProjectId, testRegion, testInstanceId) + request := testClient.DefaultAPI.ListUsers(testCtx, testProjectId, testRegion, testInstanceId) for _, mod := range mods { mod(&request) } @@ -156,7 +156,7 @@ func TestBuildRequest(t *testing.T) { diff := cmp.Diff(request, tt.expectedRequest, cmp.AllowUnexported(tt.expectedRequest), - cmpopts.EquateComparable(testCtx), + cmpopts.EquateComparable(testCtx, postgresflex.DefaultAPIService{}), ) if diff != "" { t.Fatalf("Data does not match: %s", diff) diff --git a/internal/cmd/postgresflex/user/reset-password/reset_password.go b/internal/cmd/postgresflex/user/reset-password/reset_password.go index 19e34dd2e..7a6ce4efb 100644 --- a/internal/cmd/postgresflex/user/reset-password/reset_password.go +++ b/internal/cmd/postgresflex/user/reset-password/reset_password.go @@ -7,7 +7,7 @@ import ( "github.com/stackitcloud/stackit-cli/internal/pkg/types" "github.com/spf13/cobra" - "github.com/stackitcloud/stackit-sdk-go/services/postgresflex" + postgresflex "github.com/stackitcloud/stackit-sdk-go/services/postgresflex/v2api" "github.com/stackitcloud/stackit-cli/internal/pkg/args" "github.com/stackitcloud/stackit-cli/internal/pkg/errors" @@ -60,13 +60,13 @@ func NewCmd(params *types.CmdParams) *cobra.Command { return err } - instanceLabel, err := postgresflexUtils.GetInstanceName(ctx, apiClient, model.ProjectId, model.Region, model.InstanceId) + instanceLabel, err := postgresflexUtils.GetInstanceName(ctx, apiClient.DefaultAPI, model.ProjectId, model.Region, model.InstanceId) if err != nil { params.Printer.Debug(print.ErrorLevel, "get instance name: %v", err) instanceLabel = model.InstanceId } - userLabel, err := postgresflexUtils.GetUserName(ctx, apiClient, model.ProjectId, model.Region, model.InstanceId, model.UserId) + userLabel, err := postgresflexUtils.GetUserName(ctx, apiClient.DefaultAPI, model.ProjectId, model.Region, model.InstanceId, model.UserId) if err != nil { params.Printer.Debug(print.ErrorLevel, "get user name: %v", err) userLabel = model.UserId @@ -119,15 +119,15 @@ func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inpu } func buildRequest(ctx context.Context, model *inputModel, apiClient *postgresflex.APIClient) postgresflex.ApiResetUserRequest { - req := apiClient.ResetUser(ctx, model.ProjectId, model.Region, model.InstanceId, model.UserId) + req := apiClient.DefaultAPI.ResetUser(ctx, model.ProjectId, model.Region, model.InstanceId, model.UserId) return req } func outputResult(p *print.Printer, outputFormat, userLabel, instanceLabel string, user *postgresflex.ResetUserResponse) error { - if user == nil { - return fmt.Errorf("no response passed") - } return p.OutputResult(outputFormat, user, func() error { + if user == nil { + return fmt.Errorf("no response passed") + } p.Outputf("Reset password for user %q of instance %q\n\n", userLabel, instanceLabel) if item := user.Item; item != nil { p.Outputf("Username: %s\n", utils.PtrString(item.Username)) diff --git a/internal/cmd/postgresflex/user/reset-password/reset_password_test.go b/internal/cmd/postgresflex/user/reset-password/reset_password_test.go index 799bbc712..4ee3fc726 100644 --- a/internal/cmd/postgresflex/user/reset-password/reset_password_test.go +++ b/internal/cmd/postgresflex/user/reset-password/reset_password_test.go @@ -7,7 +7,7 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" "github.com/google/uuid" - "github.com/stackitcloud/stackit-sdk-go/services/postgresflex" + postgresflex "github.com/stackitcloud/stackit-sdk-go/services/postgresflex/v2api" "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/testparams" @@ -17,7 +17,7 @@ import ( type testCtxKey struct{} var testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") -var testClient = &postgresflex.APIClient{} +var testClient = &postgresflex.APIClient{DefaultAPI: &postgresflex.DefaultAPIService{}} var testProjectId = uuid.NewString() var testInstanceId = uuid.NewString() var testUserId = "12345" @@ -62,7 +62,7 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { } func fixtureRequest(mods ...func(request *postgresflex.ApiResetUserRequest)) postgresflex.ApiResetUserRequest { - request := testClient.ResetUser(testCtx, testProjectId, testRegion, testInstanceId, testUserId) + request := testClient.DefaultAPI.ResetUser(testCtx, testProjectId, testRegion, testInstanceId, testUserId) for _, mod := range mods { mod(&request) } @@ -184,7 +184,7 @@ func TestBuildRequest(t *testing.T) { diff := cmp.Diff(request, tt.expectedRequest, cmp.AllowUnexported(tt.expectedRequest), - cmpopts.EquateComparable(testCtx), + cmpopts.EquateComparable(testCtx, postgresflex.DefaultAPIService{}), ) if diff != "" { t.Fatalf("Data does not match: %s", diff) diff --git a/internal/cmd/postgresflex/user/update/update.go b/internal/cmd/postgresflex/user/update/update.go index 33ca9d18d..e76bce64c 100644 --- a/internal/cmd/postgresflex/user/update/update.go +++ b/internal/cmd/postgresflex/user/update/update.go @@ -16,7 +16,7 @@ import ( postgresflexUtils "github.com/stackitcloud/stackit-cli/internal/pkg/services/postgresflex/utils" "github.com/spf13/cobra" - "github.com/stackitcloud/stackit-sdk-go/services/postgresflex" + postgresflex "github.com/stackitcloud/stackit-sdk-go/services/postgresflex/v2api" ) const ( @@ -36,7 +36,7 @@ type inputModel struct { InstanceId string UserId string - Roles *[]string + Roles []string } func NewCmd(params *types.CmdParams) *cobra.Command { @@ -63,13 +63,13 @@ func NewCmd(params *types.CmdParams) *cobra.Command { return err } - instanceLabel, err := postgresflexUtils.GetInstanceName(ctx, apiClient, model.ProjectId, model.Region, model.InstanceId) + instanceLabel, err := postgresflexUtils.GetInstanceName(ctx, apiClient.DefaultAPI, model.ProjectId, model.Region, model.InstanceId) if err != nil { params.Printer.Debug(print.ErrorLevel, "get instance name: %v", err) instanceLabel = model.InstanceId } - userLabel, err := postgresflexUtils.GetUserName(ctx, apiClient, model.ProjectId, model.Region, model.InstanceId, model.UserId) + userLabel, err := postgresflexUtils.GetUserName(ctx, apiClient.DefaultAPI, model.ProjectId, model.Region, model.InstanceId, model.UserId) if err != nil { params.Printer.Debug(print.ErrorLevel, "get user name: %v", err) userLabel = model.UserId @@ -113,8 +113,8 @@ func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inpu return nil, &errors.ProjectIdError{} } - roles := roleFlag.Ptr() - if roles == nil { + roles := roleFlag.Get() + if len(roles) == 0 { return nil, &errors.EmptyUpdateError{} } @@ -130,7 +130,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inpu } func buildRequest(ctx context.Context, model *inputModel, apiClient *postgresflex.APIClient) postgresflex.ApiPartialUpdateUserRequest { - req := apiClient.PartialUpdateUser(ctx, model.ProjectId, model.Region, model.InstanceId, model.UserId) + req := apiClient.DefaultAPI.PartialUpdateUser(ctx, model.ProjectId, model.Region, model.InstanceId, model.UserId) req = req.PartialUpdateUserPayload(postgresflex.PartialUpdateUserPayload{ Roles: model.Roles, }) diff --git a/internal/cmd/postgresflex/user/update/update_test.go b/internal/cmd/postgresflex/user/update/update_test.go index c2192e84f..89a194b4b 100644 --- a/internal/cmd/postgresflex/user/update/update_test.go +++ b/internal/cmd/postgresflex/user/update/update_test.go @@ -6,18 +6,17 @@ import ( "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/testutils" - "github.com/stackitcloud/stackit-cli/internal/pkg/utils" "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" "github.com/google/uuid" - "github.com/stackitcloud/stackit-sdk-go/services/postgresflex" + postgresflex "github.com/stackitcloud/stackit-sdk-go/services/postgresflex/v2api" ) type testCtxKey struct{} var testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") -var testClient = &postgresflex.APIClient{} +var testClient = &postgresflex.APIClient{DefaultAPI: &postgresflex.DefaultAPIService{}} var testProjectId = uuid.NewString() var testInstanceId = uuid.NewString() var testUserId = "12345" @@ -55,7 +54,7 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { }, InstanceId: testInstanceId, UserId: testUserId, - Roles: utils.Ptr([]string{"login"}), + Roles: []string{"login"}, } for _, mod := range mods { mod(model) @@ -64,9 +63,9 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { } func fixtureRequest(mods ...func(request *postgresflex.ApiPartialUpdateUserRequest)) postgresflex.ApiPartialUpdateUserRequest { - request := testClient.PartialUpdateUser(testCtx, testProjectId, testRegion, testInstanceId, testUserId) + request := testClient.DefaultAPI.PartialUpdateUser(testCtx, testProjectId, testRegion, testInstanceId, testUserId) request = request.PartialUpdateUserPayload(postgresflex.PartialUpdateUserPayload{ - Roles: utils.Ptr([]string{"login"}), + Roles: []string{"login"}, }) for _, mod := range mods { mod(&request) @@ -192,7 +191,7 @@ func TestBuildRequest(t *testing.T) { diff := cmp.Diff(request, tt.expectedRequest, cmp.AllowUnexported(tt.expectedRequest), - cmpopts.EquateComparable(testCtx), + cmpopts.EquateComparable(testCtx, postgresflex.DefaultAPIService{}), ) if diff != "" { t.Fatalf("Data does not match: %s", diff) diff --git a/internal/pkg/services/postgresflex/client/client.go b/internal/pkg/services/postgresflex/client/client.go index d5b77761f..a40b07aec 100644 --- a/internal/pkg/services/postgresflex/client/client.go +++ b/internal/pkg/services/postgresflex/client/client.go @@ -6,9 +6,9 @@ import ( "github.com/stackitcloud/stackit-cli/internal/pkg/print" "github.com/spf13/viper" - "github.com/stackitcloud/stackit-sdk-go/services/postgresflex" + postgresflex "github.com/stackitcloud/stackit-sdk-go/services/postgresflex/v2api" ) func ConfigureClient(p *print.Printer, cliVersion string) (*postgresflex.APIClient, error) { - return genericclient.ConfigureClientGeneric(p, cliVersion, viper.GetString(config.PostgresFlexCustomEndpointKey), true, genericclient.CreateApiClient[*postgresflex.APIClient](postgresflex.NewAPIClient)) + return genericclient.ConfigureClientGeneric(p, cliVersion, viper.GetString(config.PostgresFlexCustomEndpointKey), false, genericclient.CreateApiClient[*postgresflex.APIClient](postgresflex.NewAPIClient)) } diff --git a/internal/pkg/services/postgresflex/utils/utils.go b/internal/pkg/services/postgresflex/utils/utils.go index fc1965bdd..4920feb15 100644 --- a/internal/pkg/services/postgresflex/utils/utils.go +++ b/internal/pkg/services/postgresflex/utils/utils.go @@ -8,20 +8,20 @@ import ( "github.com/stackitcloud/stackit-cli/internal/pkg/errors" - "github.com/stackitcloud/stackit-sdk-go/services/postgresflex" + postgresflex "github.com/stackitcloud/stackit-sdk-go/services/postgresflex/v2api" "golang.org/x/mod/semver" ) // The number of replicas is enforced by the API according to the instance type -var instanceTypeToReplicas = map[string]int64{ +var instanceTypeToReplicas = map[string]int32{ "Single": 1, "Replica": 3, } type PostgresFlexClient interface { - ListVersionsExecute(ctx context.Context, projectId, region string) (*postgresflex.ListVersionsResponse, error) - GetInstanceExecute(ctx context.Context, projectId, region, instanceId string) (*postgresflex.InstanceResponse, error) - GetUserExecute(ctx context.Context, projectId, region, instanceId, userId string) (*postgresflex.GetUserResponse, error) + ListVersions(ctx context.Context, projectId, region string) postgresflex.ApiListVersionsRequest + GetInstance(ctx context.Context, projectId, region, instanceId string) postgresflex.ApiGetInstanceRequest + GetUser(ctx context.Context, projectId, region, instanceId, userId string) postgresflex.ApiGetUserRequest } func AvailableInstanceTypes() []string { @@ -37,7 +37,7 @@ func AvailableInstanceTypes() []string { return instanceTypes } -func GetInstanceReplicas(instanceType string) (int64, error) { +func GetInstanceReplicas(instanceType string) (int32, error) { numReplicas, ok := instanceTypeToReplicas[instanceType] if !ok { return 0, fmt.Errorf("invalid instance type: %v", instanceType) @@ -45,7 +45,7 @@ func GetInstanceReplicas(instanceType string) (int64, error) { return numReplicas, nil } -func GetInstanceType(numReplicas int64) (string, error) { +func GetInstanceType(numReplicas int32) (string, error) { for k, v := range instanceTypeToReplicas { if v == numReplicas { return k, nil @@ -54,12 +54,12 @@ func GetInstanceType(numReplicas int64) (string, error) { return "", fmt.Errorf("invalid number of replicas: %v", numReplicas) } -func ValidateFlavorId(flavorId string, flavors *[]postgresflex.Flavor) error { +func ValidateFlavorId(flavorId string, flavors []postgresflex.Flavor) error { if flavors == nil { return fmt.Errorf("nil flavors") } - for _, f := range *flavors { + for _, f := range flavors { if f.Id != nil && strings.EqualFold(*f.Id, flavorId) { return nil } @@ -86,7 +86,7 @@ func ValidateStorage(storageClass *string, storageSize *int64, storages *postgre return nil } - for _, sc := range *storages.StorageClasses { + for _, sc := range storages.StorageClasses { if strings.EqualFold(*storageClass, sc) { return nil } @@ -98,13 +98,13 @@ func ValidateStorage(storageClass *string, storageSize *int64, storages *postgre } } -func LoadFlavorId(cpu, ram int64, flavors *[]postgresflex.Flavor) (*string, error) { +func LoadFlavorId(cpu, ram int64, flavors []postgresflex.Flavor) (*string, error) { if flavors == nil { return nil, fmt.Errorf("nil flavors") } availableFlavors := "" - for _, f := range *flavors { + for _, f := range flavors { if f.Id == nil || f.Cpu == nil || f.Memory == nil { continue } @@ -120,20 +120,19 @@ func LoadFlavorId(cpu, ram int64, flavors *[]postgresflex.Flavor) (*string, erro } func GetLatestPostgreSQLVersion(ctx context.Context, apiClient PostgresFlexClient, projectId, region string) (string, error) { - resp, err := apiClient.ListVersionsExecute(ctx, projectId, region) + resp, err := apiClient.ListVersions(ctx, projectId, region).Execute() if err != nil { return "", fmt.Errorf("get PostgreSQL versions: %w", err) } - versions := *resp.Versions latestVersion := "0" - for i := range versions { + for i := range resp.Versions { oldSemVer := fmt.Sprintf("v%s", latestVersion) - newSemVer := fmt.Sprintf("v%s", versions[i]) + newSemVer := fmt.Sprintf("v%s", resp.Versions[i]) if semver.Compare(newSemVer, oldSemVer) != 1 { continue } - latestVersion = versions[i] + latestVersion = resp.Versions[i] } if latestVersion == "0" { return "", fmt.Errorf("no PostgreSQL versions found") @@ -142,7 +141,7 @@ func GetLatestPostgreSQLVersion(ctx context.Context, apiClient PostgresFlexClien } func GetInstanceName(ctx context.Context, apiClient PostgresFlexClient, projectId, region, instanceId string) (string, error) { - resp, err := apiClient.GetInstanceExecute(ctx, projectId, region, instanceId) + resp, err := apiClient.GetInstance(ctx, projectId, region, instanceId).Execute() if err != nil { return "", fmt.Errorf("get PostgreSQL Flex instance: %w", err) } @@ -150,7 +149,7 @@ func GetInstanceName(ctx context.Context, apiClient PostgresFlexClient, projectI } func GetInstanceStatus(ctx context.Context, apiClient PostgresFlexClient, projectId, region, instanceId string) (string, error) { - resp, err := apiClient.GetInstanceExecute(ctx, projectId, region, instanceId) + resp, err := apiClient.GetInstance(ctx, projectId, region, instanceId).Execute() if err != nil { return "", fmt.Errorf("get PostgreSQL Flex instance: %w", err) } @@ -158,7 +157,7 @@ func GetInstanceStatus(ctx context.Context, apiClient PostgresFlexClient, projec } func GetUserName(ctx context.Context, apiClient PostgresFlexClient, projectId, region, instanceId, userId string) (string, error) { - resp, err := apiClient.GetUserExecute(ctx, projectId, region, instanceId, userId) + resp, err := apiClient.GetUser(ctx, projectId, region, instanceId, userId).Execute() if err != nil { return "", fmt.Errorf("get PostgreSQL Flex user: %w", err) } diff --git a/internal/pkg/services/postgresflex/utils/utils_test.go b/internal/pkg/services/postgresflex/utils/utils_test.go index 346debe49..34a0d4b9c 100644 --- a/internal/pkg/services/postgresflex/utils/utils_test.go +++ b/internal/pkg/services/postgresflex/utils/utils_test.go @@ -9,7 +9,7 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/uuid" - "github.com/stackitcloud/stackit-sdk-go/services/postgresflex" + postgresflex "github.com/stackitcloud/stackit-sdk-go/services/postgresflex/v2api" ) var ( @@ -25,7 +25,7 @@ const ( testRegion = "eu01" ) -type postgresFlexClientMocked struct { +type mockSettings struct { listVersionsFails bool listVersionsResp *postgresflex.ListVersionsResponse getInstanceFails bool @@ -34,25 +34,27 @@ type postgresFlexClientMocked struct { getUserResp *postgresflex.GetUserResponse } -func (m *postgresFlexClientMocked) ListVersionsExecute(_ context.Context, _, _ string) (*postgresflex.ListVersionsResponse, error) { - if m.listVersionsFails { - return nil, fmt.Errorf("could not list versions") - } - return m.listVersionsResp, nil -} - -func (m *postgresFlexClientMocked) GetInstanceExecute(_ context.Context, _, _, _ string) (*postgresflex.InstanceResponse, error) { - if m.getInstanceFails { - return nil, fmt.Errorf("could not get instance") - } - return m.getInstanceResp, nil -} - -func (m *postgresFlexClientMocked) GetUserExecute(_ context.Context, _, _, _, _ string) (*postgresflex.GetUserResponse, error) { - if m.getUserFails { - return nil, fmt.Errorf("could not get user") +func newAPIMockClient(s mockSettings) postgresflex.DefaultAPI { + return postgresflex.DefaultAPIServiceMock{ + ListVersionsExecuteMock: utils.Ptr(func(_ postgresflex.ApiListVersionsRequest) (*postgresflex.ListVersionsResponse, error) { + if s.listVersionsFails { + return nil, fmt.Errorf("could not list versions") + } + return s.listVersionsResp, nil + }), + GetInstanceExecuteMock: utils.Ptr(func(_ postgresflex.ApiGetInstanceRequest) (*postgresflex.InstanceResponse, error) { + if s.getInstanceFails { + return nil, fmt.Errorf("could not get instance") + } + return s.getInstanceResp, nil + }), + GetUserExecuteMock: utils.Ptr(func(_ postgresflex.ApiGetUserRequest) (*postgresflex.GetUserResponse, error) { + if s.getUserFails { + return nil, fmt.Errorf("could not get user") + } + return s.getUserResp, nil + }), } - return m.getUserResp, nil } func TestValidateStorage(t *testing.T) { @@ -68,7 +70,7 @@ func TestValidateStorage(t *testing.T) { storageClass: utils.Ptr("foo"), storageSize: utils.Ptr(int64(10)), storages: &postgresflex.ListStoragesResponse{ - StorageClasses: &[]string{"bar-1", "bar-2", "foo"}, + StorageClasses: []string{"bar-1", "bar-2", "foo"}, StorageRange: &postgresflex.StorageRange{ Min: utils.Ptr(int64(5)), Max: utils.Ptr(int64(20)), @@ -88,7 +90,7 @@ func TestValidateStorage(t *testing.T) { storageClass: utils.Ptr("foo"), storageSize: utils.Ptr(int64(1)), storages: &postgresflex.ListStoragesResponse{ - StorageClasses: &[]string{"bar-1", "bar-2", "foo"}, + StorageClasses: []string{"bar-1", "bar-2", "foo"}, StorageRange: &postgresflex.StorageRange{ Min: utils.Ptr(int64(5)), Max: utils.Ptr(int64(20)), @@ -101,7 +103,7 @@ func TestValidateStorage(t *testing.T) { storageClass: utils.Ptr("foo"), storageSize: utils.Ptr(int64(200)), storages: &postgresflex.ListStoragesResponse{ - StorageClasses: &[]string{"bar-1", "bar-2", "foo"}, + StorageClasses: []string{"bar-1", "bar-2", "foo"}, StorageRange: &postgresflex.StorageRange{ Min: utils.Ptr(int64(5)), Max: utils.Ptr(int64(20)), @@ -114,7 +116,7 @@ func TestValidateStorage(t *testing.T) { storageClass: utils.Ptr("foo"), storageSize: utils.Ptr(int64(5)), storages: &postgresflex.ListStoragesResponse{ - StorageClasses: &[]string{"bar-1", "bar-2", "foo"}, + StorageClasses: []string{"bar-1", "bar-2", "foo"}, StorageRange: &postgresflex.StorageRange{ Min: utils.Ptr(int64(5)), Max: utils.Ptr(int64(20)), @@ -127,7 +129,7 @@ func TestValidateStorage(t *testing.T) { storageClass: utils.Ptr("foo"), storageSize: utils.Ptr(int64(20)), storages: &postgresflex.ListStoragesResponse{ - StorageClasses: &[]string{"bar-1", "bar-2", "foo"}, + StorageClasses: []string{"bar-1", "bar-2", "foo"}, StorageRange: &postgresflex.StorageRange{ Min: utils.Ptr(int64(5)), Max: utils.Ptr(int64(20)), @@ -140,7 +142,7 @@ func TestValidateStorage(t *testing.T) { storageClass: utils.Ptr("foo"), storageSize: utils.Ptr(int64(10)), storages: &postgresflex.ListStoragesResponse{ - StorageClasses: &[]string{"bar-1", "bar-2", "bar-3"}, + StorageClasses: []string{"bar-1", "bar-2", "bar-3"}, StorageRange: &postgresflex.StorageRange{ Min: utils.Ptr(int64(5)), Max: utils.Ptr(int64(20)), @@ -167,13 +169,13 @@ func TestValidateFlavorId(t *testing.T) { tests := []struct { description string flavorId string - flavors *[]postgresflex.Flavor + flavors []postgresflex.Flavor isValid bool }{ { description: "base", flavorId: "foo", - flavors: &[]postgresflex.Flavor{ + flavors: []postgresflex.Flavor{ {Id: utils.Ptr("bar-1")}, {Id: utils.Ptr("bar-2")}, {Id: utils.Ptr("foo")}, @@ -189,13 +191,13 @@ func TestValidateFlavorId(t *testing.T) { { description: "no flavors", flavorId: "foo", - flavors: &[]postgresflex.Flavor{}, + flavors: []postgresflex.Flavor{}, isValid: false, }, { description: "nil flavor id", flavorId: "foo", - flavors: &[]postgresflex.Flavor{ + flavors: []postgresflex.Flavor{ {Id: utils.Ptr("bar-1")}, {Id: nil}, {Id: utils.Ptr("foo")}, @@ -205,7 +207,7 @@ func TestValidateFlavorId(t *testing.T) { { description: "invalid flavor", flavorId: "foo", - flavors: &[]postgresflex.Flavor{ + flavors: []postgresflex.Flavor{ {Id: utils.Ptr("bar-1")}, {Id: utils.Ptr("bar-2")}, {Id: utils.Ptr("bar-3")}, @@ -232,7 +234,7 @@ func TestLoadFlavorId(t *testing.T) { description string cpu int64 ram int64 - flavors *[]postgresflex.Flavor + flavors []postgresflex.Flavor isValid bool expectedOutput *string }{ @@ -240,7 +242,7 @@ func TestLoadFlavorId(t *testing.T) { description: "base", cpu: 2, ram: 4, - flavors: &[]postgresflex.Flavor{ + flavors: []postgresflex.Flavor{ { Id: utils.Ptr("bar-1"), Cpu: utils.Ptr(int64(2)), @@ -271,14 +273,14 @@ func TestLoadFlavorId(t *testing.T) { description: "no flavors", cpu: 2, ram: 4, - flavors: &[]postgresflex.Flavor{}, + flavors: []postgresflex.Flavor{}, isValid: false, }, { description: "flavors with details missing", cpu: 2, ram: 4, - flavors: &[]postgresflex.Flavor{ + flavors: []postgresflex.Flavor{ { Id: utils.Ptr("bar-1"), Cpu: nil, @@ -302,7 +304,7 @@ func TestLoadFlavorId(t *testing.T) { description: "match with nil id", cpu: 2, ram: 4, - flavors: &[]postgresflex.Flavor{ + flavors: []postgresflex.Flavor{ { Id: utils.Ptr("bar-1"), Cpu: utils.Ptr(int64(2)), @@ -325,7 +327,7 @@ func TestLoadFlavorId(t *testing.T) { description: "invalid settings", cpu: 2, ram: 4, - flavors: &[]postgresflex.Flavor{ + flavors: []postgresflex.Flavor{ { Id: utils.Ptr("bar-1"), Cpu: utils.Ptr(int64(2)), @@ -368,29 +370,34 @@ func TestLoadFlavorId(t *testing.T) { func TestGetLatestPostgreSQLVersion(t *testing.T) { tests := []struct { - description string - listVersionsFails bool - listVersionsResp *postgresflex.ListVersionsResponse - isValid bool - expectedOutput string + description string + mockClientSettings mockSettings + isValid bool + expectedOutput string }{ { description: "base", - listVersionsResp: &postgresflex.ListVersionsResponse{ - Versions: &[]string{"8", "10", "9"}, + mockClientSettings: mockSettings{ + listVersionsResp: &postgresflex.ListVersionsResponse{ + Versions: []string{"8", "10", "9"}, + }, }, isValid: true, expectedOutput: "10", }, { - description: "get instance fails", - listVersionsFails: true, - isValid: false, + description: "get instance fails", + mockClientSettings: mockSettings{ + listVersionsFails: true, + }, + isValid: false, }, { description: "no versions", - listVersionsResp: &postgresflex.ListVersionsResponse{ - Versions: &[]string{}, + mockClientSettings: mockSettings{ + listVersionsResp: &postgresflex.ListVersionsResponse{ + Versions: []string{}, + }, }, isValid: false, }, @@ -398,12 +405,7 @@ func TestGetLatestPostgreSQLVersion(t *testing.T) { for _, tt := range tests { t.Run(tt.description, func(t *testing.T) { - client := &postgresFlexClientMocked{ - listVersionsFails: tt.listVersionsFails, - listVersionsResp: tt.listVersionsResp, - } - - output, err := GetLatestPostgreSQLVersion(context.Background(), client, testProjectId, testRegion) + output, err := GetLatestPostgreSQLVersion(context.Background(), newAPIMockClient(tt.mockClientSettings), testProjectId, testRegion) if tt.isValid && err != nil { t.Errorf("failed on valid input") @@ -423,37 +425,35 @@ func TestGetLatestPostgreSQLVersion(t *testing.T) { func TestGetInstanceName(t *testing.T) { tests := []struct { - description string - getInstanceFails bool - getInstanceResp *postgresflex.InstanceResponse - isValid bool - expectedOutput string + description string + mockClientSettings mockSettings + isValid bool + expectedOutput string }{ { description: "base", - getInstanceResp: &postgresflex.InstanceResponse{ - Item: &postgresflex.Instance{ - Name: utils.Ptr(testInstanceName), + mockClientSettings: mockSettings{ + getInstanceResp: &postgresflex.InstanceResponse{ + Item: &postgresflex.Instance{ + Name: utils.Ptr(testInstanceName), + }, }, }, isValid: true, expectedOutput: testInstanceName, }, { - description: "get instance fails", - getInstanceFails: true, - isValid: false, + description: "get instance fails", + mockClientSettings: mockSettings{ + getInstanceFails: true, + }, + isValid: false, }, } for _, tt := range tests { t.Run(tt.description, func(t *testing.T) { - client := &postgresFlexClientMocked{ - getInstanceFails: tt.getInstanceFails, - getInstanceResp: tt.getInstanceResp, - } - - output, err := GetInstanceName(context.Background(), client, testProjectId, testRegion, testInstanceId) + output, err := GetInstanceName(context.Background(), newAPIMockClient(tt.mockClientSettings), testProjectId, testRegion, testInstanceId) if tt.isValid && err != nil { t.Errorf("failed on valid input") @@ -473,37 +473,35 @@ func TestGetInstanceName(t *testing.T) { func TestGetInstanceStatus(t *testing.T) { tests := []struct { - description string - getInstanceFails bool - getInstanceResp *postgresflex.InstanceResponse - isValid bool - expectedOutput string + description string + mockClientSettings mockSettings + isValid bool + expectedOutput string }{ { description: "base", - getInstanceResp: &postgresflex.InstanceResponse{ - Item: &postgresflex.Instance{ - Status: utils.Ptr(testStatus), + mockClientSettings: mockSettings{ + getInstanceResp: &postgresflex.InstanceResponse{ + Item: &postgresflex.Instance{ + Status: utils.Ptr(testStatus), + }, }, }, isValid: true, expectedOutput: testStatus, }, { - description: "get instance fails", - getInstanceFails: true, - isValid: false, + description: "get instance fails", + mockClientSettings: mockSettings{ + getInstanceFails: true, + }, + isValid: false, }, } for _, tt := range tests { t.Run(tt.description, func(t *testing.T) { - client := &postgresFlexClientMocked{ - getInstanceFails: tt.getInstanceFails, - getInstanceResp: tt.getInstanceResp, - } - - output, err := GetInstanceStatus(context.Background(), client, testProjectId, testRegion, testInstanceId) + output, err := GetInstanceStatus(context.Background(), newAPIMockClient(tt.mockClientSettings), testProjectId, testRegion, testInstanceId) if tt.isValid && err != nil { t.Errorf("failed on valid input") @@ -523,37 +521,35 @@ func TestGetInstanceStatus(t *testing.T) { func TestGetUserName(t *testing.T) { tests := []struct { - description string - getUserFails bool - getUserResp *postgresflex.GetUserResponse - isValid bool - expectedOutput string + description string + mockClientSettings mockSettings + isValid bool + expectedOutput string }{ { description: "base", - getUserResp: &postgresflex.GetUserResponse{ - Item: &postgresflex.UserResponse{ - Username: utils.Ptr(testUserName), + mockClientSettings: mockSettings{ + getUserResp: &postgresflex.GetUserResponse{ + Item: &postgresflex.UserResponse{ + Username: utils.Ptr(testUserName), + }, }, }, isValid: true, expectedOutput: testUserName, }, { - description: "get user fails", - getUserFails: true, - isValid: false, + description: "get user fails", + mockClientSettings: mockSettings{ + getUserFails: true, + }, + isValid: false, }, } for _, tt := range tests { t.Run(tt.description, func(t *testing.T) { - client := &postgresFlexClientMocked{ - getUserFails: tt.getUserFails, - getUserResp: tt.getUserResp, - } - - output, err := GetUserName(context.Background(), client, testProjectId, testRegion, testInstanceId, testUserId) + output, err := GetUserName(context.Background(), newAPIMockClient(tt.mockClientSettings), testProjectId, testRegion, testInstanceId, testUserId) if tt.isValid && err != nil { t.Errorf("failed on valid input") @@ -574,7 +570,7 @@ func TestGetUserName(t *testing.T) { func TestGetInstanceType(t *testing.T) { tests := []struct { description string - numReplicas int64 + numReplicas int32 expectedOutput string isValid bool }{