From 10c60c224d523bb94902d2fc06faa16633372efb Mon Sep 17 00:00:00 2001 From: shaoting-huang Date: Fri, 15 Nov 2024 16:19:15 +0800 Subject: [PATCH] add ut Signed-off-by: shaoting-huang --- configs/milvus.yaml | 47 ++++++------ internal/rootcoord/root_coord.go | 76 +++++++++++++++---- pkg/util/constant.go | 18 ++--- pkg/util/paramtable/rbac_config_test.go | 41 ++++++++++ ...privilege_group_param.go => rbac_param.go} | 20 ++--- 5 files changed, 144 insertions(+), 58 deletions(-) create mode 100644 pkg/util/paramtable/rbac_config_test.go rename pkg/util/paramtable/{privilege_group_param.go => rbac_param.go} (82%) diff --git a/configs/milvus.yaml b/configs/milvus.yaml index 8ebedb8d71c6d..e1851ad23f5f1 100644 --- a/configs/milvus.yaml +++ b/configs/milvus.yaml @@ -811,29 +811,30 @@ common: # like the old password verification when updating the credential superUsers: defaultRootPassword: Milvus # default password for root user - overrideBuildInPrivilgeGroups: - enabled: false # Whether to override build-in privilege groups - cluster: - readonly: - privileges: SelectOwnership,SelectUser,DescribeResourceGroup,ListResourceGroups # Cluster level readonly privileges - readwrite: - privileges: SelectOwnership,SelectUser,DescribeResourceGroup,ListResourceGroups,CreateOwnership,UpdateUser,DropOwnership,ManageOwnership,BackupRBAC,RestoreRBAC,CreateResourceGroup,UpdateResourceGroups,DropResourceGroup,TransferNode,TransferReplica # Cluster level readwrite privileges - admin: - privileges: SelectOwnership,SelectUser,DescribeResourceGroup,ListResourceGroups,CreateOwnership,UpdateUser,DropOwnership,ManageOwnership,BackupRBAC,RestoreRBAC,CreateResourceGroup,UpdateResourceGroups,DropResourceGroup,TransferNode,TransferReplica # Cluster level admin privileges - database: - readonly: - privileges: ListDatabases,DescribeDatabase # Database level readonly privileges - readwrite: - privileges: ListDatabases,DescribeDatabase,CreateDatabase,DropDatabase,AlterDatabase # Database level readwrite privileges - admin: - privileges: ListDatabases,DescribeDatabase,CreateDatabase,DropDatabase,AlterDatabase # Database level admin privileges - collection: - readonly: - privileges: Query,Search,IndexDetail,GetFlushState,GetLoadState,GetLoadingProgress,HasPartition,ShowPartitions,ShowCollections,ListAliases,DescribeCollection,DescribeAlias,GetStatistics # Collection level readonly privileges - readwrite: - privileges: Query,Search,IndexDetail,GetFlushState,GetLoadState,GetLoadingProgress,HasPartition,ShowPartitions,ShowCollections,ListAliases,DescribeCollection,DescribeAlias,GetStatistics,CreateIndex,DropIndex,CreatePartition,DropPartition,Load,Release,Insert,Delete,Upsert,Import,Flush,Compaction,LoadBalance,RenameCollection,CreateAlias,DropAlias,CreateCollection,DropCollection,FlushAll # Collection level readwrite privileges - admin: - privileges: Query,Search,IndexDetail,GetFlushState,GetLoadState,GetLoadingProgress,HasPartition,ShowPartitions,ShowCollections,ListAliases,DescribeCollection,DescribeAlias,GetStatistics,CreateIndex,DropIndex,CreatePartition,DropPartition,Load,Release,Insert,Delete,Upsert,Import,Flush,Compaction,LoadBalance,RenameCollection,CreateAlias,DropAlias,CreateCollection,DropCollection,FlushAll # Collection level admin privileges + rbac: + overrideBuiltInPrivilgeGroups: + enabled: false # Whether to override build-in privilege groups + cluster: + readonly: + privileges: SelectOwnership,SelectUser,DescribeResourceGroup,ListResourceGroups # Cluster level readonly privileges + readwrite: + privileges: SelectOwnership,SelectUser,DescribeResourceGroup,ListResourceGroups,CreateOwnership,UpdateUser,DropOwnership,ManageOwnership,BackupRBAC,RestoreRBAC,CreateResourceGroup,UpdateResourceGroups,DropResourceGroup,TransferNode,TransferReplica # Cluster level readwrite privileges + admin: + privileges: SelectOwnership,SelectUser,DescribeResourceGroup,ListResourceGroups,CreateOwnership,UpdateUser,DropOwnership,ManageOwnership,BackupRBAC,RestoreRBAC,CreateResourceGroup,UpdateResourceGroups,DropResourceGroup,TransferNode,TransferReplica # Cluster level admin privileges + database: + readonly: + privileges: ListDatabases,DescribeDatabase # Database level readonly privileges + readwrite: + privileges: ListDatabases,DescribeDatabase,CreateDatabase,DropDatabase,AlterDatabase # Database level readwrite privileges + admin: + privileges: ListDatabases,DescribeDatabase,CreateDatabase,DropDatabase,AlterDatabase # Database level admin privileges + collection: + readonly: + privileges: Query,Search,IndexDetail,GetFlushState,GetLoadState,GetLoadingProgress,HasPartition,ShowPartitions,ShowCollections,ListAliases,DescribeCollection,DescribeAlias,GetStatistics # Collection level readonly privileges + readwrite: + privileges: Query,Search,IndexDetail,GetFlushState,GetLoadState,GetLoadingProgress,HasPartition,ShowPartitions,ShowCollections,ListAliases,DescribeCollection,DescribeAlias,GetStatistics,CreateIndex,DropIndex,CreatePartition,DropPartition,Load,Release,Insert,Delete,Upsert,Import,Flush,Compaction,LoadBalance,RenameCollection,CreateAlias,DropAlias,CreateCollection,DropCollection,FlushAll # Collection level readwrite privileges + admin: + privileges: Query,Search,IndexDetail,GetFlushState,GetLoadState,GetLoadingProgress,HasPartition,ShowPartitions,ShowCollections,ListAliases,DescribeCollection,DescribeAlias,GetStatistics,CreateIndex,DropIndex,CreatePartition,DropPartition,Load,Release,Insert,Delete,Upsert,Import,Flush,Compaction,LoadBalance,RenameCollection,CreateAlias,DropAlias,CreateCollection,DropCollection,FlushAll # Collection level admin privileges tlsMode: 0 session: ttl: 30 # ttl value when session granting a lease to register service diff --git a/internal/rootcoord/root_coord.go b/internal/rootcoord/root_coord.go index 38807abfdffeb..b58213df9e3a5 100644 --- a/internal/rootcoord/root_coord.go +++ b/internal/rootcoord/root_coord.go @@ -576,7 +576,12 @@ func (c *Core) initRbac() error { } if Params.RoleCfg.Enabled.GetAsBool() { - return c.initBuiltinRoles() + if err := c.initBuiltinRoles(); err != nil { + return err + } + } + if err := c.initBuiltinPrivilegeGroups(); err != nil { + return err } return nil } @@ -624,6 +629,54 @@ func (c *Core) initPublicRolePrivilege() error { return nil } +func (c *Core) initBuiltinPrivilegeGroups() error { + // init built in privilege groups, if config enabled, override by config + for groupName, privileges := range util.BuiltinPrivilegeGroups { + if err := c.meta.CreatePrivilegeGroup(groupName); err != nil { + return err + } + if Params.RbacConfig.Enabled.GetAsBool() { + var confPrivs []string + switch groupName { + case "ClusterReadOnly": + confPrivs := Params.RbacConfig.ClusterReadOnlyPrivileges.GetAsStrings() + if len(confPrivs) > 0 { + privileges = confPrivs + } + case "ClusterReadWrite": + confPrivs = Params.RbacConfig.ClusterReadWritePrivileges.GetAsStrings() + case "ClusterAdmin": + confPrivs = Params.RbacConfig.ClusterAdminPrivileges.GetAsStrings() + case "DatabaseReadOnly": + confPrivs = Params.RbacConfig.DBReadOnlyPrivileges.GetAsStrings() + case "DatabaseReadWrite": + confPrivs = Params.RbacConfig.DBReadWritePrivileges.GetAsStrings() + case "DatabaseAdmin": + confPrivs = Params.RbacConfig.DBAdminPrivileges.GetAsStrings() + case "CollectionReadOnly": + confPrivs = Params.RbacConfig.CollectionReadOnlyPrivileges.GetAsStrings() + case "CollectionReadWrite": + confPrivs = Params.RbacConfig.CollectionReadWritePrivileges.GetAsStrings() + case "CollectionAdmin": + confPrivs = Params.RbacConfig.CollectionAdminPrivileges.GetAsStrings() + default: + return nil + } + if len(confPrivs) > 0 { + privileges = confPrivs + } + } + + privs := lo.Map(privileges, func(name string, _ int) *milvuspb.PrivilegeEntity { + return &milvuspb.PrivilegeEntity{Name: name} + }) + if err := c.meta.OperatePrivilegeGroup(groupName, privs, milvuspb.OperatePrivilegeGroupType_AddPrivilegesToGroup); err != nil { + return err + } + } + return nil +} + func (c *Core) initBuiltinRoles() error { rolePrivilegesMap := Params.RoleCfg.Roles.GetAsRoleDetails() for role, privilegesJSON := range rolePrivilegesMap { @@ -2623,22 +2676,13 @@ func (c *Core) OperatePrivilege(ctx context.Context, in *milvuspb.OperatePrivile } grants := []*milvuspb.GrantEntity{in.Entity} - var groups map[string][]*milvuspb.PrivilegeEntity - if util.IsBuiltinPrivilegeGroup(privName) { - // built in privilge group, expand it to all the privileges - groups = map[string][]*milvuspb.PrivilegeEntity{ - privName: lo.Map(util.BuiltinPrivilegeGroups[in.Entity.Object.Name], func(name string, _ int) *milvuspb.PrivilegeEntity { return &milvuspb.PrivilegeEntity{Name: name} }), - } - } else { - // custom privilege group - allGroups, err := c.meta.ListPrivilegeGroups() - if err != nil { - return nil, err - } - groups = lo.SliceToMap(allGroups, func(group *milvuspb.PrivilegeGroupInfo) (string, []*milvuspb.PrivilegeEntity) { - return group.GroupName, group.Privileges - }) + allGroups, err := c.meta.ListPrivilegeGroups() + if err != nil { + return nil, err } + groups := lo.SliceToMap(allGroups, func(group *milvuspb.PrivilegeGroupInfo) (string, []*milvuspb.PrivilegeEntity) { + return group.GroupName, group.Privileges + }) expandGrants, err := c.expandPrivilegeGroups(grants, groups) if err != nil { return nil, err diff --git a/pkg/util/constant.go b/pkg/util/constant.go index a49938a4bc6fd..74399f3761946 100644 --- a/pkg/util/constant.go +++ b/pkg/util/constant.go @@ -285,15 +285,15 @@ var ( } BuiltinPrivilegeGroups = map[string][]string{ - commonpb.ObjectPrivilege_PrivilegeGroupCollectionReadOnly.String(): CollectionReadOnlyPrivilegeGroup, - commonpb.ObjectPrivilege_PrivilegeGroupCollectionReadWrite.String(): CollectionReadWritePrivilegeGroup, - commonpb.ObjectPrivilege_PrivilegeGroupCollectionAdmin.String(): CollectionAdminPrivilegeGroup, - commonpb.ObjectPrivilege_PrivilegeGroupDatabaseReadOnly.String(): DatabaseReadOnlyPrivilegeGroup, - commonpb.ObjectPrivilege_PrivilegeGroupDatabaseReadWrite.String(): DatabaseReadWritePrivilegeGroup, - commonpb.ObjectPrivilege_PrivilegeGroupDatabaseAdmin.String(): DatabaseAdminPrivilegeGroup, - commonpb.ObjectPrivilege_PrivilegeGroupClusterReadOnly.String(): ClusterReadOnlyPrivilegeGroup, - commonpb.ObjectPrivilege_PrivilegeGroupClusterReadWrite.String(): ClusterReadWritePrivilegeGroup, - commonpb.ObjectPrivilege_PrivilegeGroupClusterAdmin.String(): ClusterAdminPrivilegeGroup, + MetaStore2API(commonpb.ObjectPrivilege_PrivilegeGroupCollectionReadOnly.String()): CollectionReadOnlyPrivilegeGroup, + MetaStore2API(commonpb.ObjectPrivilege_PrivilegeGroupCollectionReadWrite.String()): CollectionReadWritePrivilegeGroup, + MetaStore2API(commonpb.ObjectPrivilege_PrivilegeGroupCollectionAdmin.String()): CollectionAdminPrivilegeGroup, + MetaStore2API(commonpb.ObjectPrivilege_PrivilegeGroupDatabaseReadOnly.String()): DatabaseReadOnlyPrivilegeGroup, + MetaStore2API(commonpb.ObjectPrivilege_PrivilegeGroupDatabaseReadWrite.String()): DatabaseReadWritePrivilegeGroup, + MetaStore2API(commonpb.ObjectPrivilege_PrivilegeGroupDatabaseAdmin.String()): DatabaseAdminPrivilegeGroup, + MetaStore2API(commonpb.ObjectPrivilege_PrivilegeGroupClusterReadOnly.String()): ClusterReadOnlyPrivilegeGroup, + MetaStore2API(commonpb.ObjectPrivilege_PrivilegeGroupClusterReadWrite.String()): ClusterReadWritePrivilegeGroup, + MetaStore2API(commonpb.ObjectPrivilege_PrivilegeGroupClusterAdmin.String()): ClusterAdminPrivilegeGroup, } CollectionReadOnlyPrivilegeGroup = []string{ diff --git a/pkg/util/paramtable/rbac_config_test.go b/pkg/util/paramtable/rbac_config_test.go new file mode 100644 index 0000000000000..803fceabe2896 --- /dev/null +++ b/pkg/util/paramtable/rbac_config_test.go @@ -0,0 +1,41 @@ +// Licensed to the LF AI & Data foundation under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package paramtable + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/milvus-io/milvus/pkg/util" +) + +func TestRbacConfig_Init(t *testing.T) { + params := ComponentParam{} + params.Init(NewBaseTable(SkipRemote(true))) + cfg := ¶ms.RbacConfig + assert.Equal(t, cfg.Enabled.GetAsBool(), false) + assert.Equal(t, cfg.ClusterReadOnlyPrivileges.GetAsStrings(), util.BuiltinPrivilegeGroups["ClusterReadOnly"]) + assert.Equal(t, cfg.ClusterReadWritePrivileges.GetAsStrings(), util.BuiltinPrivilegeGroups["ClusterReadWrite"]) + assert.Equal(t, cfg.ClusterAdminPrivileges.GetAsStrings(), util.BuiltinPrivilegeGroups["ClusterAdmin"]) + assert.Equal(t, cfg.DBReadOnlyPrivileges.GetAsStrings(), util.BuiltinPrivilegeGroups["DatabaseReadOnly"]) + assert.Equal(t, cfg.DBReadWritePrivileges.GetAsStrings(), util.BuiltinPrivilegeGroups["DatabaseReadWrite"]) + assert.Equal(t, cfg.DBAdminPrivileges.GetAsStrings(), util.BuiltinPrivilegeGroups["DatabaseAdmin"]) + assert.Equal(t, cfg.CollectionReadOnlyPrivileges.GetAsStrings(), util.BuiltinPrivilegeGroups["CollectionReadOnly"]) + assert.Equal(t, cfg.CollectionReadWritePrivileges.GetAsStrings(), util.BuiltinPrivilegeGroups["CollectionReadWrite"]) + assert.Equal(t, cfg.CollectionAdminPrivileges.GetAsStrings(), util.BuiltinPrivilegeGroups["CollectionAdmin"]) +} diff --git a/pkg/util/paramtable/privilege_group_param.go b/pkg/util/paramtable/rbac_param.go similarity index 82% rename from pkg/util/paramtable/privilege_group_param.go rename to pkg/util/paramtable/rbac_param.go index aa5ce74b127ed..3d2f6d36d9c4c 100644 --- a/pkg/util/paramtable/privilege_group_param.go +++ b/pkg/util/paramtable/rbac_param.go @@ -23,7 +23,7 @@ type rbacConfig struct { func (p *rbacConfig) init(base *BaseTable) { p.Enabled = ParamItem{ - Key: "common.security.overrideBuildInPrivilgeGroups.enabled", + Key: "common.security.rbac.overrideBuiltInPrivilgeGroups.enabled", DefaultValue: "false", Version: "2.3.4", Doc: "Whether to override build-in privilege groups", @@ -32,7 +32,7 @@ func (p *rbacConfig) init(base *BaseTable) { p.Enabled.Init(base.mgr) p.ClusterReadOnlyPrivileges = ParamItem{ - Key: "common.security.cluster.readonly.privileges", + Key: "common.security.rbac.cluster.readonly.privileges", DefaultValue: strings.Join(util.ClusterReadOnlyPrivilegeGroup, ","), Version: "2.3.4", Doc: "Cluster level readonly privileges", @@ -41,7 +41,7 @@ func (p *rbacConfig) init(base *BaseTable) { p.ClusterReadOnlyPrivileges.Init(base.mgr) p.ClusterReadWritePrivileges = ParamItem{ - Key: "common.security.cluster.readwrite.privileges", + Key: "common.security.rbac.cluster.readwrite.privileges", DefaultValue: strings.Join(util.ClusterReadWritePrivilegeGroup, ","), Version: "2.3.4", Doc: "Cluster level readwrite privileges", @@ -50,7 +50,7 @@ func (p *rbacConfig) init(base *BaseTable) { p.ClusterReadWritePrivileges.Init(base.mgr) p.ClusterAdminPrivileges = ParamItem{ - Key: "common.security.cluster.admin.privileges", + Key: "common.security.rbac.cluster.admin.privileges", DefaultValue: strings.Join(util.ClusterAdminPrivilegeGroup, ","), Version: "2.3.4", Doc: "Cluster level admin privileges", @@ -59,7 +59,7 @@ func (p *rbacConfig) init(base *BaseTable) { p.ClusterAdminPrivileges.Init(base.mgr) p.DBReadOnlyPrivileges = ParamItem{ - Key: "common.security.database.readonly.privileges", + Key: "common.security.rbac.database.readonly.privileges", DefaultValue: strings.Join(util.DatabaseReadOnlyPrivilegeGroup, ","), Version: "2.3.4", Doc: "Database level readonly privileges", @@ -68,7 +68,7 @@ func (p *rbacConfig) init(base *BaseTable) { p.DBReadOnlyPrivileges.Init(base.mgr) p.DBReadWritePrivileges = ParamItem{ - Key: "common.security.database.readwrite.privileges", + Key: "common.security.rbac.database.readwrite.privileges", DefaultValue: strings.Join(util.DatabaseReadWritePrivilegeGroup, ","), Version: "2.3.4", Doc: "Database level readwrite privileges", @@ -77,7 +77,7 @@ func (p *rbacConfig) init(base *BaseTable) { p.DBReadWritePrivileges.Init(base.mgr) p.DBAdminPrivileges = ParamItem{ - Key: "common.security.database.admin.privileges", + Key: "common.security.rbac.database.admin.privileges", DefaultValue: strings.Join(util.DatabaseAdminPrivilegeGroup, ","), Version: "2.3.4", Doc: "Database level admin privileges", @@ -86,7 +86,7 @@ func (p *rbacConfig) init(base *BaseTable) { p.DBAdminPrivileges.Init(base.mgr) p.CollectionReadOnlyPrivileges = ParamItem{ - Key: "common.security.collection.readonly.privileges", + Key: "common.security.rbac.collection.readonly.privileges", DefaultValue: strings.Join(util.CollectionReadOnlyPrivilegeGroup, ","), Version: "2.3.4", Doc: "Collection level readonly privileges", @@ -95,7 +95,7 @@ func (p *rbacConfig) init(base *BaseTable) { p.CollectionReadOnlyPrivileges.Init(base.mgr) p.CollectionReadWritePrivileges = ParamItem{ - Key: "common.security.collection.readwrite.privileges", + Key: "common.security.rbac.collection.readwrite.privileges", DefaultValue: strings.Join(util.CollectionReadWritePrivilegeGroup, ","), Version: "2.3.4", Doc: "Collection level readwrite privileges", @@ -104,7 +104,7 @@ func (p *rbacConfig) init(base *BaseTable) { p.CollectionReadWritePrivileges.Init(base.mgr) p.CollectionAdminPrivileges = ParamItem{ - Key: "common.security.collection.admin.privileges", + Key: "common.security.rbac.collection.admin.privileges", DefaultValue: strings.Join(util.CollectionAdminPrivilegeGroup, ","), Version: "2.3.4", Doc: "Collection level admin privileges",