Browse Source

Merge pull request #5674 from mitake/auth-v3-get-users-roles

*: support getting all users and roles in auth v3
Xiang Li 9 years ago
parent
commit
3488555bc3

+ 34 - 2
Documentation/dev-guide/api_reference_v3.md

@@ -12,13 +12,15 @@ This is a generated documentation. Please read the proto files for more.
 | AuthDisable | AuthDisableRequest | AuthDisableResponse | AuthDisable disables authentication. |
 | Authenticate | AuthenticateRequest | AuthenticateResponse | Authenticate processes an authenticate request. |
 | UserAdd | AuthUserAddRequest | AuthUserAddResponse | UserAdd adds a new user. |
-| UserGet | AuthUserGetRequest | AuthUserGetResponse | UserGet gets detailed user information or lists all users. |
+| UserGet | AuthUserGetRequest | AuthUserGetResponse | UserGet gets detailed user information. |
+| UserList | AuthUserListRequest | AuthUserListResponse | UserList gets a list of all users. |
 | UserDelete | AuthUserDeleteRequest | AuthUserDeleteResponse | UserDelete deletes a specified user. |
 | UserChangePassword | AuthUserChangePasswordRequest | AuthUserChangePasswordResponse | UserChangePassword changes the password of a specified user. |
 | UserGrantRole | AuthUserGrantRoleRequest | AuthUserGrantRoleResponse | UserGrant grants a role to a specified user. |
 | UserRevokeRole | AuthUserRevokeRoleRequest | AuthUserRevokeRoleResponse | UserRevokeRole revokes a role of specified user. |
 | RoleAdd | AuthRoleAddRequest | AuthRoleAddResponse | RoleAdd adds a new role. |
-| RoleGet | AuthRoleGetRequest | AuthRoleGetResponse | RoleGet gets detailed role information or lists all roles. |
+| RoleGet | AuthRoleGetRequest | AuthRoleGetResponse | RoleGet gets detailed role information. |
+| RoleList | AuthRoleListRequest | AuthRoleListResponse | RoleList gets lists of all roles. |
 | RoleDelete | AuthRoleDeleteRequest | AuthRoleDeleteResponse | RoleDelete deletes a specified role. |
 | RoleGrantPermission | AuthRoleGrantPermissionRequest | AuthRoleGrantPermissionResponse | RoleGrantPermission grants a permission of a specified key or range to a specified role. |
 | RoleRevokePermission | AuthRoleRevokePermissionRequest | AuthRoleRevokePermissionResponse | RoleRevokePermission revokes a key or range permission of a specified role. |
@@ -204,6 +206,21 @@ Empty field.
 
 
 
+##### message `AuthRoleListRequest` (etcdserver/etcdserverpb/rpc.proto)
+
+Empty field.
+
+
+
+##### message `AuthRoleListResponse` (etcdserver/etcdserverpb/rpc.proto)
+
+| Field | Description | Type |
+| ----- | ----------- | ---- |
+| header |  | ResponseHeader |
+| roles |  | (slice of) string |
+
+
+
 ##### message `AuthRoleRevokePermissionRequest` (etcdserver/etcdserverpb/rpc.proto)
 
 | Field | Description | Type |
@@ -306,6 +323,21 @@ Empty field.
 
 
 
+##### message `AuthUserListRequest` (etcdserver/etcdserverpb/rpc.proto)
+
+Empty field.
+
+
+
+##### message `AuthUserListResponse` (etcdserver/etcdserverpb/rpc.proto)
+
+| Field | Description | Type |
+| ----- | ----------- | ---- |
+| header |  | ResponseHeader |
+| users |  | (slice of) string |
+
+
+
 ##### message `AuthUserRevokeRoleRequest` (etcdserver/etcdserverpb/rpc.proto)
 
 | Field | Description | Type |

+ 85 - 3
auth/store.go

