Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 3c12262

Browse files
committedDec 25, 2024·
fix privilege group list and list collections
Signed-off-by: shaoting-huang <[email protected]>
1 parent 648078e commit 3c12262

10 files changed

+257
-204
lines changed
 

‎configs/milvus.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -801,7 +801,7 @@ common:
801801
superUsers:
802802
defaultRootPassword: "Milvus" # default password for root user. The maximum length is 72 characters, and double quotes are required.
803803
rbac:
804-
overrideBuiltInPrivilgeGroups:
804+
overrideBuiltInPrivilegeGroups:
805805
enabled: false # Whether to override build-in privilege groups
806806
cluster:
807807
readonly:

‎internal/proxy/privilege_interceptor_test.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -576,9 +576,9 @@ func TestBuiltinPrivilegeGroup(t *testing.T) {
576576
mgr := newShardClientMgr()
577577

578578
policies := []string{}
579-
for _, priv := range util.BuiltinPrivilegeGroups["ClusterReadOnly"] {
580-
objectType := util.GetObjectType(priv)
581-
policies = append(policies, funcutil.PolicyForPrivilege("role1", objectType, "*", util.PrivilegeNameForMetastore(priv), "default"))
579+
for _, priv := range Params.RbacConfig.GetDefaultPrivilegeGroup("ClusterReadOnly").Privileges {
580+
objectType := util.GetObjectType(priv.Name)
581+
policies = append(policies, funcutil.PolicyForPrivilege("role1", objectType, "*", util.PrivilegeNameForMetastore(priv.Name), "default"))
582582
}
583583
client.listPolicy = func(ctx context.Context, in *internalpb.ListPolicyRequest) (*internalpb.ListPolicyResponse, error) {
584584
return &internalpb.ListPolicyResponse{

‎internal/rootcoord/root_coord.go

+3-56
Original file line numberDiff line numberDiff line change
@@ -611,50 +611,6 @@ func (c *Core) initPublicRolePrivilege() error {
611611
return nil
612612
}
613613

614-
func (c *Core) initBuiltinPrivilegeGroups() []*milvuspb.PrivilegeGroupInfo {
615-
// init built in privilege groups, override by config if rbac config enabled
616-
builtinGroups := make([]*milvuspb.PrivilegeGroupInfo, 0)
617-
for groupName, privileges := range util.BuiltinPrivilegeGroups {
618-
if Params.RbacConfig.Enabled.GetAsBool() {
619-
var confPrivs []string
620-
switch groupName {
621-
case "ClusterReadOnly":
622-
confPrivs = Params.RbacConfig.ClusterReadOnlyPrivileges.GetAsStrings()
623-
case "ClusterReadWrite":
624-
confPrivs = Params.RbacConfig.ClusterReadWritePrivileges.GetAsStrings()
625-
case "ClusterAdmin":
626-
confPrivs = Params.RbacConfig.ClusterAdminPrivileges.GetAsStrings()
627-
case "DatabaseReadOnly":
628-
confPrivs = Params.RbacConfig.DBReadOnlyPrivileges.GetAsStrings()
629-
case "DatabaseReadWrite":
630-
confPrivs = Params.RbacConfig.DBReadWritePrivileges.GetAsStrings()
631-
case "DatabaseAdmin":
632-
confPrivs = Params.RbacConfig.DBAdminPrivileges.GetAsStrings()
633-
case "CollectionReadOnly":
634-
confPrivs = Params.RbacConfig.CollectionReadOnlyPrivileges.GetAsStrings()
635-
case "CollectionReadWrite":
636-
confPrivs = Params.RbacConfig.CollectionReadWritePrivileges.GetAsStrings()
637-
case "CollectionAdmin":
638-
confPrivs = Params.RbacConfig.CollectionAdminPrivileges.GetAsStrings()
639-
default:
640-
return nil
641-
}
642-
if len(confPrivs) > 0 {
643-
privileges = confPrivs
644-
}
645-
}
646-
647-
privs := lo.Map(privileges, func(name string, _ int) *milvuspb.PrivilegeEntity {
648-
return &milvuspb.PrivilegeEntity{Name: name}
649-
})
650-
builtinGroups = append(builtinGroups, &milvuspb.PrivilegeGroupInfo{
651-
GroupName: groupName,
652-
Privileges: privs,
653-
})
654-
}
655-
return builtinGroups
656-
}
657-
658614
func (c *Core) initBuiltinRoles() error {
659615
rolePrivilegesMap := Params.RoleCfg.Roles.GetAsRoleDetails()
660616
for role, privilegesJSON := range rolePrivilegesMap {
@@ -2622,7 +2578,7 @@ func (c *Core) isValidPrivilege(ctx context.Context, privilegeName string, objec
26222578
if customPrivGroup {
26232579
return fmt.Errorf("can not operate the custom privilege group [%s]", privilegeName)
26242580
}
2625-
if lo.Contains(lo.Keys(util.BuiltinPrivilegeGroups), privilegeName) {
2581+
if lo.Contains(Params.RbacConfig.GetDefaultPrivilegeGroupNames(), privilegeName) {
26262582
return fmt.Errorf("can not operate the built-in privilege group [%s]", privilegeName)
26272583
}
26282584
// check object privileges for built-in privileges
@@ -2731,7 +2687,7 @@ func (c *Core) OperatePrivilege(ctx context.Context, in *milvuspb.OperatePrivile
27312687
grants := []*milvuspb.GrantEntity{in.Entity}
27322688

27332689
allGroups, err := c.meta.ListPrivilegeGroups()
2734-
allGroups = append(allGroups, c.initBuiltinPrivilegeGroups()...)
2690+
allGroups = append(allGroups, Params.RbacConfig.GetDefaultPrivilegeGroups()...)
27352691
if err != nil {
27362692
return nil, err
27372693
}
@@ -3204,16 +3160,7 @@ func (c *Core) ListPrivilegeGroups(ctx context.Context, in *milvuspb.ListPrivile
32043160
metrics.RootCoordDDLReqLatency.WithLabelValues(method).Observe(float64(tr.ElapseSpan().Milliseconds()))
32053161

32063162
// append built in privilege groups
3207-
for groupName, privileges := range util.BuiltinPrivilegeGroups {
3208-
privGroups = append(privGroups, &milvuspb.PrivilegeGroupInfo{
3209-
GroupName: groupName,
3210-
Privileges: lo.Map(privileges, func(p string, _ int) *milvuspb.PrivilegeEntity {
3211-
return &milvuspb.PrivilegeEntity{
3212-
Name: p,
3213-
}
3214-
}),
3215-
})
3216-
}
3163+
privGroups = append(privGroups, Params.RbacConfig.GetDefaultPrivilegeGroups()...)
32173164
return &milvuspb.ListPrivilegeGroupsResponse{
32183165
Status: merr.Success(),
32193166
PrivilegeGroups: privGroups,

‎internal/rootcoord/root_coord_test.go

-23
Original file line numberDiff line numberDiff line change
@@ -1898,29 +1898,6 @@ func TestCore_InitRBAC(t *testing.T) {
18981898
err := c.initRbac()
18991899
assert.NoError(t, err)
19001900
})
1901-
1902-
t.Run("init default privilege groups", func(t *testing.T) {
1903-
clusterReadWrite := `SelectOwnership,SelectUser,DescribeResourceGroup`
1904-
meta := mockrootcoord.NewIMetaTable(t)
1905-
c := newTestCore(withHealthyCode(), withMeta(meta))
1906-
1907-
Params.Save(Params.RbacConfig.Enabled.Key, "true")
1908-
Params.Save(Params.RbacConfig.ClusterReadWritePrivileges.Key, clusterReadWrite)
1909-
1910-
defer func() {
1911-
Params.Reset(Params.RbacConfig.Enabled.Key)
1912-
Params.Reset(Params.RbacConfig.ClusterReadWritePrivileges.Key)
1913-
}()
1914-
1915-
builtinGroups := c.initBuiltinPrivilegeGroups()
1916-
fmt.Println(builtinGroups)
1917-
assert.Equal(t, len(util.BuiltinPrivilegeGroups), len(builtinGroups))
1918-
for _, group := range builtinGroups {
1919-
if group.GroupName == "ClusterReadWrite" {
1920-
assert.Equal(t, len(group.Privileges), 3)
1921-
}
1922-
}
1923-
})
19241901
}
19251902

19261903
func TestCore_BackupRBAC(t *testing.T) {

‎internal/rootcoord/show_collection_task.go

+5-2
Original file line numberDiff line numberDiff line change
@@ -88,12 +88,15 @@ func (t *showCollectionTask) Execute(ctx context.Context) error {
8888
}
8989
for _, entity := range entities {
9090
objectType := entity.GetObject().GetName()
91+
priv := entity.GetGrantor().GetPrivilege().GetName()
9192
if objectType == commonpb.ObjectType_Global.String() &&
92-
entity.GetGrantor().GetPrivilege().GetName() == util.PrivilegeNameForAPI(commonpb.ObjectPrivilege_PrivilegeAll.String()) {
93+
priv == util.PrivilegeNameForAPI(commonpb.ObjectPrivilege_PrivilegeAll.String()) {
9394
privilegeColls.Insert(util.AnyWord)
9495
return privilegeColls, nil
9596
}
96-
if objectType != commonpb.ObjectType_Collection.String() {
97+
// should list collection level built-in privilege group objects
98+
if objectType != commonpb.ObjectType_Collection.String() &&
99+
!Params.RbacConfig.IsCollectionPrivilegeGroup(priv) {
97100
continue
98101
}
99102
collectionName := entity.GetObjectName()

‎internal/rootcoord/show_collection_task_test.go

+51
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,57 @@ func TestShowCollectionsAuth(t *testing.T) {
325325
assert.Equal(t, "foo", task.Rsp.GetCollectionNames()[0])
326326
})
327327

328+
t.Run("collection level privilege group", func(t *testing.T) {
329+
Params.Save(Params.CommonCfg.AuthorizationEnabled.Key, "true")
330+
defer Params.Reset(Params.CommonCfg.AuthorizationEnabled.Key)
331+
meta := mockrootcoord.NewIMetaTable(t)
332+
core := newTestCore(withMeta(meta))
333+
334+
meta.EXPECT().SelectUser(mock.Anything, mock.Anything, mock.Anything).
335+
Return([]*milvuspb.UserResult{
336+
{
337+
User: &milvuspb.UserEntity{
338+
Name: "foo",
339+
},
340+
Roles: []*milvuspb.RoleEntity{
341+
{
342+
Name: "hoooo",
343+
},
344+
},
345+
},
346+
}, nil).Once()
347+
meta.EXPECT().SelectGrant(mock.Anything, mock.Anything).Return([]*milvuspb.GrantEntity{
348+
{
349+
Object: &milvuspb.ObjectEntity{Name: commonpb.ObjectType_Global.String()},
350+
Grantor: &milvuspb.GrantorEntity{
351+
Privilege: &milvuspb.PrivilegeEntity{
352+
Name: util.PrivilegeNameForAPI(commonpb.ObjectPrivilege_PrivilegeGroupCollectionReadOnly.String()),
353+
},
354+
},
355+
ObjectName: util.AnyWord,
356+
},
357+
}, nil).Once()
358+
meta.EXPECT().ListCollections(mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return([]*model.Collection{
359+
{
360+
DBID: 1,
361+
CollectionID: 100,
362+
Name: "foo",
363+
CreateTime: tsoutil.GetCurrentTime(),
364+
},
365+
}, nil).Once()
366+
367+
task := &showCollectionTask{
368+
baseTask: newBaseTask(context.Background(), core),
369+
Req: &milvuspb.ShowCollectionsRequest{DbName: "default"},
370+
Rsp: &milvuspb.ShowCollectionsResponse{},
371+
}
372+
ctx := GetContext(context.Background(), "foo:root")
373+
err := task.Execute(ctx)
374+
assert.NoError(t, err)
375+
assert.Equal(t, 1, len(task.Rsp.GetCollectionNames()))
376+
assert.Equal(t, "foo", task.Rsp.GetCollectionNames()[0])
377+
})
378+
328379
t.Run("all collection", func(t *testing.T) {
329380
Params.Save(Params.CommonCfg.AuthorizationEnabled.Key, "true")
330381
defer Params.Reset(Params.CommonCfg.AuthorizationEnabled.Key)

‎pkg/util/constant.go

-95
Original file line numberDiff line numberDiff line change
@@ -290,101 +290,6 @@ var (
290290
commonpb.ObjectPrivilege_PrivilegeAlterDatabase.String(),
291291
commonpb.ObjectPrivilege_PrivilegeFlush.String(),
292292
}
293-
294-
BuiltinPrivilegeGroups = map[string][]string{
295-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeGroupCollectionReadOnly.String()): CollectionReadOnlyPrivilegeGroup,
296-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeGroupCollectionReadWrite.String()): CollectionReadWritePrivilegeGroup,
297-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeGroupCollectionAdmin.String()): CollectionAdminPrivilegeGroup,
298-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeGroupDatabaseReadOnly.String()): DatabaseReadOnlyPrivilegeGroup,
299-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeGroupDatabaseReadWrite.String()): DatabaseReadWritePrivilegeGroup,
300-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeGroupDatabaseAdmin.String()): DatabaseAdminPrivilegeGroup,
301-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeGroupClusterReadOnly.String()): ClusterReadOnlyPrivilegeGroup,
302-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeGroupClusterReadWrite.String()): ClusterReadWritePrivilegeGroup,
303-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeGroupClusterAdmin.String()): ClusterAdminPrivilegeGroup,
304-
}
305-
306-
CollectionReadOnlyPrivilegeGroup = []string{
307-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeQuery.String()),
308-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeSearch.String()),
309-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeIndexDetail.String()),
310-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeGetFlushState.String()),
311-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeGetLoadState.String()),
312-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeGetLoadingProgress.String()),
313-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeHasPartition.String()),
314-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeShowPartitions.String()),
315-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeDescribeCollection.String()),
316-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeDescribeAlias.String()),
317-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeGetStatistics.String()),
318-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeListAliases.String()),
319-
}
320-
321-
CollectionReadWritePrivilegeGroup = append(CollectionReadOnlyPrivilegeGroup,
322-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeLoad.String()),
323-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeRelease.String()),
324-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeInsert.String()),
325-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeDelete.String()),
326-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeUpsert.String()),
327-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeImport.String()),
328-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeFlush.String()),
329-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeCompaction.String()),
330-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeLoadBalance.String()),
331-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeCreateIndex.String()),
332-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeDropIndex.String()),
333-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeCreatePartition.String()),
334-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeDropPartition.String()),
335-
)
336-
337-
CollectionAdminPrivilegeGroup = append(CollectionReadWritePrivilegeGroup,
338-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeCreateAlias.String()),
339-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeDropAlias.String()),
340-
)
341-
342-
DatabaseReadOnlyPrivilegeGroup = []string{
343-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeShowCollections.String()),
344-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeDescribeDatabase.String()),
345-
}
346-
347-
DatabaseReadWritePrivilegeGroup = append(DatabaseReadOnlyPrivilegeGroup,
348-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeAlterDatabase.String()),
349-
)
350-
351-
DatabaseAdminPrivilegeGroup = append(DatabaseReadWritePrivilegeGroup,
352-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeCreateCollection.String()),
353-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeDropCollection.String()),
354-
)
355-
356-
ClusterReadOnlyPrivilegeGroup = []string{
357-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeListDatabases.String()),
358-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeSelectOwnership.String()),
359-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeSelectUser.String()),
360-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeDescribeResourceGroup.String()),
361-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeListResourceGroups.String()),
362-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeListPrivilegeGroups.String()),
363-
}
364-
365-
ClusterReadWritePrivilegeGroup = append(ClusterReadOnlyPrivilegeGroup,
366-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeFlushAll.String()),
367-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeTransferNode.String()),
368-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeTransferReplica.String()),
369-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeUpdateResourceGroups.String()),
370-
)
371-
372-
ClusterAdminPrivilegeGroup = append(ClusterReadWritePrivilegeGroup,
373-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeBackupRBAC.String()),
374-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeRestoreRBAC.String()),
375-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeCreateDatabase.String()),
376-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeDropDatabase.String()),
377-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeCreateOwnership.String()),
378-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeDropOwnership.String()),
379-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeManageOwnership.String()),
380-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeCreateResourceGroup.String()),
381-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeDropResourceGroup.String()),
382-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeUpdateUser.String()),
383-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeRenameCollection.String()),
384-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeCreatePrivilegeGroup.String()),
385-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeDropPrivilegeGroup.String()),
386-
MetaStore2API(commonpb.ObjectPrivilege_PrivilegeOperatePrivilegeGroup.String()),
387-
)
388293
)
389294

