Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
milvus
milvus
提交
13f69bfc
M
milvus
项目概览
milvus
/
milvus
10 个月 前同步成功
通知
260
Star
22476
Fork
2472
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
M
milvus
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
未验证
提交
13f69bfc
编写于
8月 04, 2023
作者:
S
SimFG
提交者:
GitHub
8月 04, 2023
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Delete the user-role mapping info when deleting the user (#25988) (#26048)
Signed-off-by:
N
SimFG
<
bang.fu@zilliz.com
>
上级
fa4be1ef
变更
10
隐藏空白更改
内联
并排
Showing
10 changed file
with
728 addition
and
113 deletion
+728
-113
internal/metastore/kv/rootcoord/kv_catalog.go
internal/metastore/kv/rootcoord/kv_catalog.go
+36
-4
internal/metastore/kv/rootcoord/kv_catalog_test.go
internal/metastore/kv/rootcoord/kv_catalog_test.go
+65
-13
internal/proxy/impl.go
internal/proxy/impl.go
+2
-1
internal/proxy/meta_cache.go
internal/proxy/meta_cache.go
+18
-0
internal/proxy/proxy_test.go
internal/proxy/proxy_test.go
+76
-9
internal/rootcoord/mock_test.go
internal/rootcoord/mock_test.go
+122
-0
internal/rootcoord/root_coord.go
internal/rootcoord/root_coord.go
+130
-86
internal/rootcoord/root_coord_test.go
internal/rootcoord/root_coord_test.go
+250
-0
internal/rootcoord/step.go
internal/rootcoord/step.go
+26
-0
internal/util/typeutil/cache.go
internal/util/typeutil/cache.go
+3
-0
未找到文件。
internal/metastore/kv/rootcoord/kv_catalog.go
浏览文件 @
13f69bfc
...
...
@@ -541,9 +541,24 @@ func (kc *Catalog) DropPartition(ctx context.Context, dbID int64, collectionID t
func
(
kc
*
Catalog
)
DropCredential
(
ctx
context
.
Context
,
username
string
)
error
{
k
:=
fmt
.
Sprintf
(
"%s/%s"
,
CredentialPrefix
,
username
)
err
:=
kc
.
Txn
.
Remove
(
k
)
userResults
,
err
:=
kc
.
ListUser
(
ctx
,
util
.
DefaultTenant
,
&
milvuspb
.
UserEntity
{
Name
:
username
},
true
)
if
err
!=
nil
&&
!
common
.
IsKeyNotExistError
(
err
)
{
log
.
Warn
(
"fail to list user"
,
zap
.
String
(
"key"
,
k
),
zap
.
Error
(
err
))
return
err
}
deleteKeys
:=
make
([]
string
,
0
,
len
(
userResults
)
+
1
)
deleteKeys
=
append
(
deleteKeys
,
k
)
for
_
,
userResult
:=
range
userResults
{
if
userResult
.
User
.
Name
==
username
{
for
_
,
role
:=
range
userResult
.
Roles
{
userRoleKey
:=
funcutil
.
HandleTenantForEtcdKey
(
RoleMappingPrefix
,
util
.
DefaultTenant
,
fmt
.
Sprintf
(
"%s/%s"
,
username
,
role
.
Name
))
deleteKeys
=
append
(
deleteKeys
,
userRoleKey
)
}
}
}
err
=
kc
.
Txn
.
MultiRemove
(
deleteKeys
)
if
err
!=
nil
{
log
.
Error
(
"drop credential update meta fai
l"
,
zap
.
String
(
"key"
,
k
),
zap
.
Error
(
err
))
log
.
Warn
(
"fail to drop credentia
l"
,
zap
.
String
(
"key"
,
k
),
zap
.
Error
(
err
))
return
err
}
...
...
@@ -736,9 +751,26 @@ func (kc *Catalog) CreateRole(ctx context.Context, tenant string, entity *milvus
func
(
kc
*
Catalog
)
DropRole
(
ctx
context
.
Context
,
tenant
string
,
roleName
string
)
error
{
k
:=
funcutil
.
HandleTenantForEtcdKey
(
RolePrefix
,
tenant
,
roleName
)
err
:=
kc
.
Txn
.
Remove
(
k
)
roleResults
,
err
:=
kc
.
ListRole
(
ctx
,
tenant
,
&
milvuspb
.
RoleEntity
{
Name
:
roleName
},
true
)
if
err
!=
nil
&&
!
common
.
IsKeyNotExistError
(
err
)
{
log
.
Warn
(
"fail to list role"
,
zap
.
String
(
"key"
,
k
),
zap
.
Error
(
err
))
return
err
}
deleteKeys
:=
make
([]
string
,
0
,
len
(
roleResults
)
+
1
)
deleteKeys
=
append
(
deleteKeys
,
k
)
for
_
,
roleResult
:=
range
roleResults
{
if
roleResult
.
Role
.
Name
==
roleName
{
for
_
,
userInfo
:=
range
roleResult
.
Users
{
userRoleKey
:=
funcutil
.
HandleTenantForEtcdKey
(
RoleMappingPrefix
,
tenant
,
fmt
.
Sprintf
(
"%s/%s"
,
userInfo
.
Name
,
roleName
))
deleteKeys
=
append
(
deleteKeys
,
userRoleKey
)
}
}
}
err
=
kc
.
Txn
.
MultiRemove
(
deleteKeys
)
if
err
!=
nil
{
log
.
Error
(
"fail to drop role"
,
zap
.
String
(
"key"
,
k
),
zap
.
Error
(
err
))
log
.
Warn
(
"fail to drop role"
,
zap
.
String
(
"key"
,
k
),
zap
.
Error
(
err
))
return
err
}
return
nil
...
...
internal/metastore/kv/rootcoord/kv_catalog_test.go
浏览文件 @
13f69bfc
...
...
@@ -10,10 +10,12 @@ import (
"testing"
"github.com/golang/protobuf/proto"
"github.com/milvus-io/milvus/internal/log"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
"go.uber.org/atomic"
"go.uber.org/zap"
"golang.org/x/exp/maps"
"github.com/milvus-io/milvus-proto/go-api/v2/commonpb"
...
...
@@ -1236,6 +1238,12 @@ func TestCatalog_DropCollection(t *testing.T) {
})
}
func
getUserInfoMetaString
(
username
string
)
string
{
validInfo
:=
internalpb
.
CredentialInfo
{
Username
:
username
,
EncryptedPassword
:
"pwd"
+
username
}
validBytes
,
_
:=
json
.
Marshal
(
validInfo
)
return
string
(
validBytes
)
}
func
TestRBAC_Credential
(
t
*
testing
.
T
)
{
ctx
:=
context
.
TODO
()
...
...
@@ -1345,12 +1353,34 @@ func TestRBAC_Credential(t *testing.T) {
kvmock
=
mocks
.
NewTxnKV
(
t
)
c
=
&
Catalog
{
Txn
:
kvmock
}
dropFailName
=
"drop-fail"
dropFailKey
=
fmt
.
Sprintf
(
"%s/%s"
,
CredentialPrefix
,
dropFailName
)
validName
=
"user1"
validUserRoleKeyPrefix
=
funcutil
.
HandleTenantForEtcdKey
(
RoleMappingPrefix
,
util
.
DefaultTenant
,
validName
)
dropFailName
=
"drop-fail"
dropUserRoleKeyPrefix
=
funcutil
.
HandleTenantForEtcdKey
(
RoleMappingPrefix
,
util
.
DefaultTenant
,
dropFailName
)
getFailName
=
"get-fail"
)
kvmock
.
EXPECT
()
.
Remove
(
dropFailKey
)
.
Return
(
errors
.
New
(
"Mock invalid remove"
))
kvmock
.
EXPECT
()
.
Remove
(
mock
.
Anything
)
.
Return
(
nil
)
kvmock
.
EXPECT
()
.
MultiRemove
([]
string
{
fmt
.
Sprintf
(
"%s/%s"
,
CredentialPrefix
,
dropFailName
)})
.
Return
(
errors
.
New
(
"Mock drop fail"
))
kvmock
.
EXPECT
()
.
MultiRemove
(
[]
string
{
fmt
.
Sprintf
(
"%s/%s"
,
CredentialPrefix
,
validName
),
validUserRoleKeyPrefix
+
"/role1"
,
validUserRoleKeyPrefix
+
"/role2"
,
},
)
.
Return
(
nil
)
kvmock
.
EXPECT
()
.
MultiRemove
(
mock
.
Anything
)
.
Return
(
errors
.
New
(
"Mock invalid multi remove"
))
kvmock
.
EXPECT
()
.
Load
(
fmt
.
Sprintf
(
"%s/%s"
,
CredentialPrefix
,
getFailName
))
.
Return
(
""
,
errors
.
New
(
"Mock invalid load"
))
kvmock
.
EXPECT
()
.
Load
(
fmt
.
Sprintf
(
"%s/%s"
,
CredentialPrefix
,
validName
))
.
Return
(
getUserInfoMetaString
(
validName
),
nil
)
kvmock
.
EXPECT
()
.
Load
(
fmt
.
Sprintf
(
"%s/%s"
,
CredentialPrefix
,
dropFailName
))
.
Return
(
getUserInfoMetaString
(
dropFailName
),
nil
)
kvmock
.
EXPECT
()
.
LoadWithPrefix
(
validUserRoleKeyPrefix
)
.
Return
(
[]
string
{
validUserRoleKeyPrefix
+
"/role1"
,
validUserRoleKeyPrefix
+
"/role2"
},
[]
string
{
""
,
""
},
nil
,
)
kvmock
.
EXPECT
()
.
LoadWithPrefix
(
dropUserRoleKeyPrefix
)
.
Return
([]
string
{},
[]
string
{},
nil
)
tests
:=
[]
struct
{
description
string
...
...
@@ -1358,8 +1388,8 @@ func TestRBAC_Credential(t *testing.T) {
user
string
}{
{
"valid user1"
,
true
,
"user1"
},
{
"
valid user2"
,
true
,
"user2"
},
{
"valid user1"
,
true
,
validName
},
{
"
invalid user get-fail"
,
false
,
getFailName
},
{
"invalid user drop-fail"
,
false
,
dropFailName
},
}
...
...
@@ -1582,20 +1612,42 @@ func TestRBAC_Role(t *testing.T) {
kvmock
=
mocks
.
NewTxnKV
(
t
)
c
=
&
Catalog
{
Txn
:
kvmock
}
errorName
=
"error"
errorPath
=
funcutil
.
HandleTenantForEtcdKey
(
RolePrefix
,
tenant
,
errorName
)
validName
=
"role1"
errorName
=
"error"
getFailName
=
"get-fail"
)
kvmock
.
EXPECT
()
.
MultiRemove
([]
string
{
funcutil
.
HandleTenantForEtcdKey
(
RolePrefix
,
tenant
,
errorName
)})
.
Return
(
errors
.
New
(
"remove error"
))
kvmock
.
EXPECT
()
.
MultiRemove
([]
string
{
funcutil
.
HandleTenantForEtcdKey
(
RolePrefix
,
tenant
,
validName
),
funcutil
.
HandleTenantForEtcdKey
(
RoleMappingPrefix
,
tenant
,
fmt
.
Sprintf
(
"%s/%s"
,
"user1"
,
validName
)),
funcutil
.
HandleTenantForEtcdKey
(
RoleMappingPrefix
,
tenant
,
fmt
.
Sprintf
(
"%s/%s"
,
"user2"
,
validName
)),
})
.
Return
(
nil
)
kvmock
.
EXPECT
()
.
MultiRemove
(
mock
.
Anything
)
.
Run
(
func
(
keys
[]
string
)
{
log
.
Info
(
"keys"
,
zap
.
Any
(
"keys"
,
keys
))
})
.
Return
(
errors
.
New
(
"mock multi remove error"
))
getRoleMappingKey
:=
func
(
username
,
rolename
string
)
string
{
return
funcutil
.
HandleTenantForEtcdKey
(
RoleMappingPrefix
,
tenant
,
fmt
.
Sprintf
(
"%s/%s"
,
username
,
rolename
))
}
kvmock
.
EXPECT
()
.
LoadWithPrefix
(
funcutil
.
HandleTenantForEtcdKey
(
RoleMappingPrefix
,
tenant
,
""
))
.
Return
(
[]
string
{
getRoleMappingKey
(
"user1"
,
validName
),
getRoleMappingKey
(
"user2"
,
validName
),
getRoleMappingKey
(
"user3"
,
"role3"
)},
[]
string
{},
nil
,
)
kvmock
.
EXPECT
()
.
Remove
(
errorPath
)
.
Return
(
errors
.
New
(
"mock remove error"
))
.
Once
()
kvmock
.
EXPECT
()
.
Remove
(
mock
.
Anything
)
.
Return
(
nil
)
.
Once
()
kvmock
.
EXPECT
()
.
Load
(
funcutil
.
HandleTenantForEtcdKey
(
RolePrefix
,
tenant
,
getFailName
))
.
Return
(
""
,
errors
.
New
(
"mock load error"
))
kvmock
.
EXPECT
()
.
Load
(
funcutil
.
HandleTenantForEtcdKey
(
RolePrefix
,
tenant
,
validName
))
.
Return
(
""
,
nil
)
kvmock
.
EXPECT
()
.
Load
(
funcutil
.
HandleTenantForEtcdKey
(
RolePrefix
,
tenant
,
errorName
))
.
Return
(
""
,
nil
)
tests
:=
[]
struct
{
description
string
isValid
bool
role
string
role
string
}{
{
"valid role role1"
,
true
,
"role1"
},
{
"valid role role1"
,
true
,
validName
},
{
"fail to get role info"
,
false
,
getFailName
},
{
"invalid role error"
,
false
,
errorName
},
}
...
...
internal/proxy/impl.go
浏览文件 @
13f69bfc
...
...
@@ -4942,9 +4942,10 @@ func (node *Proxy) OperatePrivilege(ctx context.Context, req *milvuspb.OperatePr
}
curUser
,
err
:=
GetCurUserFromContext
(
ctx
)
if
err
!=
nil
{
log
.
Warn
(
"fail to get current user"
,
zap
.
Error
(
err
))
return
&
commonpb
.
Status
{
ErrorCode
:
commonpb
.
ErrorCode_UnexpectedError
,
Reason
:
err
.
Error
()
,
Reason
:
"fail to get current user, please make sure the authorizationEnabled setting in the milvus.yaml is true"
,
},
nil
}
req
.
Entity
.
Grantor
.
User
=
&
milvuspb
.
UserEntity
{
Name
:
curUser
}
...
...
internal/proxy/meta_cache.go
浏览文件 @
13f69bfc
...
...
@@ -882,7 +882,10 @@ func (m *MetaCache) expireShardLeaderCache(ctx context.Context) {
func
(
m
*
MetaCache
)
InitPolicyInfo
(
info
[]
string
,
userRoles
[]
string
)
{
m
.
mu
.
Lock
()
defer
m
.
mu
.
Unlock
()
m
.
unsafeInitPolicyInfo
(
info
,
userRoles
)
}
func
(
m
*
MetaCache
)
unsafeInitPolicyInfo
(
info
[]
string
,
userRoles
[]
string
)
{
m
.
privilegeInfos
=
util
.
StringSet
(
info
)
for
_
,
userRole
:=
range
userRoles
{
user
,
role
,
err
:=
funcutil
.
DecodeUserRoleCache
(
userRole
)
...
...
@@ -940,6 +943,21 @@ func (m *MetaCache) RefreshPolicyInfo(op typeutil.CacheOp) error {
if
m
.
userToRoles
[
user
]
!=
nil
{
delete
(
m
.
userToRoles
[
user
],
role
)
}
case
typeutil
.
CacheDeleteUser
:
delete
(
m
.
userToRoles
,
op
.
OpKey
)
case
typeutil
.
CacheDropRole
:
for
user
:=
range
m
.
userToRoles
{
delete
(
m
.
userToRoles
[
user
],
op
.
OpKey
)
}
case
typeutil
.
CacheRefresh
:
resp
,
err
:=
m
.
rootCoord
.
ListPolicy
(
context
.
Background
(),
&
internalpb
.
ListPolicyRequest
{})
if
err
!=
nil
{
log
.
Error
(
"fail to init meta cache"
,
zap
.
Error
(
err
))
return
err
}
m
.
userToRoles
=
make
(
map
[
string
]
map
[
string
]
struct
{})
m
.
privilegeInfos
=
make
(
map
[
string
]
struct
{})
m
.
unsafeInitPolicyInfo
(
resp
.
PolicyInfos
,
resp
.
UserRoles
)
default
:
return
fmt
.
Errorf
(
"invalid opType, op_type: %d, op_key: %s"
,
int
(
op
.
OpType
),
op
.
OpKey
)
}
...
...
internal/proxy/proxy_test.go
浏览文件 @
13f69bfc
...
...
@@ -20,6 +20,7 @@ import (
"context"
"errors"
"fmt"
"math/rand"
"net"
"os"
"strconv"
...
...
@@ -30,13 +31,6 @@ import (
"github.com/golang/protobuf/proto"
grpc_middleware
"github.com/grpc-ecosystem/go-grpc-middleware"
ot
"github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing"
"github.com/prometheus/client_golang/prometheus"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"go.uber.org/zap"
"google.golang.org/grpc"
"google.golang.org/grpc/keepalive"
"github.com/milvus-io/milvus-proto/go-api/v2/commonpb"
"github.com/milvus-io/milvus-proto/go-api/v2/milvuspb"
"github.com/milvus-io/milvus-proto/go-api/v2/schemapb"
...
...
@@ -78,6 +72,12 @@ import (
"github.com/milvus-io/milvus/internal/util/sessionutil"
"github.com/milvus-io/milvus/internal/util/trace"
"github.com/milvus-io/milvus/internal/util/typeutil"
"github.com/prometheus/client_golang/prometheus"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"go.uber.org/zap"
"google.golang.org/grpc"
"google.golang.org/grpc/keepalive"
)
const
(
...
...
@@ -2196,7 +2196,6 @@ func TestProxy(t *testing.T) {
updateCredentialReq
.
NewPassword
=
crypto
.
Base64Encode
(
newPassword
)
updateResp
,
err
=
proxy
.
UpdateCredential
(
rootCtx
,
updateCredentialReq
)
assert
.
NoError
(
t
,
err
)
fmt
.
Println
(
"simfg fubang:"
,
updateResp
)
assert
.
Equal
(
t
,
commonpb
.
ErrorCode_Success
,
updateResp
.
ErrorCode
)
})
...
...
@@ -2220,7 +2219,8 @@ func TestProxy(t *testing.T) {
getCredentialReq
.
Username
=
"("
getResp
,
err
=
rootCoordClient
.
GetCredential
(
ctx
,
getCredentialReq
)
assert
.
Error
(
t
,
err
)
assert
.
NoError
(
t
,
err
)
assert
.
NotEqual
(
t
,
commonpb
.
ErrorCode_Success
,
getResp
.
Status
.
ErrorCode
)
})
wg
.
Add
(
1
)
...
...
@@ -3368,6 +3368,73 @@ func testProxyRole(ctx context.Context, t *testing.T, proxy *Proxy) {
assert
.
Equal
(
t
,
commonpb
.
ErrorCode_Success
,
opResp
.
ErrorCode
)
})
wg
.
Add
(
1
)
t
.
Run
(
"User Role mapping info"
,
func
(
t
*
testing
.
T
)
{
defer
wg
.
Done
()
ctx
:=
context
.
Background
()
username
:=
fmt
.
Sprintf
(
"user%d"
,
rand
.
Int31
())
roleName
:=
fmt
.
Sprintf
(
"role%d"
,
rand
.
Int31
())
{
createCredentialResp
,
err
:=
proxy
.
CreateCredential
(
ctx
,
&
milvuspb
.
CreateCredentialRequest
{
Username
:
username
,
Password
:
crypto
.
Base64Encode
(
"userpwd"
)})
assert
.
NoError
(
t
,
err
)
assert
.
Equal
(
t
,
commonpb
.
ErrorCode_Success
,
createCredentialResp
.
ErrorCode
)
createRoleResp
,
err
:=
proxy
.
CreateRole
(
ctx
,
&
milvuspb
.
CreateRoleRequest
{
Entity
:
&
milvuspb
.
RoleEntity
{
Name
:
roleName
}})
assert
.
NoError
(
t
,
err
)
assert
.
Equal
(
t
,
commonpb
.
ErrorCode_Success
,
createRoleResp
.
ErrorCode
)
}
{
resp
,
err
:=
proxy
.
OperateUserRole
(
ctx
,
&
milvuspb
.
OperateUserRoleRequest
{
Username
:
username
,
RoleName
:
roleName
})
assert
.
NoError
(
t
,
err
)
assert
.
Equal
(
t
,
commonpb
.
ErrorCode_Success
,
resp
.
ErrorCode
)
}
{
resp
,
err
:=
proxy
.
OperateUserRole
(
ctx
,
&
milvuspb
.
OperateUserRoleRequest
{
Username
:
username
,
RoleName
:
"admin"
})
assert
.
NoError
(
t
,
err
)
assert
.
Equal
(
t
,
commonpb
.
ErrorCode_Success
,
resp
.
ErrorCode
)
}
{
selectUserResp
,
err
:=
proxy
.
SelectUser
(
ctx
,
&
milvuspb
.
SelectUserRequest
{
User
:
&
milvuspb
.
UserEntity
{
Name
:
username
},
IncludeRoleInfo
:
true
})
assert
.
NoError
(
t
,
err
)
assert
.
Equal
(
t
,
commonpb
.
ErrorCode_Success
,
selectUserResp
.
Status
.
ErrorCode
)
assert
.
Equal
(
t
,
2
,
len
(
selectUserResp
.
Results
[
0
]
.
Roles
))
selectRoleResp
,
err
:=
proxy
.
SelectRole
(
ctx
,
&
milvuspb
.
SelectRoleRequest
{
Role
:
&
milvuspb
.
RoleEntity
{
Name
:
roleName
},
IncludeUserInfo
:
true
})
assert
.
NoError
(
t
,
err
)
assert
.
Equal
(
t
,
commonpb
.
ErrorCode_Success
,
selectRoleResp
.
Status
.
ErrorCode
)
assert
.
Equal
(
t
,
1
,
len
(
selectRoleResp
.
Results
[
0
]
.
Users
))
}
{
resp
,
err
:=
proxy
.
DropRole
(
ctx
,
&
milvuspb
.
DropRoleRequest
{
RoleName
:
roleName
})
assert
.
NoError
(
t
,
err
)
assert
.
Equal
(
t
,
commonpb
.
ErrorCode_Success
,
resp
.
ErrorCode
)
}
{
selectUserResp
,
err
:=
proxy
.
SelectUser
(
ctx
,
&
milvuspb
.
SelectUserRequest
{
User
:
&
milvuspb
.
UserEntity
{
Name
:
username
},
IncludeRoleInfo
:
true
})
assert
.
NoError
(
t
,
err
)
assert
.
Equal
(
t
,
commonpb
.
ErrorCode_Success
,
selectUserResp
.
Status
.
ErrorCode
)
assert
.
Equal
(
t
,
1
,
len
(
selectUserResp
.
Results
[
0
]
.
Roles
))
selectRoleResp
,
err
:=
proxy
.
SelectRole
(
ctx
,
&
milvuspb
.
SelectRoleRequest
{
Role
:
&
milvuspb
.
RoleEntity
{
Name
:
roleName
},
IncludeUserInfo
:
true
})
assert
.
NoError
(
t
,
err
)
assert
.
Equal
(
t
,
commonpb
.
ErrorCode_Success
,
selectRoleResp
.
Status
.
ErrorCode
)
assert
.
Equal
(
t
,
0
,
len
(
selectRoleResp
.
Results
))
}
{
resp
,
err
:=
proxy
.
DeleteCredential
(
ctx
,
&
milvuspb
.
DeleteCredentialRequest
{
Username
:
username
})
assert
.
NoError
(
t
,
err
)
assert
.
Equal
(
t
,
commonpb
.
ErrorCode_Success
,
resp
.
ErrorCode
)
time
.
Sleep
(
time
.
Second
)
}
{
selectUserResp
,
err
:=
proxy
.
SelectUser
(
ctx
,
&
milvuspb
.
SelectUserRequest
{
User
:
&
milvuspb
.
UserEntity
{
Name
:
username
},
IncludeRoleInfo
:
true
})
assert
.
NoError
(
t
,
err
)
assert
.
Equal
(
t
,
commonpb
.
ErrorCode_Success
,
selectUserResp
.
Status
.
ErrorCode
)
assert
.
Equal
(
t
,
0
,
len
(
selectUserResp
.
Results
))
}
})
wg
.
Wait
()
}
...
...
internal/rootcoord/mock_test.go
浏览文件 @
13f69bfc
...
...
@@ -22,6 +22,8 @@ import (
"math/rand"
"os"
"github.com/milvus-io/milvus/internal/proto/internalpb"
"go.uber.org/zap"
"github.com/milvus-io/milvus-proto/go-api/v2/commonpb"
...
...
@@ -72,6 +74,21 @@ type mockMetaTable struct {
GetCollectionVirtualChannelsFunc
func
(
colID
int64
)
[]
string
AlterCollectionFunc
func
(
ctx
context
.
Context
,
oldColl
*
model
.
Collection
,
newColl
*
model
.
Collection
,
ts
Timestamp
)
error
RenameCollectionFunc
func
(
ctx
context
.
Context
,
oldName
string
,
newName
string
,
ts
Timestamp
)
error
AddCredentialFunc
func
(
credInfo
*
internalpb
.
CredentialInfo
)
error
GetCredentialFunc
func
(
username
string
)
(
*
internalpb
.
CredentialInfo
,
error
)
DeleteCredentialFunc
func
(
username
string
)
error
AlterCredentialFunc
func
(
credInfo
*
internalpb
.
CredentialInfo
)
error
ListCredentialUsernamesFunc
func
()
(
*
milvuspb
.
ListCredUsersResponse
,
error
)
CreateRoleFunc
func
(
tenant
string
,
entity
*
milvuspb
.
RoleEntity
)
error
DropRoleFunc
func
(
tenant
string
,
roleName
string
)
error
OperateUserRoleFunc
func
(
tenant
string
,
userEntity
*
milvuspb
.
UserEntity
,
roleEntity
*
milvuspb
.
RoleEntity
,
operateType
milvuspb
.
OperateUserRoleType
)
error
SelectRoleFunc
func
(
tenant
string
,
entity
*
milvuspb
.
RoleEntity
,
includeUserInfo
bool
)
([]
*
milvuspb
.
RoleResult
,
error
)
SelectUserFunc
func
(
tenant
string
,
entity
*
milvuspb
.
UserEntity
,
includeRoleInfo
bool
)
([]
*
milvuspb
.
UserResult
,
error
)
OperatePrivilegeFunc
func
(
tenant
string
,
entity
*
milvuspb
.
GrantEntity
,
operateType
milvuspb
.
OperatePrivilegeType
)
error
SelectGrantFunc
func
(
tenant
string
,
entity
*
milvuspb
.
GrantEntity
)
([]
*
milvuspb
.
GrantEntity
,
error
)
DropGrantFunc
func
(
tenant
string
,
role
*
milvuspb
.
RoleEntity
)
error
ListPolicyFunc
func
(
tenant
string
)
([]
string
,
error
)
ListUserRoleFunc
func
(
tenant
string
)
([]
string
,
error
)
}
func
(
m
mockMetaTable
)
ListDatabases
(
ctx
context
.
Context
,
ts
typeutil
.
Timestamp
)
([]
*
model
.
Database
,
error
)
{
...
...
@@ -154,6 +171,66 @@ func (m mockMetaTable) GetCollectionVirtualChannels(colID int64) []string {
return
m
.
GetCollectionVirtualChannelsFunc
(
colID
)
}
func
(
m
mockMetaTable
)
AddCredential
(
credInfo
*
internalpb
.
CredentialInfo
)
error
{
return
m
.
AddCredentialFunc
(
credInfo
)
}
func
(
m
mockMetaTable
)
GetCredential
(
username
string
)
(
*
internalpb
.
CredentialInfo
,
error
)
{
return
m
.
GetCredentialFunc
(
username
)
}
func
(
m
mockMetaTable
)
DeleteCredential
(
username
string
)
error
{
return
m
.
DeleteCredentialFunc
(
username
)
}
func
(
m
mockMetaTable
)
AlterCredential
(
credInfo
*
internalpb
.
CredentialInfo
)
error
{
return
m
.
AlterCredentialFunc
(
credInfo
)
}
func
(
m
mockMetaTable
)
ListCredentialUsernames
()
(
*
milvuspb
.
ListCredUsersResponse
,
error
)
{
return
m
.
ListCredentialUsernamesFunc
()
}
func
(
m
mockMetaTable
)
CreateRole
(
tenant
string
,
entity
*
milvuspb
.
RoleEntity
)
error
{
return
m
.
CreateRoleFunc
(
tenant
,
entity
)
}
func
(
m
mockMetaTable
)
DropRole
(
tenant
string
,
roleName
string
)
error
{
return
m
.
DropRoleFunc
(
tenant
,
roleName
)
}
func
(
m
mockMetaTable
)
OperateUserRole
(
tenant
string
,
userEntity
*
milvuspb
.
UserEntity
,
roleEntity
*
milvuspb
.
RoleEntity
,
operateType
milvuspb
.
OperateUserRoleType
)
error
{
return
m
.
OperateUserRoleFunc
(
tenant
,
userEntity
,
roleEntity
,
operateType
)
}
func
(
m
mockMetaTable
)
SelectRole
(
tenant
string
,
entity
*
milvuspb
.
RoleEntity
,
includeUserInfo
bool
)
([]
*
milvuspb
.
RoleResult
,
error
)
{
return
m
.
SelectRoleFunc
(
tenant
,
entity
,
includeUserInfo
)
}
func
(
m
mockMetaTable
)
SelectUser
(
tenant
string
,
entity
*
milvuspb
.
UserEntity
,
includeRoleInfo
bool
)
([]
*
milvuspb
.
UserResult
,
error
)
{
return
m
.
SelectUserFunc
(
tenant
,
entity
,
includeRoleInfo
)
}
func
(
m
mockMetaTable
)
OperatePrivilege
(
tenant
string
,
entity
*
milvuspb
.
GrantEntity
,
operateType
milvuspb
.
OperatePrivilegeType
)
error
{
return
m
.
OperatePrivilegeFunc
(
tenant
,
entity
,
operateType
)
}
func
(
m
mockMetaTable
)
SelectGrant
(
tenant
string
,
entity
*
milvuspb
.
GrantEntity
)
([]
*
milvuspb
.
GrantEntity
,
error
)
{
return
m
.
SelectGrantFunc
(
tenant
,
entity
)
}
func
(
m
mockMetaTable
)
DropGrant
(
tenant
string
,
role
*
milvuspb
.
RoleEntity
)
error
{
return
m
.
DropGrantFunc
(
tenant
,
role
)
}
func
(
m
mockMetaTable
)
ListPolicy
(
tenant
string
)
([]
string
,
error
)
{
return
m
.
ListPolicyFunc
(
tenant
)
}
func
(
m
mockMetaTable
)
ListUserRole
(
tenant
string
)
([]
string
,
error
)
{
return
m
.
ListUserRoleFunc
(
tenant
)
}
func
newMockMetaTable
()
*
mockMetaTable
{
return
&
mockMetaTable
{}
}
...
...
@@ -409,6 +486,51 @@ func withInvalidMeta() Opt {
meta
.
DropAliasFunc
=
func
(
ctx
context
.
Context
,
dbName
string
,
alias
string
,
ts
Timestamp
)
error
{
return
errors
.
New
(
"error mock DropAlias"
)
}
meta
.
AddCredentialFunc
=
func
(
credInfo
*
internalpb
.
CredentialInfo
)
error
{
return
errors
.
New
(
"error mock AddCredential"
)
}
meta
.
GetCredentialFunc
=
func
(
username
string
)
(
*
internalpb
.
CredentialInfo
,
error
)
{
return
nil
,
errors
.
New
(
"error mock GetCredential"
)
}
meta
.
DeleteCredentialFunc
=
func
(
username
string
)
error
{
return
errors
.
New
(
"error mock DeleteCredential"
)
}
meta
.
AlterCredentialFunc
=
func
(
credInfo
*
internalpb
.
CredentialInfo
)
error
{
return
errors
.
New
(
"error mock AlterCredential"
)
}
meta
.
ListCredentialUsernamesFunc
=
func
()
(
*
milvuspb
.
ListCredUsersResponse
,
error
)
{
return
nil
,
errors
.
New
(
"error mock ListCredentialUsernames"
)
}
meta
.
CreateRoleFunc
=
func
(
tenant
string
,
entity
*
milvuspb
.
RoleEntity
)
error
{
return
errors
.
New
(
"error mock CreateRole"
)
}
meta
.
DropRoleFunc
=
func
(
tenant
string
,
roleName
string
)
error
{
return
errors
.
New
(
"error mock DropRole"
)
}
meta
.
OperateUserRoleFunc
=
func
(
tenant
string
,
userEntity
*
milvuspb
.
UserEntity
,
roleEntity
*
milvuspb
.
RoleEntity
,
operateType
milvuspb
.
OperateUserRoleType
)
error
{
return
errors
.
New
(
"error mock OperateUserRole"
)
}
meta
.
SelectUserFunc
=
func
(
tenant
string
,
entity
*
milvuspb
.
UserEntity
,
includeRoleInfo
bool
)
([]
*
milvuspb
.
UserResult
,
error
)
{
return
nil
,
errors
.
New
(
"error mock SelectUser"
)
}
meta
.
SelectRoleFunc
=
func
(
tenant
string
,
entity
*
milvuspb
.
RoleEntity
,
includeUserInfo
bool
)
([]
*
milvuspb
.
RoleResult
,
error
)
{
return
nil
,
errors
.
New
(
"error mock SelectRole"
)
}
meta
.
OperatePrivilegeFunc
=
func
(
tenant
string
,
entity
*
milvuspb
.
GrantEntity
,
operateType
milvuspb
.
OperatePrivilegeType
)
error
{
return
errors
.
New
(
"error mock OperatePrivilege"
)
}
meta
.
SelectGrantFunc
=
func
(
tenant
string
,
entity
*
milvuspb
.
GrantEntity
)
([]
*
milvuspb
.
GrantEntity
,
error
)
{
return
nil
,
errors
.
New
(
"error mock SelectGrant"
)
}
meta
.
DropGrantFunc
=
func
(
tenant
string
,
role
*
milvuspb
.
RoleEntity
)
error
{
return
errors
.
New
(
"error mock DropGrant"
)
}
meta
.
ListPolicyFunc
=
func
(
tenant
string
)
([]
string
,
error
)
{
return
nil
,
errors
.
New
(
"error mock ListPolicy"
)
}
meta
.
ListUserRoleFunc
=
func
(
tenant
string
)
([]
string
,
error
)
{
return
nil
,
errors
.
New
(
"error mock ListUserRole"
)
}
return
withMeta
(
meta
)
}
...
...
internal/rootcoord/root_coord.go
浏览文件 @
13f69bfc
...
...
@@ -669,6 +669,18 @@ func (c *Core) startInternal() error {
c
.
startServerLoop
()
c
.
UpdateStateCode
(
commonpb
.
StateCode_Healthy
)
// refresh rbac cache
if
err
:=
retry
.
Do
(
c
.
ctx
,
func
()
error
{
if
err
:=
c
.
proxyClientManager
.
RefreshPolicyInfoCache
(
c
.
ctx
,
&
proxypb
.
RefreshPolicyInfoCacheRequest
{
OpType
:
int32
(
typeutil
.
CacheRefresh
),
});
err
!=
nil
{
log
.
Warn
(
"fail to refresh policy info cache"
,
zap
.
Error
(
err
))
return
err
}
return
nil
},
retry
.
Attempts
(
100
),
retry
.
Sleep
(
time
.
Second
));
err
!=
nil
{
log
.
Panic
(
"fail to refresh policy info cache"
,
zap
.
Error
(
err
))
}
logutil
.
Logger
(
c
.
ctx
)
.
Info
(
"rootcoord startup successfully"
)
return
nil
...
...
@@ -2113,7 +2125,7 @@ func (c *Core) GetCredential(ctx context.Context, in *rootcoordpb.GetCredentialR
metrics
.
RootCoordDDLReqCounter
.
WithLabelValues
(
method
,
metrics
.
FailLabel
)
.
Inc
()
return
&
rootcoordpb
.
GetCredentialResponse
{
Status
:
failStatus
(
commonpb
.
ErrorCode_GetCredentialFailure
,
"GetCredential failed: "
+
err
.
Error
()),
},
err
},
nil
}
log
.
Info
(
"GetCredential success"
,
zap
.
String
(
"role"
,
typeutil
.
RootCoordRole
),
zap
.
String
(
"username"
,
in
.
Username
))
...
...
@@ -2171,35 +2183,61 @@ func (c *Core) DeleteCredential(ctx context.Context, in *milvuspb.DeleteCredenti
metrics
.
RootCoordDDLReqCounter
.
WithLabelValues
(
method
,
metrics
.
TotalLabel
)
.
Inc
()
tr
:=
timerecord
.
NewTimeRecorder
(
method
)
var
status
*
commonpb
.
Status
defer
func
()
{
if
status
.
ErrorCode
!=
commonpb
.
ErrorCode_Success
{
metrics
.
RootCoordDDLReqCounter
.
WithLabelValues
(
method
,
metrics
.
FailLabel
)
.
Inc
()
}
}()
ctxLog
:=
log
.
Ctx
(
ctx
)
.
With
(
zap
.
String
(
"role"
,
typeutil
.
RootCoordRole
),
zap
.
String
(
"username"
,
in
.
Username
))
if
code
,
ok
:=
c
.
checkHealthy
();
!
ok
{
ret
:
=
&
commonpb
.
Status
{}
setNotServingStatus
(
ret
,
code
)
return
ret
,
nil
status
=
&
commonpb
.
Status
{}
setNotServingStatus
(
status
,
code
)
return
status
,
nil
}
// delete data on storage
err
:=
c
.
meta
.
DeleteCredential
(
in
.
Username
)
if
err
!=
nil
{
log
.
Error
(
"DeleteCredential remove credential failed"
,
zap
.
String
(
"role"
,
typeutil
.
RootCoordRole
),
zap
.
String
(
"username"
,
in
.
Username
),
zap
.
Error
(
err
))
metrics
.
RootCoordDDLReqCounter
.
WithLabelValues
(
method
,
metrics
.
FailLabel
)
.
Inc
()
return
failStatus
(
commonpb
.
ErrorCode_DeleteCredentialFailure
,
"DeleteCredential failed: "
+
err
.
Error
()),
err
}
// invalidate proxy's local cache
err
=
c
.
ExpireCredCache
(
ctx
,
in
.
Username
)
redoTask
:=
newBaseRedoTask
(
c
.
stepExecutor
)
redoTask
.
AddSyncStep
(
NewSimpleStep
(
"delete credential meta data"
,
func
(
ctx
context
.
Context
)
([]
nestedStep
,
error
)
{
err
:=
c
.
meta
.
DeleteCredential
(
in
.
Username
)
if
err
!=
nil
{
ctxLog
.
Warn
(
"delete credential meta data failed"
,
zap
.
Error
(
err
))
}
return
nil
,
err
}))
redoTask
.
AddAsyncStep
(
NewSimpleStep
(
"delete credential cache"
,
func
(
ctx
context
.
Context
)
([]
nestedStep
,
error
)
{
err
:=
c
.
ExpireCredCache
(
ctx
,
in
.
Username
)
if
err
!=
nil
{
ctxLog
.
Warn
(
"delete credential cache failed"
,
zap
.
Error
(
err
))
}
return
nil
,
err
}))
redoTask
.
AddAsyncStep
(
NewSimpleStep
(
"delete user role cache for the user"
,
func
(
ctx
context
.
Context
)
([]
nestedStep
,
error
)
{
err
:=
c
.
proxyClientManager
.
RefreshPolicyInfoCache
(
ctx
,
&
proxypb
.
RefreshPolicyInfoCacheRequest
{
OpType
:
int32
(
typeutil
.
CacheDeleteUser
),
OpKey
:
in
.
Username
,
})
if
err
!=
nil
{
ctxLog
.
Warn
(
"delete user role cache failed for the user"
,
zap
.
Error
(
err
))
}
return
nil
,
err
}))
err
:=
redoTask
.
Execute
(
ctx
)
if
err
!=
nil
{
log
.
Error
(
"DeleteCredential expire credential cache failed"
,
zap
.
String
(
"role"
,
typeutil
.
RootCoordRole
),
zap
.
String
(
"username"
,
in
.
Username
)
,
zap
.
Error
(
err
))
metrics
.
RootCoordDDLReqCounter
.
WithLabelValues
(
method
,
metrics
.
FailLabel
)
.
Inc
(
)
return
failStatus
(
commonpb
.
ErrorCode_DeleteCredentialFailure
,
"DeleteCredential failed: "
+
err
.
Error
())
,
nil
errMsg
:=
"fail to execute task when deleting the user"
ctxLog
.
Warn
(
errMsg
,
zap
.
Error
(
err
))
status
=
failStatus
(
commonpb
.
ErrorCode_DeleteCredentialFailure
,
errMsg
)
return
status
,
nil
}
log
.
Info
(
"DeleteCredential success"
,
zap
.
String
(
"role"
,
typeutil
.
RootCoordRole
),
zap
.
String
(
"username"
,
in
.
Username
)
)
ctxLog
.
Info
(
"DeleteCredential success"
)
metrics
.
RootCoordDDLReqCounter
.
WithLabelValues
(
method
,
metrics
.
SuccessLabel
)
.
Inc
()
metrics
.
RootCoordDDLReqLatency
.
WithLabelValues
(
method
)
.
Observe
(
float64
(
tr
.
ElapseSpan
()
.
Milliseconds
()))
metrics
.
RootCoordNumOfCredentials
.
Dec
()
return
succStatus
(),
nil
status
=
succStatus
()
return
status
,
nil
}
// ListCredUsers list all usernames
...
...
@@ -2217,11 +2255,11 @@ func (c *Core) ListCredUsers(ctx context.Context, in *milvuspb.ListCredUsersRequ
credInfo
,
err
:=
c
.
meta
.
ListCredentialUsernames
()
if
err
!=
nil
{
log
.
Error
(
"ListCredUsers query usernames failed"
,
zap
.
String
(
"role"
,
typeutil
.
RootCoordRole
),
zap
.
Int64
(
"msgID"
,
in
.
Base
.
MsgID
),
zap
.
Error
(
err
))
zap
.
Any
(
"in"
,
in
),
zap
.
Error
(
err
))
metrics
.
RootCoordDDLReqCounter
.
WithLabelValues
(
method
,
metrics
.
FailLabel
)
.
Inc
()
return
&
milvuspb
.
ListCredUsersResponse
{
Status
:
failStatus
(
commonpb
.
ErrorCode_ListCredUsersFailure
,
"ListCredUsers failed: "
+
err
.
Error
()),
},
err
},
nil
}
log
.
Info
(
"ListCredUsers success"
,
zap
.
String
(
"role"
,
typeutil
.
RootCoordRole
))
...
...
@@ -2277,7 +2315,8 @@ func (c *Core) DropRole(ctx context.Context, in *milvuspb.DropRoleRequest) (*com
method
:=
"DropRole"
metrics
.
RootCoordDDLReqCounter
.
WithLabelValues
(
method
,
metrics
.
TotalLabel
)
.
Inc
()
tr
:=
timerecord
.
NewTimeRecorder
(
method
)
logger
.
Debug
(
method
,
zap
.
Any
(
"in"
,
in
))
ctxLog
:=
log
.
Ctx
(
ctx
)
.
With
(
zap
.
String
(
"role"
,
typeutil
.
RootCoordRole
),
zap
.
String
(
"role_name"
,
in
.
RoleName
))
ctxLog
.
Debug
(
method
)
if
code
,
ok
:=
c
.
checkHealthy
();
!
ok
{
ret
:=
&
commonpb
.
Status
{}
...
...
@@ -2286,7 +2325,7 @@ func (c *Core) DropRole(ctx context.Context, in *milvuspb.DropRoleRequest) (*com
}
if
_
,
err
:=
c
.
meta
.
SelectRole
(
util
.
DefaultTenant
,
&
milvuspb
.
RoleEntity
{
Name
:
in
.
RoleName
},
false
);
err
!=
nil
{
errMsg
:=
"not found the role, maybe the role isn't existed or internal system error"
log
.
Error
(
errMsg
,
zap
.
Any
(
"in"
,
in
)
,
zap
.
Error
(
err
))
ctxLog
.
Warn
(
errMsg
,
zap
.
Error
(
err
))
return
failStatus
(
commonpb
.
ErrorCode_DropRoleFailure
,
errMsg
),
nil
}
...
...
@@ -2295,42 +2334,36 @@ func (c *Core) DropRole(ctx context.Context, in *milvuspb.DropRoleRequest) (*com
})
if
len
(
grantEntities
)
!=
0
{
errMsg
:=
"fail to drop the role that it has privileges. Use REVOKE API to revoke privileges"
log
.
Error
(
errMsg
,
zap
.
Any
(
"in"
,
in
),
zap
.
Error
(
err
))
return
failStatus
(
commonpb
.
ErrorCode_DropRoleFailure
,
errMsg
),
nil
}
roleResults
,
err
:=
c
.
meta
.
SelectRole
(
util
.
DefaultTenant
,
&
milvuspb
.
RoleEntity
{
Name
:
in
.
RoleName
},
true
)
if
err
!=
nil
{
errMsg
:=
"fail to find the role by role name, maybe the role isn't existed or internal system error"
log
.
Error
(
errMsg
,
zap
.
Any
(
"in"
,
in
),
zap
.
Error
(
err
))
ctxLog
.
Warn
(
errMsg
,
zap
.
Error
(
err
))
return
failStatus
(
commonpb
.
ErrorCode_DropRoleFailure
,
errMsg
),
nil
}
logger
.
Debug
(
"role to user info"
,
zap
.
Int
(
"counter"
,
len
(
roleResults
)))
for
_
,
roleResult
:=
range
roleResults
{
for
index
,
userEntity
:=
range
roleResult
.
Users
{
if
err
=
c
.
meta
.
OperateUserRole
(
util
.
DefaultTenant
,
&
milvuspb
.
UserEntity
{
Name
:
userEntity
.
Name
},
&
milvuspb
.
RoleEntity
{
Name
:
roleResult
.
Role
.
Name
},
milvuspb
.
OperateUserRoleType_RemoveUserFromRole
);
err
!=
nil
{
if
common
.
IsIgnorableError
(
err
)
{
continue
}
errMsg
:=
"fail to remove user from role"
log
.
Error
(
errMsg
,
zap
.
Any
(
"in"
,
in
),
zap
.
String
(
"role_name"
,
roleResult
.
Role
.
Name
),
zap
.
String
(
"username"
,
userEntity
.
Name
),
zap
.
Int
(
"current_index"
,
index
),
zap
.
Error
(
err
))
return
failStatus
(
commonpb
.
ErrorCode_OperateUserRoleFailure
,
errMsg
),
nil
}
redoTask
:=
newBaseRedoTask
(
c
.
stepExecutor
)
redoTask
.
AddSyncStep
(
NewSimpleStep
(
"drop role meta data"
,
func
(
ctx
context
.
Context
)
([]
nestedStep
,
error
)
{
err
:=
c
.
meta
.
DropRole
(
util
.
DefaultTenant
,
in
.
RoleName
)
if
err
!=
nil
{
ctxLog
.
Warn
(
"drop role mata data failed"
,
zap
.
Error
(
err
))
}
}
if
err
=
c
.
meta
.
DropGrant
(
util
.
DefaultTenant
,
&
milvuspb
.
RoleEntity
{
Name
:
in
.
RoleName
});
err
!=
nil
{
errMsg
:=
"fail to drop the grant"
log
.
Error
(
errMsg
,
zap
.
Any
(
"in"
,
in
),
zap
.
Error
(
err
))
return
failStatus
(
commonpb
.
ErrorCode_DropRoleFailure
,
errMsg
),
nil
}
if
err
=
c
.
meta
.
DropRole
(
util
.
DefaultTenant
,
in
.
RoleName
);
err
!=
nil
{
errMsg
:=
"fail to drop the role"
log
.
Error
(
errMsg
,
zap
.
Any
(
"in"
,
in
),
zap
.
Error
(
err
))
return
nil
,
err
}))
redoTask
.
AddAsyncStep
(
NewSimpleStep
(
"drop role cache"
,
func
(
ctx
context
.
Context
)
([]
nestedStep
,
error
)
{
err
:=
c
.
proxyClientManager
.
RefreshPolicyInfoCache
(
ctx
,
&
proxypb
.
RefreshPolicyInfoCacheRequest
{
OpType
:
int32
(
typeutil
.
CacheDropRole
),
OpKey
:
in
.
RoleName
,
})
if
err
!=
nil
{
ctxLog
.
Warn
(
"delete user role cache failed for the role"
,
zap
.
Error
(
err
))
}
return
nil
,
err
}))
err
=
redoTask
.
Execute
(
ctx
)
if
err
!=
nil
{
errMsg
:=
"fail to execute task when dropping the role"
ctxLog
.
Warn
(
errMsg
,
zap
.
Error
(
err
))
return
failStatus
(
commonpb
.
ErrorCode_DropRoleFailure
,
errMsg
),
nil
}
logger
.
Debug
(
method
+
" success"
,
zap
.
String
(
"role_name"
,
in
.
RoleName
)
)
ctxLog
.
Debug
(
method
+
" success"
)
metrics
.
RootCoordDDLReqCounter
.
WithLabelValues
(
method
,
metrics
.
SuccessLabel
)
.
Inc
()
metrics
.
RootCoordDDLReqLatency
.
WithLabelValues
(
method
)
.
Observe
(
float64
(
tr
.
ElapseSpan
()
.
Milliseconds
()))
metrics
.
RootCoordNumOfRoles
.
Dec
()
...
...
@@ -2368,17 +2401,16 @@ func (c *Core) OperateUserRole(ctx context.Context, in *milvuspb.OperateUserRole
}
}
updateCache
:=
true
if
err
:=
c
.
meta
.
OperateUserRole
(
util
.
DefaultTenant
,
&
milvuspb
.
UserEntity
{
Name
:
in
.
Username
},
&
milvuspb
.
RoleEntity
{
Name
:
in
.
RoleName
},
in
.
Type
);
err
!=
nil
{
if
!
common
.
IsIgnorableError
(
err
)
{
errMsg
:=
"fail to operate user to role"
log
.
Error
(
errMsg
,
zap
.
Any
(
"in"
,
in
)
,
zap
.
Error
(
err
))
return
failStatus
(
commonpb
.
ErrorCode_OperateUserRoleFailure
,
errMsg
),
nil
redoTask
:=
newBaseRedoTask
(
c
.
stepExecutor
)
redoTask
.
AddSyncStep
(
NewSimpleStep
(
"operate user role meta data"
,
func
(
ctx
context
.
Context
)
([]
nestedStep
,
error
)
{
err
:=
c
.
meta
.
OperateUserRole
(
util
.
DefaultTenant
,
&
milvuspb
.
UserEntity
{
Name
:
in
.
Username
},
&
milvuspb
.
RoleEntity
{
Name
:
in
.
RoleName
},
in
.
Type
)
if
err
!=
nil
&&
!
common
.
IsIgnorableError
(
err
)
{
log
.
Warn
(
"operate user role mata data failed"
,
zap
.
Error
(
err
))
return
nil
,
err
}
updateCache
=
false
}
if
updateCache
{
return
nil
,
nil
}))
redoTask
.
AddAsyncStep
(
NewSimpleStep
(
"operate user role cache"
,
func
(
ctx
context
.
Context
)
([]
nestedStep
,
error
)
{
var
opType
int32
switch
in
.
Type
{
case
milvuspb
.
OperateUserRoleType_AddUserToRole
:
...
...
@@ -2387,17 +2419,23 @@ func (c *Core) OperateUserRole(ctx context.Context, in *milvuspb.OperateUserRole
opType
=
int32
(
typeutil
.
CacheRemoveUserFromRole
)
default
:
errMsg
:=
"invalid operate type for the OperateUserRole api"
log
.
Error
(
errMsg
,
zap
.
Any
(
"in"
,
in
))
return
failStatus
(
commonpb
.
ErrorCode_OperateUserRoleFailure
,
errMsg
)
,
nil
log
.
Warn
(
errMsg
,
zap
.
Any
(
"in"
,
in
))
return
nil
,
nil
}
if
err
:=
c
.
proxyClientManager
.
RefreshPolicyInfoCache
(
ctx
,
&
proxypb
.
RefreshPolicyInfoCacheRequest
{
OpType
:
opType
,
OpKey
:
funcutil
.
EncodeUserRoleCache
(
in
.
Username
,
in
.
RoleName
),
});
err
!=
nil
{
errMsg
:=
"fail to refresh policy info cache"
log
.
Error
(
errMsg
,
zap
.
Any
(
"in"
,
in
),
zap
.
Error
(
err
))
return
failStatus
(
commonpb
.
ErrorCode_OperateUserRoleFailure
,
errMsg
),
nil
log
.
Warn
(
"fail to refresh policy info cache"
,
zap
.
Any
(
"in"
,
in
),
zap
.
Error
(
err
))
return
nil
,
err
}
return
nil
,
nil
}))
err
:=
redoTask
.
Execute
(
ctx
)
if
err
!=
nil
{
errMsg
:=
"fail to execute task when operate the user and role"
log
.
Warn
(
errMsg
,
zap
.
Error
(
err
))
return
failStatus
(
commonpb
.
ErrorCode_OperateUserRoleFailure
,
errMsg
),
nil
}
logger
.
Debug
(
method
+
" success"
)
...
...
@@ -2610,17 +2648,17 @@ func (c *Core) OperatePrivilege(ctx context.Context, in *milvuspb.OperatePrivile
if
in
.
Entity
.
Object
.
Name
==
commonpb
.
ObjectType_Global
.
String
()
{
in
.
Entity
.
ObjectName
=
util
.
AnyWord
}
updateCache
:=
true
if
err
:=
c
.
meta
.
OperatePrivilege
(
util
.
DefaultTenant
,
in
.
Entity
,
in
.
Type
);
err
!=
nil
{
if
!
common
.
IsIgnorableError
(
err
)
{
errMsg
:=
"fail to operate the privilege"
log
.
Error
(
errMsg
,
zap
.
Any
(
"in"
,
in
),
zap
.
Error
(
err
))
return
failStatus
(
commonpb
.
ErrorCode_OperatePrivilegeFailure
,
errMsg
),
nil
}
updateCache
=
false
}
if
updateCache
{
redoTask
:=
newBaseRedoTask
(
c
.
stepExecutor
)
redoTask
.
AddSyncStep
(
NewSimpleStep
(
"operate privilege meta data"
,
func
(
ctx
context
.
Context
)
([]
nestedStep
,
error
)
{
err
:=
c
.
meta
.
OperatePrivilege
(
util
.
DefaultTenant
,
in
.
Entity
,
in
.
Type
)
if
err
!=
nil
&&
!
common
.
IsIgnorableError
(
err
)
{
log
.
Warn
(
"fail to operate the privilege"
,
zap
.
Any
(
"in"
,
in
),
zap
.
Error
(
err
))
return
nil
,
err
}
return
nil
,
nil
}))
redoTask
.
AddAsyncStep
(
NewSimpleStep
(
"operate privilege cache"
,
func
(
ctx
context
.
Context
)
([]
nestedStep
,
error
)
{
var
opType
int32
switch
in
.
Type
{
case
milvuspb
.
OperatePrivilegeType_Grant
:
...
...
@@ -2628,18 +2666,24 @@ func (c *Core) OperatePrivilege(ctx context.Context, in *milvuspb.OperatePrivile
case
milvuspb
.
OperatePrivilegeType_Revoke
:
opType
=
int32
(
typeutil
.
CacheRevokePrivilege
)
default
:
errMsg
:=
"invalid operate type for the OperatePrivilege api"
log
.
Error
(
errMsg
,
zap
.
Any
(
"in"
,
in
))
return
failStatus
(
commonpb
.
ErrorCode_OperatePrivilegeFailure
,
errMsg
),
nil
log
.
Warn
(
"invalid operate type for the OperatePrivilege api"
,
zap
.
Any
(
"in"
,
in
))
return
nil
,
nil
}
if
err
:=
c
.
proxyClientManager
.
RefreshPolicyInfoCache
(
ctx
,
&
proxypb
.
RefreshPolicyInfoCacheRequest
{
OpType
:
opType
,
OpKey
:
funcutil
.
PolicyForPrivilege
(
in
.
Entity
.
Role
.
Name
,
in
.
Entity
.
Object
.
Name
,
in
.
Entity
.
ObjectName
,
in
.
Entity
.
Grantor
.
Privilege
.
Name
,
in
.
Entity
.
DbName
),
});
err
!=
nil
{
errMsg
:=
"fail to refresh policy info cache"
log
.
Error
(
errMsg
,
zap
.
Any
(
"in"
,
in
),
zap
.
Error
(
err
))
return
failStatus
(
commonpb
.
ErrorCode_OperatePrivilegeFailure
,
errMsg
),
nil
log
.
Warn
(
"fail to refresh policy info cache"
,
zap
.
Any
(
"in"
,
in
),
zap
.
Error
(
err
))
return
nil
,
err
}
return
nil
,
nil
}))
err
:=
redoTask
.
Execute
(
ctx
)
if
err
!=
nil
{
errMsg
:=
"fail to execute task when operating the privilege"
log
.
Warn
(
errMsg
,
zap
.
Error
(
err
))
return
failStatus
(
commonpb
.
ErrorCode_OperatePrivilegeFailure
,
errMsg
),
nil
}
logger
.
Debug
(
method
+
" success"
)
...
...
internal/rootcoord/root_coord_test.go
浏览文件 @
13f69bfc
...
...
@@ -1446,6 +1446,36 @@ func TestCore_Rbac(t *testing.T) {
// not healthy.
c
.
stateCode
.
Store
(
commonpb
.
StateCode_Abnormal
)
{
resp
,
err
:=
c
.
CreateCredential
(
ctx
,
&
internalpb
.
CredentialInfo
{})
assert
.
NoError
(
t
,
err
)
assert
.
Equal
(
t
,
commonpb
.
ErrorCode_NotReadyServe
,
resp
.
ErrorCode
)
}
{
resp
,
err
:=
c
.
DeleteCredential
(
ctx
,
&
milvuspb
.
DeleteCredentialRequest
{})
assert
.
NoError
(
t
,
err
)
assert
.
Equal
(
t
,
commonpb
.
ErrorCode_NotReadyServe
,
resp
.
ErrorCode
)
}
{
resp
,
err
:=
c
.
UpdateCredential
(
ctx
,
&
internalpb
.
CredentialInfo
{})
assert
.
NoError
(
t
,
err
)
assert
.
Equal
(
t
,
commonpb
.
ErrorCode_NotReadyServe
,
resp
.
ErrorCode
)
}
{
resp
,
err
:=
c
.
GetCredential
(
ctx
,
&
rootcoordpb
.
GetCredentialRequest
{})
assert
.
NoError
(
t
,
err
)
assert
.
Equal
(
t
,
commonpb
.
ErrorCode_NotReadyServe
,
resp
.
Status
.
ErrorCode
)
}
{
resp
,
err
:=
c
.
ListCredUsers
(
ctx
,
&
milvuspb
.
ListCredUsersRequest
{})
assert
.
NoError
(
t
,
err
)
assert
.
Equal
(
t
,
commonpb
.
ErrorCode_NotReadyServe
,
resp
.
Status
.
ErrorCode
)
}
{
resp
,
err
:=
c
.
CreateRole
(
ctx
,
&
milvuspb
.
CreateRoleRequest
{})
assert
.
NoError
(
t
,
err
)
...
...
@@ -1727,6 +1757,226 @@ func TestRootCoord_CheckHealth(t *testing.T) {
})
}
func
TestRootCoord_RBACError
(
t
*
testing
.
T
)
{
ctx
:=
context
.
Background
()
c
:=
newTestCore
(
withHealthyCode
(),
withInvalidMeta
())
t
.
Run
(
"create credential failed"
,
func
(
t
*
testing
.
T
)
{
resp
,
err
:=
c
.
CreateCredential
(
ctx
,
&
internalpb
.
CredentialInfo
{
Username
:
"foo"
,
EncryptedPassword
:
"bar"
})
assert
.
NoError
(
t
,
err
)
assert
.
NotEqual
(
t
,
commonpb
.
ErrorCode_Success
,
resp
.
ErrorCode
)
})
t
.
Run
(
"get credential failed"
,
func
(
t
*
testing
.
T
)
{
resp
,
err
:=
c
.
GetCredential
(
ctx
,
&
rootcoordpb
.
GetCredentialRequest
{
Username
:
"foo"
})
assert
.
NoError
(
t
,
err
)
assert
.
NotEqual
(
t
,
commonpb
.
ErrorCode_Success
,
resp
.
Status
.
ErrorCode
)
})
t
.
Run
(
"update credential failed"
,
func
(
t
*
testing
.
T
)
{
resp
,
err
:=
c
.
UpdateCredential
(
ctx
,
&
internalpb
.
CredentialInfo
{})
assert
.
NoError
(
t
,
err
)
assert
.
NotEqual
(
t
,
commonpb
.
ErrorCode_Success
,
resp
.
ErrorCode
)
})
t
.
Run
(
"delete credential failed"
,
func
(
t
*
testing
.
T
)
{
resp
,
err
:=
c
.
DeleteCredential
(
ctx
,
&
milvuspb
.
DeleteCredentialRequest
{
Username
:
"foo"
})
assert
.
NoError
(
t
,
err
)
assert
.
NotEqual
(
t
,
commonpb
.
ErrorCode_Success
,
resp
.
ErrorCode
)
})
t
.
Run
(
"list credential failed"
,
func
(
t
*
testing
.
T
)
{
resp
,
err
:=
c
.
ListCredUsers
(
ctx
,
&
milvuspb
.
ListCredUsersRequest
{})
assert
.
NoError
(
t
,
err
)
assert
.
NotEqual
(
t
,
commonpb
.
ErrorCode_Success
,
resp
.
Status
.
ErrorCode
)
})
t
.
Run
(
"create role failed"
,
func
(
t
*
testing
.
T
)
{
resp
,
err
:=
c
.
CreateRole
(
ctx
,
&
milvuspb
.
CreateRoleRequest
{
Entity
:
&
milvuspb
.
RoleEntity
{
Name
:
"foo"
}})
assert
.
NoError
(
t
,
err
)
assert
.
NotEqual
(
t
,
commonpb
.
ErrorCode_Success
,
resp
.
ErrorCode
)
})
t
.
Run
(
"drop role failed"
,
func
(
t
*
testing
.
T
)
{
resp
,
err
:=
c
.
DropRole
(
ctx
,
&
milvuspb
.
DropRoleRequest
{
RoleName
:
"foo"
})
assert
.
NoError
(
t
,
err
)
assert
.
NotEqual
(
t
,
commonpb
.
ErrorCode_Success
,
resp
.
ErrorCode
)
mockMeta
:=
c
.
meta
.
(
*
mockMetaTable
)
mockMeta
.
SelectRoleFunc
=
func
(
tenant
string
,
entity
*
milvuspb
.
RoleEntity
,
includeUserInfo
bool
)
([]
*
milvuspb
.
RoleResult
,
error
)
{
return
nil
,
nil
}
defer
func
()
{
mockMeta
.
SelectRoleFunc
=
func
(
tenant
string
,
entity
*
milvuspb
.
RoleEntity
,
includeUserInfo
bool
)
([]
*
milvuspb
.
RoleResult
,
error
)
{
return
nil
,
errors
.
New
(
"mock error"
)
}
}()
{
resp
,
err
:=
c
.
DropRole
(
ctx
,
&
milvuspb
.
DropRoleRequest
{
RoleName
:
"foo"
})
assert
.
NoError
(
t
,
err
)
assert
.
NotEqual
(
t
,
commonpb
.
ErrorCode_Success
,
resp
.
ErrorCode
)
}
mockMeta
.
SelectGrantFunc
=
func
(
tenant
string
,
entity
*
milvuspb
.
GrantEntity
)
([]
*
milvuspb
.
GrantEntity
,
error
)
{
return
[]
*
milvuspb
.
GrantEntity
{{}},
nil
}
defer
func
()
{
mockMeta
.
SelectGrantFunc
=
func
(
tenant
string
,
entity
*
milvuspb
.
GrantEntity
)
([]
*
milvuspb
.
GrantEntity
,
error
)
{
return
nil
,
errors
.
New
(
"mock error"
)
}
}()
{
resp
,
err
:=
c
.
DropRole
(
ctx
,
&
milvuspb
.
DropRoleRequest
{
RoleName
:
"foo"
})
assert
.
NoError
(
t
,
err
)
assert
.
NotEqual
(
t
,
commonpb
.
ErrorCode_Success
,
resp
.
ErrorCode
)
}
})
t
.
Run
(
"operate user role failed"
,
func
(
t
*
testing
.
T
)
{
mockMeta
:=
c
.
meta
.
(
*
mockMetaTable
)
mockMeta
.
SelectRoleFunc
=
func
(
tenant
string
,
entity
*
milvuspb
.
RoleEntity
,
includeUserInfo
bool
)
([]
*
milvuspb
.
RoleResult
,
error
)
{
return
nil
,
nil
}
mockMeta
.
SelectUserFunc
=
func
(
tenant
string
,
entity
*
milvuspb
.
UserEntity
,
includeRoleInfo
bool
)
([]
*
milvuspb
.
UserResult
,
error
)
{
return
nil
,
nil
}
resp
,
err
:=
c
.
OperateUserRole
(
ctx
,
&
milvuspb
.
OperateUserRoleRequest
{
RoleName
:
"foo"
,
Username
:
"bar"
,
Type
:
milvuspb
.
OperateUserRoleType_AddUserToRole
})
assert
.
NoError
(
t
,
err
)
assert
.
NotEqual
(
t
,
commonpb
.
ErrorCode_Success
,
resp
.
ErrorCode
)
mockMeta
.
SelectRoleFunc
=
func
(
tenant
string
,
entity
*
milvuspb
.
RoleEntity
,
includeUserInfo
bool
)
([]
*
milvuspb
.
RoleResult
,
error
)
{
return
nil
,
errors
.
New
(
"mock error"
)
}
mockMeta
.
SelectUserFunc
=
func
(
tenant
string
,
entity
*
milvuspb
.
UserEntity
,
includeRoleInfo
bool
)
([]
*
milvuspb
.
UserResult
,
error
)
{
return
nil
,
errors
.
New
(
"mock error"
)
}
})
t
.
Run
(
"select role failed"
,
func
(
t
*
testing
.
T
)
{
{
resp
,
err
:=
c
.
SelectRole
(
ctx
,
&
milvuspb
.
SelectRoleRequest
{
Role
:
&
milvuspb
.
RoleEntity
{
Name
:
"foo"
}})
assert
.
NoError
(
t
,
err
)
assert
.
NotEqual
(
t
,
commonpb
.
ErrorCode_Success
,
resp
.
Status
.
ErrorCode
)
}
{
resp
,
err
:=
c
.
SelectRole
(
ctx
,
&
milvuspb
.
SelectRoleRequest
{})
assert
.
NoError
(
t
,
err
)
assert
.
NotEqual
(
t
,
commonpb
.
ErrorCode_Success
,
resp
.
Status
.
ErrorCode
)
}
})
t
.
Run
(
"select user failed"
,
func
(
t
*
testing
.
T
)
{
{
resp
,
err
:=
c
.
SelectUser
(
ctx
,
&
milvuspb
.
SelectUserRequest
{
User
:
&
milvuspb
.
UserEntity
{
Name
:
"foo"
}})
assert
.
NoError
(
t
,
err
)
assert
.
NotEqual
(
t
,
commonpb
.
ErrorCode_Success
,
resp
.
Status
.
ErrorCode
)
}
{
resp
,
err
:=
c
.
SelectUser
(
ctx
,
&
milvuspb
.
SelectUserRequest
{})
assert
.
NoError
(
t
,
err
)
assert
.
NotEqual
(
t
,
commonpb
.
ErrorCode_Success
,
resp
.
Status
.
ErrorCode
)
}
})
t
.
Run
(
"operate privilege failed"
,
func
(
t
*
testing
.
T
)
{
{
resp
,
err
:=
c
.
OperatePrivilege
(
ctx
,
&
milvuspb
.
OperatePrivilegeRequest
{
Type
:
milvuspb
.
OperatePrivilegeType
(
100
)})
assert
.
NoError
(
t
,
err
)
assert
.
NotEqual
(
t
,
commonpb
.
ErrorCode_Success
,
resp
.
ErrorCode
)
}
{
resp
,
err
:=
c
.
OperatePrivilege
(
ctx
,
&
milvuspb
.
OperatePrivilegeRequest
{
Type
:
milvuspb
.
OperatePrivilegeType_Grant
})
assert
.
NoError
(
t
,
err
)
assert
.
NotEqual
(
t
,
commonpb
.
ErrorCode_Success
,
resp
.
ErrorCode
)
}
{
resp
,
err
:=
c
.
OperatePrivilege
(
ctx
,
&
milvuspb
.
OperatePrivilegeRequest
{
Entity
:
&
milvuspb
.
GrantEntity
{
Object
:
&
milvuspb
.
ObjectEntity
{
Name
:
"CollectionErr"
}}})
assert
.
NoError
(
t
,
err
)
assert
.
NotEqual
(
t
,
commonpb
.
ErrorCode_Success
,
resp
.
ErrorCode
)
}
{
resp
,
err
:=
c
.
OperatePrivilege
(
ctx
,
&
milvuspb
.
OperatePrivilegeRequest
{
Entity
:
&
milvuspb
.
GrantEntity
{
Object
:
&
milvuspb
.
ObjectEntity
{
Name
:
"Collection"
},
Role
:
&
milvuspb
.
RoleEntity
{
Name
:
"foo"
}}})
assert
.
NoError
(
t
,
err
)
assert
.
NotEqual
(
t
,
commonpb
.
ErrorCode_Success
,
resp
.
ErrorCode
)
}
mockMeta
:=
c
.
meta
.
(
*
mockMetaTable
)
mockMeta
.
SelectRoleFunc
=
func
(
tenant
string
,
entity
*
milvuspb
.
RoleEntity
,
includeUserInfo
bool
)
([]
*
milvuspb
.
RoleResult
,
error
)
{
return
nil
,
nil
}
{
resp
,
err
:=
c
.
OperatePrivilege
(
ctx
,
&
milvuspb
.
OperatePrivilegeRequest
{
Entity
:
&
milvuspb
.
GrantEntity
{
Role
:
&
milvuspb
.
RoleEntity
{
Name
:
"foo"
},
Object
:
&
milvuspb
.
ObjectEntity
{
Name
:
"Collection"
},
ObjectName
:
"col1"
,
Grantor
:
&
milvuspb
.
GrantorEntity
{
User
:
&
milvuspb
.
UserEntity
{
Name
:
"root"
},
Privilege
:
&
milvuspb
.
PrivilegeEntity
{
Name
:
"Insert"
},
},
},
Type
:
milvuspb
.
OperatePrivilegeType_Grant
})
assert
.
NoError
(
t
,
err
)
assert
.
NotEqual
(
t
,
commonpb
.
ErrorCode_Success
,
resp
.
ErrorCode
)
}
mockMeta
.
SelectUserFunc
=
func
(
tenant
string
,
entity
*
milvuspb
.
UserEntity
,
includeRoleInfo
bool
)
([]
*
milvuspb
.
UserResult
,
error
)
{
return
nil
,
nil
}
resp
,
err
:=
c
.
OperatePrivilege
(
ctx
,
&
milvuspb
.
OperatePrivilegeRequest
{
Entity
:
&
milvuspb
.
GrantEntity
{
Role
:
&
milvuspb
.
RoleEntity
{
Name
:
"foo"
},
Object
:
&
milvuspb
.
ObjectEntity
{
Name
:
"Collection"
},
ObjectName
:
"col1"
,
Grantor
:
&
milvuspb
.
GrantorEntity
{
User
:
&
milvuspb
.
UserEntity
{
Name
:
"root"
},
Privilege
:
&
milvuspb
.
PrivilegeEntity
{
Name
:
"Insert"
},
},
},
Type
:
milvuspb
.
OperatePrivilegeType_Grant
})
assert
.
NoError
(
t
,
err
)
assert
.
NotEqual
(
t
,
commonpb
.
ErrorCode_Success
,
resp
.
ErrorCode
)
mockMeta
.
SelectRoleFunc
=
func
(
tenant
string
,
entity
*
milvuspb
.
RoleEntity
,
includeUserInfo
bool
)
([]
*
milvuspb
.
RoleResult
,
error
)
{
return
nil
,
errors
.
New
(
"mock error"
)
}
mockMeta
.
SelectUserFunc
=
func
(
tenant
string
,
entity
*
milvuspb
.
UserEntity
,
includeRoleInfo
bool
)
([]
*
milvuspb
.
UserResult
,
error
)
{
return
nil
,
errors
.
New
(
"mock error"
)
}
})
t
.
Run
(
"select grant failed"
,
func
(
t
*
testing
.
T
)
{
{
resp
,
err
:=
c
.
SelectGrant
(
ctx
,
&
milvuspb
.
SelectGrantRequest
{})
assert
.
NoError
(
t
,
err
)
assert
.
NotEqual
(
t
,
commonpb
.
ErrorCode_Success
,
resp
.
Status
.
ErrorCode
)
}
{
resp
,
err
:=
c
.
SelectGrant
(
ctx
,
&
milvuspb
.
SelectGrantRequest
{
Entity
:
&
milvuspb
.
GrantEntity
{
Role
:
&
milvuspb
.
RoleEntity
{
Name
:
"foo"
}}})
assert
.
NoError
(
t
,
err
)
assert
.
NotEqual
(
t
,
commonpb
.
ErrorCode_Success
,
resp
.
Status
.
ErrorCode
)
}
mockMeta
:=
c
.
meta
.
(
*
mockMetaTable
)
mockMeta
.
SelectRoleFunc
=
func
(
tenant
string
,
entity
*
milvuspb
.
RoleEntity
,
includeUserInfo
bool
)
([]
*
milvuspb
.
RoleResult
,
error
)
{
return
nil
,
nil
}
{
resp
,
err
:=
c
.
SelectGrant
(
ctx
,
&
milvuspb
.
SelectGrantRequest
{
Entity
:
&
milvuspb
.
GrantEntity
{
Role
:
&
milvuspb
.
RoleEntity
{
Name
:
"foo"
},
Object
:
&
milvuspb
.
ObjectEntity
{
Name
:
"CollectionFoo"
}}})
assert
.
NoError
(
t
,
err
)
assert
.
NotEqual
(
t
,
commonpb
.
ErrorCode_Success
,
resp
.
Status
.
ErrorCode
)
}
{
resp
,
err
:=
c
.
SelectGrant
(
ctx
,
&
milvuspb
.
SelectGrantRequest
{
Entity
:
&
milvuspb
.
GrantEntity
{
Role
:
&
milvuspb
.
RoleEntity
{
Name
:
"foo"
},
Object
:
&
milvuspb
.
ObjectEntity
{
Name
:
"Collection"
}}})
assert
.
NoError
(
t
,
err
)
assert
.
NotEqual
(
t
,
commonpb
.
ErrorCode_Success
,
resp
.
Status
.
ErrorCode
)
}
mockMeta
.
SelectRoleFunc
=
func
(
tenant
string
,
entity
*
milvuspb
.
RoleEntity
,
includeUserInfo
bool
)
([]
*
milvuspb
.
RoleResult
,
error
)
{
return
nil
,
errors
.
New
(
"mock error"
)
}
})
t
.
Run
(
"list policy failed"
,
func
(
t
*
testing
.
T
)
{
resp
,
err
:=
c
.
ListPolicy
(
ctx
,
&
internalpb
.
ListPolicyRequest
{})
assert
.
NoError
(
t
,
err
)
assert
.
NotEqual
(
t
,
commonpb
.
ErrorCode_Success
,
resp
.
Status
.
ErrorCode
)
mockMeta
:=
c
.
meta
.
(
*
mockMetaTable
)
mockMeta
.
ListPolicyFunc
=
func
(
tenant
string
)
([]
string
,
error
)
{
return
[]
string
{},
nil
}
resp
,
err
=
c
.
ListPolicy
(
ctx
,
&
internalpb
.
ListPolicyRequest
{})
assert
.
NoError
(
t
,
err
)
assert
.
NotEqual
(
t
,
commonpb
.
ErrorCode_Success
,
resp
.
Status
.
ErrorCode
)
mockMeta
.
ListPolicyFunc
=
func
(
tenant
string
)
([]
string
,
error
)
{
return
[]
string
{},
errors
.
New
(
"mock error"
)
}
})
}
func
TestCore_Stop
(
t
*
testing
.
T
)
{
t
.
Run
(
"abnormal stop before component is ready"
,
func
(
t
*
testing
.
T
)
{
c
:=
&
Core
{}
...
...
internal/rootcoord/step.go
浏览文件 @
13f69bfc
...
...
@@ -438,3 +438,29 @@ func (b *confirmGCStep) Desc() string {
func
(
b
*
confirmGCStep
)
Weight
()
stepPriority
{
return
stepPriorityLow
}
type
simpleStep
struct
{
desc
string
weight
stepPriority
executeFunc
func
(
ctx
context
.
Context
)
([]
nestedStep
,
error
)
}
func
NewSimpleStep
(
desc
string
,
executeFunc
func
(
ctx
context
.
Context
)
([]
nestedStep
,
error
))
nestedStep
{
return
&
simpleStep
{
desc
:
desc
,
weight
:
stepPriorityNormal
,
executeFunc
:
executeFunc
,
}
}
func
(
s
*
simpleStep
)
Execute
(
ctx
context
.
Context
)
([]
nestedStep
,
error
)
{
return
s
.
executeFunc
(
ctx
)
}
func
(
s
*
simpleStep
)
Desc
()
string
{
return
s
.
desc
}
func
(
s
*
simpleStep
)
Weight
()
stepPriority
{
return
s
.
weight
}
internal/util/typeutil/cache.go
浏览文件 @
13f69bfc
...
...
@@ -7,6 +7,9 @@ const (
CacheRemoveUserFromRole
CacheGrantPrivilege
CacheRevokePrivilege
CacheDeleteUser
CacheDropRole
CacheRefresh
)
type
CacheOp
struct
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录