@@ -83,7 +83,7 @@ type AuthStore interface {
 	// UserGrantRole grants a role to the user
 	UserGrantRole(r *pb.AuthUserGrantRoleRequest) (*pb.AuthUserGrantRoleResponse, error)
 
-	// UserGet gets the detailed information of a user
+	// UserGet gets the detailed information of a users
 	UserGet(r *pb.AuthUserGetRequest) (*pb.AuthUserGetResponse, error)
 
 	// UserRevokeRole revokes a role of a user
@@ -104,6 +104,12 @@ type AuthStore interface {
 	// RoleDelete gets the detailed information of a role
 	RoleDelete(r *pb.AuthRoleDeleteRequest) (*pb.AuthRoleDeleteResponse, error)
 
+	// UserList gets a list of all users
+	UserList(r *pb.AuthUserListRequest) (*pb.AuthUserListResponse, error)
+
+	// RoleList gets a list of all roles
+	RoleList(r *pb.AuthRoleListRequest) (*pb.AuthRoleListResponse, error)
+
 	// UsernameFromToken gets a username from the given Token
 	UsernameFromToken(token string) (string, bool)
 
@@ -339,12 +345,13 @@ func (as *authStore) UserGet(r *pb.AuthUserGetRequest) (*pb.AuthUserGetResponse,
 	tx.Lock()
 	defer tx.Unlock()
 
+	var resp pb.AuthUserGetResponse
+
 	user := getUser(tx, r.Name)
 	if user == nil {
 		return nil, ErrUserNotFound
 	}
 
-	var resp pb.AuthUserGetResponse
 	for _, role := range user.Roles {
 		resp.Roles = append(resp.Roles, role)
 	}
@@ -352,6 +359,22 @@ func (as *authStore) UserGet(r *pb.AuthUserGetRequest) (*pb.AuthUserGetResponse,
 	return &resp, nil
 }
 
+func (as *authStore) UserList(r *pb.AuthUserListRequest) (*pb.AuthUserListResponse, error) {
+	tx := as.be.BatchTx()
+	tx.Lock()
+	defer tx.Unlock()
+
+	var resp pb.AuthUserListResponse
+
+	users := getAllUsers(tx)
+
+	for _, u := range users {
+		resp.Users = append(resp.Users, string(u.Name))
+	}
+
+	return &resp, nil
+}
+
 func (as *authStore) UserRevokeRole(r *pb.AuthUserRevokeRoleRequest) (*pb.AuthUserRevokeRoleResponse, error) {
 	tx := as.be.BatchTx()
 	tx.Lock()
@@ -390,12 +413,13 @@ func (as *authStore) RoleGet(r *pb.AuthRoleGetRequest) (*pb.AuthRoleGetResponse,
 	tx.Lock()
 	defer tx.Unlock()
 
+	var resp pb.AuthRoleGetResponse
+
 	role := getRole(tx, r.Role)
 	if role == nil {
 		return nil, ErrRoleNotFound
 	}
 
-	var resp pb.AuthRoleGetResponse
 	for _, perm := range role.KeyPermission {
 		resp.Perm = append(resp.Perm, perm)
 	}
@@ -403,6 +427,22 @@ func (as *authStore) RoleGet(r *pb.AuthRoleGetRequest) (*pb.AuthRoleGetResponse,
 	return &resp, nil
 }
 
+func (as *authStore) RoleList(r *pb.AuthRoleListRequest) (*pb.AuthRoleListResponse, error) {
+	tx := as.be.BatchTx()
+	tx.Lock()
+	defer tx.Unlock()
+
+	var resp pb.AuthRoleListResponse
+
+	roles := getAllRoles(tx)
+
+	for _, r := range roles {
+		resp.Roles = append(resp.Roles, string(r.Name))
+	}
+
+	return &resp, nil
+}
+
 func (as *authStore) RoleRevokePermission(r *pb.AuthRoleRevokePermissionRequest) (*pb.AuthRoleRevokePermissionResponse, error) {
 	tx := as.be.BatchTx()
 	tx.Lock()
@@ -613,6 +653,27 @@ func getUser(tx backend.BatchTx, username string) *authpb.User {
 	return user
 }
 
+func getAllUsers(tx backend.BatchTx) []*authpb.User {
+	_, vs := tx.UnsafeRange(authUsersBucketName, []byte{0}, []byte{0xff}, -1)
+	if len(vs) == 0 {
+		return nil
+	}
+
+	var users []*authpb.User
+
+	for _, v := range vs {
+		user := &authpb.User{}
+		err := user.Unmarshal(v)
+		if err != nil {
+			plog.Panicf("failed to unmarshal user struct: %s", err)
+		}
+
+		users = append(users, user)
+	}
+
+	return users
+}
+
 func putUser(tx backend.BatchTx, user *authpb.User) {
 	b, err := user.Marshal()
 	if err != nil {
@@ -639,6 +700,27 @@ func getRole(tx backend.BatchTx, rolename string) *authpb.Role {
 	return role
 }
 
+func getAllRoles(tx backend.BatchTx) []*authpb.Role {
+	_, vs := tx.UnsafeRange(authRolesBucketName, []byte{0}, []byte{0xff}, -1)
+	if len(vs) == 0 {
+		return nil
+	}
+
+	var roles []*authpb.Role
+
+	for _, v := range vs {
+		role := &authpb.Role{}
+		err := role.Unmarshal(v)
+		if err != nil {
+			plog.Panicf("failed to unmarshal role struct: %s", err)
+		}
+
+		roles = append(roles, role)
+	}
+
+	return roles
+}
+
 func putRole(tx backend.BatchTx, role *authpb.Role) {
 	b, err := role.Marshal()
 	if err != nil {

+ 18 - 0
clientv3/auth.go

@@ -39,6 +39,8 @@ type (
 	AuthRoleGetResponse              pb.AuthRoleGetResponse
 	AuthRoleRevokePermissionResponse pb.AuthRoleRevokePermissionResponse
 	AuthRoleDeleteResponse           pb.AuthRoleDeleteResponse
+	AuthUserListResponse             pb.AuthUserListResponse
+	AuthRoleListResponse             pb.AuthRoleListResponse
 
 	PermissionType authpb.Permission_Type
 )
@@ -71,6 +73,9 @@ type Auth interface {
 	// UserGet gets a detailed information of a user.
 	UserGet(ctx context.Context, name string) (*AuthUserGetResponse, error)
 
+	// UserList gets a list of all users.
+	UserList(ctx context.Context) (*AuthUserListResponse, error)
+
 	// UserRevokeRole revokes a role of a user.
 	UserRevokeRole(ctx context.Context, name string, role string) (*AuthUserRevokeRoleResponse, error)
 
@@ -83,6 +88,9 @@ type Auth interface {
 	// RoleGet gets a detailed information of a role.
 	RoleGet(ctx context.Context, role string) (*AuthRoleGetResponse, error)
 
+	// RoleList gets a list of all roles.
+	RoleList(ctx context.Context) (*AuthRoleListResponse, error)
+
 	// RoleRevokePermission revokes a permission from a role.
 	RoleRevokePermission(ctx context.Context, role string, key, rangeEnd string) (*AuthRoleRevokePermissionResponse, error)
 
@@ -141,6 +149,11 @@ func (auth *auth) UserGet(ctx context.Context, name string) (*AuthUserGetRespons
 	return (*AuthUserGetResponse)(resp), toErr(ctx, err)
 }
 
+func (auth *auth) UserList(ctx context.Context) (*AuthUserListResponse, error) {
+	resp, err := auth.remote.UserList(ctx, &pb.AuthUserListRequest{})
+	return (*AuthUserListResponse)(resp), toErr(ctx, err)
+}
+
 func (auth *auth) UserRevokeRole(ctx context.Context, name string, role string) (*AuthUserRevokeRoleResponse, error) {
 	resp, err := auth.remote.UserRevokeRole(ctx, &pb.AuthUserRevokeRoleRequest{Name: name, Role: role})
 	return (*AuthUserRevokeRoleResponse)(resp), toErr(ctx, err)
@@ -166,6 +179,11 @@ func (auth *auth) RoleGet(ctx context.Context, role string) (*AuthRoleGetRespons
 	return (*AuthRoleGetResponse)(resp), toErr(ctx, err)
 }
 
+func (auth *auth) RoleList(ctx context.Context) (*AuthRoleListResponse, error) {
+	resp, err := auth.remote.RoleList(ctx, &pb.AuthRoleListRequest{})
+	return (*AuthRoleListResponse)(resp), toErr(ctx, err)
+}
+
 func (auth *auth) RoleRevokePermission(ctx context.Context, role string, key, rangeEnd string) (*AuthRoleRevokePermissionResponse, error) {
 	resp, err := auth.remote.RoleRevokePermission(ctx, &pb.AuthRoleRevokePermissionRequest{Role: role, Key: key, RangeEnd: rangeEnd})
 	return (*AuthRoleRevokePermissionResponse)(resp), toErr(ctx, err)

+ 28 - 2
etcdctl/ctlv3/command/role_command.go

@@ -32,6 +32,7 @@ func NewRoleCommand() *cobra.Command {
 	ac.AddCommand(newRoleAddCommand())
 	ac.AddCommand(newRoleDeleteCommand())
 	ac.AddCommand(newRoleGetCommand())
+	ac.AddCommand(newRoleListCommand())
 	ac.AddCommand(newRoleRevokePermissionCommand())
 	ac.AddCommand(newRoleGrantPermissionCommand())
 
@@ -62,6 +63,14 @@ func newRoleGetCommand() *cobra.Command {
 	}
 }
 
+func newRoleListCommand() *cobra.Command {
+	return &cobra.Command{
+		Use:   "list",
+		Short: "list up all roles",
+		Run:   roleListCommandFunc,
+	}
+}
+
 func newRoleGrantPermissionCommand() *cobra.Command {
 	return &cobra.Command{
 		Use:   "grant-permission <role name> <permission type> <key> [endkey]",
@@ -112,12 +121,13 @@ func roleGetCommandFunc(cmd *cobra.Command, args []string) {
 		ExitWithError(ExitBadArgs, fmt.Errorf("role get command requires role name as its argument."))
 	}
 
-	resp, err := mustClientFromCmd(cmd).Auth.RoleGet(context.TODO(), args[0])
+	name := args[0]
+	resp, err := mustClientFromCmd(cmd).Auth.RoleGet(context.TODO(), name)
 	if err != nil {
 		ExitWithError(ExitError, err)
 	}
 
-	fmt.Printf("Role %s\n", args[0])
+	fmt.Printf("Role %s\n", name)
 	fmt.Println("KV Read:")
 	for _, perm := range resp.Perm {
 		if perm.PermType == clientv3.PermRead || perm.PermType == clientv3.PermReadWrite {
@@ -140,6 +150,22 @@ func roleGetCommandFunc(cmd *cobra.Command, args []string) {
 	}
 }
 
+// roleListCommandFunc executes the "role list" command.
+func roleListCommandFunc(cmd *cobra.Command, args []string) {
+	if len(args) != 0 {
+		ExitWithError(ExitBadArgs, fmt.Errorf("role list command requires no arguments."))
+	}
+
+	resp, err := mustClientFromCmd(cmd).Auth.RoleList(context.TODO())
+	if err != nil {
+		ExitWithError(ExitError, err)
+	}
+
+	for _, role := range resp.Roles {
+		fmt.Printf("%s\n", role)
+	}
+}
+
 // roleGrantPermissionCommandFunc executes the "role grant-permission" command.
 func roleGrantPermissionCommandFunc(cmd *cobra.Command, args []string) {
 	if len(args) < 3 {

+ 28 - 2
etcdctl/ctlv3/command/user_command.go

@@ -33,6 +33,7 @@ func NewUserCommand() *cobra.Command {
 	ac.AddCommand(newUserAddCommand())
 	ac.AddCommand(newUserDeleteCommand())
 	ac.AddCommand(newUserGetCommand())
+	ac.AddCommand(newUserListCommand())
 	ac.AddCommand(newUserChangePasswordCommand())
 	ac.AddCommand(newUserGrantRoleCommand())
 	ac.AddCommand(newUserRevokeRoleCommand())
@@ -73,6 +74,14 @@ func newUserGetCommand() *cobra.Command {
 	}
 }
 
+func newUserListCommand() *cobra.Command {
+	return &cobra.Command{
+		Use:   "list",
+		Short: "list up all users",
+		Run:   userListCommandFunc,
+	}
+}
+
 func newUserChangePasswordCommand() *cobra.Command {
 	cmd := cobra.Command{
 		Use:   "passwd <user name>",
@@ -143,12 +152,13 @@ func userGetCommandFunc(cmd *cobra.Command, args []string) {
 		ExitWithError(ExitBadArgs, fmt.Errorf("user get command requires user name as its argument."))
 	}
 
-	resp, err := mustClientFromCmd(cmd).Auth.UserGet(context.TODO(), args[0])
+	name := args[0]
+	resp, err := mustClientFromCmd(cmd).Auth.UserGet(context.TODO(), name)
 	if err != nil {
 		ExitWithError(ExitError, err)
 	}
 
-	fmt.Printf("User: %s\n", args[0])
+	fmt.Printf("User: %s\n", name)
 	fmt.Printf("Roles:")
 	for _, role := range resp.Roles {
 		fmt.Printf(" %s", role)
@@ -156,6 +166,22 @@ func userGetCommandFunc(cmd *cobra.Command, args []string) {
 	fmt.Printf("\n")
 }
 
+// userListCommandFunc executes the "user list" command.
+func userListCommandFunc(cmd *cobra.Command, args []string) {
+	if len(args) != 0 {
+		ExitWithError(ExitBadArgs, fmt.Errorf("user list command requires no arguments."))
+	}
+
+	resp, err := mustClientFromCmd(cmd).Auth.UserList(context.TODO())
+	if err != nil {
+		ExitWithError(ExitError, err)
+	}
+
+	for _, user := range resp.Users {
+		fmt.Printf("%s\n", user)
+	}
+}
+
 // userChangePasswordCommandFunc executes the "user passwd" command.
 func userChangePasswordCommandFunc(cmd *cobra.Command, args []string) {
 	if len(args) != 1 {

+ 16 - 0
etcdserver/api/v3rpc/auth.go

@@ -76,6 +76,14 @@ func (as *AuthServer) RoleGet(ctx context.Context, r *pb.AuthRoleGetRequest) (*p
 	return resp, nil
 }
 
+func (as *AuthServer) RoleList(ctx context.Context, r *pb.AuthRoleListRequest) (*pb.AuthRoleListResponse, error) {
+	resp, err := as.authenticator.RoleList(ctx, r)
+	if err != nil {
+		return nil, togRPCError(err)
+	}
+	return resp, nil
+}
+
 func (as *AuthServer) RoleRevokePermission(ctx context.Context, r *pb.AuthRoleRevokePermissionRequest) (*pb.AuthRoleRevokePermissionResponse, error) {
 	resp, err := as.authenticator.RoleRevokePermission(ctx, r)
 	if err != nil {
@@ -116,6 +124,14 @@ func (as *AuthServer) UserGet(ctx context.Context, r *pb.AuthUserGetRequest) (*p
 	return resp, nil
 }
 
+func (as *AuthServer) UserList(ctx context.Context, r *pb.AuthUserListRequest) (*pb.AuthUserListResponse, error) {
+	resp, err := as.authenticator.UserList(ctx, r)
+	if err != nil {
+		return nil, togRPCError(err)
+	}
+	return resp, nil
+}
+
 func (as *AuthServer) UserGrantRole(ctx context.Context, r *pb.AuthUserGrantRoleRequest) (*pb.AuthUserGrantRoleResponse, error) {
 	resp, err := as.authenticator.UserGrantRole(ctx, r)
 	if err != nil {

+ 14 - 0
etcdserver/apply.go

@@ -78,6 +78,8 @@ type applierV3 interface {
 	RoleGet(ua *pb.AuthRoleGetRequest) (*pb.AuthRoleGetResponse, error)
 	RoleRevokePermission(ua *pb.AuthRoleRevokePermissionRequest) (*pb.AuthRoleRevokePermissionResponse, error)
 	RoleDelete(ua *pb.AuthRoleDeleteRequest) (*pb.AuthRoleDeleteResponse, error)
+	UserList(ua *pb.AuthUserListRequest) (*pb.AuthUserListResponse, error)
+	RoleList(ua *pb.AuthRoleListRequest) (*pb.AuthRoleListResponse, error)
 }
 
 type applierV3backend struct {
@@ -140,6 +142,10 @@ func (a *applierV3backend) Apply(r *pb.InternalRaftRequest) *applyResult {
 		ar.resp, ar.err = a.s.applyV3.RoleRevokePermission(r.AuthRoleRevokePermission)
 	case r.AuthRoleDelete != nil:
 		ar.resp, ar.err = a.s.applyV3.RoleDelete(r.AuthRoleDelete)
+	case r.AuthUserList != nil:
+		ar.resp, ar.err = a.s.applyV3.UserList(r.AuthUserList)
+	case r.AuthRoleList != nil:
+		ar.resp, ar.err = a.s.applyV3.RoleList(r.AuthRoleList)
 	default:
 		panic("not implemented")
 	}
@@ -590,6 +596,14 @@ func (a *applierV3backend) RoleDelete(r *pb.AuthRoleDeleteRequest) (*pb.AuthRole
 	return a.s.AuthStore().RoleDelete(r)
 }
 
+func (a *applierV3backend) UserList(r *pb.AuthUserListRequest) (*pb.AuthUserListResponse, error) {
+	return a.s.AuthStore().UserList(r)
+}
+
+func (a *applierV3backend) RoleList(r *pb.AuthRoleListRequest) (*pb.AuthRoleListResponse, error) {
+	return a.s.AuthStore().RoleList(r)
+}
+
 type quotaApplierV3 struct {
 	applierV3
 	q Quota

+ 4 - 0
etcdserver/apply_auth.go

@@ -146,6 +146,10 @@ func needAdminPermission(r *pb.InternalRaftRequest) bool {
 		return true
 	case r.AuthRoleDelete != nil:
 		return true
+	case r.AuthUserList != nil:
+		return true
+	case r.AuthRoleList != nil:
+		return true
 	default:
 		return false
 	}

+ 4 - 0
etcdserver/etcdserverpb/etcdserver.pb.go

@@ -72,6 +72,8 @@
 		AuthUserRevokeRoleRequest
 		AuthRoleAddRequest
 		AuthRoleGetRequest
+		AuthUserListRequest
+		AuthRoleListRequest
 		AuthRoleDeleteRequest
 		AuthRoleGrantPermissionRequest
 		AuthRoleRevokePermissionRequest
@@ -86,6 +88,8 @@
 		AuthUserRevokeRoleResponse
 		AuthRoleAddResponse
 		AuthRoleGetResponse
+		AuthRoleListResponse
+		AuthUserListResponse
 		AuthRoleDeleteResponse
 		AuthRoleGrantPermissionResponse
 		AuthRoleRevokePermissionResponse

+ 162 - 60
etcdserver/etcdserverpb/raft_internal.pb.go

@@ -53,6 +53,8 @@ type InternalRaftRequest struct {
 	AuthUserChangePassword   *AuthUserChangePasswordRequest   `protobuf:"bytes,1103,opt,name=auth_user_change_password,json=authUserChangePassword" json:"auth_user_change_password,omitempty"`
 	AuthUserGrantRole        *AuthUserGrantRoleRequest        `protobuf:"bytes,1104,opt,name=auth_user_grant_role,json=authUserGrantRole" json:"auth_user_grant_role,omitempty"`
 	AuthUserRevokeRole       *AuthUserRevokeRoleRequest       `protobuf:"bytes,1105,opt,name=auth_user_revoke_role,json=authUserRevokeRole" json:"auth_user_revoke_role,omitempty"`
+	AuthUserList             *AuthUserListRequest             `protobuf:"bytes,1106,opt,name=auth_user_list,json=authUserList" json:"auth_user_list,omitempty"`
+	AuthRoleList             *AuthRoleListRequest             `protobuf:"bytes,1107,opt,name=auth_role_list,json=authRoleList" json:"auth_role_list,omitempty"`
 	AuthRoleAdd              *AuthRoleAddRequest              `protobuf:"bytes,1200,opt,name=auth_role_add,json=authRoleAdd" json:"auth_role_add,omitempty"`
 	AuthRoleDelete           *AuthRoleDeleteRequest           `protobuf:"bytes,1201,opt,name=auth_role_delete,json=authRoleDelete" json:"auth_role_delete,omitempty"`
 	AuthRoleGet              *AuthRoleGetRequest              `protobuf:"bytes,1202,opt,name=auth_role_get,json=authRoleGet" json:"auth_role_get,omitempty"`
@@ -355,17 +357,41 @@ func (m *InternalRaftRequest) MarshalTo(data []byte) (int, error) {
 		}
 		i += n19
 	}
+	if m.AuthUserList != nil {
+		data[i] = 0x92
+		i++
+		data[i] = 0x45
+		i++
+		i = encodeVarintRaftInternal(data, i, uint64(m.AuthUserList.Size()))
+		n20, err := m.AuthUserList.MarshalTo(data[i:])
+		if err != nil {
+			return 0, err
+		}
+		i += n20
+	}
+	if m.AuthRoleList != nil {
+		data[i] = 0x9a
+		i++
+		data[i] = 0x45
+		i++
+		i = encodeVarintRaftInternal(data, i, uint64(m.AuthRoleList.Size()))
+		n21, err := m.AuthRoleList.MarshalTo(data[i:])
+		if err != nil {
+			return 0, err
+		}
+		i += n21
+	}
 	if m.AuthRoleAdd != nil {
 		data[i] = 0x82
 		i++
 		data[i] = 0x4b
 		i++
 		i = encodeVarintRaftInternal(data, i, uint64(m.AuthRoleAdd.Size()))
-		n20, err := m.AuthRoleAdd.MarshalTo(data[i:])
+		n22, err := m.AuthRoleAdd.MarshalTo(data[i:])
 		if err != nil {
 			return 0, err
 		}
-		i += n20
+		i += n22
 	}
 	if m.AuthRoleDelete != nil {
 		data[i] = 0x8a
@@ -373,11 +399,11 @@ func (m *InternalRaftRequest) MarshalTo(data []byte) (int, error) {
 		data[i] = 0x4b
 		i++
 		i = encodeVarintRaftInternal(data, i, uint64(m.AuthRoleDelete.Size()))
-		n21, err := m.AuthRoleDelete.MarshalTo(data[i:])
+		n23, err := m.AuthRoleDelete.MarshalTo(data[i:])
 		if err != nil {
 			return 0, err
 		}
-		i += n21
+		i += n23
 	}
 	if m.AuthRoleGet != nil {
 		data[i] = 0x92
@@ -385,11 +411,11 @@ func (m *InternalRaftRequest) MarshalTo(data []byte) (int, error) {
 		data[i] = 0x4b
 		i++
 		i = encodeVarintRaftInternal(data, i, uint64(m.AuthRoleGet.Size()))
-		n22, err := m.AuthRoleGet.MarshalTo(data[i:])
+		n24, err := m.AuthRoleGet.MarshalTo(data[i:])
 		if err != nil {
 			return 0, err
 		}
-		i += n22
+		i += n24
 	}
 	if m.AuthRoleGrantPermission != nil {
 		data[i] = 0x9a
@@ -397,11 +423,11 @@ func (m *InternalRaftRequest) MarshalTo(data []byte) (int, error) {
 		data[i] = 0x4b
 		i++
 		i = encodeVarintRaftInternal(data, i, uint64(m.AuthRoleGrantPermission.Size()))
-		n23, err := m.AuthRoleGrantPermission.MarshalTo(data[i:])
+		n25, err := m.AuthRoleGrantPermission.MarshalTo(data[i:])
 		if err != nil {
 			return 0, err
 		}
-		i += n23
+		i += n25
 	}
 	if m.AuthRoleRevokePermission != nil {
 		data[i] = 0xa2
@@ -409,11 +435,11 @@ func (m *InternalRaftRequest) MarshalTo(data []byte) (int, error) {
 		data[i] = 0x4b
 		i++
 		i = encodeVarintRaftInternal(data, i, uint64(m.AuthRoleRevokePermission.Size()))
-		n24, err := m.AuthRoleRevokePermission.MarshalTo(data[i:])
+		n26, err := m.AuthRoleRevokePermission.MarshalTo(data[i:])
 		if err != nil {
 			return 0, err
 		}
-		i += n24
+		i += n26
 	}
 	return i, nil
 }
@@ -594,6 +620,14 @@ func (m *InternalRaftRequest) Size() (n int) {
 		l = m.AuthUserRevokeRole.Size()
 		n += 2 + l + sovRaftInternal(uint64(l))
 	}
+	if m.AuthUserList != nil {
+		l = m.AuthUserList.Size()
+		n += 2 + l + sovRaftInternal(uint64(l))
+	}
+	if m.AuthRoleList != nil {
+		l = m.AuthRoleList.Size()
+		n += 2 + l + sovRaftInternal(uint64(l))
+	}
 	if m.AuthRoleAdd != nil {
 		l = m.AuthRoleAdd.Size()
 		n += 2 + l + sovRaftInternal(uint64(l))
@@ -1427,6 +1461,72 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error {
 				return err
 			}
 			iNdEx = postIndex
+		case 1106:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field AuthUserList", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRaftInternal
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := data[iNdEx]
+				iNdEx++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthRaftInternal
+			}
+			postIndex := iNdEx + msglen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.AuthUserList == nil {
+				m.AuthUserList = &AuthUserListRequest{}
+			}
+			if err := m.AuthUserList.Unmarshal(data[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 1107:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field AuthRoleList", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRaftInternal
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := data[iNdEx]
+				iNdEx++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthRaftInternal
+			}
+			postIndex := iNdEx + msglen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.AuthRoleList == nil {
+				m.AuthRoleList = &AuthRoleListRequest{}
+			}
+			if err := m.AuthRoleList.Unmarshal(data[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
 		case 1200:
 			if wireType != 2 {
 				return fmt.Errorf("proto: wrong wireType = %d for field AuthRoleAdd", wireType)
@@ -1906,54 +2006,56 @@ var (
 )
 
 var fileDescriptorRaftInternal = []byte{
-	// 770 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x7c, 0x95, 0x4b, 0x6f, 0x13, 0x3b,
-	0x14, 0xc7, 0x6f, 0xd2, 0x67, 0x9c, 0xa4, 0xb7, 0xd7, 0x6d, 0x2f, 0x26, 0x95, 0x4a, 0x09, 0xe2,
-	0x0d, 0x05, 0xb5, 0x4b, 0x16, 0x10, 0x9a, 0xaa, 0x54, 0x42, 0xa8, 0x1a, 0x15, 0x09, 0x89, 0xc5,
-	0xc8, 0xcd, 0x98, 0x74, 0x60, 0x5e, 0x78, 0x9c, 0x52, 0xbe, 0x15, 0xaf, 0x0f, 0xd1, 0x05, 0x8f,
-	0xb2, 0x65, 0x05, 0xac, 0xd8, 0xc3, 0x07, 0xc0, 0xaf, 0xf1, 0xcc, 0x24, 0x4e, 0x17, 0x91, 0x66,
-	0xce, 0xf9, 0x9f, 0xdf, 0x39, 0x9e, 0xbf, 0x1d, 0x83, 0x05, 0x8a, 0x9f, 0x31, 0xd7, 0x8f, 0x18,
-	0xa1, 0x11, 0x0e, 0xd6, 0x12, 0x1a, 0xb3, 0x18, 0x36, 0x08, 0xeb, 0x79, 0x29, 0xa1, 0x87, 0x84,
-	0x26, 0xfb, 0xad, 0xc5, 0x7e, 0xdc, 0x8f, 0x65, 0xe2, 0x96, 0x78, 0x52, 0x9a, 0xd6, 0x7c, 0xae,
-	0xd1, 0x91, 0x1a, 0x4d, 0x7a, 0xea, 0xb1, 0x7d, 0x07, 0x34, 0x1d, 0xf2, 0x72, 0x40, 0x52, 0xf6,
-	0x80, 0x60, 0x8f, 0x50, 0x38, 0x07, 0xaa, 0x3b, 0x5d, 0x54, 0x59, 0xad, 0x5c, 0x99, 0x74, 0xaa,
-	0x7e, 0x17, 0xb6, 0xc0, 0xec, 0x20, 0x15, 0x2d, 0x43, 0x82, 0xaa, 0x3c, 0x5a, 0x73, 0xcc, 0x7b,
-	0xfb, 0x5b, 0x13, 0x2c, 0xec, 0xe8, 0x81, 0x1c, 0x3e, 0x9d, 0x26, 0x8d, 0x30, 0x2e, 0x82, 0xea,
-	0xe1, 0xba, 0xac, 0xae, 0xaf, 0x2f, 0xad, 0x15, 0x47, 0x5e, 0xd3, 0x25, 0x0e, 0x17, 0xc0, 0xdb,
-	0x60, 0x8a, 0xe2, 0xa8, 0x4f, 0xd0, 0x84, 0x54, 0xb6, 0x86, 0x94, 0x22, 0x95, 0xc9, 0x95, 0x10,
-	0x5e, 0x03, 0x13, 0xc9, 0x80, 0xa1, 0x49, 0xa9, 0x47, 0x65, 0xfd, 0xee, 0x20, 0x9b, 0xc7, 0x11,
-	0x22, 0xb8, 0x09, 0x1a, 0x1e, 0x09, 0x08, 0x23, 0xae, 0x6a, 0x32, 0x25, 0x8b, 0x56, 0xcb, 0x45,
-	0x5d, 0xa9, 0x28, 0xb5, 0xaa, 0x7b, 0x79, 0x4c, 0x34, 0x64, 0x47, 0x11, 0x9a, 0xb6, 0x35, 0xdc,
-	0x3b, 0x8a, 0x4c, 0x43, 0x2e, 0x82, 0x77, 0x01, 0xe8, 0xc5, 0x61, 0x82, 0x7b, 0xcc, 0x8f, 0x23,
-	0x34, 0x23, 0x4b, 0xce, 0x95, 0x4b, 0x36, 0x4d, 0x3e, 0xab, 0x2c, 0x94, 0xc0, 0x7b, 0xa0, 0x1e,
-	0x10, 0x9c, 0x12, 0xb7, 0xcf, 0x27, 0x66, 0x68, 0xd6, 0x46, 0x78, 0x28, 0x04, 0xdb, 0x22, 0x6f,
-	0x08, 0x81, 0x09, 0x89, 0x35, 0x2b, 0x02, 0x25, 0x87, 0xf1, 0x0b, 0x82, 0x6a, 0xb6, 0x35, 0x4b,
-	0x84, 0x23, 0x05, 0x66, 0xcd, 0x41, 0x1e, 0x13, 0xb6, 0xe0, 0x00, 0xd3, 0x10, 0x01, 0x9b, 0x2d,
-	0x1d, 0x91, 0x32, 0xb6, 0x48, 0x21, 0xdc, 0x00, 0xd3, 0x07, 0x72, 0x37, 0x21, 0x4f, 0x96, 0x2c,
-	0x5b, 0x3d, 0x57, 0x1b, 0xce, 0xd1, 0x52, 0xd8, 0x01, 0x75, 0x3c, 0x60, 0x07, 0x2e, 0x89, 0xf0,
-	0x7e, 0x40, 0xd0, 0x2f, 0xeb, 0x07, 0xeb, 0x70, 0xc5, 0x96, 0x14, 0x98, 0xe5, 0x62, 0x13, 0x82,
-	0x5d, 0xd0, 0x90, 0x08, 0xcf, 0x4f, 0x25, 0xe3, 0xf7, 0x8c, 0x6d, 0xbd, 0x82, 0xd1, 0x55, 0x0a,
-	0xb3, 0x5e, 0x9c, 0xc7, 0xe0, 0x23, 0x45, 0x21, 0x11, 0xf3, 0x7b, 0x98, 0x11, 0xf4, 0x47, 0x51,
-	0xae, 0x96, 0x29, 0xd9, 0xbe, 0xef, 0x14, 0xa4, 0x19, 0xae, 0x54, 0x0f, 0xb7, 0x40, 0x53, 0x4e,
-	0x25, 0x8e, 0x8d, 0x8b, 0x3d, 0x0f, 0x7d, 0x9c, 0x1d, 0x37, 0xd6, 0x63, 0xfe, 0xd6, 0xf1, 0xbc,
-	0xd2, 0x58, 0x3a, 0xc6, 0xc7, 0x9a, 0xcf, 0x31, 0x6a, 0x4f, 0xa2, 0x4f, 0x8a, 0x74, 0xc1, 0x4e,
-	0xd2, 0x9b, 0x59, 0xc3, 0xe6, 0x70, 0x29, 0x5c, 0x1e, 0xab, 0x4f, 0x18, 0xfa, 0x7c, 0xea, 0x58,
-	0xdb, 0x84, 0x8d, 0x8c, 0xc5, 0x63, 0xb0, 0x0f, 0xce, 0xe6, 0x98, 0xde, 0x81, 0x38, 0x25, 0x6e,
-	0x82, 0xd3, 0xf4, 0x55, 0x4c, 0x3d, 0xf4, 0x45, 0x21, 0xaf, 0xdb, 0x91, 0x9b, 0x52, 0xbd, 0xab,
-	0xc5, 0x19, 0xfd, 0x7f, 0x6c, 0x4d, 0xc3, 0x27, 0x60, 0xb1, 0x30, 0xaf, 0xd8, 0xde, 0x2e, 0x8d,
-	0xb9, 0xc9, 0x27, 0xaa, 0xc7, 0xa5, 0x31, 0x63, 0xcb, 0xa3, 0x11, 0xe7, 0x56, 0xff, 0x87, 0x87,
-	0x33, 0xf0, 0x29, 0x58, 0xca, 0xc9, 0xea, 0xa4, 0x28, 0xf4, 0x57, 0x85, 0xbe, 0x6c, 0x47, 0xeb,
-	0x23, 0x53, 0x60, 0x43, 0x3c, 0x92, 0x32, 0x9f, 0x59, 0x00, 0xa5, 0xfb, 0x6f, 0x6a, 0xe3, 0x3e,
-	0xb3, 0xd0, 0x0f, 0xbb, 0xaf, 0x63, 0xc6, 0x7d, 0x89, 0xd1, 0xee, 0xbf, 0xad, 0x8d, 0x73, 0x5f,
-	0x54, 0x59, 0xdc, 0xcf, 0xc3, 0xe5, 0xb1, 0x84, 0xfb, 0xef, 0x4e, 0x1d, 0x6b, 0xd8, 0x7d, 0x1d,
-	0x83, 0xcf, 0x41, 0xab, 0x80, 0x91, 0xa6, 0x24, 0x84, 0x86, 0x7e, 0x9a, 0x8a, 0xff, 0xbc, 0xf7,
-	0x8a, 0x79, 0x63, 0x0c, 0x53, 0xc8, 0x77, 0x8d, 0x3a, 0xe3, 0x9f, 0xc1, 0xf6, 0x3c, 0x0c, 0xc1,
-	0x72, 0xde, 0x4b, 0xdb, 0x54, 0x68, 0xf6, 0x41, 0x35, 0xbb, 0x69, 0x6f, 0xa6, 0x1c, 0x19, 0xed,
-	0x86, 0xf0, 0x18, 0x41, 0xfb, 0x5f, 0xd0, 0xdc, 0x0a, 0x13, 0xf6, 0xda, 0x21, 0x69, 0x12, 0x47,
-	0x29, 0x69, 0x27, 0x60, 0xf9, 0x94, 0x43, 0x0f, 0x21, 0x98, 0x94, 0x97, 0x64, 0x45, 0x5e, 0x92,
-	0xf2, 0x59, 0x5c, 0x9e, 0xe6, 0x2c, 0xe8, 0xcb, 0x33, 0x7b, 0x87, 0xe7, 0x41, 0x23, 0xf5, 0xc3,
-	0x84, 0xaf, 0x85, 0xf1, 0xc6, 0x91, 0xbc, 0xf4, 0x6a, 0x4e, 0x5d, 0xc5, 0xf6, 0x44, 0xe8, 0xfe,
-	0xfc, 0xf1, 0x8f, 0x95, 0x7f, 0x8e, 0x7f, 0xae, 0x54, 0x4e, 0xf8, 0xef, 0x3b, 0xff, 0xed, 0x4f,
-	0xcb, 0x5b, 0x7b, 0xe3, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xa6, 0x96, 0x31, 0x96, 0x0d, 0x08,
-	0x00, 0x00,
+	// 808 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x7c, 0x96, 0x4b, 0x6f, 0xd3, 0x4a,
+	0x14, 0xc7, 0x6f, 0xd2, 0x67, 0x26, 0x69, 0x6e, 0xef, 0xb4, 0xbd, 0x77, 0x6e, 0x2a, 0x95, 0x36,
+	0x88, 0x37, 0x14, 0xd4, 0x2e, 0x59, 0x40, 0x68, 0xaa, 0xb6, 0x52, 0x85, 0x2a, 0xab, 0x48, 0x48,
+	0x2c, 0xac, 0x69, 0x3c, 0xa4, 0x06, 0xbf, 0xb0, 0x27, 0xa5, 0x7c, 0x2b, 0x5e, 0x1f, 0xa2, 0x0b,
+	0x1e, 0x05, 0xbe, 0x00, 0xb0, 0x62, 0xc5, 0x06, 0x3e, 0x00, 0xf3, 0xf2, 0xd8, 0x4e, 0xc6, 0x5d,
+	0x44, 0xb2, 0xcf, 0xf9, 0x9f, 0xdf, 0x39, 0xd3, 0xf9, 0x8f, 0xa7, 0x60, 0x2e, 0xc6, 0x8f, 0xa9,
+	0xed, 0x06, 0x94, 0xc4, 0x01, 0xf6, 0x56, 0xa3, 0x38, 0xa4, 0x21, 0x6c, 0x10, 0xda, 0x73, 0x12,
+	0x12, 0x1f, 0x91, 0x38, 0x3a, 0x68, 0xcd, 0xf7, 0xc3, 0x7e, 0x28, 0x12, 0x37, 0xf9, 0x93, 0xd4,
+	0xb4, 0x66, 0x33, 0x8d, 0x8a, 0xd4, 0xe2, 0xa8, 0x27, 0x1f, 0xdb, 0xb7, 0xc1, 0x8c, 0x45, 0x9e,
+	0x0d, 0x48, 0x42, 0xb7, 0x09, 0x76, 0x48, 0x0c, 0x9b, 0xa0, 0xba, 0xd3, 0x45, 0x95, 0xe5, 0xca,
+	0xe5, 0x71, 0xab, 0xea, 0x76, 0x61, 0x0b, 0x4c, 0x0f, 0x12, 0xde, 0xd2, 0x27, 0xa8, 0xca, 0xa2,
+	0x35, 0x4b, 0xbf, 0xb7, 0x7f, 0x36, 0xc1, 0xdc, 0x8e, 0x1a, 0xc8, 0x62, 0xd3, 0x29, 0xd2, 0x08,
+	0xe3, 0x02, 0xa8, 0x1e, 0xad, 0x89, 0xea, 0xfa, 0xda, 0xc2, 0x6a, 0x7e, 0xe4, 0x55, 0x55, 0x62,
+	0x31, 0x01, 0xbc, 0x05, 0x26, 0x62, 0x1c, 0xf4, 0x09, 0x1a, 0x13, 0xca, 0xd6, 0x90, 0x92, 0xa7,
+	0x52, 0xb9, 0x14, 0xc2, 0xab, 0x60, 0x2c, 0x1a, 0x50, 0x34, 0x2e, 0xf4, 0xa8, 0xa8, 0xdf, 0x1b,
+	0xa4, 0xf3, 0x58, 0x5c, 0x04, 0x37, 0x40, 0xc3, 0x21, 0x1e, 0xa1, 0xc4, 0x96, 0x4d, 0x26, 0x44,
+	0xd1, 0x72, 0xb1, 0xa8, 0x2b, 0x14, 0x85, 0x56, 0x75, 0x27, 0x8b, 0xf1, 0x86, 0xf4, 0x38, 0x40,
+	0x93, 0xa6, 0x86, 0xfb, 0xc7, 0x81, 0x6e, 0xc8, 0x44, 0xf0, 0x0e, 0x00, 0xbd, 0xd0, 0x8f, 0x70,
+	0x8f, 0xba, 0x61, 0x80, 0xa6, 0x44, 0xc9, 0xb9, 0x62, 0xc9, 0x86, 0xce, 0xa7, 0x95, 0xb9, 0x12,
+	0x78, 0x17, 0xd4, 0x3d, 0x82, 0x13, 0x62, 0xf7, 0xd9, 0xc4, 0x14, 0x4d, 0x9b, 0x08, 0xbb, 0x5c,
+	0xb0, 0xc5, 0xf3, 0x9a, 0xe0, 0xe9, 0x10, 0x5f, 0xb3, 0x24, 0xc4, 0xe4, 0x28, 0x7c, 0x4a, 0x50,
+	0xcd, 0xb4, 0x66, 0x81, 0xb0, 0x84, 0x40, 0xaf, 0xd9, 0xcb, 0x62, 0x7c, 0x5b, 0xb0, 0x87, 0x63,
+	0x1f, 0x01, 0xd3, 0xb6, 0x74, 0x78, 0x4a, 0x6f, 0x8b, 0x10, 0xc2, 0x75, 0x30, 0x79, 0x28, 0xdc,
+	0x84, 0x1c, 0x51, 0xb2, 0x68, 0xdc, 0x73, 0x69, 0x38, 0x4b, 0x49, 0x61, 0x07, 0xd4, 0xf1, 0x80,
+	0x1e, 0xda, 0x24, 0xc0, 0x07, 0x1e, 0x41, 0x3f, 0x8c, 0x7f, 0xb0, 0x0e, 0x53, 0x6c, 0x0a, 0x81,
+	0x5e, 0x2e, 0xd6, 0x21, 0xd8, 0x05, 0x0d, 0x81, 0x70, 0xdc, 0x44, 0x30, 0x7e, 0x4d, 0x99, 0xd6,
+	0xcb, 0x19, 0x5d, 0xa9, 0xd0, 0xeb, 0xc5, 0x59, 0x0c, 0xde, 0x97, 0x14, 0x12, 0x50, 0xb7, 0x87,
+	0x29, 0x41, 0xbf, 0x25, 0xe5, 0x4a, 0x91, 0x92, 0xfa, 0xbe, 0x93, 0x93, 0xa6, 0xb8, 0x42, 0x3d,
+	0xdc, 0x04, 0x33, 0x62, 0x2a, 0x7e, 0x6c, 0x6c, 0xec, 0x38, 0xe8, 0xdd, 0x74, 0xd9, 0x58, 0x0f,
+	0xd8, 0x5b, 0xc7, 0x71, 0x0a, 0x63, 0xa9, 0x18, 0x1b, 0x6b, 0x36, 0xc3, 0x48, 0x4f, 0xa2, 0xf7,
+	0x92, 0x74, 0xde, 0x4c, 0x52, 0x66, 0x56, 0xb0, 0x26, 0x2e, 0x84, 0x8b, 0x63, 0xf5, 0x09, 0x45,
+	0x1f, 0xce, 0x1c, 0x6b, 0x8b, 0xd0, 0x91, 0xb1, 0x58, 0x0c, 0xf6, 0xc1, 0xff, 0x19, 0xa6, 0x77,
+	0xc8, 0x4f, 0x89, 0x1d, 0xe1, 0x24, 0x79, 0x1e, 0xc6, 0x0e, 0xfa, 0x28, 0x91, 0xd7, 0xcc, 0xc8,
+	0x0d, 0xa1, 0xde, 0x53, 0xe2, 0x94, 0xfe, 0x2f, 0x36, 0xa6, 0xe1, 0x43, 0x30, 0x9f, 0x9b, 0x97,
+	0xdb, 0xdb, 0x8e, 0x43, 0xb6, 0xc9, 0xa7, 0xb2, 0xc7, 0xc5, 0x92, 0xb1, 0xc5, 0xd1, 0x08, 0xb3,
+	0xad, 0xfe, 0x07, 0x0f, 0x67, 0xe0, 0x23, 0xb0, 0x90, 0x91, 0xe5, 0x49, 0x91, 0xe8, 0x4f, 0x12,
+	0x7d, 0xc9, 0x8c, 0x56, 0x47, 0x26, 0xc7, 0x86, 0x78, 0x24, 0x05, 0xb7, 0x41, 0x33, 0x83, 0x7b,
+	0x6e, 0x42, 0xd1, 0x67, 0x49, 0x5d, 0x31, 0x53, 0x77, 0x99, 0xa4, 0xe0, 0xa3, 0x34, 0xa8, 0x49,
+	0x7c, 0x34, 0x49, 0xfa, 0x52, 0x4a, 0xe2, 0xad, 0x47, 0x48, 0x69, 0x50, 0x6f, 0xbd, 0x20, 0x71,
+	0x47, 0xbe, 0xac, 0x95, 0x6d, 0x3d, 0xaf, 0x19, 0x76, 0xa4, 0x8a, 0x69, 0x47, 0x0a, 0x8c, 0x72,
+	0xe4, 0xab, 0x5a, 0x99, 0x23, 0x79, 0x95, 0xc1, 0x91, 0x59, 0xb8, 0x38, 0x16, 0x77, 0xe4, 0xeb,
+	0x33, 0xc7, 0x1a, 0x76, 0xa4, 0x8a, 0xc1, 0x27, 0xa0, 0x95, 0xc3, 0x08, 0xa3, 0x44, 0x24, 0xf6,
+	0xdd, 0x24, 0xe1, 0xdf, 0xe1, 0x37, 0x92, 0x79, 0xbd, 0x84, 0xc9, 0xe5, 0x7b, 0x5a, 0x9d, 0xf2,
+	0xff, 0xc3, 0xe6, 0x3c, 0xf4, 0xc1, 0x62, 0xd6, 0x4b, 0x59, 0x27, 0xd7, 0xec, 0xad, 0x6c, 0x76,
+	0xc3, 0xdc, 0x4c, 0xba, 0x64, 0xb4, 0x1b, 0xc2, 0x25, 0x82, 0xf6, 0xdf, 0x60, 0x66, 0xd3, 0x8f,
+	0xe8, 0x0b, 0x8b, 0x24, 0x51, 0x18, 0x24, 0xa4, 0x1d, 0x81, 0xc5, 0x33, 0x3e, 0x44, 0x10, 0x82,
+	0x71, 0x71, 0x71, 0x57, 0xc4, 0xc5, 0x2d, 0x9e, 0xf9, 0x85, 0xae, 0xcf, 0xa7, 0xba, 0xd0, 0xd3,
+	0x77, 0xb8, 0x02, 0x1a, 0x89, 0xeb, 0x47, 0x6c, 0x2d, 0x94, 0x35, 0x0e, 0xc4, 0x45, 0x5c, 0xb3,
+	0xea, 0x32, 0xb6, 0xcf, 0x43, 0xf7, 0x66, 0x4f, 0xbe, 0x2d, 0xfd, 0x75, 0xf2, 0x7d, 0xa9, 0x72,
+	0xca, 0x7e, 0x5f, 0xd9, 0xef, 0x60, 0x52, 0xfc, 0x27, 0xb1, 0xfe, 0x27, 0x00, 0x00, 0xff, 0xff,
+	0xdc, 0xb1, 0xbb, 0xb7, 0xa1, 0x08, 0x00, 0x00,
 }

+ 2 - 0
etcdserver/etcdserverpb/raft_internal.proto

@@ -46,6 +46,8 @@ message InternalRaftRequest {
   AuthUserChangePasswordRequest auth_user_change_password = 1103;
   AuthUserGrantRoleRequest auth_user_grant_role = 1104;
   AuthUserRevokeRoleRequest auth_user_revoke_role = 1105;
+  AuthUserListRequest auth_user_list = 1106;
+  AuthRoleListRequest auth_role_list = 1107;
 
   AuthRoleAddRequest auth_role_add = 1200;
   AuthRoleDeleteRequest auth_role_delete = 1201;

File diff suppressed because it is too large
+ 664 - 50
etcdserver/etcdserverpb/rpc.pb.go


+ 90 - 0
etcdserver/etcdserverpb/rpc.pb.gw.go

@@ -387,6 +387,19 @@ func request_Auth_UserGet_0(ctx context.Context, marshaler runtime.Marshaler, cl
 
 }
 
+func request_Auth_UserList_0(ctx context.Context, marshaler runtime.Marshaler, client AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq AuthUserListRequest
+	var metadata runtime.ServerMetadata
+
+	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
+		return nil, metadata, grpc.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := client.UserList(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+	return msg, metadata, err
+
+}
+
 func request_Auth_UserDelete_0(ctx context.Context, marshaler runtime.Marshaler, client AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
 	var protoReq AuthUserDeleteRequest
 	var metadata runtime.ServerMetadata
@@ -465,6 +478,19 @@ func request_Auth_RoleGet_0(ctx context.Context, marshaler runtime.Marshaler, cl
 
 }
 
+func request_Auth_RoleList_0(ctx context.Context, marshaler runtime.Marshaler, client AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq AuthRoleListRequest
+	var metadata runtime.ServerMetadata
+
+	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
+		return nil, metadata, grpc.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := client.RoleList(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+	return msg, metadata, err
+
+}
+
 func request_Auth_RoleDelete_0(ctx context.Context, marshaler runtime.Marshaler, client AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
 	var protoReq AuthRoleDeleteRequest
 	var metadata runtime.ServerMetadata
@@ -1403,6 +1429,34 @@ func RegisterAuthHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.
 
 	})
 
+	mux.Handle("POST", pattern_Auth_UserList_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(ctx)
+		defer cancel()
+		if cn, ok := w.(http.CloseNotifier); ok {
+			go func(done <-chan struct{}, closed <-chan bool) {
+				select {
+				case <-done:
+				case <-closed:
+					cancel()
+				}
+			}(ctx.Done(), cn.CloseNotify())
+		}
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateContext(ctx, req)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+		}
+		resp, md, err := request_Auth_UserList_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_Auth_UserList_0(ctx, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
 	mux.Handle("POST", pattern_Auth_UserDelete_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
 		ctx, cancel := context.WithCancel(ctx)
 		defer cancel()
@@ -1571,6 +1625,34 @@ func RegisterAuthHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.
 
 	})
 
+	mux.Handle("POST", pattern_Auth_RoleList_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(ctx)
+		defer cancel()
+		if cn, ok := w.(http.CloseNotifier); ok {
+			go func(done <-chan struct{}, closed <-chan bool) {
+				select {
+				case <-done:
+				case <-closed:
+					cancel()
+				}
+			}(ctx.Done(), cn.CloseNotify())
+		}
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateContext(ctx, req)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+		}
+		resp, md, err := request_Auth_RoleList_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_Auth_RoleList_0(ctx, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
 	mux.Handle("POST", pattern_Auth_RoleDelete_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
 		ctx, cancel := context.WithCancel(ctx)
 		defer cancel()
@@ -1669,6 +1751,8 @@ var (
 
 	pattern_Auth_UserGet_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3alpha", "auth", "user", "get"}, ""))
 
+	pattern_Auth_UserList_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3alpha", "auth", "user", "list"}, ""))
+
 	pattern_Auth_UserDelete_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3alpha", "auth", "user", "delete"}, ""))
 
 	pattern_Auth_UserChangePassword_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3alpha", "auth", "user", "changepw"}, ""))
@@ -1681,6 +1765,8 @@ var (
 
 	pattern_Auth_RoleGet_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3alpha", "auth", "role", "get"}, ""))
 
+	pattern_Auth_RoleList_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3alpha", "auth", "role", "list"}, ""))
+
 	pattern_Auth_RoleDelete_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3alpha", "auth", "role", "delete"}, ""))
 
 	pattern_Auth_RoleGrantPermission_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3alpha", "auth", "role", "grant"}, ""))
@@ -1699,6 +1785,8 @@ var (
 
 	forward_Auth_UserGet_0 = runtime.ForwardResponseMessage
 
+	forward_Auth_UserList_0 = runtime.ForwardResponseMessage
+
 	forward_Auth_UserDelete_0 = runtime.ForwardResponseMessage
 
 	forward_Auth_UserChangePassword_0 = runtime.ForwardResponseMessage
@@ -1711,6 +1799,8 @@ var (
 
 	forward_Auth_RoleGet_0 = runtime.ForwardResponseMessage
 
+	forward_Auth_RoleList_0 = runtime.ForwardResponseMessage
+
 	forward_Auth_RoleDelete_0 = runtime.ForwardResponseMessage
 
 	forward_Auth_RoleGrantPermission_0 = runtime.ForwardResponseMessage

+ 36 - 2
etcdserver/etcdserverpb/rpc.proto

@@ -214,7 +214,7 @@ service Auth {
     };
   }
 
-  // UserGet gets detailed user information or lists all users.
+  // UserGet gets detailed user information.
   rpc UserGet(AuthUserGetRequest) returns (AuthUserGetResponse) {
       option (google.api.http) = {
         post: "/v3alpha/auth/user/get"
@@ -222,6 +222,14 @@ service Auth {
     };
   }
 
+  // UserList gets a list of all users.
+  rpc UserList(AuthUserListRequest) returns (AuthUserListResponse) {
+      option (google.api.http) = {
+        post: "/v3alpha/auth/user/list"
+        body: "*"
+    };
+  }
+
   // UserDelete deletes a specified user.
   rpc UserDelete(AuthUserDeleteRequest) returns (AuthUserDeleteResponse) {
       option (google.api.http) = {
@@ -262,7 +270,7 @@ service Auth {
     };
   }
 
-  // RoleGet gets detailed role information or lists all roles.
+  // RoleGet gets detailed role information.
   rpc RoleGet(AuthRoleGetRequest) returns (AuthRoleGetResponse) {
       option (google.api.http) = {
         post: "/v3alpha/auth/role/get"
@@ -270,6 +278,14 @@ service Auth {
     };
   }
 
+  // RoleList gets lists of all roles.
+  rpc RoleList(AuthRoleListRequest) returns (AuthRoleListResponse) {
+      option (google.api.http) = {
+        post: "/v3alpha/auth/role/list"
+        body: "*"
+    };
+  }
+
   // RoleDelete deletes a specified role.
   rpc RoleDelete(AuthRoleDeleteRequest) returns (AuthRoleDeleteResponse) {
       option (google.api.http) = {
@@ -766,6 +782,12 @@ message AuthRoleGetRequest {
   string role = 1;
 }
 
+message AuthUserListRequest {
+}
+
+message AuthRoleListRequest {
+}
+
 message AuthRoleDeleteRequest {
   string role = 1;
 }
@@ -833,6 +855,18 @@ message AuthRoleGetResponse {
   repeated authpb.Permission perm = 2;
 }
 
+message AuthRoleListResponse {
+  ResponseHeader header = 1;
+
+  repeated string roles = 2;
+}
+
+message AuthUserListResponse {
+  ResponseHeader header = 1;
+
+  repeated string users = 2;
+}
+
 message AuthRoleDeleteResponse {
   ResponseHeader header = 1;
 }

+ 24 - 0
etcdserver/v3_server.go

@@ -72,6 +72,8 @@ type Authenticator interface {
 	RoleGet(ctx context.Context, r *pb.AuthRoleGetRequest) (*pb.AuthRoleGetResponse, error)
 	RoleRevokePermission(ctx context.Context, r *pb.AuthRoleRevokePermissionRequest) (*pb.AuthRoleRevokePermissionResponse, error)
 	RoleDelete(ctx context.Context, r *pb.AuthRoleDeleteRequest) (*pb.AuthRoleDeleteResponse, error)
+	UserList(ctx context.Context, r *pb.AuthUserListRequest) (*pb.AuthUserListResponse, error)
+	RoleList(ctx context.Context, r *pb.AuthRoleListRequest) (*pb.AuthRoleListResponse, error)
 }
 
 func (s *EtcdServer) Range(ctx context.Context, r *pb.RangeRequest) (*pb.RangeResponse, error) {
@@ -350,6 +352,17 @@ func (s *EtcdServer) UserGet(ctx context.Context, r *pb.AuthUserGetRequest) (*pb
 	return result.resp.(*pb.AuthUserGetResponse), nil
 }
 
+func (s *EtcdServer) UserList(ctx context.Context, r *pb.AuthUserListRequest) (*pb.AuthUserListResponse, error) {
+	result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{AuthUserList: r})
+	if err != nil {
+		return nil, err
+	}
+	if result.err != nil {
+		return nil, result.err
+	}
+	return result.resp.(*pb.AuthUserListResponse), nil
+}
+
 func (s *EtcdServer) UserRevokeRole(ctx context.Context, r *pb.AuthUserRevokeRoleRequest) (*pb.AuthUserRevokeRoleResponse, error) {
 	result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{AuthUserRevokeRole: r})
 	if err != nil {
@@ -394,6 +407,17 @@ func (s *EtcdServer) RoleGet(ctx context.Context, r *pb.AuthRoleGetRequest) (*pb
 	return result.resp.(*pb.AuthRoleGetResponse), nil
 }
 
+func (s *EtcdServer) RoleList(ctx context.Context, r *pb.AuthRoleListRequest) (*pb.AuthRoleListResponse, error) {
+	result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{AuthRoleList: r})
+	if err != nil {
+		return nil, err
+	}
+	if result.err != nil {
+		return nil, result.err
+	}
+	return result.resp.(*pb.AuthRoleListResponse), nil
+}
+
 func (s *EtcdServer) RoleRevokePermission(ctx context.Context, r *pb.AuthRoleRevokePermissionRequest) (*pb.AuthRoleRevokePermissionResponse, error) {
 	result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{AuthRoleRevokePermission: r})
 	if err != nil {

Some files were not shown because too many files changed in this diff