390295
// StringSet convert array to map for conveniently check if the array contains an element

‎pkg/util/paramtable/rbac_config_test.go

+30-11
Original file line numberDiff line numberDiff line change
@@ -20,22 +20,41 @@ import (
2020
"testing"
2121

2222
"github.com/stretchr/testify/assert"
23-
24-
"github.com/milvus-io/milvus/pkg/util"
2523
)
2624

2725
func TestRbacConfig_Init(t *testing.T) {
2826
params := ComponentParam{}
2927
params.Init(NewBaseTable(SkipRemote(true)))
3028
cfg := &params.RbacConfig
29+
assert.Equal(t, len(cfg.GetDefaultPrivilegeGroupNames()), 9)
30+
assert.True(t, cfg.IsCollectionPrivilegeGroup("CollectionReadOnly"))
31+
assert.False(t, cfg.IsCollectionPrivilegeGroup("DatabaseReadOnly"))
3132
assert.Equal(t, cfg.Enabled.GetAsBool(), false)
32-
assert.Equal(t, cfg.ClusterReadOnlyPrivileges.GetAsStrings(), util.BuiltinPrivilegeGroups["ClusterReadOnly"])
33-
assert.Equal(t, cfg.ClusterReadWritePrivileges.GetAsStrings(), util.BuiltinPrivilegeGroups["ClusterReadWrite"])
34-
assert.Equal(t, cfg.ClusterAdminPrivileges.GetAsStrings(), util.BuiltinPrivilegeGroups["ClusterAdmin"])
35-
assert.Equal(t, cfg.DBReadOnlyPrivileges.GetAsStrings(), util.BuiltinPrivilegeGroups["DatabaseReadOnly"])
36-
assert.Equal(t, cfg.DBReadWritePrivileges.GetAsStrings(), util.BuiltinPrivilegeGroups["DatabaseReadWrite"])
37-
assert.Equal(t, cfg.DBAdminPrivileges.GetAsStrings(), util.BuiltinPrivilegeGroups["DatabaseAdmin"])
38-
assert.Equal(t, cfg.CollectionReadOnlyPrivileges.GetAsStrings(), util.BuiltinPrivilegeGroups["CollectionReadOnly"])
39-
assert.Equal(t, cfg.CollectionReadWritePrivileges.GetAsStrings(), util.BuiltinPrivilegeGroups["CollectionReadWrite"])
40-
assert.Equal(t, cfg.CollectionAdminPrivileges.GetAsStrings(), util.BuiltinPrivilegeGroups["CollectionAdmin"])
33+
assert.Equal(t, cfg.ClusterReadOnlyPrivileges.GetAsStrings(), builtinPrivilegeGroups["ClusterReadOnly"])
34+
assert.Equal(t, cfg.ClusterReadWritePrivileges.GetAsStrings(), builtinPrivilegeGroups["ClusterReadWrite"])
35+
assert.Equal(t, cfg.ClusterAdminPrivileges.GetAsStrings(), builtinPrivilegeGroups["ClusterAdmin"])
36+
assert.Equal(t, cfg.DBReadOnlyPrivileges.GetAsStrings(), builtinPrivilegeGroups["DatabaseReadOnly"])
37+
assert.Equal(t, cfg.DBReadWritePrivileges.GetAsStrings(), builtinPrivilegeGroups["DatabaseReadWrite"])
38+
assert.Equal(t, cfg.DBAdminPrivileges.GetAsStrings(), builtinPrivilegeGroups["DatabaseAdmin"])
39+
assert.Equal(t, cfg.CollectionReadOnlyPrivileges.GetAsStrings(), builtinPrivilegeGroups["CollectionReadOnly"])
40+
assert.Equal(t, cfg.CollectionReadWritePrivileges.GetAsStrings(), builtinPrivilegeGroups["CollectionReadWrite"])
41+
assert.Equal(t, cfg.CollectionAdminPrivileges.GetAsStrings(), builtinPrivilegeGroups["CollectionAdmin"])
42+
}
43+
44+
func TestRbacConfig_Override(t *testing.T) {
45+
params := ComponentParam{}
46+
params.Init(NewBaseTable(SkipRemote(true)))
47+
48+
clusterReadWrite := `SelectOwnership,SelectUser,DescribeResourceGroup`
49+
50+
params.Save(params.RbacConfig.Enabled.Key, "true")
51+
params.Save(params.RbacConfig.ClusterReadWritePrivileges.Key, clusterReadWrite)
52+
53+
defer func() {
54+
params.Reset(params.RbacConfig.Enabled.Key)
55+
params.Reset(params.RbacConfig.ClusterReadWritePrivileges.Key)
56+
}()
57+
58+
group := params.RbacConfig.GetDefaultPrivilegeGroup("ClusterReadWrite")
59+
assert.Equal(t, len(group.Privileges), 3)
4160
}

