diff --git a/go.mod b/go.mod index 2ea9f9433..0488bc2b3 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/spf13/viper v1.21.0 github.com/stackitcloud/stackit-sdk-go/core v0.26.0 github.com/stackitcloud/stackit-sdk-go/services/alb v0.14.2 - github.com/stackitcloud/stackit-sdk-go/services/authorization v0.12.0 + github.com/stackitcloud/stackit-sdk-go/services/authorization v0.15.2 github.com/stackitcloud/stackit-sdk-go/services/cdn v1.16.0 github.com/stackitcloud/stackit-sdk-go/services/dns v0.21.0 github.com/stackitcloud/stackit-sdk-go/services/edge v0.4.3 diff --git a/go.sum b/go.sum index d6e912fa3..6607d056d 100644 --- a/go.sum +++ b/go.sum @@ -594,8 +594,8 @@ github.com/stackitcloud/stackit-sdk-go/core v0.26.0 h1:jQEb9gkehfp6VCP6TcYk7BI10 github.com/stackitcloud/stackit-sdk-go/core v0.26.0/go.mod h1:WU1hhxnjXw2EV7CYa1nlEvNpMiRY6CvmIOaHuL3pOaA= github.com/stackitcloud/stackit-sdk-go/services/alb v0.14.2 h1:hGzfOJjlCRoFpri5eYIiwhE27qu02pKZLprKvbsTC/w= github.com/stackitcloud/stackit-sdk-go/services/alb v0.14.2/go.mod h1:eK6oRB5Tmpt6KbXQ4UYBGg2LgW5bPtVoncL9E8JSRww= -github.com/stackitcloud/stackit-sdk-go/services/authorization v0.12.0 h1:HxPgBu04j5tj6nfZ2r0l6v4VXC0/tYOGe4sA5Addra8= -github.com/stackitcloud/stackit-sdk-go/services/authorization v0.12.0/go.mod h1:uYI9pHAA2g84jJN25ejFUxa0/JtfpPZqMDkctQ1BzJk= +github.com/stackitcloud/stackit-sdk-go/services/authorization v0.15.2 h1:b7WJ/vwxlVmNNX91kI3obqGcuoPAyaCbDL5aCMQ/sNg= +github.com/stackitcloud/stackit-sdk-go/services/authorization v0.15.2/go.mod h1:T/JF25XGJ3GqER/1L2N//DgY8x5tY7gA3N+/0nvmOWY= github.com/stackitcloud/stackit-sdk-go/services/cdn v1.16.0 h1:Wqxx0PDTL2F5gqI5jjznuJY0TdqECltjA0aa/rHY63U= github.com/stackitcloud/stackit-sdk-go/services/cdn v1.16.0/go.mod h1:MHB1N3EQ9GuAduAQoNS+gb1MjrWJieszbpOso9TQv5s= github.com/stackitcloud/stackit-sdk-go/services/dns v0.21.0 h1:ZVkptfVCAqpaPWkE+WIopM9XdzqgbVcwmX5L1jZqqx8= diff --git a/internal/cmd/organization/member/add/add.go b/internal/cmd/organization/member/add/add.go index 325669ae3..f6e864190 100644 --- a/internal/cmd/organization/member/add/add.go +++ b/internal/cmd/organization/member/add/add.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/authorization" + authorization "github.com/stackitcloud/stackit-sdk-go/services/authorization/v2api" "github.com/stackitcloud/stackit-cli/internal/pkg/args" "github.com/stackitcloud/stackit-cli/internal/pkg/examples" @@ -15,7 +15,6 @@ import ( "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/print" "github.com/stackitcloud/stackit-cli/internal/pkg/services/authorization/client" - "github.com/stackitcloud/stackit-cli/internal/pkg/utils" ) const ( @@ -30,9 +29,9 @@ const ( type inputModel struct { *globalflags.GlobalFlagModel - OrganizationId *string + OrganizationId string Subject string - Role *string + Role string } func NewCmd(params *types.CmdParams) *cobra.Command { @@ -59,7 +58,7 @@ func NewCmd(params *types.CmdParams) *cobra.Command { return err } - prompt := fmt.Sprintf("Are you sure you want to add the %s role to %s on organization with ID %q?", *model.Role, model.Subject, *model.OrganizationId) + prompt := fmt.Sprintf("Are you sure you want to add the %s role to %s on organization with ID %q?", model.Role, model.Subject, model.OrganizationId) err = params.Printer.PromptForConfirmation(prompt) if err != nil { return err @@ -101,9 +100,9 @@ func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inpu model := inputModel{ GlobalFlagModel: globalFlags, - OrganizationId: flags.FlagToStringPointer(p, cmd, organizationIdFlag), + OrganizationId: flags.FlagToStringValue(p, cmd, organizationIdFlag), Subject: subject, - Role: flags.FlagToStringPointer(p, cmd, roleFlag), + Role: flags.FlagToStringValue(p, cmd, roleFlag), } p.DebugInputModel(model) @@ -111,15 +110,15 @@ func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inpu } func buildRequest(ctx context.Context, model *inputModel, apiClient *authorization.APIClient) authorization.ApiAddMembersRequest { - req := apiClient.AddMembers(ctx, *model.OrganizationId) + req := apiClient.DefaultAPI.AddMembers(ctx, model.OrganizationId) req = req.AddMembersPayload(authorization.AddMembersPayload{ - Members: utils.Ptr([]authorization.Member{ + Members: []authorization.Member{ { - Subject: utils.Ptr(model.Subject), + Subject: model.Subject, Role: model.Role, }, - }), - ResourceType: utils.Ptr(organizationResourceType), + }, + ResourceType: organizationResourceType, }) return req } diff --git a/internal/cmd/organization/member/add/add_test.go b/internal/cmd/organization/member/add/add_test.go index dfe3300f0..a8555a9b8 100644 --- a/internal/cmd/organization/member/add/add_test.go +++ b/internal/cmd/organization/member/add/add_test.go @@ -4,19 +4,18 @@ import ( "context" "testing" - "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/stackitcloud/stackit-sdk-go/services/authorization" + authorization "github.com/stackitcloud/stackit-sdk-go/services/authorization/v2api" + + "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" + "github.com/stackitcloud/stackit-cli/internal/pkg/testutils" ) type testCtxKey struct{} var testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") -var testClient = &authorization.APIClient{} +var testClient = &authorization.APIClient{DefaultAPI: &authorization.DefaultAPIService{}} var testOrganizationID = "some-organization-id" var testSubject = "someone@domain.com" var testRole = "reader" @@ -45,9 +44,9 @@ func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]st func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { model := &inputModel{ GlobalFlagModel: &globalflags.GlobalFlagModel{Verbosity: globalflags.VerbosityDefault}, - OrganizationId: utils.Ptr(testOrganizationID), + OrganizationId: testOrganizationID, Subject: testSubject, - Role: utils.Ptr(testRole), + Role: testRole, } for _, mod := range mods { mod(model) @@ -56,15 +55,15 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { } func fixtureRequest(mods ...func(request *authorization.ApiAddMembersRequest)) authorization.ApiAddMembersRequest { - request := testClient.AddMembers(testCtx, testOrganizationID) + request := testClient.DefaultAPI.AddMembers(testCtx, testOrganizationID) request = request.AddMembersPayload(authorization.AddMembersPayload{ - Members: utils.Ptr([]authorization.Member{ + Members: []authorization.Member{ { - Subject: &testSubject, - Role: &testRole, + Subject: testSubject, + Role: testRole, }, - }), - ResourceType: utils.Ptr(organizationResourceType), + }, + ResourceType: organizationResourceType, }) for _, mod := range mods { @@ -148,7 +147,7 @@ func TestBuildRequest(t *testing.T) { diff := cmp.Diff(request, tt.expectedRequest, cmp.AllowUnexported(tt.expectedRequest), - cmpopts.EquateComparable(testCtx), + cmpopts.EquateComparable(testCtx, authorization.DefaultAPIService{}), ) if diff != "" { t.Fatalf("Data does not match: %s", diff) diff --git a/internal/cmd/organization/member/list/list.go b/internal/cmd/organization/member/list/list.go index 3858c277e..faff697bd 100644 --- a/internal/cmd/organization/member/list/list.go +++ b/internal/cmd/organization/member/list/list.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/authorization" + authorization "github.com/stackitcloud/stackit-sdk-go/services/authorization/v2api" "github.com/stackitcloud/stackit-cli/internal/pkg/args" "github.com/stackitcloud/stackit-cli/internal/pkg/errors" @@ -18,7 +18,6 @@ import ( "github.com/stackitcloud/stackit-cli/internal/pkg/print" "github.com/stackitcloud/stackit-cli/internal/pkg/services/authorization/client" "github.com/stackitcloud/stackit-cli/internal/pkg/tables" - "github.com/stackitcloud/stackit-cli/internal/pkg/utils" ) const ( @@ -39,7 +38,7 @@ var sortByFlag = flags.StringEnumFlag( type inputModel struct { *globalflags.GlobalFlagModel - OrganizationId *string + OrganizationId string Subject *string Limit *int64 SortBy string @@ -81,18 +80,14 @@ func NewCmd(params *types.CmdParams) *cobra.Command { if err != nil { return fmt.Errorf("list members: %w", err) } - members := *resp.Members - if len(members) == 0 { - params.Printer.Info("No members found for organization with ID %q\n", *model.OrganizationId) - return nil - } + members := resp.Members // Truncate output if model.Limit != nil && len(members) > int(*model.Limit) { members = members[:*model.Limit] } - return outputResult(params.Printer, model.OutputFormat, model.SortBy, members) + return outputResult(params.Printer, model.OutputFormat, model.OrganizationId, model.SortBy, members) }, } configureFlags(cmd) @@ -122,7 +117,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command, _ []string) (*inputModel, model := inputModel{ GlobalFlagModel: globalFlags, - OrganizationId: flags.FlagToStringPointer(p, cmd, organizationIdFlag), + OrganizationId: flags.FlagToStringValue(p, cmd, organizationIdFlag), Subject: flags.FlagToStringPointer(p, cmd, subjectFlag), Limit: flags.FlagToInt64Pointer(p, cmd, limitFlag), SortBy: sortByFlag.Get(), @@ -133,20 +128,20 @@ func parseInput(p *print.Printer, cmd *cobra.Command, _ []string) (*inputModel, } func buildRequest(ctx context.Context, model *inputModel, apiClient *authorization.APIClient) authorization.ApiListMembersRequest { - req := apiClient.ListMembers(ctx, organizationResourceType, *model.OrganizationId) + req := apiClient.DefaultAPI.ListMembers(ctx, organizationResourceType, model.OrganizationId) if model.Subject != nil { req = req.Subject(*model.Subject) } return req } -func outputResult(p *print.Printer, outputFormat, sortBy string, members []authorization.Member) error { +func outputResult(p *print.Printer, outputFormat, organizationId, sortBy string, members []authorization.Member) error { sortFn := func(i, j int) bool { switch sortBy { case "subject": - return *members[i].Subject < *members[j].Subject + return members[i].Subject < members[j].Subject case "role": - return *members[i].Role < *members[j].Role + return members[i].Role < members[j].Role default: return false } @@ -154,6 +149,11 @@ func outputResult(p *print.Printer, outputFormat, sortBy string, members []autho sort.SliceStable(members, sortFn) return p.OutputResult(outputFormat, members, func() error { + if len(members) == 0 { + p.Outputf("No members found for organization with ID %q\n", organizationId) + return nil + } + table := tables.NewTable() table.SetHeader("SUBJECT", "ROLE") for i := range members { @@ -162,7 +162,7 @@ func outputResult(p *print.Printer, outputFormat, sortBy string, members []autho if i > 0 && sortFn(i-1, i) { table.AddSeparator() } - table.AddRow(utils.PtrString(m.Subject), utils.PtrString(m.Role)) + table.AddRow(m.Subject, m.Role) } switch sortBy { diff --git a/internal/cmd/organization/member/list/list_test.go b/internal/cmd/organization/member/list/list_test.go index cd553c654..990417c95 100644 --- a/internal/cmd/organization/member/list/list_test.go +++ b/internal/cmd/organization/member/list/list_test.go @@ -11,13 +11,13 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" - "github.com/stackitcloud/stackit-sdk-go/services/authorization" + authorization "github.com/stackitcloud/stackit-sdk-go/services/authorization/v2api" ) type testCtxKey struct{} var testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") -var testClient = &authorization.APIClient{} +var testClient = &authorization.APIClient{DefaultAPI: &authorization.DefaultAPIService{}} var testOrganizationID = "some-organization-id" func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]string { @@ -34,7 +34,7 @@ func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]st func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { model := &inputModel{ GlobalFlagModel: &globalflags.GlobalFlagModel{Verbosity: globalflags.VerbosityDefault}, - OrganizationId: utils.Ptr(testOrganizationID), + OrganizationId: testOrganizationID, Limit: utils.Ptr(int64(10)), SortBy: "subject", } @@ -45,7 +45,7 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { } func fixtureRequest(mods ...func(request *authorization.ApiListMembersRequest)) authorization.ApiListMembersRequest { - request := testClient.ListMembers(testCtx, organizationResourceType, testOrganizationID) + request := testClient.DefaultAPI.ListMembers(testCtx, organizationResourceType, testOrganizationID) 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, authorization.DefaultAPIService{}), ) if diff != "" { t.Fatalf("Data does not match: %s", diff) @@ -167,9 +167,10 @@ func TestBuildRequest(t *testing.T) { func TestOutputResult(t *testing.T) { type args struct { - outputFormat string - sortBy string - members []authorization.Member + outputFormat string + organizationId string + sortBy string + members []authorization.Member } tests := []struct { name string @@ -199,7 +200,7 @@ func TestOutputResult(t *testing.T) { params := testparams.NewTestParams() for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if err := outputResult(params.Printer, tt.args.outputFormat, tt.args.sortBy, tt.args.members); (err != nil) != tt.wantErr { + if err := outputResult(params.Printer, tt.args.outputFormat, tt.args.organizationId, tt.args.sortBy, tt.args.members); (err != nil) != tt.wantErr { t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr) } }) diff --git a/internal/cmd/organization/member/remove/remove.go b/internal/cmd/organization/member/remove/remove.go index 27e95be67..d4e4324ea 100644 --- a/internal/cmd/organization/member/remove/remove.go +++ b/internal/cmd/organization/member/remove/remove.go @@ -6,16 +6,15 @@ import ( "github.com/stackitcloud/stackit-cli/internal/pkg/types" + "github.com/spf13/cobra" + authorization "github.com/stackitcloud/stackit-sdk-go/services/authorization/v2api" + "github.com/stackitcloud/stackit-cli/internal/pkg/args" "github.com/stackitcloud/stackit-cli/internal/pkg/examples" "github.com/stackitcloud/stackit-cli/internal/pkg/flags" "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/print" "github.com/stackitcloud/stackit-cli/internal/pkg/services/authorization/client" - "github.com/stackitcloud/stackit-cli/internal/pkg/utils" - - "github.com/spf13/cobra" - "github.com/stackitcloud/stackit-sdk-go/services/authorization" ) const ( @@ -31,9 +30,9 @@ const ( type inputModel struct { *globalflags.GlobalFlagModel - OrganizationId *string + OrganizationId string Subject string - Role *string + Role string Force bool } @@ -68,7 +67,7 @@ func NewCmd(params *types.CmdParams) *cobra.Command { return err } - prompt := fmt.Sprintf("Are you sure you want to remove the %s role from %s on organization with ID %q?", *model.Role, model.Subject, *model.OrganizationId) + prompt := fmt.Sprintf("Are you sure you want to remove the %s role from %s on organization with ID %q?", model.Role, model.Subject, model.OrganizationId) if model.Force { prompt = fmt.Sprintf("%s This will also remove other roles of the subject that would stop the removal of the requested role", prompt) } @@ -108,9 +107,9 @@ func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inpu model := inputModel{ GlobalFlagModel: globalFlags, - OrganizationId: flags.FlagToStringPointer(p, cmd, organizationIdFlag), + OrganizationId: flags.FlagToStringValue(p, cmd, organizationIdFlag), Subject: subject, - Role: flags.FlagToStringPointer(p, cmd, roleFlag), + Role: flags.FlagToStringValue(p, cmd, roleFlag), Force: flags.FlagToBoolValue(p, cmd, forceFlag), } @@ -119,15 +118,15 @@ func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inpu } func buildRequest(ctx context.Context, model *inputModel, apiClient *authorization.APIClient) authorization.ApiRemoveMembersRequest { - req := apiClient.RemoveMembers(ctx, *model.OrganizationId) + req := apiClient.DefaultAPI.RemoveMembers(ctx, model.OrganizationId) payload := authorization.RemoveMembersPayload{ - Members: utils.Ptr([]authorization.Member{ + Members: []authorization.Member{ { - Subject: utils.Ptr(model.Subject), + Subject: model.Subject, Role: model.Role, }, - }), - ResourceType: utils.Ptr(organizationResourceType), + }, + ResourceType: organizationResourceType, } payload.ForceRemove = &model.Force req = req.RemoveMembersPayload(payload) diff --git a/internal/cmd/organization/member/remove/remove_test.go b/internal/cmd/organization/member/remove/remove_test.go index 81f1a368c..b9032138a 100644 --- a/internal/cmd/organization/member/remove/remove_test.go +++ b/internal/cmd/organization/member/remove/remove_test.go @@ -10,13 +10,13 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" - "github.com/stackitcloud/stackit-sdk-go/services/authorization" + authorization "github.com/stackitcloud/stackit-sdk-go/services/authorization/v2api" ) type testCtxKey struct{} var testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") -var testClient = &authorization.APIClient{} +var testClient = &authorization.APIClient{DefaultAPI: &authorization.DefaultAPIService{}} var testOrganizationID = "some-organization-id" var testSubject = "someone@domain.com" var testRole = "reader" @@ -45,9 +45,9 @@ func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]st func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { model := &inputModel{ GlobalFlagModel: &globalflags.GlobalFlagModel{Verbosity: globalflags.VerbosityDefault}, - OrganizationId: utils.Ptr(testOrganizationID), + OrganizationId: testOrganizationID, Subject: testSubject, - Role: utils.Ptr(testRole), + Role: testRole, } for _, mod := range mods { mod(model) @@ -56,15 +56,15 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { } func fixtureRequest(mods ...func(request *authorization.ApiRemoveMembersRequest)) authorization.ApiRemoveMembersRequest { - request := testClient.RemoveMembers(testCtx, testOrganizationID) + request := testClient.DefaultAPI.RemoveMembers(testCtx, testOrganizationID) request = request.RemoveMembersPayload(authorization.RemoveMembersPayload{ - Members: utils.Ptr([]authorization.Member{ + Members: []authorization.Member{ { - Subject: &testSubject, - Role: &testRole, + Subject: testSubject, + Role: testRole, }, - }), - ResourceType: utils.Ptr(organizationResourceType), + }, + ResourceType: organizationResourceType, ForceRemove: utils.Ptr(false), }) @@ -158,15 +158,15 @@ func TestBuildRequest(t *testing.T) { model: fixtureInputModel(func(model *inputModel) { model.Force = true }), - expectedRequest: testClient.RemoveMembers(testCtx, testOrganizationID). + expectedRequest: testClient.DefaultAPI.RemoveMembers(testCtx, testOrganizationID). RemoveMembersPayload(authorization.RemoveMembersPayload{ - Members: utils.Ptr([]authorization.Member{ + Members: []authorization.Member{ { - Subject: &testSubject, - Role: &testRole, + Subject: testSubject, + Role: testRole, }, - }), - ResourceType: utils.Ptr(organizationResourceType), + }, + ResourceType: organizationResourceType, ForceRemove: utils.Ptr(true), }), }, @@ -178,7 +178,7 @@ func TestBuildRequest(t *testing.T) { diff := cmp.Diff(request, tt.expectedRequest, cmp.AllowUnexported(tt.expectedRequest), - cmpopts.EquateComparable(testCtx), + cmpopts.EquateComparable(testCtx, authorization.DefaultAPIService{}), ) if diff != "" { t.Fatalf("Data does not match: %s", diff) diff --git a/internal/cmd/organization/role/list/list.go b/internal/cmd/organization/role/list/list.go index f9e7e4bf7..f301579a9 100644 --- a/internal/cmd/organization/role/list/list.go +++ b/internal/cmd/organization/role/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/authorization" + authorization "github.com/stackitcloud/stackit-sdk-go/services/authorization/v2api" "github.com/stackitcloud/stackit-cli/internal/pkg/args" "github.com/stackitcloud/stackit-cli/internal/pkg/errors" @@ -17,7 +17,6 @@ import ( "github.com/stackitcloud/stackit-cli/internal/pkg/print" "github.com/stackitcloud/stackit-cli/internal/pkg/services/authorization/client" "github.com/stackitcloud/stackit-cli/internal/pkg/tables" - "github.com/stackitcloud/stackit-cli/internal/pkg/utils" ) const ( @@ -30,7 +29,7 @@ const ( type inputModel struct { *globalflags.GlobalFlagModel - OrganizationId *string + OrganizationId string Limit *int64 } @@ -70,18 +69,14 @@ func NewCmd(params *types.CmdParams) *cobra.Command { if err != nil { return fmt.Errorf("get organization roles: %w", err) } - roles := *resp.Roles - if len(roles) == 0 { - params.Printer.Info("No roles found for organization with ID %q\n", *model.OrganizationId) - return nil - } + roles := resp.Roles // Truncate output if model.Limit != nil && len(roles) > int(*model.Limit) { roles = roles[:*model.Limit] } - return outputRolesResult(params.Printer, model.OutputFormat, roles) + return outputRolesResult(params.Printer, model.OutputFormat, model.OrganizationId, roles) }, } configureFlags(cmd) @@ -109,7 +104,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command, _ []string) (*inputModel, model := inputModel{ GlobalFlagModel: globalFlags, - OrganizationId: flags.FlagToStringPointer(p, cmd, organizationIdFlag), + OrganizationId: flags.FlagToStringValue(p, cmd, organizationIdFlag), Limit: flags.FlagToInt64Pointer(p, cmd, limitFlag), } @@ -118,23 +113,26 @@ func parseInput(p *print.Printer, cmd *cobra.Command, _ []string) (*inputModel, } func buildRequest(ctx context.Context, model *inputModel, apiClient *authorization.APIClient) authorization.ApiListRolesRequest { - return apiClient.ListRoles(ctx, organizationResourceType, *model.OrganizationId) + return apiClient.DefaultAPI.ListRoles(ctx, organizationResourceType, model.OrganizationId) } -func outputRolesResult(p *print.Printer, outputFormat string, roles []authorization.Role) error { +func outputRolesResult(p *print.Printer, outputFormat, organizationId string, roles []authorization.Role) error { return p.OutputResult(outputFormat, roles, func() error { + if len(roles) == 0 { + p.Outputf("No roles found for organization with ID %q\n", organizationId) + return nil + } + table := tables.NewTable() table.SetHeader("ROLE NAME", "ROLE DESCRIPTION", "PERMISSION NAME", "PERMISSION DESCRIPTION") - for i := range roles { - r := roles[i] + for _, r := range roles { if r.Permissions != nil { - for j := range *r.Permissions { - p := (*r.Permissions)[j] + for _, p := range r.Permissions { table.AddRow( - utils.PtrString(r.Name), - utils.PtrString(r.Description), - utils.PtrString(p.Name), - utils.PtrString(p.Description), + r.Name, + r.Description, + p.Name, + p.Description, ) } table.AddSeparator() diff --git a/internal/cmd/organization/role/list/list_test.go b/internal/cmd/organization/role/list/list_test.go index 4a758d7a9..a75959e79 100644 --- a/internal/cmd/organization/role/list/list_test.go +++ b/internal/cmd/organization/role/list/list_test.go @@ -11,13 +11,13 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" - "github.com/stackitcloud/stackit-sdk-go/services/authorization" + authorization "github.com/stackitcloud/stackit-sdk-go/services/authorization/v2api" ) type testCtxKey struct{} var testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") -var testClient = &authorization.APIClient{} +var testClient = &authorization.APIClient{DefaultAPI: &authorization.DefaultAPIService{}} var testOrganizationID = "some-organization-id" func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]string { @@ -34,7 +34,7 @@ func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]st func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { model := &inputModel{ GlobalFlagModel: &globalflags.GlobalFlagModel{Verbosity: globalflags.VerbosityDefault}, - OrganizationId: utils.Ptr(testOrganizationID), + OrganizationId: testOrganizationID, Limit: utils.Ptr(int64(10)), } for _, mod := range mods { @@ -44,7 +44,7 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { } func fixtureRequest(mods ...func(request *authorization.ApiListRolesRequest)) authorization.ApiListRolesRequest { - request := testClient.ListRoles(testCtx, organizationResourceType, testOrganizationID) + request := testClient.DefaultAPI.ListRoles(testCtx, organizationResourceType, testOrganizationID) for _, mod := range mods { mod(&request) } @@ -119,7 +119,7 @@ func TestBuildRequest(t *testing.T) { diff := cmp.Diff(request, tt.expectedRequest, cmp.AllowUnexported(tt.expectedRequest), - cmpopts.EquateComparable(testCtx), + cmpopts.EquateComparable(testCtx, authorization.DefaultAPIService{}), ) if diff != "" { t.Fatalf("Data does not match: %s", diff) @@ -130,8 +130,9 @@ func TestBuildRequest(t *testing.T) { func TestOutputResult(t *testing.T) { type args struct { - outputFormat string - roles []authorization.Role + outputFormat string + organizationId string + roles []authorization.Role } tests := []struct { name string @@ -161,7 +162,7 @@ func TestOutputResult(t *testing.T) { params := testparams.NewTestParams() for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if err := outputRolesResult(params.Printer, tt.args.outputFormat, tt.args.roles); (err != nil) != tt.wantErr { + if err := outputRolesResult(params.Printer, tt.args.outputFormat, tt.args.organizationId, tt.args.roles); (err != nil) != tt.wantErr { t.Errorf("outputRolesResult() error = %v, wantErr %v", err, tt.wantErr) } }) diff --git a/internal/cmd/project/member/add/add.go b/internal/cmd/project/member/add/add.go index 0901fba52..14cc1a873 100644 --- a/internal/cmd/project/member/add/add.go +++ b/internal/cmd/project/member/add/add.go @@ -6,6 +6,9 @@ import ( "github.com/stackitcloud/stackit-cli/internal/pkg/types" + "github.com/spf13/cobra" + authorization "github.com/stackitcloud/stackit-sdk-go/services/authorization/v2api" + "github.com/stackitcloud/stackit-cli/internal/pkg/args" "github.com/stackitcloud/stackit-cli/internal/pkg/errors" "github.com/stackitcloud/stackit-cli/internal/pkg/examples" @@ -14,10 +17,6 @@ import ( "github.com/stackitcloud/stackit-cli/internal/pkg/print" "github.com/stackitcloud/stackit-cli/internal/pkg/projectname" "github.com/stackitcloud/stackit-cli/internal/pkg/services/authorization/client" - "github.com/stackitcloud/stackit-cli/internal/pkg/utils" - - "github.com/spf13/cobra" - "github.com/stackitcloud/stackit-sdk-go/services/authorization" ) const ( @@ -32,7 +31,7 @@ type inputModel struct { *globalflags.GlobalFlagModel Subject string - Role *string + Role string } func NewCmd(params *types.CmdParams) *cobra.Command { @@ -71,7 +70,7 @@ func NewCmd(params *types.CmdParams) *cobra.Command { projectLabel = model.ProjectId } - prompt := fmt.Sprintf("Are you sure you want to add the role %q to %s on project %q?", *model.Role, model.Subject, projectLabel) + prompt := fmt.Sprintf("Are you sure you want to add the role %q to %s on project %q?", model.Role, model.Subject, projectLabel) err = params.Printer.PromptForConfirmation(prompt) if err != nil { return err @@ -84,7 +83,7 @@ func NewCmd(params *types.CmdParams) *cobra.Command { return fmt.Errorf("add member: %w", err) } - params.Printer.Info("Added the role %q to %s on project %q\n", utils.PtrString(model.Role), model.Subject, projectLabel) + params.Printer.Info("Added the role %q to %s on project %q\n", model.Role, model.Subject, projectLabel) return nil }, } @@ -110,7 +109,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inpu model := inputModel{ GlobalFlagModel: globalFlags, Subject: subject, - Role: flags.FlagToStringPointer(p, cmd, roleFlag), + Role: flags.FlagToStringValue(p, cmd, roleFlag), } p.DebugInputModel(model) @@ -118,15 +117,15 @@ func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inpu } func buildRequest(ctx context.Context, model *inputModel, apiClient *authorization.APIClient) authorization.ApiAddMembersRequest { - req := apiClient.AddMembers(ctx, model.ProjectId) + req := apiClient.DefaultAPI.AddMembers(ctx, model.ProjectId) req = req.AddMembersPayload(authorization.AddMembersPayload{ - Members: utils.Ptr([]authorization.Member{ + Members: []authorization.Member{ { - Subject: utils.Ptr(model.Subject), + Subject: model.Subject, Role: model.Role, }, - }), - ResourceType: utils.Ptr(projectResourceType), + }, + ResourceType: projectResourceType, }) return req } diff --git a/internal/cmd/project/member/add/add_test.go b/internal/cmd/project/member/add/add_test.go index fa8cb5f04..963de0b35 100644 --- a/internal/cmd/project/member/add/add_test.go +++ b/internal/cmd/project/member/add/add_test.go @@ -4,14 +4,13 @@ import ( "context" "testing" - "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/authorization" + authorization "github.com/stackitcloud/stackit-sdk-go/services/authorization/v2api" + + "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" + "github.com/stackitcloud/stackit-cli/internal/pkg/testutils" ) var projectIdFlag = globalflags.ProjectIdFlag @@ -19,7 +18,7 @@ var projectIdFlag = globalflags.ProjectIdFlag type testCtxKey struct{} var testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") -var testClient = &authorization.APIClient{} +var testClient = &authorization.APIClient{DefaultAPI: &authorization.DefaultAPIService{}} var testProjectId = uuid.NewString() var testSubject = "someone@domain.com" var testRole = "reader" @@ -52,7 +51,7 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { Verbosity: globalflags.VerbosityDefault, }, Subject: testSubject, - Role: utils.Ptr(testRole), + Role: testRole, } for _, mod := range mods { mod(model) @@ -61,15 +60,15 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { } func fixtureRequest(mods ...func(request *authorization.ApiAddMembersRequest)) authorization.ApiAddMembersRequest { - request := testClient.AddMembers(testCtx, testProjectId) + request := testClient.DefaultAPI.AddMembers(testCtx, testProjectId) request = request.AddMembersPayload(authorization.AddMembersPayload{ - Members: utils.Ptr([]authorization.Member{ + Members: []authorization.Member{ { - Subject: &testSubject, - Role: &testRole, + Subject: testSubject, + Role: testRole, }, - }), - ResourceType: utils.Ptr(projectResourceType), + }, + ResourceType: projectResourceType, }) for _, mod := range mods { @@ -147,7 +146,7 @@ func TestBuildRequest(t *testing.T) { diff := cmp.Diff(request, tt.expectedRequest, cmp.AllowUnexported(tt.expectedRequest), - cmpopts.EquateComparable(testCtx), + cmpopts.EquateComparable(testCtx, authorization.DefaultAPIService{}), ) if diff != "" { t.Fatalf("Data does not match: %s", diff) diff --git a/internal/cmd/project/member/list/list.go b/internal/cmd/project/member/list/list.go index 1dd53f369..4db5dbfa5 100644 --- a/internal/cmd/project/member/list/list.go +++ b/internal/cmd/project/member/list/list.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/authorization" + authorization "github.com/stackitcloud/stackit-sdk-go/services/authorization/v2api" "github.com/stackitcloud/stackit-cli/internal/pkg/args" "github.com/stackitcloud/stackit-cli/internal/pkg/errors" @@ -19,7 +19,6 @@ import ( "github.com/stackitcloud/stackit-cli/internal/pkg/projectname" "github.com/stackitcloud/stackit-cli/internal/pkg/services/authorization/client" "github.com/stackitcloud/stackit-cli/internal/pkg/tables" - "github.com/stackitcloud/stackit-cli/internal/pkg/utils" ) const ( @@ -80,15 +79,12 @@ func NewCmd(params *types.CmdParams) *cobra.Command { if err != nil { return fmt.Errorf("list members: %w", err) } - members := *resp.Members - if len(members) == 0 { - projectLabel, err := projectname.GetProjectName(ctx, params.Printer, params.CliVersion, cmd) - if err != nil { - params.Printer.Debug(print.ErrorLevel, "get project name: %v", err) - projectLabel = model.ProjectId - } - params.Printer.Info("No members found for project %q\n", projectLabel) - return nil + members := resp.Members + + projectLabel, err := projectname.GetProjectName(ctx, params.Printer, params.CliVersion, cmd) + if err != nil { + params.Printer.Debug(print.ErrorLevel, "get project name: %v", err) + projectLabel = model.ProjectId } // Truncate output @@ -96,7 +92,7 @@ func NewCmd(params *types.CmdParams) *cobra.Command { members = members[:*model.Limit] } - return outputResult(params.Printer, *model, members) + return outputResult(params.Printer, *model, projectLabel, members) }, } configureFlags(cmd) @@ -135,23 +131,23 @@ func parseInput(p *print.Printer, cmd *cobra.Command, _ []string) (*inputModel, } func buildRequest(ctx context.Context, model *inputModel, apiClient *authorization.APIClient) authorization.ApiListMembersRequest { - req := apiClient.ListMembers(ctx, projectResourceType, model.ProjectId) + req := apiClient.DefaultAPI.ListMembers(ctx, projectResourceType, model.ProjectId) if model.Subject != nil { req = req.Subject(*model.Subject) } return req } -func outputResult(p *print.Printer, model inputModel, members []authorization.Member) error { +func outputResult(p *print.Printer, model inputModel, projectLabel string, members []authorization.Member) error { if model.GlobalFlagModel == nil { return fmt.Errorf("globalflags are empty") } sortFn := func(i, j int) bool { switch model.SortBy { case "subject": - return utils.PtrString(members[i].Subject) < utils.PtrString(members[j].Subject) + return members[i].Subject < members[j].Subject case "role": - return utils.PtrString(members[i].Role) < utils.PtrString(members[j].Role) + return members[i].Role < members[j].Role default: return false } @@ -159,6 +155,10 @@ func outputResult(p *print.Printer, model inputModel, members []authorization.Me sort.SliceStable(members, sortFn) return p.OutputResult(model.OutputFormat, members, func() error { + if len(members) == 0 { + p.Outputf("No members found for project %q\n", projectLabel) + } + table := tables.NewTable() table.SetHeader("SUBJECT", "ROLE") for i := range members { @@ -167,7 +167,7 @@ func outputResult(p *print.Printer, model inputModel, members []authorization.Me if i > 0 && sortFn(i-1, i) { table.AddSeparator() } - table.AddRow(utils.PtrString(m.Subject), utils.PtrString(m.Role)) + table.AddRow(m.Subject, m.Role) } switch model.SortBy { diff --git a/internal/cmd/project/member/list/list_test.go b/internal/cmd/project/member/list/list_test.go index 4c31dc91c..b468e8d61 100644 --- a/internal/cmd/project/member/list/list_test.go +++ b/internal/cmd/project/member/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/authorization" + authorization "github.com/stackitcloud/stackit-sdk-go/services/authorization/v2api" "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/testparams" @@ -20,7 +20,7 @@ var projectIdFlag = globalflags.ProjectIdFlag type testCtxKey struct{} var testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") -var testClient = &authorization.APIClient{} +var testClient = &authorization.APIClient{DefaultAPI: &authorization.DefaultAPIService{}} var testProjectId = uuid.NewString() func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]string { @@ -50,7 +50,7 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { } func fixtureRequest(mods ...func(request *authorization.ApiListMembersRequest)) authorization.ApiListMembersRequest { - request := testClient.ListMembers(testCtx, projectResourceType, testProjectId) + request := testClient.DefaultAPI.ListMembers(testCtx, projectResourceType, testProjectId) for _, mod := range mods { mod(&request) } @@ -161,7 +161,7 @@ func TestBuildRequest(t *testing.T) { diff := cmp.Diff(request, tt.expectedRequest, cmp.AllowUnexported(tt.expectedRequest), - cmpopts.EquateComparable(testCtx), + cmpopts.EquateComparable(testCtx, authorization.DefaultAPIService{}), ) if diff != "" { t.Fatalf("Data does not match: %s", diff) @@ -172,38 +172,65 @@ func TestBuildRequest(t *testing.T) { func Test_outputResult(t *testing.T) { type args struct { - model inputModel - members []authorization.Member + model inputModel + projectLabel string + members []authorization.Member } tests := []struct { name string args args wantErr bool }{ - {"empty", args{model: inputModel{GlobalFlagModel: &globalflags.GlobalFlagModel{}}}, false}, - {"base", args{inputModel{ - GlobalFlagModel: &globalflags.GlobalFlagModel{}, - Subject: utils.Ptr("subject"), - Limit: nil, - SortBy: "", - }, nil}, false}, - {"complete", args{inputModel{ - GlobalFlagModel: &globalflags.GlobalFlagModel{}, - Subject: utils.Ptr("subject"), - Limit: nil, - SortBy: "", + { + name: "empty", + args: args{ + model: inputModel{ + GlobalFlagModel: &globalflags.GlobalFlagModel{}}, + }, + wantErr: false, + }, + { + name: "base", + args: args{ + model: inputModel{ + GlobalFlagModel: &globalflags.GlobalFlagModel{}, + Subject: utils.Ptr("subject"), + Limit: nil, + SortBy: "", + }, + members: nil}, + wantErr: false, + }, + { + name: "complete", + args: args{ + model: inputModel{ + GlobalFlagModel: &globalflags.GlobalFlagModel{}, + Subject: utils.Ptr("subject"), + Limit: nil, + SortBy: "", + }, + members: []authorization.Member{ + { + Role: "role1", + Subject: "subject1", + }, + { + Role: "role2", + Subject: "subject2", + }, + { + Role: "role3", + Subject: "subject3", + }, + }}, + wantErr: false, }, - []authorization.Member{ - {Role: utils.Ptr("role1"), Subject: utils.Ptr("subject1")}, - {Role: utils.Ptr("role2"), Subject: utils.Ptr("subject2")}, - {Role: utils.Ptr("role3"), Subject: utils.Ptr("subject3")}, - }}, - false}, } params := testparams.NewTestParams() for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if err := outputResult(params.Printer, tt.args.model, tt.args.members); (err != nil) != tt.wantErr { + if err := outputResult(params.Printer, tt.args.model, tt.args.projectLabel, tt.args.members); (err != nil) != tt.wantErr { t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr) } }) diff --git a/internal/cmd/project/member/remove/remove.go b/internal/cmd/project/member/remove/remove.go index 70a7c46d6..bc578205e 100644 --- a/internal/cmd/project/member/remove/remove.go +++ b/internal/cmd/project/member/remove/remove.go @@ -6,6 +6,9 @@ import ( "github.com/stackitcloud/stackit-cli/internal/pkg/types" + "github.com/spf13/cobra" + authorization "github.com/stackitcloud/stackit-sdk-go/services/authorization/v2api" + "github.com/stackitcloud/stackit-cli/internal/pkg/args" "github.com/stackitcloud/stackit-cli/internal/pkg/errors" "github.com/stackitcloud/stackit-cli/internal/pkg/examples" @@ -14,10 +17,6 @@ import ( "github.com/stackitcloud/stackit-cli/internal/pkg/print" "github.com/stackitcloud/stackit-cli/internal/pkg/projectname" "github.com/stackitcloud/stackit-cli/internal/pkg/services/authorization/client" - "github.com/stackitcloud/stackit-cli/internal/pkg/utils" - - "github.com/spf13/cobra" - "github.com/stackitcloud/stackit-sdk-go/services/authorization" ) const ( @@ -33,7 +32,7 @@ type inputModel struct { *globalflags.GlobalFlagModel Subject string - Role *string + Role string Force bool } @@ -74,7 +73,7 @@ func NewCmd(params *types.CmdParams) *cobra.Command { projectLabel = model.ProjectId } - prompt := fmt.Sprintf("Are you sure you want to remove the role %q from %s on project %q?", *model.Role, model.Subject, projectLabel) + prompt := fmt.Sprintf("Are you sure you want to remove the role %q from %s on project %q?", model.Role, model.Subject, projectLabel) if model.Force { prompt = fmt.Sprintf("%s This will also remove other roles of the subject that would stop the removal of the requested role", prompt) } @@ -90,7 +89,7 @@ func NewCmd(params *types.CmdParams) *cobra.Command { return fmt.Errorf("remove member: %w", err) } - params.Printer.Info("Removed the role %q from %s on project %q\n", utils.PtrString(model.Role), model.Subject, projectLabel) + params.Printer.Info("Removed the role %q from %s on project %q\n", model.Role, model.Subject, projectLabel) return nil }, } @@ -117,7 +116,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inpu model := inputModel{ GlobalFlagModel: globalFlags, Subject: subject, - Role: flags.FlagToStringPointer(p, cmd, roleFlag), + Role: flags.FlagToStringValue(p, cmd, roleFlag), Force: flags.FlagToBoolValue(p, cmd, forceFlag), } @@ -126,15 +125,15 @@ func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inpu } func buildRequest(ctx context.Context, model *inputModel, apiClient *authorization.APIClient) authorization.ApiRemoveMembersRequest { - req := apiClient.RemoveMembers(ctx, model.ProjectId) + req := apiClient.DefaultAPI.RemoveMembers(ctx, model.ProjectId) payload := authorization.RemoveMembersPayload{ - Members: utils.Ptr([]authorization.Member{ + Members: []authorization.Member{ { - Subject: utils.Ptr(model.Subject), + Subject: model.Subject, Role: model.Role, }, - }), - ResourceType: utils.Ptr(projectResourceType), + }, + ResourceType: projectResourceType, } payload.ForceRemove = &model.Force req = req.RemoveMembersPayload(payload) diff --git a/internal/cmd/project/member/remove/remove_test.go b/internal/cmd/project/member/remove/remove_test.go index d0fc6d8f0..95ed9254c 100644 --- a/internal/cmd/project/member/remove/remove_test.go +++ b/internal/cmd/project/member/remove/remove_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/authorization" + authorization "github.com/stackitcloud/stackit-sdk-go/services/authorization/v2api" ) var projectIdFlag = globalflags.ProjectIdFlag @@ -19,7 +19,7 @@ var projectIdFlag = globalflags.ProjectIdFlag type testCtxKey struct{} var testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") -var testClient = &authorization.APIClient{} +var testClient = &authorization.APIClient{DefaultAPI: &authorization.DefaultAPIService{}} var testProjectId = uuid.NewString() var testSubject = "someone@domain.com" var testRole = "reader" @@ -52,7 +52,7 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { Verbosity: globalflags.VerbosityDefault, }, Subject: testSubject, - Role: utils.Ptr(testRole), + Role: testRole, } for _, mod := range mods { mod(model) @@ -61,15 +61,15 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { } func fixtureRequest(mods ...func(request *authorization.ApiRemoveMembersRequest)) authorization.ApiRemoveMembersRequest { - request := testClient.RemoveMembers(testCtx, testProjectId) + request := testClient.DefaultAPI.RemoveMembers(testCtx, testProjectId) request = request.RemoveMembersPayload(authorization.RemoveMembersPayload{ - Members: utils.Ptr([]authorization.Member{ + Members: []authorization.Member{ { - Subject: &testSubject, - Role: &testRole, + Subject: testSubject, + Role: testRole, }, - }), - ResourceType: utils.Ptr(projectResourceType), + }, + ResourceType: projectResourceType, ForceRemove: utils.Ptr(false), }) @@ -157,15 +157,15 @@ func TestBuildRequest(t *testing.T) { model: fixtureInputModel(func(model *inputModel) { model.Force = true }), - expectedRequest: testClient.RemoveMembers(testCtx, testProjectId). + expectedRequest: testClient.DefaultAPI.RemoveMembers(testCtx, testProjectId). RemoveMembersPayload(authorization.RemoveMembersPayload{ - Members: utils.Ptr([]authorization.Member{ + Members: []authorization.Member{ { - Subject: &testSubject, - Role: &testRole, + Subject: testSubject, + Role: testRole, }, - }), - ResourceType: utils.Ptr(projectResourceType), + }, + ResourceType: projectResourceType, ForceRemove: utils.Ptr(true), }), }, @@ -177,7 +177,7 @@ func TestBuildRequest(t *testing.T) { diff := cmp.Diff(request, tt.expectedRequest, cmp.AllowUnexported(tt.expectedRequest), - cmpopts.EquateComparable(testCtx), + cmpopts.EquateComparable(testCtx, authorization.DefaultAPIService{}), ) if diff != "" { t.Fatalf("Data does not match: %s", diff) diff --git a/internal/cmd/project/role/list/list.go b/internal/cmd/project/role/list/list.go index 292cad0d2..e3180437a 100644 --- a/internal/cmd/project/role/list/list.go +++ b/internal/cmd/project/role/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/authorization" + authorization "github.com/stackitcloud/stackit-sdk-go/services/authorization/v2api" "github.com/stackitcloud/stackit-cli/internal/pkg/args" "github.com/stackitcloud/stackit-cli/internal/pkg/errors" @@ -18,7 +18,6 @@ import ( "github.com/stackitcloud/stackit-cli/internal/pkg/projectname" "github.com/stackitcloud/stackit-cli/internal/pkg/services/authorization/client" "github.com/stackitcloud/stackit-cli/internal/pkg/tables" - "github.com/stackitcloud/stackit-cli/internal/pkg/utils" ) const ( @@ -69,15 +68,12 @@ func NewCmd(params *types.CmdParams) *cobra.Command { if err != nil { return fmt.Errorf("get project roles: %w", err) } - roles := *resp.Roles - if len(roles) == 0 { - projectLabel, err := projectname.GetProjectName(ctx, params.Printer, params.CliVersion, cmd) - if err != nil { - params.Printer.Debug(print.ErrorLevel, "get project name: %v", err) - projectLabel = model.ProjectId - } - params.Printer.Info("No roles found for project %q\n", projectLabel) - return nil + roles := resp.Roles + + projectLabel, err := projectname.GetProjectName(ctx, params.Printer, params.CliVersion, cmd) + if err != nil { + params.Printer.Debug(print.ErrorLevel, "get project name: %v", err) + projectLabel = model.ProjectId } // Truncate output @@ -85,7 +81,7 @@ func NewCmd(params *types.CmdParams) *cobra.Command { roles = roles[:*model.Limit] } - return outputRolesResult(params.Printer, model.OutputFormat, roles) + return outputRolesResult(params.Printer, model.OutputFormat, projectLabel, roles) }, } configureFlags(cmd) @@ -120,22 +116,24 @@ func parseInput(p *print.Printer, cmd *cobra.Command, _ []string) (*inputModel, } func buildRequest(ctx context.Context, model *inputModel, apiClient *authorization.APIClient) authorization.ApiListRolesRequest { - return apiClient.ListRoles(ctx, projectResourceType, model.ProjectId) + return apiClient.DefaultAPI.ListRoles(ctx, projectResourceType, model.ProjectId) } -func outputRolesResult(p *print.Printer, outputFormat string, roles []authorization.Role) error { +func outputRolesResult(p *print.Printer, outputFormat, projectLabel string, roles []authorization.Role) error { return p.OutputResult(outputFormat, roles, func() error { + if len(roles) == 0 { + p.Outputf("No roles found for project %q\n", projectLabel) + } + table := tables.NewTable() table.SetHeader("ROLE NAME", "ROLE DESCRIPTION", "PERMISSION NAME", "PERMISSION DESCRIPTION") - for i := range roles { - r := roles[i] - for j := range *r.Permissions { - p := (*r.Permissions)[j] + for _, r := range roles { + for _, p := range r.Permissions { table.AddRow( - utils.PtrString(r.Name), - utils.PtrString(r.Description), - utils.PtrString(p.Name), - utils.PtrString(p.Description), + r.Name, + r.Description, + p.Name, + p.Description, ) } table.AddSeparator() diff --git a/internal/cmd/project/role/list/list_test.go b/internal/cmd/project/role/list/list_test.go index 74d044fc2..c8fe0abb2 100644 --- a/internal/cmd/project/role/list/list_test.go +++ b/internal/cmd/project/role/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/authorization" + authorization "github.com/stackitcloud/stackit-sdk-go/services/authorization/v2api" "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/testparams" @@ -20,7 +20,7 @@ var projectIdFlag = globalflags.ProjectIdFlag type testCtxKey struct{} var testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") -var testClient = &authorization.APIClient{} +var testClient = &authorization.APIClient{DefaultAPI: &authorization.DefaultAPIService{}} var testProjectId = uuid.NewString() func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]string { @@ -49,7 +49,7 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { } func fixtureRequest(mods ...func(request *authorization.ApiListRolesRequest)) authorization.ApiListRolesRequest { - request := testClient.ListRoles(testCtx, projectResourceType, testProjectId) + request := testClient.DefaultAPI.ListRoles(testCtx, projectResourceType, testProjectId) for _, mod := range mods { mod(&request) } @@ -124,7 +124,7 @@ func TestBuildRequest(t *testing.T) { diff := cmp.Diff(request, tt.expectedRequest, cmp.AllowUnexported(tt.expectedRequest), - cmpopts.EquateComparable(testCtx), + cmpopts.EquateComparable(testCtx, authorization.DefaultAPIService{}), ) if diff != "" { t.Fatalf("Data does not match: %s", diff) @@ -136,6 +136,7 @@ func TestBuildRequest(t *testing.T) { func Test_outputRolesResult(t *testing.T) { type args struct { outputFormat string + projectLabel string roles []authorization.Role } tests := []struct { @@ -143,23 +144,36 @@ func Test_outputRolesResult(t *testing.T) { args args wantErr bool }{ - {"empty", args{}, false}, - {"standard", args{"", nil}, false}, - {"complete", args{"", []authorization.Role{ - { - Description: utils.Ptr("description"), - Id: utils.Ptr("id"), - Name: utils.Ptr("name"), - Permissions: &[]authorization.Permission{ - {Description: utils.Ptr("description"), Name: utils.Ptr("name")}, - }, + { + name: "empty", + args: args{}, + wantErr: false, + }, + {name: "standard", + args: args{ + outputFormat: "", + roles: nil, }, - }}, false}, + wantErr: false}, + {name: "complete", + args: args{ + outputFormat: "", + roles: []authorization.Role{ + { + Description: "description", + Id: utils.Ptr("id"), + Name: "name", + Permissions: []authorization.Permission{ + {Description: "description", Name: "name"}, + }, + }, + }}, wantErr: false, + }, } params := testparams.NewTestParams() for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if err := outputRolesResult(params.Printer, tt.args.outputFormat, tt.args.roles); (err != nil) != tt.wantErr { + if err := outputRolesResult(params.Printer, tt.args.outputFormat, tt.args.projectLabel, tt.args.roles); (err != nil) != tt.wantErr { t.Errorf("outputRolesResult() error = %v, wantErr %v", err, tt.wantErr) } }) diff --git a/internal/pkg/services/authorization/client/client.go b/internal/pkg/services/authorization/client/client.go index 8646a8120..bf167bde5 100644 --- a/internal/pkg/services/authorization/client/client.go +++ b/internal/pkg/services/authorization/client/client.go @@ -6,7 +6,7 @@ import ( "github.com/stackitcloud/stackit-cli/internal/pkg/print" "github.com/spf13/viper" - "github.com/stackitcloud/stackit-sdk-go/services/authorization" + authorization "github.com/stackitcloud/stackit-sdk-go/services/authorization/v2api" ) func ConfigureClient(p *print.Printer, cliVersion string) (*authorization.APIClient, error) {