通过 SDK 管理身份凭证
除了在 Web 控制台上进行身份凭证管理,Zilliz Cloud 还支持通过 SDK 来管理。这种功能扩展极大地提高了灵活性,并比仅使用 Web 控制台提供了更多的自定义选项。
在 Zilliz Cloud 后端,存在以下三种内置角色选项:
-
db_admin
:拥有对整个集群及其关联资源的完全控制权限。 -
db_rw
:具有在集群内读取、写入及管理 Collection 和索引的权限。 -
db_ro
:拥有查看集群资源的权限,但无法进行创建、修改或删除等操作。
有关更多集群内置角色信息,请参考集群内置角色。
开始前
创建集群用户
要创建一个集群用户,请使用以下代码:
- Python
- NodeJS
- Java
- Go
import json, os, time
from pymilvus import connections, Role, utility
# 0. Connect to cluster
CLUSTER_ENDPOINT="YOUR_CLUSTER_ENDPOINT" # Set your cluster endpoint
TOKEN="YOUR_CLUSTER_TOKEN" # Set your token
connections.connect(
alias='default',
# Public endpoint obtained from Zilliz Cloud
uri=CLUSTER_ENDPOINT,
# API key or a colon-separated cluster username and password
token=TOKEN,
)
# 1. Create user
if not 'user1' in utility.list_usernames():
utility.create_user(user='user1', password='P@ssw0rd!')
// 1. Connect to the cluster
const client = new MilvusClient({address, token})
// 2. Create user
const users1 = await client.listUsers()
if (!users1.usernames.includes("user1")) {
await client.createUser({
username: "user1",
password: "P@ssw0rd!",
})
}
String clusterEndpoint = "YOUR_CLUSTER_ENDPOINT";
String token = "YOUR_CLUSTER_TOKEN";
// 1. Connect to Zilliz Cloud cluster
ConnectParam connectParam = ConnectParam.newBuilder()
.withUri(clusterEndpoint)
.withToken(token)
.build();
MilvusServiceClient client = new MilvusServiceClient(connectParam);
System.out.println("Connected to Zilliz Cloud!");
// Output:
// Connected to Zilliz Cloud!
// 2. Create a user
CreateCredentialParam createCredentialParam = CreateCredentialParam.newBuilder()
.withUsername("user1")
.withPassword("P@ssw0rd!")
.build();
R<RpcStatus> res = client.createCredential(createCredentialParam);
if (res.getException() != null) {
System.err.println("Failed to create user!");
return;
}
System.out.println("User created!");
// Output:
// User created!
CLUSTER_ENDPOINT := "YOUR_CLUSTER_ENDPOINT"
TOKEN := "YOUR_CLUSTER_TOKEN"
USERNAME := "user1"
PASSWORD1 := "P@ssw0rd!"
PASSWORD2 := "P@ssw0rd!!"
// 1. Connect to cluster
connParams := client.Config{
Address: CLUSTER_ENDPOINT,
APIKey: TOKEN,
}
conn, err := client.NewClient(context.Background(), connParams)
if err != nil {
log.Fatal("Failed to connect to Zilliz Cloud:", err.Error())
}
// 2. Create a user
err = conn.CreateCredential(
context.Background(), // context
USERNAME, // username
PASSWORD1, // password
)
if err != nil {
log.Fatal("Failed to create user:", err.Error())
}
📘说明
密码将不会再次显示,请务必记下并妥善保存在安全的地方。
创建集群用户后,您可以使用该用户的用户名和密码连接到集群。请查看连接集群以了解更多详情。
更新用户凭证
要更新用户密码,请使用以下代码:
- Python
- NodeJS
- Java
- Go
# 2. Update a user credential
utility.update_password(
user='user1',
old_password='P@ssw0rd!',
new_password='P@ssw0rd!!'
)
// 3. Update a user credential
await client.updateUser({
username: "user1",
oldPassword: "P@ssw0rd!",
newPassword: "P@ssw0rd!!",
})
// 3. Update a user credential
UpdateCredentialParam updateCredentialParam = UpdateCredentialParam.newBuilder()
.withUsername("user1")
.withOldPassword("P@ssw0rd!")
.withNewPassword("P@ssw0rd!!")
.build();
R<RpcStatus> updateCreRes = client.updateCredential(updateCredentialParam);
if (updateCreRes.getException() != null) {
System.err.println("Failed to update user credential!");
return;
}
System.out.println("User credential updated!");
// Output:
// User credential updated!
// 2. Update a user credential
err = conn.UpdateCredential(
context.Background(), // context
USERNAME, // username
PASSWORD1, // old password
PASSWORD2, // new password
)
if err != nil {
log.Fatal("Failed to update user credential:", err.Error())
}
列出集群用户
要列出所有的集群用户:
- Python
- NodeJS
- Java
- Go
# 3. List users
print(utility.list_usernames())
# Output
#
# ["db_admin", "user1"]
userInfo = utility.list_users(include_role_info=True)
users = [ { "user": u.username, "roles": list(u.roles) } for u in userInfo.groups ]
print(users)
# Output
#
# [
# {
# "user": "db_admin",
# "roles": [
# "db_admin"
# ]
# },
# {
# "user": "user1",
# "roles": []
# }
# ]
// 4. List users
const users = await client.listUsers()
console.log(users.usernames)
// Output
//
// [ 'db_admin', 'user1' ]
//
// 4. List users
ListCredUsersParam listCredUsersParam = ListCredUsersParam.newBuilder()
.build();
R<ListCredUsersResponse> listRes = client.listCredUsers(listCredUsersParam);
if (listRes.getException() != null) {
System.err.println("Failed to list users!");
return;
}
ProtocolStringList usernames = listRes.getData().getUsernamesList();
System.out.println(usernames);
// Output:
// [
// "db_admin",
// "user1"
// ]
// 3. List users
users1, err := conn.ListCredUsers(context.Background())
if err != nil {
log.Fatal("Failed to list users:", err.Error())
}
fmt.Println("Users:", users1)
// Output:
//
// Users: [db_admin user1]
// Alternatively
users2, err := conn.ListUsers(context.Background())
if err != nil {
log.Fatal("Failed to list users:", err.Error())
}
userList := make([]string, 0)
for _, user := range users2 {
userList = append(userList, user.Name)
}
fmt.Println("Users:", userList)
// Output:
//
// Users: [db_admin user1]
为集群用户分配角色
为 user1
分配 db_ro
角色:
- Python
- NodeJS
- Java
- Go
# 4. Assign role
role = Role("db_ro") # Valid values: "db_admin", "db_rw", "db_ro"
role.add_user("user1")
# 5. Get users of a specific role
users = list(role.get_users())
print(users)
# Output
#
# ["user1"]
# 6. List roles
roleInfo = utility.list_roles(include_user_info=True)
roles = [ { "role": g.role_name, "users": list(g.users) } for g in roleInfo.groups ]
print(roles)
# Output
#
# [
# {
# "role": "db_admin",
# "users": [
# "db_admin"
# ]
# },
# {
# "role": "db_ro",
# "users": [
# "user1"
# ]
# },
# {
# "role": "db_rw",
# "users": []
# }
# ]
// 5. Assign role to user
await client.addUserToRole({
username: "user1",
rolename: "db_ro",
})
// 6. List roles
const roles = await client.listRoles()
console.log(roles.results)
// Output
//
// [
// { users: [ [Object] ], role: { name: 'db_admin' } },
// { users: [], role: { name: 'db_ro' } },
// { users: [], role: { name: 'db_rw' } },
// ]
//
// 5. Assign role to user
AddUserToRoleParam addUserToRoleParam = AddUserToRoleParam.newBuilder()
.withUserName("user1")
.withRoleName("db_ro")
.build();
R<RpcStatus> addRes = client.addUserToRole(addUserToRoleParam);
if (addRes.getException() != null) {
System.err.println("Failed to assign role to user!");
return;
}
System.out.println("Role assigned to user!");
// Output:
// Role assigned to user!
// 6. Get users of a specific role
SelectRoleParam selectRoleParam = SelectRoleParam.newBuilder()
.withRoleName("db_ro")
.withIncludeUserInfo(true)
.build();
R<SelectRoleResponse> selectRoleRes = client.selectRole(selectRoleParam);
if (selectRoleRes.getException() != null) {
System.err.println("Failed to list roles!");
return;
}
List<RoleResult> roles = selectRoleRes.getData().getResultsList();
List<JSONObject> roleList = new ArrayList<>();
for (RoleResult role : roles) {
role.getAllFields().forEach((k, v) -> {
roleList.add(new JSONObject().fluentPut(k.getName(), v));
});
}
System.out.println(roleList);
// Output:
// [
// {"role": {"name": "db_ro"}},
// {"users": [{"name": "user1"}]}
// ]
// 7. Get roles of a specific user
SelectUserParam selectUserParam = SelectUserParam.newBuilder()
.withUserName("user1")
.withIncludeRoleInfo(true)
.build();
R<SelectUserResponse> selectUserRes = client.selectUser(selectUserParam);
if (selectUserRes.getException() != null) {
System.err.println("Failed to list roles!");
return;
}
List<UserResult> users = selectUserRes.getData().getResultsList();
List<JSONObject> userList = new ArrayList<>();
for (UserResult user : users) {
user.getAllFields().forEach((k, v) -> {
userList.add(new JSONObject().fluentPut(k.getName(), v));
});
}
System.out.println(userList);
// Output:
// [
// {"user": {"name": "user1"}},
// {"roles": [{"name": "db_ro"}]}
// ]
// 4. Assign role
rolename := "db_ro"
err = conn.AddUserRole(
context.Background(), // context
USERNAME, // username
rolename, // role
)
if err != nil {
log.Fatal("Failed to assign role:", err.Error())
}
// 5. List roles
roles, err := conn.ListRoles(
context.Background(), // context
)
if err != nil {
log.Fatal("Failed to list roles:", err.Error())
}
roleList := make([]interface{}, 0, 1)
for _, role := range roles {
roleList = append(roleList, role.Name)
}
fmt.Println("Roles:", roleList)
// Output:
//
// Roles: [db_admin db_ro db_rw]
撤销用户角色
要从用户中撤销角色:
- Python
- NodeJS
- Java
- Go
# 7. Remove role from user
role.remove_user("user1")
// 7. Remove role from user
await client.removeUserFromRole({
username: "user1",
rolename: "db_ro",
})
// 8. Remove role from user
RemoveUserFromRoleParam removeUserFromRoleParam = RemoveUserFromRoleParam.newBuilder()
.withUserName("user1")
.withRoleName("db_ro")
.build();
R<RpcStatus> removeRes = client.removeUserFromRole(removeUserFromRoleParam);
if (removeRes.getException() != null) {
System.err.println("Failed to remove user from role!");
return;
}
System.out.println("User removed from role!");
// 6. Remove role from user
err = conn.RemoveUserRole(
context.Background(), // context
USERNAME, // username
rolename, // role
)
if err != nil {
log.Fatal("Failed to remove user from role:", err.Error())
}
删除用户
如果某个用户不再需要,可以如下方式删除:
- Python
- NodeJS
- Java
- Go
# 8. Delete user
utility.delete_user('user1')
// 8. Delete user
await client.deleteUser({
username: "user1",
})
// 8. Delete user
DeleteCredentialParam deleteCredentialParam = DeleteCredentialParam.newBuilder()
.withUsername("user1")
.build();
R<RpcStatus> deleteRes = client.deleteCredential(deleteCredentialParam);
if (deleteRes.getException() != null) {
System.err.println("Failed to delete user!");
return;
}
System.out.println("User deleted!");
// Output:
// User deleted!
// 7. Delete user
err = conn.DeleteCredential(
context.Background(), // context
USERNAME, // username
)
if err != nil {
log.Fatal("Failed to delete user:", err.Error())
}
📘说明
集群默认用户 db_admin 不支持删除。