‎pkg/util/paramtable/rbac_param.go

+161-10
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,110 @@
33
import (
44
"strings"
55

6+
"github.com/samber/lo"
7+
8+
"github.com/milvus-io/milvus-proto/go-api/v2/commonpb"
9+
"github.com/milvus-io/milvus-proto/go-api/v2/milvuspb"
610
"github.com/milvus-io/milvus/pkg/util"
711
)
812

13+
var (
14+
builtinPrivilegeGroups = map[string][]string{
15+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeGroupCollectionReadOnly.String()): collectionReadOnlyPrivilegeGroup,
16+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeGroupCollectionReadWrite.String()): collectionReadWritePrivilegeGroup,
17+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeGroupCollectionAdmin.String()): collectionAdminPrivilegeGroup,
18+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeGroupDatabaseReadOnly.String()): databaseReadOnlyPrivilegeGroup,
19+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeGroupDatabaseReadWrite.String()): databaseReadWritePrivilegeGroup,
20+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeGroupDatabaseAdmin.String()): databaseAdminPrivilegeGroup,
21+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeGroupClusterReadOnly.String()): clusterReadOnlyPrivilegeGroup,
22+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeGroupClusterReadWrite.String()): clusterReadWritePrivilegeGroup,
23+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeGroupClusterAdmin.String()): clusterAdminPrivilegeGroup,
24+
}
25+
26+
collectionReadOnlyPrivilegeGroup = []string{
27+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeQuery.String()),
28+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeSearch.String()),
29+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeIndexDetail.String()),
30+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeGetFlushState.String()),
31+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeGetLoadState.String()),
32+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeGetLoadingProgress.String()),
33+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeHasPartition.String()),
34+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeShowPartitions.String()),
35+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeDescribeCollection.String()),
36+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeDescribeAlias.String()),
37+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeGetStatistics.String()),
38+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeListAliases.String()),
39+
}
40+
41+
collectionReadWritePrivilegeGroup = append(collectionReadOnlyPrivilegeGroup,
42+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeLoad.String()),
43+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeRelease.String()),
44+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeInsert.String()),
45+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeDelete.String()),
46+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeUpsert.String()),
47+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeImport.String()),
48+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeFlush.String()),
49+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeCompaction.String()),
50+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeLoadBalance.String()),
51+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeCreateIndex.String()),
52+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeDropIndex.String()),
53+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeCreatePartition.String()),
54+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeDropPartition.String()),
55+
)
56+
57+
collectionAdminPrivilegeGroup = append(collectionReadWritePrivilegeGroup,
58+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeCreateAlias.String()),
59+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeDropAlias.String()),
60+
)
61+
62+
databaseReadOnlyPrivilegeGroup = []string{
63+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeShowCollections.String()),
64+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeDescribeDatabase.String()),
65+
}
66+
67+
databaseReadWritePrivilegeGroup = append(databaseReadOnlyPrivilegeGroup,
68+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeAlterDatabase.String()),
69+
)
70+
71+
databaseAdminPrivilegeGroup = append(databaseReadWritePrivilegeGroup,
72+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeCreateCollection.String()),
73+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeDropCollection.String()),
74+
)
75+
76+
clusterReadOnlyPrivilegeGroup = []string{
77+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeListDatabases.String()),
78+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeSelectOwnership.String()),
79+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeSelectUser.String()),
80+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeDescribeResourceGroup.String()),
81+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeListResourceGroups.String()),
82+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeListPrivilegeGroups.String()),
83+
}
84+
85+
clusterReadWritePrivilegeGroup = append(clusterReadOnlyPrivilegeGroup,
86+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeFlushAll.String()),
87+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeTransferNode.String()),
88+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeTransferReplica.String()),
89+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeUpdateResourceGroups.String()),
90+
)
91+
92+
clusterAdminPrivilegeGroup = append(clusterReadWritePrivilegeGroup,
93+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeBackupRBAC.String()),
94+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeRestoreRBAC.String()),
95+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeCreateDatabase.String()),
96+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeDropDatabase.String()),
97+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeCreateOwnership.String()),
98+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeDropOwnership.String()),
99+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeManageOwnership.String()),
100+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeCreateResourceGroup.String()),
101+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeDropResourceGroup.String()),
102+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeUpdateUser.String()),
103+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeRenameCollection.String()),
104+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeCreatePrivilegeGroup.String()),
105+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeDropPrivilegeGroup.String()),
106+
util.MetaStore2API(commonpb.ObjectPrivilege_PrivilegeOperatePrivilegeGroup.String()),
107+
)
108+
)
109+
9110
type rbacConfig struct {
10111
Enabled ParamItem `refreshable:"false"`
11112
ClusterReadOnlyPrivileges ParamItem `refreshable:"false"`
@@ -23,7 +124,7 @@
23124

24125
func (p *rbacConfig) init(base *BaseTable) {
25126
p.Enabled = ParamItem{
26-
Key: "common.security.rbac.overrideBuiltInPrivilgeGroups.enabled",
127+
Key: "common.security.rbac.overrideBuiltInPrivilegeGroups.enabled",
27128
DefaultValue: "false",
28129
Version: "2.4.16",
29130
Doc: "Whether to override build-in privilege groups",
@@ -33,7 +134,7 @@
33134

34135
p.ClusterReadOnlyPrivileges = ParamItem{
35136
Key: "common.security.rbac.cluster.readonly.privileges",
36-
DefaultValue: strings.Join(util.ClusterReadOnlyPrivilegeGroup, ","),
137+
DefaultValue: strings.Join(clusterReadOnlyPrivilegeGroup, ","),
37138
Version: "2.4.16",
38139
Doc: "Cluster level readonly privileges",
39140
Export: true,
@@ -42,7 +143,7 @@
42143

43144
p.ClusterReadWritePrivileges = ParamItem{
44145
Key: "common.security.rbac.cluster.readwrite.privileges",
45-
DefaultValue: strings.Join(util.ClusterReadWritePrivilegeGroup, ","),
146+
DefaultValue: strings.Join(clusterReadWritePrivilegeGroup, ","),
46147
Version: "2.4.16",
47148
Doc: "Cluster level readwrite privileges",
48149
Export: true,
@@ -51,7 +152,7 @@
51152

52153
p.ClusterAdminPrivileges = ParamItem{
53154
Key: "common.security.rbac.cluster.admin.privileges",
54-
DefaultValue: strings.Join(util.ClusterAdminPrivilegeGroup, ","),
155+
DefaultValue: strings.Join(clusterAdminPrivilegeGroup, ","),
55156
Version: "2.4.16",
56157
Doc: "Cluster level admin privileges",
57158
Export: true,
@@ -60,7 +161,7 @@
60161

61162
p.DBReadOnlyPrivileges = ParamItem{
62163
Key: "common.security.rbac.database.readonly.privileges",
63-
DefaultValue: strings.Join(util.DatabaseReadOnlyPrivilegeGroup, ","),
164+
DefaultValue: strings.Join(databaseReadOnlyPrivilegeGroup, ","),
64165
Version: "2.4.16",
65166
Doc: "Database level readonly privileges",
66167
Export: true,
@@ -69,7 +170,7 @@
69170

70171
p.DBReadWritePrivileges = ParamItem{
71172
Key: "common.security.rbac.database.readwrite.privileges",
72-
DefaultValue: strings.Join(util.DatabaseReadWritePrivilegeGroup, ","),
173+
DefaultValue: strings.Join(databaseReadWritePrivilegeGroup, ","),
73174
Version: "2.4.16",
74175
Doc: "Database level readwrite privileges",
75176
Export: true,
@@ -78,7 +179,7 @@
78179

79180
p.DBAdminPrivileges = ParamItem{
80181
Key: "common.security.rbac.database.admin.privileges",
81-
DefaultValue: strings.Join(util.DatabaseAdminPrivilegeGroup, ","),
182+
DefaultValue: strings.Join(databaseAdminPrivilegeGroup, ","),
82183
Version: "2.4.16",
83184
Doc: "Database level admin privileges",
84185
Export: true,
@@ -87,7 +188,7 @@
87188

88189
p.CollectionReadOnlyPrivileges = ParamItem{
89190
Key: "common.security.rbac.collection.readonly.privileges",
90-
DefaultValue: strings.Join(util.CollectionReadOnlyPrivilegeGroup, ","),
191+
DefaultValue: strings.Join(collectionReadOnlyPrivilegeGroup, ","),
91192
Version: "2.4.16",
92193
Doc: "Collection level readonly privileges",
93194
Export: true,
@@ -96,7 +197,7 @@
96197

97198
p.CollectionReadWritePrivileges = ParamItem{
98199
Key: "common.security.rbac.collection.readwrite.privileges",
99-
DefaultValue: strings.Join(util.CollectionReadWritePrivilegeGroup, ","),
200+
DefaultValue: strings.Join(collectionReadWritePrivilegeGroup, ","),
100201
Version: "2.4.16",
101202
Doc: "Collection level readwrite privileges",
102203
Export: true,
@@ -105,10 +206,60 @@
105206

106207
p.CollectionAdminPrivileges = ParamItem{
107208
Key: "common.security.rbac.collection.admin.privileges",
108-
DefaultValue: strings.Join(util.CollectionAdminPrivilegeGroup, ","),
209+
DefaultValue: strings.Join(collectionAdminPrivilegeGroup, ","),
109210
Version: "2.4.16",
110211
Doc: "Collection level admin privileges",
111212
Export: true,
112213
}
113214
p.CollectionAdminPrivileges.Init(base.mgr)
114215
}
216+
217+
func (p *rbacConfig) GetDefaultPrivilegeGroups() []*milvuspb.PrivilegeGroupInfo {
218+
privilegeGroupConfigs := []struct {
219+
GroupName string
220+
Privileges func() []string
221+
}{
222+
{"ClusterReadOnly", p.ClusterReadOnlyPrivileges.GetAsStrings},
223+
{"ClusterReadWrite", p.ClusterReadWritePrivileges.GetAsStrings},
224+
{"ClusterAdmin", p.ClusterAdminPrivileges.GetAsStrings},
225+
{"DatabaseReadOnly", p.DBReadOnlyPrivileges.GetAsStrings},
226+
{"DatabaseReadWrite", p.DBReadWritePrivileges.GetAsStrings},
227+
{"DatabaseAdmin", p.DBAdminPrivileges.GetAsStrings},
228+
{"CollectionReadOnly", p.CollectionReadOnlyPrivileges.GetAsStrings},
229+
{"CollectionReadWrite", p.CollectionReadWritePrivileges.GetAsStrings},
230+
{"CollectionAdmin", p.CollectionAdminPrivileges.GetAsStrings},
231+
}
232+
233+
builtinGroups := make([]*milvuspb.PrivilegeGroupInfo, 0, len(privilegeGroupConfigs))
234+
for _, config := range privilegeGroupConfigs {
235+
privileges := lo.Map(config.Privileges(), func(name string, _ int) *milvuspb.PrivilegeEntity {
236+
return &milvuspb.PrivilegeEntity{Name: name}
237+
})
238+
builtinGroups = append(builtinGroups, &milvuspb.PrivilegeGroupInfo{
239+
GroupName: config.GroupName,
240+
Privileges: privileges,
241+
})
242+
}
243+
return builtinGroups
244+
}
245+
246+
func (p *rbacConfig) GetDefaultPrivilegeGroup(privName string) *milvuspb.PrivilegeGroupInfo {
247+
for _, group := range p.GetDefaultPrivilegeGroups() {
248+
if group.GroupName == privName {
249+
return group
250+
}
251+
}
252+
return nil
253+
}
254+
255+
func (p *rbacConfig) GetDefaultPrivilegeGroupNames() []string {
256+
return lo.Keys(builtinPrivilegeGroups)
257+
}
258+
259+
func (p *rbacConfig) IsCollectionPrivilegeGroup(privName string) bool {
260+
collectionPrivilegeGroups := lo.PickBy(builtinPrivilegeGroups, func(groupName string, _ []string) bool {
261+
return strings.Contains(groupName, "Collection")
262+
})
263+
_, exists := collectionPrivilegeGroups[privName]
264+
return exists
265+
}

‎tests/integration/rbac/privilege_group_test.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ func (s *PrivilegeGroupTestSuite) TestBuiltinPrivilegeGroup() {
6868
resp, _ = s.operatePrivilege(ctx, roleName, "Admin", commonpb.ObjectType_Global.String(), milvuspb.OperatePrivilegeType_Grant)
6969
s.True(merr.Ok(resp))
7070

71-
for _, builtinGroup := range lo.Keys(util.BuiltinPrivilegeGroups) {
71+
for _, builtinGroup := range paramtable.Get().RbacConfig.GetDefaultPrivilegeGroupNames() {
7272
resp, _ = s.operatePrivilege(ctx, roleName, builtinGroup, commonpb.ObjectType_Global.String(), milvuspb.OperatePrivilegeType_Grant)
7373
s.False(merr.Ok(resp))
7474
}
@@ -157,7 +157,7 @@ func (s *PrivilegeGroupTestSuite) TestGrantV2BuiltinPrivilegeGroup() {
157157
s.NoError(err)
158158
s.True(merr.Ok(createRoleResp))
159159

160-
for _, builtinGroup := range lo.Keys(util.BuiltinPrivilegeGroups) {
160+
for _, builtinGroup := range paramtable.Get().RbacConfig.GetDefaultPrivilegeGroupNames() {
161161
resp, _ := s.operatePrivilegeV2(ctx, roleName, builtinGroup, util.AnyWord, util.AnyWord, milvuspb.OperatePrivilegeType_Grant)
162162
s.True(merr.Ok(resp))
163163
}
@@ -314,7 +314,7 @@ func (s *PrivilegeGroupTestSuite) TestGrantV2CustomPrivilegeGroup() {
314314
// Validate the group was dropped
315315
listResp, err := s.Cluster.Proxy.ListPrivilegeGroups(ctx, &milvuspb.ListPrivilegeGroupsRequest{})
316316
s.NoError(err)
317-
s.Equal(len(util.BuiltinPrivilegeGroups), len(listResp.PrivilegeGroups))
317+
s.Equal(len(paramtable.Get().RbacConfig.GetDefaultPrivilegeGroupNames()), len(listResp.PrivilegeGroups))
318318

319319
// validate edge cases
320320
resp, _ = s.operatePrivilegeV2(ctx, role, util.AnyWord, util.AnyWord, util.AnyWord, milvuspb.OperatePrivilegeType_Grant)

0 commit comments

Comments
 (0)
Please sign in to comment.