Skip to content

Commit

Permalink
fix: [GoSDK] Return role without grants
Browse files Browse the repository at this point in the history
Related to milvus-io#40274

Previousy DescribeRole returns only roles with grants, this PR add
select role action to check role existence.

Also added database properties related option

Signed-off-by: Congqi Xia <[email protected]>
  • Loading branch information
congqixia committed Mar 3, 2025
1 parent 8eb662b commit e553896
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 19 deletions.
14 changes: 11 additions & 3 deletions client/milvusclient/database_options.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,18 +61,26 @@ type CreateDatabaseOption interface {
}

type createDatabaseOption struct {
dbName string
dbName string
Properties map[string]string
}

func (opt *createDatabaseOption) Request() *milvuspb.CreateDatabaseRequest {
return &milvuspb.CreateDatabaseRequest{
DbName: opt.dbName,
DbName: opt.dbName,
Properties: entity.MapKvPairs(opt.Properties),
}
}

func (opt *createDatabaseOption) WithProperty(key string, val any) *createDatabaseOption {
opt.Properties[key] = fmt.Sprintf("%v", val)
return opt
}

func NewCreateDatabaseOption(dbName string) *createDatabaseOption {
return &createDatabaseOption{
dbName: dbName,
dbName: dbName,
Properties: make(map[string]string),
}
}

Expand Down
39 changes: 24 additions & 15 deletions client/milvusclient/rbac.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,30 +128,39 @@ func (c *Client) DropRole(ctx context.Context, opt DropRoleOption, callOpts ...g
}

func (c *Client) DescribeRole(ctx context.Context, option DescribeRoleOption, callOptions ...grpc.CallOption) (*entity.Role, error) {
req := option.Request()

var role *entity.Role
err := c.callService(func(milvusService milvuspb.MilvusServiceClient) error {
resp, err := milvusService.SelectGrant(ctx, req, callOptions...)
if err := merr.CheckRPCCall(resp, err); err != nil {
roleResp, err := milvusService.SelectRole(ctx, option.SelectRoleRequest(), callOptions...)
if err := merr.CheckRPCCall(roleResp, err); err != nil {
return err
}
if len(resp.GetEntities()) == 0 {

if len(roleResp.GetResults()) == 0 {
return errors.New("role not found")
}

role = &entity.Role{
RoleName: req.GetEntity().GetRole().GetName(),
Privileges: lo.Map(resp.GetEntities(), func(g *milvuspb.GrantEntity, _ int) entity.GrantItem {
return entity.GrantItem{
Object: g.Object.GetName(),
ObjectName: g.GetObjectName(),
RoleName: g.GetRole().GetName(),
Grantor: g.GetGrantor().GetUser().GetName(),
Privilege: g.GetGrantor().GetPrivilege().GetName(),
}
}),
RoleName: roleResp.GetResults()[0].GetRole().GetName(),
}

resp, err := milvusService.SelectGrant(ctx, option.Request(), callOptions...)
if err := merr.CheckRPCCall(resp, err); err != nil {
return err
}
if len(resp.GetEntities()) == 0 {
return errors.New("role not found")
}

role.Privileges = lo.Map(resp.GetEntities(), func(g *milvuspb.GrantEntity, _ int) entity.GrantItem {
return entity.GrantItem{
Object: g.GetObject().GetName(),
ObjectName: g.GetObjectName(),
RoleName: g.GetRole().GetName(),
Grantor: g.GetGrantor().GetUser().GetName(),
Privilege: g.GetGrantor().GetPrivilege().GetName(),
}
})

return nil
})
return role, err
Expand Down
9 changes: 9 additions & 0 deletions client/milvusclient/rbac_options.go
Original file line number Diff line number Diff line change
Expand Up @@ -234,13 +234,22 @@ func NewDropRoleOption(roleName string) *dropDropRoleOption {
}

type DescribeRoleOption interface {
SelectRoleRequest() *milvuspb.SelectRoleRequest
Request() *milvuspb.SelectGrantRequest
}

type describeRoleOption struct {
roleName string
}

func (opt *describeRoleOption) SelectRoleRequest() *milvuspb.SelectRoleRequest {
return &milvuspb.SelectRoleRequest{
Role: &milvuspb.RoleEntity{
Name: opt.roleName,
},
}
}

func (opt *describeRoleOption) Request() *milvuspb.SelectGrantRequest {
return &milvuspb.SelectGrantRequest{
Entity: &milvuspb.GrantEntity{
Expand Down
13 changes: 12 additions & 1 deletion client/milvusclient/rbac_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,16 @@ func (s *RoleSuite) TestDescribeRole() {

s.Run("success", func() {
roleName := fmt.Sprintf("role_%s", s.randString(5))
s.mock.EXPECT().SelectRole(mock.Anything, mock.Anything).RunAndReturn(func(ctx context.Context, r *milvuspb.SelectRoleRequest) (*milvuspb.SelectRoleResponse, error) {
s.Equal(roleName, r.GetRole().GetName())
return &milvuspb.SelectRoleResponse{
Results: []*milvuspb.RoleResult{
{
Role: &milvuspb.RoleEntity{Name: roleName},
},
},
}, nil
}).Once()
s.mock.EXPECT().SelectGrant(mock.Anything, mock.Anything).RunAndReturn(func(ctx context.Context, r *milvuspb.SelectGrantRequest) (*milvuspb.SelectGrantResponse, error) {
s.Equal(roleName, r.GetEntity().GetRole().GetName())
return &milvuspb.SelectGrantResponse{
Expand Down Expand Up @@ -329,7 +339,8 @@ func (s *RoleSuite) TestDescribeRole() {
})

s.Run("failure", func() {
s.mock.EXPECT().SelectGrant(mock.Anything, mock.Anything).Return(nil, merr.WrapErrServiceInternal("mocked")).Once()
s.mock.EXPECT().SelectRole(mock.Anything, mock.Anything).Return(nil, merr.WrapErrServiceInternal("mocked")).Once()
// s.mock.EXPECT().SelectGrant(mock.Anything, mock.Anything).Return(nil, merr.WrapErrServiceInternal("mocked")).Once()

_, err := s.client.DescribeRole(ctx, NewDescribeRoleOption("role"))
s.Error(err)
Expand Down

0 comments on commit e553896

Please sign in to comment.