init repo

This commit is contained in:
vaalacat
2024-01-06 09:36:56 +00:00
committed by Vaala Cat
commit 88197a5e11
175 changed files with 20826 additions and 0 deletions

2
.env.sample Normal file
View File

@@ -0,0 +1,2 @@
APP_GLOBAL_SECRET="123"
MASTER_RPC_HOST=127.0.0.1

6
.gitignore vendored Normal file
View File

@@ -0,0 +1,6 @@
.vscode
__debug*
.env
tmp
*.db
frp-panel

61
README.md Normal file
View File

@@ -0,0 +1,61 @@
项目如下
项目包含三个角色
1. Master: 控制节点接受来自前端的请求并负责管理Client和Server
2. Server: 服务端受控制节点控制负责对客户端提供服务包含frps和rpc(用于连接Master)服务
3. Client: 客户端受控制节点控制包含frpc和rpc(用于连接Master)服务
启动方式:
- master: `go run cmd/*.go master` 或是 `frp-panel master`
- client: `go run cmd/*.go client -i <clientID> -s <clientSecret>` 或是 `frp-panel client -i <clientID> -s <clientSecret>`
- server: `go run cmd/*.go server -i <serverID> -s <serverSecret>` 或是 `frp-panel server -i <serverID> -s <serverSecret>`
项目配置文件会默认读取当前文件夹下的.env文件项目内置了样例配置文件可以按照自己的需求进行修改
```
.
|-- biz # 主要业务逻辑
| |-- client # 客户端逻辑这里指的是frp-panel的客户端
| |-- master # frp-panel 控制平面负责处理前端请求并且使用rpc管理frp-panel的server和client
| | |-- auth # 认证模块,包含用户认证和客户端认证
| | |-- client # 客户端模块包含前端管理客户端的各种API
| | |-- server # 服务端模块包含前端管理服务端的各种API
| | `-- user # 用户模块,包含用户管理、用户信息获取等
| `-- server # 服务端逻辑这里指的是frp-panel的服务端
|-- cache # 缓存用于存储frps的认证token
|-- cmd # 命令行入口main函数的所在地负责按需启动各个模块
|-- common
|-- conf
|-- dao # data access object任何和数据库相关的操作会调用这个库
|-- doc # 文档
|-- idl # idl定义
|-- middleware # api的中间件包含JWT和context相关用于处理api请求鉴权通过后会把用户信息注入到context可以通过common包获取
|-- models # 数据库模型,用于定义数据库表。同时包含实体定义
|-- pb # protobuf生成的pb文件
|-- rpc # 各种rpc的所在地包含Client/Server调用Master的逻辑也包含Master使用Stream调用Client和Server的逻辑
|-- services # 各种需要在内存中持久运行的模块,这个包可以管理各个服务的运行/停止
| |-- api # api服务运行需要外部传入一个ginRouter
| |-- client # frp的客户端即frpc可以控制frpc的各种配置/开始与停止
| |-- master # master服务包含rpc的服务端定义接收到rpc请求后会调用biz包处理逻辑
| |-- rpcclient # 有状态的rpc客户端因为rpc的client都没有公网ip因此在rpc client启动时会调用master的stream长连接rpc建立连接后Master和Client通过这个包通信
| `-- server # frp的服务端即frps可以控制frps的各种配置/开始与停止
|-- tunnel # tunnel模块用于管理tunnel也就是管理frpc和frps服务
|-- utils
|-- watcher # 定时运行的任务比如每30秒更新一次配置文件
`-- www
|-- api
|-- components # 这里面有一个apitest组件用于测试
| `-- ui
|-- lib
| `-- pb
|-- pages
|-- public
|-- store
|-- styles
`-- types
```
详细架构调用图
![structure](doc/callvis.svg)

View File

@@ -0,0 +1,26 @@
package client
import (
"context"
"github.com/VaalaCat/frp-panel/pb"
"github.com/VaalaCat/frp-panel/tunnel"
"github.com/sirupsen/logrus"
)
func RemoveFrpcHandler(ctx context.Context, req *pb.RemoveFRPCRequest) (*pb.RemoveFRPCResponse, error) {
logrus.Infof("remove frpc, req: [%+v]", req)
cli := tunnel.GetClientController().Get(req.GetClientId())
if cli == nil {
logrus.Infof("client not found, no need to remove")
return &pb.RemoveFRPCResponse{
Status: &pb.Status{Code: pb.RespCode_RESP_CODE_INVALID, Message: "client not found"},
}, nil
}
cli.Stop()
tunnel.GetClientController().Delete(req.GetClientId())
return &pb.RemoveFRPCResponse{
Status: &pb.Status{Code: pb.RespCode_RESP_CODE_SUCCESS, Message: "ok"},
}, nil
}

23
biz/client/rpc_handler.go Normal file
View File

@@ -0,0 +1,23 @@
package client
import (
"github.com/VaalaCat/frp-panel/common"
"github.com/VaalaCat/frp-panel/pb"
"github.com/sirupsen/logrus"
)
func HandleServerMessage(req *pb.ServerMessage) *pb.ClientMessage {
logrus.Infof("client get a server message, origin is: [%+v]", req)
switch req.Event {
case pb.Event_EVENT_UPDATE_FRPC:
return common.WrapperServerMsg(req, UpdateFrpcHander)
case pb.Event_EVENT_REMOVE_FRPC:
return common.WrapperServerMsg(req, RemoveFrpcHandler)
default:
}
return &pb.ClientMessage{
Event: pb.Event_EVENT_ERROR,
Data: []byte("unknown event"),
}
}

View File

@@ -0,0 +1,78 @@
package client
import (
"context"
"reflect"
"github.com/VaalaCat/frp-panel/pb"
"github.com/VaalaCat/frp-panel/rpc"
"github.com/VaalaCat/frp-panel/services/client"
"github.com/VaalaCat/frp-panel/tunnel"
"github.com/VaalaCat/frp-panel/utils"
"github.com/sirupsen/logrus"
)
func PullConfig(clientID, clientSecret string) error {
logrus.Infof("start to pull client config, clientID: [%s]", clientID)
ctx := context.Background()
cli, err := rpc.MasterCli(ctx)
if err != nil {
logrus.WithError(err).Error("cannot get master client")
return err
}
resp, err := cli.PullClientConfig(ctx, &pb.PullClientConfigReq{
Base: &pb.ClientBase{
ClientId: clientID,
ClientSecret: clientSecret,
},
})
if err != nil {
logrus.WithError(err).Error("cannot pull client config")
return err
}
if len(resp.GetClient().GetConfig()) == 0 {
logrus.Infof("client [%s] config is empty, wait for server init", clientID)
return nil
}
c, p, v, err := utils.LoadClientConfig([]byte(resp.GetClient().GetConfig()), true)
if err != nil {
logrus.WithError(err).Error("cannot load client config")
return err
}
ctrl := tunnel.GetClientController()
if t := ctrl.Get(clientID); t == nil {
ctrl.Add(clientID, client.NewClientHandler(c, p, v))
ctrl.Run(clientID)
} else {
if !reflect.DeepEqual(t.GetCommonCfg(), c) {
logrus.Infof("client %s config changed, will recreate it", clientID)
tcli := ctrl.Get(clientID)
if tcli != nil {
tcli.Stop()
ctrl.Delete(clientID)
}
ctrl.Add(clientID, client.NewClientHandler(c, p, v))
ctrl.Run(clientID)
} else {
logrus.Infof("client %s already exists, update if need", clientID)
tcli := ctrl.Get(clientID)
if tcli == nil || !tcli.Running() {
if tcli != nil {
tcli.Stop()
ctrl.Delete(clientID)
}
ctrl.Add(clientID, client.NewClientHandler(c, p, v))
ctrl.Run(clientID)
} else {
tcli.Update(p, v)
}
}
}
logrus.Infof("pull client config success, clientID: [%s]", clientID)
return nil
}

View File

@@ -0,0 +1,50 @@
package client
import (
"context"
"fmt"
"reflect"
"github.com/VaalaCat/frp-panel/pb"
"github.com/VaalaCat/frp-panel/services/client"
"github.com/VaalaCat/frp-panel/tunnel"
"github.com/VaalaCat/frp-panel/utils"
"github.com/sirupsen/logrus"
)
func UpdateFrpcHander(ctx context.Context, req *pb.UpdateFRPCRequest) (*pb.UpdateFRPCResponse, error) {
logrus.Infof("update frpc, req: [%+v]", req)
content := req.GetConfig()
c, p, v, err := utils.LoadClientConfig(content, false)
if err != nil {
logrus.WithError(err).Errorf("cannot load config")
return &pb.UpdateFRPCResponse{
Status: &pb.Status{Code: pb.RespCode_RESP_CODE_INVALID, Message: err.Error()},
}, err
}
cli := tunnel.GetClientController().Get(req.GetClientId())
if cli == nil {
logrus.Errorf("cannot get client, id: [%s]", req.GetClientId())
return &pb.UpdateFRPCResponse{
Status: &pb.Status{Code: pb.RespCode_RESP_CODE_INVALID, Message: "cannot get client"},
}, fmt.Errorf("cannot get client")
}
if reflect.DeepEqual(c, cli.GetCommonCfg()) {
logrus.Warnf("client config not changed")
cli.Update(p, v)
} else {
tcli := tunnel.GetClientController().Get(req.GetClientId())
if tcli != nil {
tcli.Stop()
tunnel.GetClientController().Delete(req.GetClientId())
}
tunnel.GetClientController().Add(req.GetClientId(), client.NewClientHandler(c, p, v))
tunnel.GetClientController().Run(req.GetClientId())
}
return &pb.UpdateFRPCResponse{
Status: &pb.Status{Code: pb.RespCode_RESP_CODE_SUCCESS, Message: "ok"},
}, nil
}

View File

@@ -0,0 +1,84 @@
package auth
import (
"net/http"
"github.com/VaalaCat/frp-panel/cache"
"github.com/VaalaCat/frp-panel/dao"
plugin "github.com/fatedier/frp/pkg/plugin/server"
"github.com/gin-gonic/gin"
"github.com/sirupsen/logrus"
)
type Response struct {
Msg string `json:"msg"`
}
type HTTPError struct {
Code int
Err error
}
func (e *HTTPError) Error() string {
return e.Err.Error()
}
type HandlerFunc func(ctx *gin.Context) (interface{}, error)
func MakeGinHandlerFunc(handler HandlerFunc) gin.HandlerFunc {
return func(ctx *gin.Context) {
res, err := handler(ctx)
if err != nil {
logrus.Infof("handle %s error: %v", ctx.Request.URL.Path, err)
switch e := err.(type) {
case *HTTPError:
ctx.JSON(e.Code, &Response{Msg: e.Err.Error()})
default:
ctx.JSON(500, &Response{Msg: err.Error()})
}
return
}
ctx.JSON(http.StatusOK, res)
}
}
func HandleLogin(ctx *gin.Context) (interface{}, error) {
var r plugin.Request
var content plugin.LoginContent
r.Content = &content
if err := ctx.BindJSON(&r); err != nil {
return nil, &HTTPError{
Code: http.StatusBadRequest,
Err: err,
}
}
var res plugin.Response
token := content.Metas["token"]
if len(content.User) == 0 || len(token) == 0 {
res.Reject = true
res.RejectReason = "user or meta token can not be empty"
return res, nil
}
userToken, err := cache.Get().Get([]byte(content.User))
if err != nil {
u, err := dao.GetUserByUserName(content.User)
if err != nil || u == nil {
res.Reject = true
res.RejectReason = "invalid frp auth"
return res, nil
}
cache.Get().Set([]byte(u.GetUserName()), []byte(u.GetToken()), 0)
userToken = []byte(u.GetToken())
}
if string(userToken) == token {
res.Unchange = true
return res, nil
}
res.Reject = true
res.RejectReason = "invalid meta token"
return res, nil
}

24
biz/master/auth/init.go Normal file
View File

@@ -0,0 +1,24 @@
package auth
import (
"github.com/VaalaCat/frp-panel/cache"
"github.com/VaalaCat/frp-panel/dao"
"github.com/VaalaCat/frp-panel/models"
"github.com/samber/lo"
"github.com/sirupsen/logrus"
)
func InitAuth() {
logrus.Info("start to init frp user auth token")
u, err := dao.AdminGetAllUsers()
if err != nil {
logrus.WithError(err).Fatalf("init frp user auth token failed")
}
lo.ForEach(u, func(user *models.UserEntity, _ int) {
cache.Get().Set([]byte(user.GetUserName()), []byte(user.GetToken()), 0)
})
logrus.Infof("init frp user auth token success, count: %d", len(u))
}

37
biz/master/auth/login.go Normal file
View File

@@ -0,0 +1,37 @@
package auth
import (
"context"
"fmt"
"github.com/VaalaCat/frp-panel/conf"
"github.com/VaalaCat/frp-panel/dao"
"github.com/VaalaCat/frp-panel/middleware"
"github.com/VaalaCat/frp-panel/pb"
"github.com/gin-gonic/gin"
)
func LoginHandler(c context.Context, req *pb.LoginRequest) (*pb.LoginResponse, error) {
username := req.GetUsername()
password := req.GetPassword()
ok, user, err := dao.CheckUserPassword(username, password)
if err != nil {
return nil, err
}
if !ok {
return &pb.LoginResponse{
Status: &pb.Status{Code: pb.RespCode_RESP_CODE_INVALID, Message: "invalid username or password"},
}, nil
}
tokenStr := conf.GetCommonJWT(fmt.Sprint(user.GetUserID()))
ginCtx := c.(*gin.Context)
middleware.PushTokenStr(ginCtx, tokenStr)
return &pb.LoginResponse{
Status: &pb.Status{Code: pb.RespCode_RESP_CODE_SUCCESS, Message: "ok"},
Token: &tokenStr,
}, nil
}

View File

@@ -0,0 +1,51 @@
package auth
import (
"context"
"fmt"
"github.com/VaalaCat/frp-panel/dao"
"github.com/VaalaCat/frp-panel/models"
"github.com/VaalaCat/frp-panel/pb"
"github.com/VaalaCat/frp-panel/utils"
"github.com/google/uuid"
)
func RegisterHandler(c context.Context, req *pb.RegisterRequest) (*pb.RegisterResponse, error) {
username := req.GetUsername()
password := req.GetPassword()
email := req.GetEmail()
if username == "" || password == "" || email == "" {
return &pb.RegisterResponse{
Status: &pb.Status{Code: pb.RespCode_RESP_CODE_INVALID, Message: "invalid username or password or email"},
}, fmt.Errorf("invalid username or password or email")
}
hashedPassword, err := utils.HashPassword(password)
if err != nil {
return &pb.RegisterResponse{
Status: &pb.Status{Code: pb.RespCode_RESP_CODE_INVALID, Message: err.Error()},
}, err
}
newUser := &models.UserEntity{
UserName: username,
Password: hashedPassword,
Email: email,
Status: models.STATUS_NORMAL,
Role: models.ROLE_NORMAL,
Token: uuid.New().String(),
}
err = dao.CreateUser(newUser)
if err != nil {
return &pb.RegisterResponse{
Status: &pb.Status{Code: pb.RespCode_RESP_CODE_INVALID, Message: err.Error()},
}, err
}
return &pb.RegisterResponse{
Status: &pb.Status{Code: pb.RespCode_RESP_CODE_SUCCESS, Message: "ok"},
}, nil
}

View File

@@ -0,0 +1,45 @@
package client
import (
"context"
"github.com/VaalaCat/frp-panel/common"
"github.com/VaalaCat/frp-panel/dao"
"github.com/VaalaCat/frp-panel/models"
"github.com/VaalaCat/frp-panel/pb"
"github.com/google/uuid"
)
func InitClientHandler(c context.Context, req *pb.InitClientRequest) (*pb.InitClientResponse, error) {
userClientID := req.GetClientId()
userInfo := common.GetUserInfo(c)
if !userInfo.Valid() {
return &pb.InitClientResponse{
Status: &pb.Status{Code: pb.RespCode_RESP_CODE_INVALID, Message: "invalid user"},
}, nil
}
if len(userClientID) == 0 {
return &pb.InitClientResponse{
Status: &pb.Status{Code: pb.RespCode_RESP_CODE_INVALID, Message: "invalid client id"},
}, nil
}
globalClientID := common.GlobalClientID(userInfo.GetUserName(), userClientID)
if err := dao.CreateClient(userInfo,
&models.ClientEntity{
ClientID: globalClientID,
TenantID: userInfo.GetTenantID(),
UserID: userInfo.GetUserID(),
ConnectSecret: uuid.New().String(),
}); err != nil {
return nil, err
}
return &pb.InitClientResponse{
Status: &pb.Status{Code: pb.RespCode_RESP_CODE_SUCCESS, Message: "ok"},
ClientId: &globalClientID,
}, nil
}

View File

@@ -0,0 +1,37 @@
package client
import (
"context"
"github.com/VaalaCat/frp-panel/common"
"github.com/VaalaCat/frp-panel/dao"
"github.com/VaalaCat/frp-panel/pb"
"github.com/sirupsen/logrus"
)
func DeleteClientHandler(ctx context.Context, req *pb.DeleteClientRequest) (*pb.DeleteClientResponse, error) {
logrus.Infof("delete client, req: [%+v]", req)
userInfo := common.GetUserInfo(ctx)
clientID := req.GetClientId()
if !userInfo.Valid() {
return &pb.DeleteClientResponse{
Status: &pb.Status{Code: pb.RespCode_RESP_CODE_INVALID, Message: "invalid user"},
}, nil
}
if len(clientID) == 0 {
return &pb.DeleteClientResponse{
Status: &pb.Status{Code: pb.RespCode_RESP_CODE_INVALID, Message: "invalid client id"},
}, nil
}
if err := dao.DeleteClient(userInfo, clientID); err != nil {
return nil, err
}
return &pb.DeleteClientResponse{
Status: &pb.Status{Code: pb.RespCode_RESP_CODE_SUCCESS, Message: "ok"},
}, nil
}

View File

@@ -0,0 +1,54 @@
package client
import (
"context"
"fmt"
"github.com/VaalaCat/frp-panel/common"
"github.com/VaalaCat/frp-panel/dao"
"github.com/VaalaCat/frp-panel/pb"
"github.com/VaalaCat/frp-panel/rpc"
"github.com/sirupsen/logrus"
)
func RemoveFrpcHandler(c context.Context, req *pb.RemoveFRPCRequest) (*pb.RemoveFRPCResponse, error) {
logrus.Infof("remove frpc, req: [%+v]", req)
var (
clientID = req.GetClientId()
userInfo = common.GetUserInfo(c)
)
if len(clientID) == 0 {
logrus.Errorf("invalid client id")
return nil, fmt.Errorf("invalid client id")
}
_, err := dao.GetClientByClientID(userInfo, clientID)
if err != nil {
logrus.WithError(err).Errorf("cannot get client, id: [%s]", clientID)
return nil, err
}
err = dao.DeleteClient(userInfo, clientID)
if err != nil {
logrus.WithError(err).Errorf("cannot delete client, id: [%s]", clientID)
return nil, err
}
go func() {
resp, err := rpc.CallClient(c, req.GetClientId(), pb.Event_EVENT_REMOVE_FRPC, req)
if err != nil {
logrus.WithError(err).Errorf("remove event send to client error, client id: [%s]", req.GetClientId())
}
if resp == nil {
logrus.Errorf("cannot get response, client id: [%s]", req.GetClientId())
}
}()
logrus.Infof("remove frpc success, client id: [%s]", req.GetClientId())
return &pb.RemoveFRPCResponse{
Status: &pb.Status{Code: pb.RespCode_RESP_CODE_SUCCESS, Message: "ok"},
}, nil
}

View File

@@ -0,0 +1,46 @@
package client
import (
"context"
"github.com/VaalaCat/frp-panel/common"
"github.com/VaalaCat/frp-panel/dao"
"github.com/VaalaCat/frp-panel/pb"
"github.com/samber/lo"
"github.com/sirupsen/logrus"
)
func GetClientHandler(ctx context.Context, req *pb.GetClientRequest) (*pb.GetClientResponse, error) {
logrus.Infof("get client, req: [%+v]", req)
var (
userInfo = common.GetUserInfo(ctx)
clientID = req.GetClientId()
)
if !userInfo.Valid() {
return &pb.GetClientResponse{
Status: &pb.Status{Code: pb.RespCode_RESP_CODE_INVALID, Message: "invalid user"},
}, nil
}
if len(clientID) == 0 {
return &pb.GetClientResponse{
Status: &pb.Status{Code: pb.RespCode_RESP_CODE_INVALID, Message: "invalid client id"},
}, nil
}
client, err := dao.GetClientByClientID(userInfo, clientID)
if err != nil {
return nil, err
}
return &pb.GetClientResponse{
Status: &pb.Status{Code: pb.RespCode_RESP_CODE_SUCCESS, Message: "ok"},
Client: &pb.Client{
Id: lo.ToPtr(client.ClientID),
Secret: lo.ToPtr(client.ConnectSecret),
Config: lo.ToPtr(string(client.ConfigContent)),
},
}, nil
}

View File

@@ -0,0 +1,34 @@
package client
import (
"fmt"
"github.com/VaalaCat/frp-panel/dao"
"github.com/VaalaCat/frp-panel/models"
)
type ValidateableClientRequest interface {
GetClientSecret() string
GetClientId() string
}
func ValidateClientRequest(req ValidateableClientRequest) (*models.ClientEntity, error) {
if req == nil {
return nil, fmt.Errorf("invalid request")
}
if req.GetClientId() == "" || req.GetClientSecret() == "" {
return nil, fmt.Errorf("invalid request")
}
var (
cli *models.ClientEntity
err error
)
if cli, err = dao.ValidateClientSecret(req.GetClientId(), req.GetClientSecret()); err != nil {
return nil, err
}
return cli, nil
}

View File

@@ -0,0 +1,46 @@
package client
import (
"context"
"github.com/VaalaCat/frp-panel/common"
"github.com/VaalaCat/frp-panel/dao"
"github.com/VaalaCat/frp-panel/models"
"github.com/VaalaCat/frp-panel/pb"
"github.com/samber/lo"
"github.com/sirupsen/logrus"
)
func ListClientsHandler(ctx context.Context, req *pb.ListClientsRequest) (*pb.ListClientsResponse, error) {
logrus.Infof("list client, req: [%+v]", req)
var (
userInfo = common.GetUserInfo(ctx)
)
if !userInfo.Valid() {
return &pb.ListClientsResponse{
Status: &pb.Status{Code: pb.RespCode_RESP_CODE_INVALID, Message: "invalid user"},
}, nil
}
page := int(req.GetPage())
pageSize := int(req.GetPageSize())
clients, err := dao.ListClients(userInfo, page, pageSize)
if err != nil {
return nil, err
}
respClients := lo.Map(clients, func(c *models.ClientEntity, _ int) *pb.Client {
return &pb.Client{
Id: lo.ToPtr(c.ClientID),
Secret: lo.ToPtr(c.ConnectSecret),
Config: lo.ToPtr(string(c.ConfigContent)),
}
})
return &pb.ListClientsResponse{
Status: &pb.Status{Code: pb.RespCode_RESP_CODE_SUCCESS, Message: "ok"},
Clients: respClients,
}, nil
}

View File

@@ -0,0 +1,27 @@
package client
import (
"context"
"github.com/VaalaCat/frp-panel/models"
"github.com/VaalaCat/frp-panel/pb"
"github.com/samber/lo"
)
func RPCPullConfig(ctx context.Context, req *pb.PullClientConfigReq) (*pb.PullClientConfigResp, error) {
var (
err error
cli *models.ClientEntity
)
if cli, err = ValidateClientRequest(req.GetBase()); err != nil {
return nil, err
}
return &pb.PullClientConfigResp{
Client: &pb.Client{
Id: lo.ToPtr(cli.ClientID),
Config: lo.ToPtr(string(cli.ConfigContent)),
},
}, nil
}

View File

@@ -0,0 +1,41 @@
package client
import (
"context"
"github.com/VaalaCat/frp-panel/common"
"github.com/VaalaCat/frp-panel/dao"
"github.com/VaalaCat/frp-panel/models"
"github.com/samber/lo"
"github.com/sirupsen/logrus"
)
func SyncTunnel(ctx context.Context, userInfo models.UserInfo) error {
clis, err := dao.GetAllClients(userInfo)
if err != nil {
return err
}
lo.ForEach(clis, func(cli *models.ClientEntity, _ int) {
cfg, err := cli.GetConfigContent()
if err != nil {
logrus.WithError(err).Errorf("cannot get client config content, id: [%s]", cli.ClientID)
return
}
cfg.User = userInfo.GetUserName()
cfg.Metadatas = map[string]string{
common.FRPAuthTokenKey: userInfo.GetToken(),
}
if err := cli.SetConfigContent(*cfg); err != nil {
logrus.WithError(err).Errorf("cannot set client config content, id: [%s]", cli.ClientID)
return
}
if err := dao.UpdateClient(userInfo, cli); err != nil {
logrus.WithError(err).Errorf("cannot update client, id: [%s]", cli.ClientID)
return
}
logrus.Infof("update client success, id: [%s]", cli.ClientID)
})
return nil
}

View File

@@ -0,0 +1,113 @@
package client
import (
"context"
"encoding/json"
"fmt"
"github.com/VaalaCat/frp-panel/common"
"github.com/VaalaCat/frp-panel/dao"
"github.com/VaalaCat/frp-panel/pb"
"github.com/VaalaCat/frp-panel/rpc"
"github.com/VaalaCat/frp-panel/utils"
v1 "github.com/fatedier/frp/pkg/config/v1"
"github.com/samber/lo"
"github.com/sirupsen/logrus"
)
func UpdateFrpcHander(c context.Context, req *pb.UpdateFRPCRequest) (*pb.UpdateFRPCResponse, error) {
logrus.Infof("update frpc, req: [%+v]", req)
var (
content = req.GetConfig()
serverID = req.GetServerId()
clientID = req.GetClientId()
userInfo = common.GetUserInfo(c)
)
cliCfg, err := utils.LoadClientConfigNormal(content, true)
if err != nil {
logrus.WithError(err).Errorf("cannot load config")
return &pb.UpdateFRPCResponse{
Status: &pb.Status{Code: pb.RespCode_RESP_CODE_INVALID, Message: err.Error()},
}, err
}
cli, err := dao.GetClientByClientID(userInfo, req.GetClientId())
if err != nil {
logrus.WithError(err).Errorf("cannot get client, id: [%s]", req.GetClientId())
return &pb.UpdateFRPCResponse{
Status: &pb.Status{Code: pb.RespCode_RESP_CODE_INVALID, Message: "cannot get client"},
}, fmt.Errorf("cannot get client")
}
srv, err := dao.GetServerByServerID(userInfo, req.GetServerId())
if err != nil || srv == nil || len(srv.ServerIP) == 0 || len(srv.ConfigContent) == 0 {
logrus.WithError(err).Errorf("cannot get server, server is not prepared, id: [%s]", req.GetServerId())
return &pb.UpdateFRPCResponse{
Status: &pb.Status{Code: pb.RespCode_RESP_CODE_INVALID, Message: "cannot get server"},
}, fmt.Errorf("cannot get server")
}
srvConf, err := srv.GetConfigContent()
if srvConf == nil || err != nil {
logrus.WithError(err).Errorf("cannot get server, id: [%s]", serverID)
return nil, err
}
cliCfg.ServerAddr = srv.ServerIP
cliCfg.ServerPort = srvConf.BindPort
cliCfg.User = userInfo.GetUserName()
cliCfg.Auth = v1.AuthClientConfig{}
cliCfg.Metadatas = map[string]string{
common.FRPAuthTokenKey: userInfo.GetToken(),
}
newCfg := struct {
v1.ClientCommonConfig
Proxies []v1.ProxyConfigurer `json:"proxies,omitempty"`
Visitors []v1.VisitorBaseConfig `json:"visitors,omitempty"`
}{
ClientCommonConfig: cliCfg.ClientCommonConfig,
Proxies: lo.Map(cliCfg.Proxies, func(item v1.TypedProxyConfig, _ int) v1.ProxyConfigurer {
return item.ProxyConfigurer
}),
Visitors: lo.Map(cliCfg.Visitors, func(item v1.TypedVisitorConfig, _ int) v1.VisitorBaseConfig {
return *item.GetBaseConfig()
}),
}
rawCliConf, err := json.Marshal(newCfg)
if err != nil {
logrus.WithError(err).Error("cannot marshal config")
return nil, err
}
cli.ConfigContent = rawCliConf
if err := dao.UpdateClient(userInfo, cli); err != nil {
logrus.WithError(err).Errorf("cannot update client, id: [%s]", clientID)
return nil, err
}
cliReq := &pb.UpdateFRPCRequest{
ClientId: lo.ToPtr(clientID),
ServerId: lo.ToPtr(serverID),
Config: rawCliConf,
}
go func() {
resp, err := rpc.CallClient(c, req.GetClientId(), pb.Event_EVENT_UPDATE_FRPC, cliReq)
if err != nil {
logrus.WithError(err).Errorf("update event send to client error, server: [%s], client: [%s]", serverID, req.GetClientId())
}
if resp == nil {
logrus.Errorf("cannot get response, server: [%s], client: [%s]", serverID, req.GetClientId())
}
}()
logrus.Infof("update frpc success, client id: [%s]", req.GetClientId())
return &pb.UpdateFRPCResponse{
Status: &pb.Status{Code: pb.RespCode_RESP_CODE_SUCCESS, Message: "ok"},
}, nil
}

60
biz/master/handler.go Normal file
View File

@@ -0,0 +1,60 @@
package master
import (
"github.com/VaalaCat/frp-panel/biz/master/auth"
"github.com/VaalaCat/frp-panel/biz/master/client"
"github.com/VaalaCat/frp-panel/biz/master/server"
"github.com/VaalaCat/frp-panel/biz/master/user"
"github.com/VaalaCat/frp-panel/common"
"github.com/VaalaCat/frp-panel/middleware"
"github.com/gin-gonic/gin"
)
func NewRouter() *gin.Engine {
router := gin.Default()
ConfigureRouter(router)
return router
}
func ConfigureRouter(router *gin.Engine) {
router.POST("/auth", auth.MakeGinHandlerFunc(auth.HandleLogin))
api := router.Group("/api")
v1 := api.Group("/v1")
{
authRouter := v1.Group("/auth")
{
authRouter.POST("/login", common.Wrapper(auth.LoginHandler))
authRouter.POST("/register", common.Wrapper(auth.RegisterHandler))
}
userRouter := v1.Group("/user", middleware.JWTAuth, middleware.AuthCtx)
{
userRouter.POST("/get", common.Wrapper(user.GetUserInfoHandler))
userRouter.POST("/update", common.Wrapper(user.UpdateUserInfoHander))
}
clientRouter := v1.Group("/client", middleware.JWTAuth, middleware.AuthCtx)
{
clientRouter.POST("/get", common.Wrapper(client.GetClientHandler))
clientRouter.POST("/init", common.Wrapper(client.InitClientHandler))
clientRouter.POST("/delete", common.Wrapper(client.DeleteClientHandler))
clientRouter.POST("/list", common.Wrapper(client.ListClientsHandler))
}
serverRouter := v1.Group("/server", middleware.JWTAuth, middleware.AuthCtx)
{
serverRouter.POST("/get", common.Wrapper(server.GetServerHandler))
serverRouter.POST("/init", common.Wrapper(server.InitServerHandler))
serverRouter.POST("/delete", common.Wrapper(server.DeleteServerHandler))
serverRouter.POST("/list", common.Wrapper(server.ListServersHandler))
}
frpcRouter := v1.Group("/frpc", middleware.JWTAuth, middleware.AuthCtx)
{
frpcRouter.POST("/update", common.Wrapper(client.UpdateFrpcHander))
frpcRouter.POST("/delete", common.Wrapper(client.RemoveFrpcHandler))
}
frpsRouter := v1.Group("/frps", middleware.JWTAuth, middleware.AuthCtx)
{
frpsRouter.POST("/update", common.Wrapper(server.UpdateFrpsHander))
frpsRouter.POST("/delete", common.Wrapper(server.RemoveFrpsHandler))
}
}
}

View File

@@ -0,0 +1,49 @@
package server
import (
"context"
"github.com/VaalaCat/frp-panel/common"
"github.com/VaalaCat/frp-panel/dao"
"github.com/VaalaCat/frp-panel/models"
"github.com/VaalaCat/frp-panel/pb"
"github.com/google/uuid"
)
func InitServerHandler(c context.Context, req *pb.InitServerRequest) (*pb.InitServerResponse, error) {
var (
userServerID = req.GetServerId()
serverIP = req.GetServerIp()
userInfo = common.GetUserInfo(c)
)
if !userInfo.Valid() {
return &pb.InitServerResponse{
Status: &pb.Status{Code: pb.RespCode_RESP_CODE_INVALID, Message: "invalid user"},
}, nil
}
if len(userServerID) == 0 || len(serverIP) == 0 {
return &pb.InitServerResponse{
Status: &pb.Status{Code: pb.RespCode_RESP_CODE_INVALID, Message: "request invalid"},
}, nil
}
globalServerID := common.GlobalClientID(userInfo.GetUserName(), userServerID)
if err := dao.CreateServer(userInfo,
&models.ServerEntity{
ServerID: globalServerID,
TenantID: userInfo.GetTenantID(),
UserID: userInfo.GetUserID(),
ConnectSecret: uuid.New().String(),
ServerIP: serverIP,
}); err != nil {
return nil, err
}
return &pb.InitServerResponse{
Status: &pb.Status{Code: pb.RespCode_RESP_CODE_SUCCESS, Message: "ok"},
ServerId: &globalServerID,
}, nil
}

View File

@@ -0,0 +1,36 @@
package server
import (
"context"
"github.com/VaalaCat/frp-panel/common"
"github.com/VaalaCat/frp-panel/dao"
"github.com/VaalaCat/frp-panel/pb"
)
func DeleteServerHandler(c context.Context, req *pb.DeleteServerRequest) (*pb.DeleteServerResponse, error) {
var (
userServerID = req.GetServerId()
userInfo = common.GetUserInfo(c)
)
if !userInfo.Valid() {
return &pb.DeleteServerResponse{
Status: &pb.Status{Code: pb.RespCode_RESP_CODE_INVALID, Message: "invalid user"},
}, nil
}
if len(userServerID) == 0 {
return &pb.DeleteServerResponse{
Status: &pb.Status{Code: pb.RespCode_RESP_CODE_INVALID, Message: "invalid client id"},
}, nil
}
if err := dao.DeleteServer(userInfo, userServerID); err != nil {
return nil, err
}
return &pb.DeleteServerResponse{
Status: &pb.Status{Code: pb.RespCode_RESP_CODE_SUCCESS, Message: "ok"},
}, nil
}

View File

@@ -0,0 +1,46 @@
package server
import (
"context"
"github.com/VaalaCat/frp-panel/common"
"github.com/VaalaCat/frp-panel/dao"
"github.com/VaalaCat/frp-panel/pb"
"github.com/VaalaCat/frp-panel/rpc"
"github.com/sirupsen/logrus"
)
func RemoveFrpsHandler(c context.Context, req *pb.RemoveFRPSRequest) (*pb.RemoveFRPSResponse, error) {
logrus.Infof("remove frps, req: [%+v]", req)
var (
serverID = req.GetServerId()
userInfo = common.GetUserInfo(c)
)
srv, err := dao.GetServerByServerID(userInfo, serverID)
if srv == nil || err != nil {
logrus.WithError(err).Errorf("cannot get server, id: [%s]", serverID)
return nil, err
}
if err = dao.DeleteServer(userInfo, serverID); err != nil {
logrus.WithError(err).Errorf("cannot delete server, id: [%s]", serverID)
return nil, err
}
go func() {
resp, err := rpc.CallClient(c, req.GetServerId(), pb.Event_EVENT_REMOVE_FRPS, req)
if err != nil {
logrus.WithError(err).Errorf("remove event send to server error, server id: [%s]", req.GetServerId())
}
if resp == nil {
logrus.Errorf("cannot get response, server id: [%s]", req.GetServerId())
}
}()
return &pb.RemoveFRPSResponse{
Status: &pb.Status{Code: pb.RespCode_RESP_CODE_SUCCESS, Message: "ok"},
}, nil
}

View File

@@ -0,0 +1,43 @@
package server
import (
"context"
"github.com/VaalaCat/frp-panel/common"
"github.com/VaalaCat/frp-panel/dao"
"github.com/VaalaCat/frp-panel/pb"
"github.com/samber/lo"
)
func GetServerHandler(c context.Context, req *pb.GetServerRequest) (*pb.GetServerResponse, error) {
var (
userServerID = req.GetServerId()
userInfo = common.GetUserInfo(c)
)
if !userInfo.Valid() {
return &pb.GetServerResponse{
Status: &pb.Status{Code: pb.RespCode_RESP_CODE_INVALID, Message: "invalid user"},
}, nil
}
if len(userServerID) == 0 {
return &pb.GetServerResponse{
Status: &pb.Status{Code: pb.RespCode_RESP_CODE_INVALID, Message: "invalid client id"},
}, nil
}
serverEntity, err := dao.GetServerByServerID(userInfo, userServerID)
if err != nil {
return nil, err
}
return &pb.GetServerResponse{
Status: &pb.Status{Code: pb.RespCode_RESP_CODE_SUCCESS, Message: "ok"},
Server: &pb.Server{
Id: lo.ToPtr(serverEntity.ServerID),
Config: lo.ToPtr(string(serverEntity.ConfigContent)),
Secret: lo.ToPtr(serverEntity.ConnectSecret),
},
}, nil
}

View File

@@ -0,0 +1,34 @@
package server
import (
"fmt"
"github.com/VaalaCat/frp-panel/dao"
"github.com/VaalaCat/frp-panel/models"
)
type ValidateableServerRequest interface {
GetServerSecret() string
GetServerId() string
}
func ValidateServerRequest(req ValidateableServerRequest) (*models.ServerEntity, error) {
if req == nil {
return nil, fmt.Errorf("invalid request")
}
if req.GetServerId() == "" || req.GetServerSecret() == "" {
return nil, fmt.Errorf("invalid request")
}
var (
cli *models.ServerEntity
err error
)
if cli, err = dao.ValidateServerSecret(req.GetServerId(), req.GetServerSecret()); err != nil {
return nil, err
}
return cli, nil
}

View File

@@ -0,0 +1,40 @@
package server
import (
"context"
"github.com/VaalaCat/frp-panel/common"
"github.com/VaalaCat/frp-panel/dao"
"github.com/VaalaCat/frp-panel/models"
"github.com/VaalaCat/frp-panel/pb"
"github.com/samber/lo"
)
func ListServersHandler(c context.Context, req *pb.ListServersRequest) (*pb.ListServersResponse, error) {
var (
userInfo = common.GetUserInfo(c)
page = int(req.GetPage())
pageSize = int(req.GetPageSize())
)
if !userInfo.Valid() {
return &pb.ListServersResponse{
Status: &pb.Status{Code: pb.RespCode_RESP_CODE_INVALID, Message: "invalid user"},
}, nil
}
servers, err := dao.ListServers(userInfo, page, pageSize)
if err != nil {
return nil, err
}
return &pb.ListServersResponse{
Status: &pb.Status{Code: pb.RespCode_RESP_CODE_SUCCESS, Message: "ok"},
Servers: lo.Map(servers, func(c *models.ServerEntity, _ int) *pb.Server {
return &pb.Server{
Id: lo.ToPtr(c.ServerID),
Config: lo.ToPtr(string(c.ConfigContent)),
}
}),
}, nil
}

View File

@@ -0,0 +1,31 @@
package server
import (
"context"
"github.com/VaalaCat/frp-panel/models"
"github.com/VaalaCat/frp-panel/pb"
"github.com/sirupsen/logrus"
)
func FRPAuth(ctx context.Context, req *pb.FRPAuthRequest) (*pb.FRPAuthResponse, error) {
logrus.Infof("frpc auth, req: [%+v]", req)
var (
err error
cli *models.ServerEntity
)
if cli, err = ValidateServerRequest(req.GetBase()); err != nil {
return &pb.FRPAuthResponse{
Status: &pb.Status{Code: pb.RespCode_RESP_CODE_INVALID, Message: err.Error()},
Ok: false,
}, err
}
logrus.Infof("frpc auth success, server: [%+v]", cli.ServerID)
return &pb.FRPAuthResponse{
Status: &pb.Status{Code: pb.RespCode_RESP_CODE_SUCCESS, Message: "ok"},
Ok: true,
}, nil
}

View File

@@ -0,0 +1,25 @@
package server
import (
"context"
"github.com/VaalaCat/frp-panel/models"
"github.com/VaalaCat/frp-panel/pb"
"github.com/samber/lo"
)
func RPCPullConfig(ctx context.Context, req *pb.PullServerConfigReq) (*pb.PullServerConfigResp, error) {
var cli *models.ServerEntity
var err error
if cli, err = ValidateServerRequest(req.GetBase()); err != nil {
return nil, err
}
return &pb.PullServerConfigResp{
Server: &pb.Server{
Id: lo.ToPtr(cli.ServerID),
Config: lo.ToPtr(string(cli.ConfigContent)),
},
}, nil
}

View File

@@ -0,0 +1,63 @@
package server
import (
"context"
"fmt"
"github.com/VaalaCat/frp-panel/common"
"github.com/VaalaCat/frp-panel/dao"
"github.com/VaalaCat/frp-panel/pb"
"github.com/VaalaCat/frp-panel/rpc"
"github.com/VaalaCat/frp-panel/utils"
"github.com/sirupsen/logrus"
)
func UpdateFrpsHander(c context.Context, req *pb.UpdateFRPSRequest) (*pb.UpdateFRPSResponse, error) {
logrus.Infof("update frps, req: [%+v]", req)
var (
serverID = req.GetServerId()
configStr = req.GetConfig()
userInfo = common.GetUserInfo(c)
)
if len(configStr) == 0 || len(serverID) == 0 {
return nil, fmt.Errorf("request invalid")
}
srv, err := dao.GetServerByServerID(userInfo, serverID)
if srv == nil || err != nil {
logrus.WithError(err).Errorf("cannot get server, id: [%s]", serverID)
return nil, err
}
srvCfg, err := utils.LoadServerConfig(configStr, true)
if srvCfg == nil || err != nil {
logrus.WithError(err).Errorf("cannot load server config")
return nil, err
}
if err := srv.SetConfigContent(srvCfg); err != nil {
logrus.WithError(err).Errorf("cannot set server config")
return nil, err
}
if err := dao.UpdateServer(userInfo, srv); err != nil {
logrus.WithError(err).Errorf("cannot update server, id: [%s]", serverID)
return nil, err
}
go func() {
resp, err := rpc.CallClient(c, req.GetServerId(), pb.Event_EVENT_UPDATE_FRPS, req)
if err != nil {
logrus.WithError(err).Errorf("update event send to server error, server id: [%s]", req.GetServerId())
}
if resp == nil {
logrus.Errorf("cannot get response, server id: [%s]", req.GetServerId())
}
}()
logrus.Infof("update frps success, id: [%s]", serverID)
return &pb.UpdateFRPSResponse{
Status: &pb.Status{Code: pb.RespCode_RESP_CODE_SUCCESS, Message: "ok"},
}, nil
}

View File

@@ -0,0 +1,26 @@
package user
import (
"context"
"fmt"
"github.com/VaalaCat/frp-panel/common"
"github.com/VaalaCat/frp-panel/pb"
"github.com/samber/lo"
)
func GetUserInfoHandler(c context.Context, req *pb.GetUserInfoRequest) (*pb.GetUserInfoResponse, error) {
userInfo := common.GetUserInfo(c)
return &pb.GetUserInfoResponse{
Status: &pb.Status{Code: pb.RespCode_RESP_CODE_SUCCESS, Message: "ok"},
UserInfo: &pb.User{
UserID: lo.ToPtr(int64(userInfo.GetUserID())),
TenantID: lo.ToPtr(int64(userInfo.GetTenantID())),
UserName: lo.ToPtr(userInfo.GetUserName()),
Email: lo.ToPtr(userInfo.GetEmail()),
Status: lo.ToPtr(fmt.Sprint(userInfo.GetStatus())),
Role: lo.ToPtr(userInfo.GetRole()),
Token: lo.ToPtr(userInfo.GetToken()),
},
}, nil
}

View File

@@ -0,0 +1,70 @@
package user
import (
"context"
"github.com/VaalaCat/frp-panel/biz/master/client"
"github.com/VaalaCat/frp-panel/common"
"github.com/VaalaCat/frp-panel/dao"
"github.com/VaalaCat/frp-panel/models"
"github.com/VaalaCat/frp-panel/pb"
"github.com/VaalaCat/frp-panel/utils"
"github.com/sirupsen/logrus"
)
func UpdateUserInfoHander(c context.Context, req *pb.UpdateUserInfoRequest) (*pb.UpdateUserInfoResponse, error) {
var (
userInfo = common.GetUserInfo(c)
)
if !userInfo.Valid() {
return &pb.UpdateUserInfoResponse{
Status: &pb.Status{Code: pb.RespCode_RESP_CODE_INVALID, Message: "invalid user"},
}, nil
}
newUserEntity := userInfo.(*models.UserEntity)
newUserInfo := req.GetUserInfo()
if newUserInfo.GetEmail() != "" {
newUserEntity.Email = newUserInfo.GetEmail()
}
if newUserInfo.GetRawPassword() != "" {
hashedPassword, err := utils.HashPassword(newUserInfo.GetRawPassword())
if err != nil {
logrus.WithError(err).Errorf("cannot hash password")
return nil, err
}
newUserEntity.Password = hashedPassword
}
if newUserInfo.GetUserName() != "" {
newUserEntity.UserName = newUserInfo.GetUserName()
}
if newUserInfo.GetToken() != "" {
newUserEntity.Token = newUserInfo.GetToken()
}
if err := dao.UpdateUser(userInfo, newUserEntity); err != nil {
return &pb.UpdateUserInfoResponse{
Status: &pb.Status{Code: pb.RespCode_RESP_CODE_INVALID, Message: err.Error()},
}, err
}
go func() {
newUser, err := dao.GetUserByUserID(userInfo.GetUserID())
if err != nil {
logrus.WithError(err).Errorf("cannot get user")
return
}
if err := client.SyncTunnel(c, newUser); err != nil {
logrus.WithError(err).Errorf("cannot sync tunnel, user need to retry update")
}
}()
return &pb.UpdateUserInfoResponse{
Status: &pb.Status{Code: pb.RespCode_RESP_CODE_SUCCESS, Message: "ok"},
}, nil
}

View File

@@ -0,0 +1,91 @@
package server
import (
"net/http"
"github.com/VaalaCat/frp-panel/pb"
"github.com/VaalaCat/frp-panel/rpc"
plugin "github.com/fatedier/frp/pkg/plugin/server"
"github.com/gin-gonic/gin"
"github.com/sirupsen/logrus"
)
func NewRouter() *gin.Engine {
router := gin.Default()
router.POST("/auth", MakeGinHandlerFunc(HandleLogin))
return router
}
type Response struct {
Msg string `json:"msg"`
}
type HTTPError struct {
Code int
Err error
}
func (e *HTTPError) Error() string {
return e.Err.Error()
}
type HandlerFunc func(ctx *gin.Context) (interface{}, error)
func MakeGinHandlerFunc(handler HandlerFunc) gin.HandlerFunc {
return func(ctx *gin.Context) {
res, err := handler(ctx)
if err != nil {
logrus.Infof("handle %s error: %v", ctx.Request.URL.Path, err)
switch e := err.(type) {
case *HTTPError:
ctx.JSON(e.Code, &Response{Msg: e.Err.Error()})
default:
ctx.JSON(500, &Response{Msg: err.Error()})
}
return
}
ctx.JSON(http.StatusOK, res)
}
}
func HandleLogin(ctx *gin.Context) (interface{}, error) {
var r plugin.Request
var content plugin.LoginContent
r.Content = &content
if err := ctx.BindJSON(&r); err != nil {
return nil, &HTTPError{
Code: http.StatusBadRequest,
Err: err,
}
}
var res plugin.Response
token := content.Metas["token"]
if len(content.User) == 0 || len(token) == 0 {
res.Reject = true
res.RejectReason = "user or meta token can not be empty"
return res, nil
}
cli, err := rpc.MasterCli(ctx)
if err != nil {
res.Reject = true
res.RejectReason = "cannot connect to master, please check master is running"
return res, nil
}
authResponse, err := cli.FRPCAuth(ctx, &pb.FRPAuthRequest{User: content.User, Token: token})
if err != nil {
res.Reject = true
res.RejectReason = "invalid meta token"
return res, nil
}
if authResponse.GetOk() {
res.Unchange = true
return res, nil
}
res.Reject = true
res.RejectReason = "invalid meta token"
return res, nil
}

View File

@@ -0,0 +1,35 @@
package server
import (
"context"
"fmt"
"github.com/VaalaCat/frp-panel/pb"
"github.com/VaalaCat/frp-panel/tunnel"
"github.com/sirupsen/logrus"
)
func RemoveFrpsHandler(ctx context.Context, req *pb.RemoveFRPSRequest) (*pb.RemoveFRPSResponse, error) {
logrus.Infof("remove frps, req: [%+v]", req)
if req.GetServerId() == "" {
return &pb.RemoveFRPSResponse{
Status: &pb.Status{Code: pb.RespCode_RESP_CODE_INVALID, Message: "server id cannot be empty"},
}, fmt.Errorf("server id cannot be empty")
}
srv := tunnel.GetServerController().Get(req.GetServerId())
if srv == nil {
logrus.Infof("server not found, no need to remove")
return &pb.RemoveFRPSResponse{
Status: &pb.Status{Code: pb.RespCode_RESP_CODE_INVALID, Message: "server not found"},
}, nil
}
srv.Stop()
tunnel.GetServerController().Delete(req.GetServerId())
return &pb.RemoveFRPSResponse{
Status: &pb.Status{Code: pb.RespCode_RESP_CODE_SUCCESS, Message: "ok"},
}, nil
}

23
biz/server/rpc_handler.go Normal file
View File

@@ -0,0 +1,23 @@
package server
import (
"github.com/VaalaCat/frp-panel/common"
"github.com/VaalaCat/frp-panel/pb"
"github.com/sirupsen/logrus"
)
func HandleServerMessage(req *pb.ServerMessage) *pb.ClientMessage {
logrus.Infof("client get a server message, origin is: [%+v]", req)
switch req.Event {
case pb.Event_EVENT_UPDATE_FRPS:
return common.WrapperServerMsg(req, UpdateFrpsHander)
case pb.Event_EVENT_REMOVE_FRPS:
return common.WrapperServerMsg(req, RemoveFrpsHandler)
default:
}
return &pb.ClientMessage{
Event: pb.Event_EVENT_ERROR,
Data: []byte("unknown event"),
}
}

View File

@@ -0,0 +1,65 @@
package server
import (
"context"
"reflect"
"github.com/VaalaCat/frp-panel/pb"
"github.com/VaalaCat/frp-panel/rpc"
"github.com/VaalaCat/frp-panel/services/server"
"github.com/VaalaCat/frp-panel/tunnel"
"github.com/VaalaCat/frp-panel/utils"
"github.com/sirupsen/logrus"
)
func PullConfig(serverID, serverSecret string) error {
logrus.Infof("start to pull server config, serverID: [%s]", serverID)
ctx := context.Background()
cli, err := rpc.MasterCli(ctx)
if err != nil {
logrus.WithError(err).Error("cannot get master server")
return err
}
resp, err := cli.PullServerConfig(ctx, &pb.PullServerConfigReq{
Base: &pb.ServerBase{
ServerId: serverID,
ServerSecret: serverSecret,
},
})
if err != nil {
logrus.WithError(err).Error("cannot pull server config")
return err
}
if len(resp.GetServer().GetConfig()) == 0 {
logrus.Infof("server [%s] config is empty, wait for server init", serverID)
return nil
}
s, err := utils.LoadServerConfig([]byte(resp.GetServer().GetConfig()), true)
if err != nil {
logrus.WithError(err).Error("cannot load server config")
return err
}
ctrl := tunnel.GetServerController()
if t := ctrl.Get(serverID); t == nil {
ctrl.Add(serverID, server.NewServerHandler(s))
ctrl.Run(serverID)
} else {
if !reflect.DeepEqual(t.GetCommonCfg(), s) {
logrus.Infof("server %s config changed, will recreate it", serverID)
srv := ctrl.Get(serverID)
if srv != nil {
srv.Stop()
ctrl.Delete(serverID)
}
ctrl.Add(serverID, server.NewServerHandler(s))
ctrl.Run(serverID)
}
}
logrus.Infof("pull server config success, serverID: [%s]", serverID)
return nil
}

View File

@@ -0,0 +1,37 @@
package server
import (
"context"
"github.com/VaalaCat/frp-panel/pb"
"github.com/VaalaCat/frp-panel/services/server"
"github.com/VaalaCat/frp-panel/tunnel"
"github.com/VaalaCat/frp-panel/utils"
"github.com/sirupsen/logrus"
)
func UpdateFrpsHander(ctx context.Context, req *pb.UpdateFRPSRequest) (*pb.UpdateFRPSResponse, error) {
logrus.Infof("update frps, req: [%+v]", req)
content := req.GetConfig()
s, err := utils.LoadServerConfig(content, true)
if err != nil {
logrus.WithError(err).Errorf("cannot load config")
return &pb.UpdateFRPSResponse{
Status: &pb.Status{Code: pb.RespCode_RESP_CODE_INVALID, Message: err.Error()},
}, err
}
serverID := req.GetServerId()
if cli := tunnel.GetServerController().Get(serverID); cli != nil {
cli.Stop()
tunnel.GetClientController().Delete(serverID)
}
tunnel.GetServerController().Add(serverID, server.NewServerHandler(s))
tunnel.GetServerController().Run(serverID)
return &pb.UpdateFRPSResponse{
Status: &pb.Status{Code: pb.RespCode_RESP_CODE_SUCCESS, Message: "ok"},
}, nil
}

21
cache/freecache.go vendored Normal file
View File

@@ -0,0 +1,21 @@
package cache
import (
"github.com/VaalaCat/frp-panel/conf"
"github.com/coocood/freecache"
"github.com/sirupsen/logrus"
)
var (
cache *freecache.Cache
)
func InitCache() {
cacheSize := conf.Get().Master.CacheSize * 1024 * 1024 // 100 MB
cache = freecache.NewCache(cacheSize)
logrus.Infof("init cache success, size: %d MB", cacheSize/1024/1024)
}
func Get() *freecache.Cache {
return cache
}

47
cmd/client.go Normal file
View File

@@ -0,0 +1,47 @@
package main
import (
bizclient "github.com/VaalaCat/frp-panel/biz/client"
"github.com/VaalaCat/frp-panel/pb"
"github.com/VaalaCat/frp-panel/services/rpcclient"
"github.com/VaalaCat/frp-panel/watcher"
"github.com/sirupsen/logrus"
"github.com/sourcegraph/conc"
)
func runClient(clientID, clientSecret string) {
logrus.Infof("start to run client")
if len(clientSecret) == 0 {
logrus.Fatal("client secret cannot be empty")
}
if len(clientID) == 0 {
logrus.Fatal("client id cannot be empty")
}
rpcclient.MustInitClientRPCSerivce(
clientID,
clientSecret,
pb.Event_EVENT_REGISTER_CLIENT,
bizclient.HandleServerMessage,
)
r := rpcclient.GetClientRPCSerivce()
defer r.Stop()
w := watcher.NewClient(bizclient.PullConfig, clientID, clientSecret)
defer w.Stop()
initClientOnce(clientID, clientSecret)
var wg conc.WaitGroup
wg.Go(r.Run)
wg.Go(w.Run)
wg.Wait()
}
func initClientOnce(clientID, clientSecret string) {
err := bizclient.PullConfig(clientID, clientSecret)
if err != nil {
logrus.WithError(err).Errorf("cannot pull client config, wait for retry")
}
}

61
cmd/cmd.go Normal file
View File

@@ -0,0 +1,61 @@
package main
import (
"fmt"
"os"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)
var (
clientSecret string
clientID string
clientCmd *cobra.Command
serverCmd *cobra.Command
masterCmd *cobra.Command
rootCmd *cobra.Command
)
func initCommand() {
hostname, err := os.Hostname()
if err != nil {
fmt.Println(err)
os.Exit(1)
}
clientCmd = &cobra.Command{
Use: "client [-s client secret] [-i client id]",
Short: "run managed frpc",
Run: func(cmd *cobra.Command, args []string) {
runClient(clientID, clientSecret)
},
}
serverCmd = &cobra.Command{
Use: "server [-s client secret] [-i client id]",
Short: "run managed frps",
Run: func(cmd *cobra.Command, args []string) {
runServer(clientID, clientSecret)
},
}
masterCmd = &cobra.Command{
Use: "master",
Short: "run frp-panel manager",
Run: func(cmd *cobra.Command, args []string) {
runMaster()
},
}
rootCmd = &cobra.Command{
Use: "frp-panel",
Short: "frp-panel is a frp panel QwQ",
}
rootCmd.AddCommand(clientCmd, serverCmd, masterCmd)
clientCmd.Flags().StringVarP(&clientSecret, "secret", "s", "", "client secret")
serverCmd.Flags().StringVarP(&clientSecret, "secret", "s", "", "client secret")
clientCmd.Flags().StringVarP(&clientID, "id", "i", hostname, "client id")
serverCmd.Flags().StringVarP(&clientID, "id", "i", hostname, "client id")
}
func initLogger() {
logrus.SetReportCaller(true)
}

18
cmd/main.go Normal file
View File

@@ -0,0 +1,18 @@
package main
import (
"github.com/VaalaCat/frp-panel/conf"
"github.com/VaalaCat/frp-panel/rpc"
"github.com/VaalaCat/frp-panel/utils"
"github.com/fatedier/golib/crypto"
)
func main() {
initLogger()
initCommand()
conf.InitConfig()
rpc.InitRPCClients()
crypto.DefaultSalt = utils.MD5(conf.Get().App.GlobalSecret)
rootCmd.Execute()
}

64
cmd/master.go Normal file
View File

@@ -0,0 +1,64 @@
package main
import (
bizmaster "github.com/VaalaCat/frp-panel/biz/master"
"github.com/VaalaCat/frp-panel/biz/master/auth"
"github.com/VaalaCat/frp-panel/cache"
"github.com/VaalaCat/frp-panel/conf"
"github.com/VaalaCat/frp-panel/models"
"github.com/VaalaCat/frp-panel/services/api"
"github.com/VaalaCat/frp-panel/services/master"
"github.com/VaalaCat/frp-panel/services/server"
"github.com/VaalaCat/frp-panel/utils"
v1 "github.com/fatedier/frp/pkg/config/v1"
"github.com/glebarez/sqlite"
"github.com/sirupsen/logrus"
"github.com/sourcegraph/conc"
"gorm.io/gorm"
)
func runMaster() {
master.MustInitMasterService()
router := bizmaster.NewRouter()
api.MustInitApiService(conf.MasterAPIListenAddr(), router)
initDatabase()
cache.InitCache()
auth.InitAuth()
logrus.Infof("start to run master")
m := master.GetMasterSerivce()
opt := utils.NewBaseFRPServerUserAuthConfig(
conf.Get().Master.InternalFRPServerPort,
[]v1.HTTPPluginOptions{conf.FRPsAuthOption()},
)
s := server.GetServerSerivce(opt)
a := api.GetAPIService()
var wg conc.WaitGroup
wg.Go(s.Run)
wg.Go(m.Run)
wg.Go(a.Run)
wg.Wait()
}
func initDatabase() {
logrus.Infof("start to init database, type: %s", conf.Get().DB.Type)
models.MustInitDBManager(nil, conf.Get().DB.Type)
switch conf.Get().DB.Type {
case "sqlite3":
if sqlitedb, err := gorm.Open(sqlite.Open(conf.Get().DB.DSN), &gorm.Config{}); err != nil {
logrus.Panic(err)
} else {
models.GetDBManager().SetDB("sqlite3", sqlitedb)
logrus.Infof("init database success, data location: [%s]", conf.Get().DB.DSN)
}
default:
logrus.Panicf("currently unsupported database type: %s", conf.Get().DB.Type)
}
models.GetDBManager().Init()
}

54
cmd/server.go Normal file
View File

@@ -0,0 +1,54 @@
package main
import (
bizserver "github.com/VaalaCat/frp-panel/biz/server"
"github.com/VaalaCat/frp-panel/conf"
"github.com/VaalaCat/frp-panel/pb"
"github.com/VaalaCat/frp-panel/services/api"
"github.com/VaalaCat/frp-panel/services/rpcclient"
"github.com/VaalaCat/frp-panel/watcher"
"github.com/sirupsen/logrus"
"github.com/sourcegraph/conc"
)
func runServer(clientID, clientSecret string) {
logrus.Infof("start to run server")
if len(clientID) == 0 {
logrus.Fatal("client id cannot be empty")
}
router := bizserver.NewRouter()
api.MustInitApiService(conf.ServerAPIListenAddr(), router)
a := api.GetAPIService()
defer a.Stop()
rpcclient.MustInitClientRPCSerivce(
clientID,
clientSecret,
pb.Event_EVENT_REGISTER_SERVER,
bizserver.HandleServerMessage,
)
r := rpcclient.GetClientRPCSerivce()
defer r.Stop()
w := watcher.NewClient(bizserver.PullConfig, clientID, clientSecret)
defer w.Stop()
initServerOnce(clientID, clientSecret)
var wg conc.WaitGroup
wg.Go(r.Run)
wg.Go(w.Run)
wg.Go(a.Run)
wg.Wait()
}
func initServerOnce(clientID, clientSecret string) {
err := bizserver.PullConfig(clientID, clientSecret)
if err != nil {
logrus.WithError(err).Errorf("cannot pull server config, wait for retry")
}
}

20
cmd/test.go Normal file
View File

@@ -0,0 +1,20 @@
package main
// func serverThings() {
// time.Sleep(5 * time.Second)
// p := pool.New().WithMaxGoroutines(500)
// for i := 0; i < 100000; i++ {
// cnt := i
// p.Go(func() {
// resp := rpc.CallClient(context.Background(), "test", &pb.ServerMessage{
// Event: pb.Event_EVENT_DATA,
// Data: []byte(fmt.Sprint(cnt)),
// })
// if string(resp.Data) != fmt.Sprint(cnt) {
// logrus.Panicf("resp: %+v", resp)
// }
// })
// }
// p.Wait()
// logrus.Infof("finish server things")
// }

4
codegen.sh Executable file
View File

@@ -0,0 +1,4 @@
#!/usr/bin/env /bin/bash
cd idl && protoc *.proto --go_out=. --go-grpc_out=. && cd ..
cd www && npx protoc --ts_out ./lib/pb -I ../idl --proto_path ../idl/common.proto ../idl/common.proto ../idl/api*.proto && cd ..

47
common/const.go Normal file
View File

@@ -0,0 +1,47 @@
package common
import "time"
const (
AuthorizationKey = "authorization"
SetAuthorizationKey = "x-set-authorization"
MsgKey = "msg"
UserIDKey = "x-vaala-userid"
EndpointKey = "endpoint"
IpAddrKey = "ipaddr"
HeaderKey = "header"
MethodKey = "method"
UAKey = "User-Agent"
ContentTypeKey = "Content-Type"
TraceIDKey = "TraceID"
TokenKey = "token"
FRPAuthTokenKey = "token"
ErrKey = "err"
UserInfoKey = "x-vaala-userinfo"
)
const (
ErrInvalidRequest = "invalid request"
ErrUserInfoNotValid = "user info not valid"
ErrInternalError = "internal error"
ErrParamNotValid = "param not valid"
ErrDB = "database error"
ErrNotFound = "data not found"
ErrCodeNotFound = "code not found"
ErrCodeAlreadyUsed = "code already used"
)
const (
ReqSuccess = "success"
)
const (
TimeLayout = time.RFC3339
)
const (
StatusPending = "pending"
StatusSuccess = "success"
StatusFailed = "failed"
StatusDone = "done"
)

21
common/context.go Normal file
View File

@@ -0,0 +1,21 @@
package common
import (
"context"
"github.com/VaalaCat/frp-panel/models"
)
func GetUserInfo(c context.Context) models.UserInfo {
val := c.Value(UserInfoKey)
if val == nil {
return nil
}
u, ok := val.(*models.UserEntity)
if !ok {
return nil
}
return u
}

64
common/helper.go Normal file
View File

@@ -0,0 +1,64 @@
package common
import (
"context"
"fmt"
"github.com/VaalaCat/frp-panel/pb"
"github.com/gin-gonic/gin"
"github.com/sirupsen/logrus"
"google.golang.org/protobuf/proto"
)
func GlobalClientID(username, clientID string) string {
return fmt.Sprintf("%s.%s", username, clientID)
}
func Wrapper[T CommonReq, U CommonResp](handler func(context.Context, *T) (*U, error)) func(c *gin.Context) {
return func(c *gin.Context) {
req, err := GetProtoRequest[T](c)
if err != nil {
ErrResp(c, &pb.CommonResponse{
Status: &pb.Status{Code: pb.RespCode_RESP_CODE_INVALID, Message: err.Error()},
}, err.Error())
return
}
resp, err := handler(c, req)
if err != nil {
ErrResp(c, resp, err.Error())
return
}
OKResp(c, resp)
}
}
func WrapperServerMsg[T CommonReq, U CommonResp](req *pb.ServerMessage, handler func(context.Context, *T) (*U, error)) *pb.ClientMessage {
r := new(T)
GetServerMessageRequest(req.GetData(), r, proto.Unmarshal)
if err := GetServerMessageRequest(req.GetData(), r, proto.Unmarshal); err != nil {
logrus.WithError(err).Errorf("cannot unmarshal")
return nil
}
ctx := context.Background()
resp, err := handler(ctx, r)
if err != nil {
logrus.WithError(err).Errorf("handler error")
return &pb.ClientMessage{
Event: pb.Event_EVENT_ERROR,
Data: []byte(err.Error()),
}
}
cliMsg, err := ProtoResp(resp)
if err != nil {
logrus.WithError(err).Errorf("cannot marshal")
return &pb.ClientMessage{
Event: pb.Event_EVENT_ERROR,
Data: []byte(err.Error()),
}
}
return cliMsg
}

84
common/request.go Normal file
View File

@@ -0,0 +1,84 @@
package common
import (
"fmt"
"github.com/VaalaCat/frp-panel/pb"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
"google.golang.org/protobuf/encoding/protojson"
"google.golang.org/protobuf/reflect/protoreflect"
)
type CommonReq interface {
pb.UpdateFRPCRequest | pb.RemoveFRPCRequest |
pb.UpdateFRPSRequest | pb.RemoveFRPSRequest |
pb.CommonResponse | pb.RegisterRequest | pb.LoginRequest |
pb.InitClientRequest | pb.ListClientsRequest | pb.GetClientRequest |
pb.DeleteClientRequest |
pb.InitServerRequest | pb.ListServersRequest | pb.GetServerRequest |
pb.DeleteServerRequest |
pb.GetUserInfoRequest | pb.UpdateUserInfoRequest
}
func GetProtoRequest[T CommonReq](c *gin.Context) (r *T, err error) {
r = new(T)
if c.ContentType() == "application/x-protobuf" {
err = c.Copy().ShouldBindWith(r, binding.ProtoBuf)
if err != nil {
return nil, err
}
} else {
b, err := c.Copy().GetRawData()
if err != nil {
return nil, err
}
err = GetServerMessageRequest(b, r, protojson.Unmarshal)
if err != nil {
return nil, err
}
}
return r, nil
}
func GetServerMessageRequest[T CommonReq](b []byte, r *T, trans func(b []byte, m protoreflect.ProtoMessage) error) (err error) {
switch ptr := any(r).(type) {
case *pb.CommonResponse:
return trans(b, ptr)
case *pb.UpdateFRPCRequest:
return trans(b, ptr)
case *pb.RemoveFRPCRequest:
return trans(b, ptr)
case *pb.UpdateFRPSRequest:
return trans(b, ptr)
case *pb.RemoveFRPSRequest:
return trans(b, ptr)
case *pb.RegisterRequest:
return trans(b, ptr)
case *pb.LoginRequest:
return trans(b, ptr)
case *pb.InitClientRequest:
return trans(b, ptr)
case *pb.ListClientsRequest:
return trans(b, ptr)
case *pb.GetClientRequest:
return trans(b, ptr)
case *pb.DeleteClientRequest:
return trans(b, ptr)
case *pb.InitServerRequest:
return trans(b, ptr)
case *pb.ListServersRequest:
return trans(b, ptr)
case *pb.GetServerRequest:
return trans(b, ptr)
case *pb.DeleteServerRequest:
return trans(b, ptr)
case *pb.GetUserInfoRequest:
return trans(b, ptr)
case *pb.UpdateUserInfoRequest:
return trans(b, ptr)
default:
}
return fmt.Errorf("cannot unmarshal unknown type: %T", r)
}

101
common/response.go Normal file
View File

@@ -0,0 +1,101 @@
package common
import (
"fmt"
"net/http"
"github.com/VaalaCat/frp-panel/pb"
"github.com/gin-gonic/gin"
"google.golang.org/protobuf/proto"
)
type CommonResp interface {
pb.UpdateFRPCResponse | pb.RemoveFRPCResponse |
pb.UpdateFRPSResponse | pb.RemoveFRPSResponse |
pb.CommonResponse | pb.RegisterResponse | pb.LoginResponse |
pb.InitClientResponse | pb.ListClientsResponse | pb.GetClientResponse |
pb.DeleteClientResponse |
pb.InitServerResponse | pb.ListServersResponse | pb.GetServerResponse |
pb.DeleteServerResponse |
pb.GetUserInfoResponse | pb.UpdateUserInfoResponse
}
func OKResp[T CommonResp](c *gin.Context, origin *T) {
c.Header(TraceIDKey, c.GetString(TraceIDKey))
if c.ContentType() == "application/x-protobuf" {
c.ProtoBuf(http.StatusOK, origin)
} else {
c.JSON(http.StatusOK, OK(ReqSuccess).WithBody(origin))
}
}
func ErrResp[T CommonResp](c *gin.Context, origin *T, err string) {
c.Header(TraceIDKey, c.GetString(TraceIDKey))
if c.ContentType() == "application/x-protobuf" {
c.ProtoBuf(http.StatusInternalServerError, origin)
} else {
c.JSON(http.StatusOK, Err(err).WithBody(origin))
}
}
func ErrUnAuthorized(c *gin.Context, err string) {
c.Header(TraceIDKey, c.GetString(TraceIDKey))
if c.ContentType() == "application/x-protobuf" {
c.ProtoBuf(http.StatusUnauthorized,
&pb.CommonResponse{Status: &pb.Status{Code: pb.RespCode_RESP_CODE_UNAUTHORIZED, Message: err}})
} else {
c.JSON(http.StatusOK, Err(err))
}
}
func ProtoResp[T CommonResp](origin *T) (*pb.ClientMessage, error) {
switch ptr := any(origin).(type) {
case *pb.CommonResponse:
rawData, err := proto.Marshal(ptr)
if err != nil {
return nil, err
}
return &pb.ClientMessage{
Event: pb.Event_EVENT_DATA,
Data: rawData,
}, nil
case *pb.UpdateFRPCResponse:
rawData, err := proto.Marshal(ptr)
if err != nil {
return nil, err
}
return &pb.ClientMessage{
Event: pb.Event_EVENT_UPDATE_FRPC,
Data: rawData,
}, nil
case *pb.RemoveFRPCResponse:
rawData, err := proto.Marshal(ptr)
if err != nil {
return nil, err
}
return &pb.ClientMessage{
Event: pb.Event_EVENT_REMOVE_FRPC,
Data: rawData,
}, nil
case *pb.UpdateFRPSResponse:
rawData, err := proto.Marshal(ptr)
if err != nil {
return nil, err
}
return &pb.ClientMessage{
Event: pb.Event_EVENT_UPDATE_FRPC,
Data: rawData,
}, nil
case *pb.RemoveFRPSResponse:
rawData, err := proto.Marshal(ptr)
if err != nil {
return nil, err
}
return &pb.ClientMessage{
Event: pb.Event_EVENT_REMOVE_FRPC,
Data: rawData,
}, nil
default:
}
return nil, fmt.Errorf("cannot unmarshal unknown type: %T", origin)
}

55
common/result.go Normal file
View File

@@ -0,0 +1,55 @@
package common
import (
"github.com/gin-gonic/gin"
)
type Result struct {
Code int `json:"code,omitempty"`
Msg string `json:"msg,omitempty"`
Data gin.H `json:"data,omitempty"`
Body interface{} `json:"body,omitempty"`
}
func (r *Result) WithMsg(message string) *Result {
r.Msg = message
return r
}
func (r *Result) WithData(data gin.H) *Result {
r.Data = data
return r
}
func (r *Result) WithKeyValue(key string, value interface{}) *Result {
if r.Data == nil {
r.Data = gin.H{}
}
r.Data[key] = value
return r
}
func (r *Result) WithBody(body interface{}) *Result {
r.Body = body
return r
}
func newResult(code int, msg string) *Result {
return &Result{
Code: code,
Msg: msg,
Data: nil,
}
}
func OK(msg string) *Result {
return newResult(200, msg)
}
func Err(msg string) *Result {
return newResult(500, msg)
}
func UnAuth(msg string) *Result {
return newResult(401, msg)
}

77
conf/helper.go Normal file
View File

@@ -0,0 +1,77 @@
package conf
import (
"fmt"
"net/url"
"time"
"github.com/VaalaCat/frp-panel/common"
"github.com/VaalaCat/frp-panel/utils"
v1 "github.com/fatedier/frp/pkg/config/v1"
"github.com/sirupsen/logrus"
)
func RPCListenAddr() string {
cfg := Get()
return fmt.Sprintf(":%d", cfg.Master.RPCPort)
}
func RPCCallAddr() string {
cfg := Get()
return fmt.Sprintf("%s:%d", cfg.Master.RPCHost, cfg.Master.RPCPort)
}
func InternalFRPServerToken() string {
cfg := Get()
return utils.MD5(fmt.Sprintf("%s:%d:%s",
cfg.Master.InternalFRPServerHost,
cfg.Master.InternalFRPServerPort,
cfg.App.GlobalSecret))
}
func JWTSecret() string {
cfg := Get()
return utils.SHA1(fmt.Sprintf("%s:%d:%s", cfg.Master.APIHost, cfg.Master.APIPort, cfg.App.GlobalSecret))
}
func MasterAPIListenAddr() string {
cfg := Get()
return fmt.Sprintf(":%d", cfg.Master.APIPort)
}
func ServerAPIListenAddr() string {
cfg := Get()
return fmt.Sprintf(":%d", cfg.Server.APIPort)
}
func FRPsAuthOption() v1.HTTPPluginOptions {
cfg := Get()
authUrl, err := url.Parse(fmt.Sprintf("http://%s:%d%s", cfg.Master.InternalFRPAuthServerHost,
cfg.Master.InternalFRPAuthServerPort,
cfg.Master.InternalFRPAuthServerPath))
if err != nil {
logrus.WithError(err).Fatalf("parse auth url error")
}
return v1.HTTPPluginOptions{
Name: "multiuser",
Ops: []string{"Login"},
Addr: authUrl.Host,
Path: authUrl.Path,
}
}
func GetCommonJWT(uid string) string {
token, _ := utils.GetJwtTokenFromMap(JWTSecret(),
time.Now().Unix(),
int64(Get().App.CookieAge),
map[string]string{common.UserIDKey: uid})
return token
}
func GetCommonJWTWithExpireTime(uid string, expSec int) string {
token, _ := utils.GetJwtTokenFromMap(JWTSecret(),
time.Now().Unix(),
int64(expSec),
map[string]string{common.UserIDKey: uid})
return token
}

74
conf/settings.go Normal file
View File

@@ -0,0 +1,74 @@
package conf
import (
"github.com/ilyakaznacheev/cleanenv"
"github.com/joho/godotenv"
"github.com/sirupsen/logrus"
)
type Config struct {
App struct {
GlobalSecret string `env:"GLOBAL_SECRET" env-required:"true" env-description:"global secret, used in manager gen secret, keep it safe"`
CookieAge int `env:"COOKIE_AGE" env-default:"86400" env-description:"cookie age in second, default is 1 day"`
CookieName string `env:"COOKIE_NAME" env-default:"frp-panel-cookie" env-description:"cookie name"`
CookiePath string `env:"COOKIE_PATH" env-default:"/" env-description:"cookie path"`
CookieDomain string `env:"COOKIE_DOMAIN" env-default:"" env-description:"cookie domain"`
CookieSecure bool `env:"COOKIE_SECURE" env-default:"false" env-description:"cookie secure"`
CookieHTTPOnly bool `env:"COOKIE_HTTP_ONLY" env-default:"true" env-description:"cookie http only"`
} `env-prefix:"APP_"`
Master struct {
APIPort int `env:"API_PORT" env-default:"9000" env-description:"master api port"`
APIHost string `env:"API_HOST" env-description:"master host, can behind proxy like cdn"`
CacheSize int `env:"CACHE_SIZE" env-default:"100" env-description:"cache size in MB"`
RPCHost string `env:"RPC_HOST" env-required:"true" env-description:"master host, is a public ip or domain"`
RPCPort int `env:"RPC_PORT" env-default:"9001" env-description:"master rpc port"`
InternalFRPServerHost string `env:"INTERNAL_FRP_SERVER_HOST" env-description:"internal frp server host, used for client connection"`
InternalFRPServerPort int `env:"INTERNAL_FRP_SERVER_PORT" env-default:"9002" env-description:"internal frp server port, used for client connection"`
InternalFRPAuthServerHost string `env:"INTERNAL_FRP_AUTH_SERVER_HOST" env-default:"127.0.0.1" env-description:"internal frp auth server host"`
InternalFRPAuthServerPort int `env:"INTERNAL_FRP_AUTH_SERVER_PORT" env-default:"9000" env-description:"internal frp auth server port"`
InternalFRPAuthServerPath string `env:"INTERNAL_FRP_AUTH_SERVER_PATH" env-default:"/auth" env-description:"internal frp auth server path"`
} `env-prefix:"MASTER_"`
Server struct {
APIPort int `env:"API_PORT" env-default:"8999" env-description:"server api port"`
} `env-prefix:"SERVER_"`
DB struct {
Type string `env:"TYPE" env-default:"sqlite3" env-description:"db type, mysql or sqlite3 and so on"`
DSN string `env:"DSN" env-default:"data.db" env-description:"db dsn, for sqlite is path, other is dsn, look at https://github.com/go-sql-driver/mysql#dsn-data-source-name"`
} `env-prefix:"DB_"`
}
var (
config *Config
)
func Get() *Config {
return config
}
func InitConfig() {
var (
err error
)
if err = godotenv.Load(); err != nil {
logrus.Infof("Error loading .env file, will use runtime env")
}
cfg := Config{}
if err = cleanenv.ReadEnv(&cfg); err != nil {
logrus.Panic(err)
}
cfg.Complete()
config = &cfg
}
func (cfg *Config) Complete() {
if len(cfg.Master.InternalFRPServerHost) == 0 {
cfg.Master.InternalFRPServerHost = cfg.Master.RPCHost
}
if len(cfg.Master.APIHost) == 0 {
cfg.Master.APIHost = cfg.Master.RPCHost
}
}

147
dao/client.go Normal file
View File

@@ -0,0 +1,147 @@
package dao
import (
"fmt"
"github.com/VaalaCat/frp-panel/models"
"github.com/samber/lo"
)
func ValidateClientSecret(clientID, clientSecret string) (*models.ClientEntity, error) {
if clientID == "" || clientSecret == "" {
return nil, fmt.Errorf("invalid client id or client secret")
}
db := models.GetDBManager().GetDefaultDB()
c := &models.Client{}
err := db.
Where(&models.Client{ClientEntity: &models.ClientEntity{
ClientID: clientID,
}}).
First(c).Error
if err != nil {
return nil, err
}
if c.ConnectSecret != clientSecret {
return nil, fmt.Errorf("invalid client secret")
}
return c.ClientEntity, nil
}
func AdminGetClientByClientID(clientID string) (*models.ClientEntity, error) {
if clientID == "" {
return nil, fmt.Errorf("invalid client id")
}
db := models.GetDBManager().GetDefaultDB()
c := &models.Client{}
err := db.
Where(&models.Client{ClientEntity: &models.ClientEntity{
ClientID: clientID,
}}).
First(c).Error
if err != nil {
return nil, err
}
return c.ClientEntity, nil
}
func GetClientByClientID(userInfo models.UserInfo, clientID string) (*models.ClientEntity, error) {
if clientID == "" {
return nil, fmt.Errorf("invalid client id")
}
db := models.GetDBManager().GetDefaultDB()
c := &models.Client{}
err := db.
Where(&models.Client{ClientEntity: &models.ClientEntity{
UserID: userInfo.GetUserID(),
TenantID: userInfo.GetTenantID(),
ClientID: clientID,
}}).
First(c).Error
if err != nil {
return nil, err
}
return c.ClientEntity, nil
}
func CreateClient(userInfo models.UserInfo, client *models.ClientEntity) error {
client.UserID = userInfo.GetUserID()
client.TenantID = userInfo.GetTenantID()
c := &models.Client{
ClientEntity: client,
}
db := models.GetDBManager().GetDefaultDB()
return db.Create(c).Error
}
func DeleteClient(userInfo models.UserInfo, clientID string) error {
if clientID == "" {
return fmt.Errorf("invalid client id")
}
db := models.GetDBManager().GetDefaultDB()
return db.Unscoped().Where(&models.Client{
ClientEntity: &models.ClientEntity{
ClientID: clientID,
UserID: userInfo.GetUserID(),
TenantID: userInfo.GetTenantID(),
},
}).Delete(&models.Client{
ClientEntity: &models.ClientEntity{
ClientID: clientID,
},
}).Error
}
func UpdateClient(userInfo models.UserInfo, client *models.ClientEntity) error {
c := &models.Client{
ClientEntity: client,
}
db := models.GetDBManager().GetDefaultDB()
return db.Where(&models.Client{
ClientEntity: &models.ClientEntity{
UserID: userInfo.GetUserID(),
TenantID: userInfo.GetTenantID(),
},
}).Save(c).Error
}
func ListClients(userInfo models.UserInfo, page, pageSize int) ([]*models.ClientEntity, error) {
if page < 1 || pageSize < 1 {
return nil, fmt.Errorf("invalid page or page size")
}
db := models.GetDBManager().GetDefaultDB()
offset := (page - 1) * pageSize
var clients []*models.Client
err := db.Where(&models.Client{
ClientEntity: &models.ClientEntity{
UserID: userInfo.GetUserID(),
TenantID: userInfo.GetTenantID(),
},
}).Offset(offset).Limit(pageSize).Find(&clients).Error
if err != nil {
return nil, err
}
return lo.Map(clients, func(c *models.Client, _ int) *models.ClientEntity {
return c.ClientEntity
}), nil
}
func GetAllClients(userInfo models.UserInfo) ([]*models.ClientEntity, error) {
db := models.GetDBManager().GetDefaultDB()
var clients []*models.Client
err := db.Where(&models.Client{
ClientEntity: &models.ClientEntity{
UserID: userInfo.GetUserID(),
TenantID: userInfo.GetTenantID(),
},
}).Find(&clients).Error
if err != nil {
return nil, err
}
return lo.Map(clients, func(c *models.Client, _ int) *models.ClientEntity {
return c.ClientEntity
}), nil
}

134
dao/server.go Normal file
View File

@@ -0,0 +1,134 @@
package dao
import (
"fmt"
"github.com/VaalaCat/frp-panel/models"
"github.com/samber/lo"
)
func ValidateServerSecret(serverID string, secret string) (*models.ServerEntity, error) {
if serverID == "" || secret == "" {
return nil, fmt.Errorf("invalid request")
}
db := models.GetDBManager().GetDefaultDB()
c := &models.Server{}
err := db.
Where(&models.Server{ServerEntity: &models.ServerEntity{
ServerID: serverID,
}}).
First(c).Error
if err != nil {
return nil, err
}
if c.ConnectSecret != secret {
return nil, fmt.Errorf("invalid secret")
}
return c.ServerEntity, nil
}
func AdminGetServerByServerID(serverID string) (*models.ServerEntity, error) {
if serverID == "" {
return nil, fmt.Errorf("invalid server id")
}
db := models.GetDBManager().GetDefaultDB()
c := &models.Server{}
err := db.
Where(&models.Server{ServerEntity: &models.ServerEntity{
ServerID: serverID,
}}).
First(c).Error
if err != nil {
return nil, err
}
return c.ServerEntity, nil
}
func GetServerByServerID(userInfo models.UserInfo, serverID string) (*models.ServerEntity, error) {
if serverID == "" {
return nil, fmt.Errorf("invalid server id")
}
db := models.GetDBManager().GetDefaultDB()
c := &models.Server{}
err := db.
Where(&models.Server{ServerEntity: &models.ServerEntity{
TenantID: userInfo.GetTenantID(),
UserID: userInfo.GetUserID(),
ServerID: serverID,
}}).
First(c).Error
if err != nil {
return nil, err
}
return c.ServerEntity, nil
}
func CreateServer(userInfo models.UserInfo, server *models.ServerEntity) error {
server.UserID = userInfo.GetUserID()
server.TenantID = userInfo.GetTenantID()
c := &models.Server{
ServerEntity: server,
}
db := models.GetDBManager().GetDefaultDB()
return db.Create(c).Error
}
func DeleteServer(userInfo models.UserInfo, serverID string) error {
if serverID == "" {
return fmt.Errorf("invalid server id")
}
db := models.GetDBManager().GetDefaultDB()
return db.Unscoped().Where(
&models.Server{
ServerEntity: &models.ServerEntity{
TenantID: userInfo.GetTenantID(),
UserID: userInfo.GetUserID(),
},
},
).Delete(&models.Server{
ServerEntity: &models.ServerEntity{
ServerID: serverID,
},
}).Error
}
func UpdateServer(userInfo models.UserInfo, server *models.ServerEntity) error {
c := &models.Server{
ServerEntity: server,
}
db := models.GetDBManager().GetDefaultDB()
return db.Where(
&models.Server{
ServerEntity: &models.ServerEntity{
UserID: userInfo.GetUserID(),
TenantID: userInfo.GetTenantID(),
},
},
).Save(c).Error
}
func ListServers(userInfo models.UserInfo, page, pageSize int) ([]*models.ServerEntity, error) {
if page < 1 || pageSize < 1 {
return nil, fmt.Errorf("invalid page or page size")
}
db := models.GetDBManager().GetDefaultDB()
offset := (page - 1) * pageSize
var servers []*models.Server
err := db.Where(
&models.Server{
ServerEntity: &models.ServerEntity{
UserID: userInfo.GetUserID(),
TenantID: userInfo.GetTenantID(),
},
},
).Offset(offset).Limit(pageSize).Find(&servers).Error
if err != nil {
return nil, err
}
return lo.Map(servers, func(c *models.Server, _ int) *models.ServerEntity {
return c.ServerEntity
}), nil
}

114
dao/user.go Normal file
View File

@@ -0,0 +1,114 @@
package dao
import (
"fmt"
"github.com/VaalaCat/frp-panel/models"
"github.com/VaalaCat/frp-panel/utils"
"github.com/samber/lo"
)
func AdminGetAllUsers() ([]*models.UserEntity, error) {
db := models.GetDBManager().GetDefaultDB()
users := make([]*models.User, 0)
err := db.Find(&users).Error
if err != nil {
return nil, err
}
return lo.Map(users,
func(u *models.User, _ int) *models.UserEntity {
return u.UserEntity
}), nil
}
func GetUserByUserID(userID int) (*models.UserEntity, error) {
if userID == 0 {
return nil, fmt.Errorf("invalid user id")
}
db := models.GetDBManager().GetDefaultDB()
u := &models.User{}
err := db.Where(&models.User{
UserEntity: &models.UserEntity{
UserID: userID,
},
}).First(u).Error
if err != nil {
return nil, err
}
return u.UserEntity, nil
}
func UpdateUser(userInfo models.UserInfo, user *models.UserEntity) error {
db := models.GetDBManager().GetDefaultDB()
user.UserID = userInfo.GetUserID()
return db.Model(&models.User{}).Where(
&models.User{
UserEntity: &models.UserEntity{
UserID: userInfo.GetUserID(),
},
},
).Save(&models.User{
UserEntity: user,
}).Error
}
func GetUserByUserName(userName string) (*models.UserEntity, error) {
if userName == "" {
return nil, fmt.Errorf("invalid user name")
}
db := models.GetDBManager().GetDefaultDB()
u := &models.User{}
err := db.Where(&models.User{
UserEntity: &models.UserEntity{
UserName: userName,
},
}).First(u).Error
if err != nil {
return nil, err
}
return u.UserEntity, nil
}
func CheckUserPassword(userNameOrEmail, password string) (bool, models.UserInfo, error) {
var user models.User
db := models.GetDBManager().GetDefaultDB()
if err := db.Where(&models.User{
UserEntity: &models.UserEntity{
UserName: userNameOrEmail,
},
}).Or(&models.User{
UserEntity: &models.UserEntity{
Email: userNameOrEmail,
},
}).First(&user).Error; err != nil {
return false, nil, err
}
return utils.CheckPasswordHash(password, user.Password), user, nil
}
func CheckUserNameAndEmail(userName, email string) error {
var user models.User
db := models.GetDBManager().GetDefaultDB()
if err := db.Where(&models.User{
UserEntity: &models.UserEntity{
UserName: userName,
},
}).Or(&models.User{
UserEntity: &models.UserEntity{
Email: email,
},
}).First(&user).Error; err != nil {
return err
}
return nil
}
func CreateUser(user *models.UserEntity) error {
u := &models.User{
UserEntity: user,
}
db := models.GetDBManager().GetDefaultDB()
return db.Create(u).Error
}

309
doc/callvis.gv Executable file
View File

@@ -0,0 +1,309 @@
digraph gocallvis {
label="github.com/VaalaCat/frp-panel/cmd";
labeljust="l";
fontname="Arial";
fontsize="14";
rankdir="LR";
bgcolor="lightgray";
style="solid";
penwidth="0.5";
pad="0.0";
nodesep="0.35";
node [shape="box" style="filled,rounded" fillcolor="honeydew" fontname="Verdana" penwidth="1.0" margin="0.05,0.0"];
edge [minlen="2"]
subgraph "cluster_focus" {
bgcolor="#e6ecfa";
label="main";
labelloc="t";
labeljust="c";
fontsize="18";
"github.com/VaalaCat/frp-panel/cmd.runClient" [ fillcolor="lightblue" label="runClient" penwidth="0.5" tooltip="github.com/VaalaCat/frp-panel/cmd.runClient | defined in client.go:12\nat client.go:31: calling [github.com/VaalaCat/frp-panel/watcher.NewClient]\nat client.go:34: calling [github.com/VaalaCat/frp-panel/cmd.initClientOnce]\nat client.go:28: calling [github.com/VaalaCat/frp-panel/services/rpcclient.GetClientRPCSerivce]\nat client.go:29: calling [(*github.com/VaalaCat/frp-panel/services/rpcclient.ClientRPC).Stop]\nat client.go:22: calling [github.com/VaalaCat/frp-panel/services/rpcclient.MustInitClientRPCSerivce]\nat client.go:32: calling [(*github.com/VaalaCat/frp-panel/watcher.client).Stop]" ]
"github.com/VaalaCat/frp-panel/cmd.initClientOnce" [ label="initClientOnce" penwidth="0.5" tooltip="github.com/VaalaCat/frp-panel/cmd.initClientOnce | defined in client.go:42\nat client.go:43: calling [github.com/VaalaCat/frp-panel/biz/client.PullConfig]" fillcolor="lightblue" ]
"github.com/VaalaCat/frp-panel/cmd.initCommand$1" [ fillcolor="lightblue" label="initCommand$1" style="dotted,filled" tooltip="github.com/VaalaCat/frp-panel/cmd.initCommand$1 | defined in cmd.go:30\nat cmd.go:31: calling [github.com/VaalaCat/frp-panel/cmd.runClient]" ]
"github.com/VaalaCat/frp-panel/cmd.runServer" [ penwidth="0.5" tooltip="github.com/VaalaCat/frp-panel/cmd.runServer | defined in server.go:14\nat server.go:38: calling [(*github.com/VaalaCat/frp-panel/watcher.client).Stop]\nat server.go:37: calling [github.com/VaalaCat/frp-panel/watcher.NewClient]\nat server.go:35: calling [(*github.com/VaalaCat/frp-panel/services/rpcclient.ClientRPC).Stop]\nat server.go:22: calling [github.com/VaalaCat/frp-panel/conf.ServerAPIListenAddr]\nat server.go:24: calling [github.com/VaalaCat/frp-panel/services/api.GetAPIService]\nat server.go:25: calling [(*github.com/VaalaCat/frp-panel/services/api.server).Stop]\nat server.go:21: calling [github.com/VaalaCat/frp-panel/biz/server.NewRouter]\nat server.go:22: calling [github.com/VaalaCat/frp-panel/services/api.MustInitApiService]\nat server.go:40: calling [github.com/VaalaCat/frp-panel/cmd.initServerOnce]\nat server.go:27: calling [github.com/VaalaCat/frp-panel/services/rpcclient.MustInitClientRPCSerivce]\nat server.go:34: calling [github.com/VaalaCat/frp-panel/services/rpcclient.GetClientRPCSerivce]" fillcolor="lightblue" label="runServer" ]
"github.com/VaalaCat/frp-panel/cmd.initServerOnce" [ fillcolor="lightblue" label="initServerOnce" penwidth="0.5" tooltip="github.com/VaalaCat/frp-panel/cmd.initServerOnce | defined in server.go:49\nat server.go:50: calling [github.com/VaalaCat/frp-panel/biz/server.PullConfig]" ]
"github.com/VaalaCat/frp-panel/cmd.initCommand$2" [ fillcolor="lightblue" label="initCommand$2" style="dotted,filled" tooltip="github.com/VaalaCat/frp-panel/cmd.initCommand$2 | defined in cmd.go:37\nat cmd.go:38: calling [github.com/VaalaCat/frp-panel/cmd.runServer]" ]
"github.com/VaalaCat/frp-panel/cmd.runMaster" [ tooltip="github.com/VaalaCat/frp-panel/cmd.runMaster | defined in master.go:20\nat master.go:34: calling [github.com/VaalaCat/frp-panel/conf.FRPsAuthOption]\nat master.go:28: calling [github.com/VaalaCat/frp-panel/biz/master/auth.InitAuth]\nat master.go:37: calling [github.com/VaalaCat/frp-panel/services/server.GetServerSerivce]\nat master.go:23: calling [github.com/VaalaCat/frp-panel/biz/master.NewRouter]\nat master.go:32: calling [github.com/VaalaCat/frp-panel/utils.NewBaseFRPServerUserAuthConfig]\nat master.go:21: calling [github.com/VaalaCat/frp-panel/services/master.MustInitMasterService]\nat master.go:24: calling [github.com/VaalaCat/frp-panel/services/api.MustInitApiService]\nat master.go:26: calling [github.com/VaalaCat/frp-panel/cmd.initDatabase]\nat master.go:33: calling [github.com/VaalaCat/frp-panel/conf.Get]\nat master.go:27: calling [github.com/VaalaCat/frp-panel/cache.InitCache]\nat master.go:24: calling [github.com/VaalaCat/frp-panel/conf.MasterAPIListenAddr]\nat master.go:31: calling [github.com/VaalaCat/frp-panel/services/master.GetMasterSerivce]\nat master.go:38: calling [github.com/VaalaCat/frp-panel/services/api.GetAPIService]" fillcolor="lightblue" label="runMaster" penwidth="0.5" ]
"github.com/VaalaCat/frp-panel/cmd.initDatabase" [ fillcolor="lightblue" label="initDatabase" penwidth="0.5" tooltip="github.com/VaalaCat/frp-panel/cmd.initDatabase | defined in master.go:47\nat master.go:48: calling [github.com/VaalaCat/frp-panel/conf.Get]\nat master.go:49: calling [github.com/VaalaCat/frp-panel/conf.Get]\nat master.go:51: calling [github.com/VaalaCat/frp-panel/conf.Get]\nat master.go:53: calling [github.com/VaalaCat/frp-panel/conf.Get]\nat master.go:60: calling [github.com/VaalaCat/frp-panel/conf.Get]\nat master.go:57: calling [github.com/VaalaCat/frp-panel/conf.Get]\nat master.go:63: calling [github.com/VaalaCat/frp-panel/models.GetDBManager]\nat master.go:56: calling [github.com/VaalaCat/frp-panel/models.GetDBManager]\nat master.go:49: calling [github.com/VaalaCat/frp-panel/models.MustInitDBManager]\nat master.go:56: calling [(*github.com/VaalaCat/frp-panel/models.dbManagerImpl).SetDB]\nat master.go:63: calling [(*github.com/VaalaCat/frp-panel/models.dbManagerImpl).Init]" ]
"github.com/VaalaCat/frp-panel/cmd.initCommand$3" [ style="dotted,filled" tooltip="github.com/VaalaCat/frp-panel/cmd.initCommand$3 | defined in cmd.go:44\nat cmd.go:45: calling [github.com/VaalaCat/frp-panel/cmd.runMaster]" fillcolor="lightblue" label="initCommand$3" ]
"github.com/VaalaCat/frp-panel/cmd.main" [ fillcolor="lightblue" label="main" penwidth="0.5" tooltip="github.com/VaalaCat/frp-panel/cmd.main | defined in main.go:10\nat main.go:16: calling [github.com/VaalaCat/frp-panel/utils.MD5]\nat main.go:13: calling [github.com/VaalaCat/frp-panel/conf.InitConfig]\nat main.go:14: calling [github.com/VaalaCat/frp-panel/rpc.InitRPCClients]\nat main.go:16: calling [github.com/VaalaCat/frp-panel/conf.Get]\nat main.go:12: calling [github.com/VaalaCat/frp-panel/cmd.initCommand]\nat main.go:11: calling [github.com/VaalaCat/frp-panel/cmd.initLogger]" ]
"github.com/VaalaCat/frp-panel/cmd.initLogger" [ fillcolor="lightblue" label="initLogger" penwidth="0.5" tooltip="github.com/VaalaCat/frp-panel/cmd.initLogger | defined in cmd.go:59" ]
"github.com/VaalaCat/frp-panel/cmd.initCommand" [ penwidth="0.5" tooltip="github.com/VaalaCat/frp-panel/cmd.initCommand | defined in cmd.go:20" fillcolor="lightblue" label="initCommand" ]
subgraph "cluster_github.com/VaalaCat/frp-panel/biz/client" {
fontsize="16";
URL="/?f=github.com/VaalaCat/frp-panel/biz/client";
fontname="Tahoma bold";
rank="sink";
label="client";
tooltip="package: github.com/VaalaCat/frp-panel/biz/client";
penwidth="0.8";
style="filled";
fillcolor="lightyellow";
"github.com/VaalaCat/frp-panel/biz/client.PullConfig" [ fillcolor="moccasin" label="PullConfig" penwidth="1.5" tooltip="github.com/VaalaCat/frp-panel/biz/client.PullConfig | defined in rpc_pull_config.go:15" ]
}
subgraph "cluster_github.com/VaalaCat/frp-panel/biz/master" {
penwidth="0.8";
style="filled";
rank="sink";
tooltip="package: github.com/VaalaCat/frp-panel/biz/master";
fontsize="16";
fillcolor="lightyellow";
fontname="Tahoma bold";
label="master";
URL="/?f=github.com/VaalaCat/frp-panel/biz/master";
"github.com/VaalaCat/frp-panel/biz/master.NewRouter" [ penwidth="1.5" tooltip="github.com/VaalaCat/frp-panel/biz/master.NewRouter | defined in handler.go:13" fillcolor="moccasin" label="NewRouter" ]
}
subgraph "cluster_github.com/VaalaCat/frp-panel/biz/master/auth" {
fillcolor="lightyellow";
label="auth";
URL="/?f=github.com/VaalaCat/frp-panel/biz/master/auth";
tooltip="package: github.com/VaalaCat/frp-panel/biz/master/auth";
penwidth="0.8";
style="filled";
fontname="Tahoma bold";
rank="sink";
fontsize="16";
"github.com/VaalaCat/frp-panel/biz/master/auth.InitAuth" [ label="InitAuth" penwidth="1.5" tooltip="github.com/VaalaCat/frp-panel/biz/master/auth.InitAuth | defined in init.go:11" fillcolor="moccasin" ]
}
subgraph "cluster_github.com/VaalaCat/frp-panel/biz/server" {
fillcolor="lightyellow";
fontname="Tahoma bold";
URL="/?f=github.com/VaalaCat/frp-panel/biz/server";
tooltip="package: github.com/VaalaCat/frp-panel/biz/server";
penwidth="0.8";
style="filled";
label="server";
fontsize="16";
rank="sink";
"github.com/VaalaCat/frp-panel/biz/server.NewRouter" [ fillcolor="moccasin" label="NewRouter" penwidth="1.5" tooltip="github.com/VaalaCat/frp-panel/biz/server.NewRouter | defined in auth_handler.go:13" ]
"github.com/VaalaCat/frp-panel/biz/server.PullConfig" [ tooltip="github.com/VaalaCat/frp-panel/biz/server.PullConfig | defined in rpc_pull_config.go:15" fillcolor="moccasin" label="PullConfig" penwidth="1.5" ]
}
subgraph "cluster_github.com/VaalaCat/frp-panel/cache" {
tooltip="package: github.com/VaalaCat/frp-panel/cache";
fontsize="16";
style="filled";
fillcolor="lightyellow";
rank="sink";
penwidth="0.8";
fontname="Tahoma bold";
label="cache";
URL="/?f=github.com/VaalaCat/frp-panel/cache";
"github.com/VaalaCat/frp-panel/cache.InitCache" [ label="InitCache" penwidth="1.5" tooltip="github.com/VaalaCat/frp-panel/cache.InitCache | defined in freecache.go:13" fillcolor="moccasin" ]
}
subgraph "cluster_github.com/VaalaCat/frp-panel/conf" {
URL="/?f=github.com/VaalaCat/frp-panel/conf";
tooltip="package: github.com/VaalaCat/frp-panel/conf";
style="filled";
rank="sink";
fillcolor="lightyellow";
fontname="Tahoma bold";
label="conf";
penwidth="0.8";
fontsize="16";
"github.com/VaalaCat/frp-panel/conf.ServerAPIListenAddr" [ label="ServerAPIListenAddr" penwidth="1.5" tooltip="github.com/VaalaCat/frp-panel/conf.ServerAPIListenAddr | defined in helper.go:42" fillcolor="moccasin" ]
"github.com/VaalaCat/frp-panel/conf.MasterAPIListenAddr" [ tooltip="github.com/VaalaCat/frp-panel/conf.MasterAPIListenAddr | defined in helper.go:37" fillcolor="moccasin" label="MasterAPIListenAddr" penwidth="1.5" ]
"github.com/VaalaCat/frp-panel/conf.Get" [ tooltip="github.com/VaalaCat/frp-panel/conf.Get | defined in settings.go:44" fillcolor="moccasin" label="Get" penwidth="1.5" ]
"github.com/VaalaCat/frp-panel/conf.FRPsAuthOption" [ fillcolor="moccasin" label="FRPsAuthOption" penwidth="1.5" tooltip="github.com/VaalaCat/frp-panel/conf.FRPsAuthOption | defined in helper.go:47" ]
"github.com/VaalaCat/frp-panel/conf.InitConfig" [ label="InitConfig" penwidth="1.5" tooltip="github.com/VaalaCat/frp-panel/conf.InitConfig | defined in settings.go:48" fillcolor="moccasin" ]
}
subgraph "cluster_github.com/VaalaCat/frp-panel/models" {
fontsize="16";
fillcolor="lightyellow";
label="models";
URL="/?f=github.com/VaalaCat/frp-panel/models";
tooltip="package: github.com/VaalaCat/frp-panel/models";
penwidth="0.8";
style="filled";
fontname="Tahoma bold";
rank="sink";
"github.com/VaalaCat/frp-panel/models.MustInitDBManager" [ fillcolor="moccasin" label="MustInitDBManager" penwidth="1.5" tooltip="github.com/VaalaCat/frp-panel/models.MustInitDBManager | defined in db.go:39" ]
"github.com/VaalaCat/frp-panel/models.GetDBManager" [ fillcolor="moccasin" label="GetDBManager" penwidth="1.5" tooltip="github.com/VaalaCat/frp-panel/models.GetDBManager | defined in db.go:55" ]
"(*github.com/VaalaCat/frp-panel/models.dbManagerImpl).Init" [ fillcolor="moccasin" label="(*dbManagerImpl).Init" penwidth="1.5" tooltip="(*github.com/VaalaCat/frp-panel/models.dbManagerImpl).Init | defined in db.go:21" ]
"(*github.com/VaalaCat/frp-panel/models.dbManagerImpl).SetDB" [ fillcolor="moccasin" label="(*dbManagerImpl).SetDB" penwidth="1.5" tooltip="(*github.com/VaalaCat/frp-panel/models.dbManagerImpl).SetDB | defined in db.go:66" ]
}
subgraph "cluster_github.com/VaalaCat/frp-panel/rpc" {
style="filled";
fontname="Tahoma bold";
tooltip="package: github.com/VaalaCat/frp-panel/rpc";
penwidth="0.8";
fillcolor="lightyellow";
rank="sink";
label="rpc";
URL="/?f=github.com/VaalaCat/frp-panel/rpc";
fontsize="16";
"github.com/VaalaCat/frp-panel/rpc.InitRPCClients" [ penwidth="1.5" tooltip="github.com/VaalaCat/frp-panel/rpc.InitRPCClients | defined in init.go:3" fillcolor="moccasin" label="InitRPCClients" ]
}
subgraph "cluster_github.com/VaalaCat/frp-panel/services/api" {
URL="/?f=github.com/VaalaCat/frp-panel/services/api";
penwidth="0.8";
fontsize="16";
rank="sink";
label="api";
style="filled";
fillcolor="lightyellow";
fontname="Tahoma bold";
tooltip="package: github.com/VaalaCat/frp-panel/services/api";
"github.com/VaalaCat/frp-panel/services/api.MustInitApiService" [ tooltip="github.com/VaalaCat/frp-panel/services/api.MustInitApiService | defined in service.go:29" fillcolor="moccasin" label="MustInitApiService" penwidth="1.5" ]
"github.com/VaalaCat/frp-panel/services/api.GetAPIService" [ fillcolor="moccasin" label="GetAPIService" penwidth="1.5" tooltip="github.com/VaalaCat/frp-panel/services/api.GetAPIService | defined in service.go:33" ]
"(*github.com/VaalaCat/frp-panel/services/api.server).Stop" [ tooltip="(*github.com/VaalaCat/frp-panel/services/api.server).Stop | defined in service.go:41" fillcolor="moccasin" label="(*server).Stop" penwidth="1.5" ]
}
subgraph "cluster_github.com/VaalaCat/frp-panel/services/master" {
style="filled";
fillcolor="lightyellow";
rank="sink";
label="master";
penwidth="0.8";
fontsize="16";
fontname="Tahoma bold";
URL="/?f=github.com/VaalaCat/frp-panel/services/master";
tooltip="package: github.com/VaalaCat/frp-panel/services/master";
"github.com/VaalaCat/frp-panel/services/master.MustInitMasterService" [ fillcolor="moccasin" label="MustInitMasterService" penwidth="1.5" tooltip="github.com/VaalaCat/frp-panel/services/master.MustInitMasterService | defined in grpc_service.go:21" ]
"github.com/VaalaCat/frp-panel/services/master.GetMasterSerivce" [ fillcolor="moccasin" label="GetMasterSerivce" penwidth="1.5" tooltip="github.com/VaalaCat/frp-panel/services/master.GetMasterSerivce | defined in grpc_service.go:29" ]
}
subgraph "cluster_github.com/VaalaCat/frp-panel/services/rpcclient" {
fontsize="16";
fontname="Tahoma bold";
URL="/?f=github.com/VaalaCat/frp-panel/services/rpcclient";
tooltip="package: github.com/VaalaCat/frp-panel/services/rpcclient";
penwidth="0.8";
fillcolor="lightyellow";
rank="sink";
label="rpcclient";
style="filled";
"github.com/VaalaCat/frp-panel/services/rpcclient.MustInitClientRPCSerivce" [ penwidth="1.5" tooltip="github.com/VaalaCat/frp-panel/services/rpcclient.MustInitClientRPCSerivce | defined in rpc_service.go:27" fillcolor="moccasin" label="MustInitClientRPCSerivce" ]
"github.com/VaalaCat/frp-panel/services/rpcclient.GetClientRPCSerivce" [ tooltip="github.com/VaalaCat/frp-panel/services/rpcclient.GetClientRPCSerivce | defined in rpc_service.go:35" fillcolor="moccasin" label="GetClientRPCSerivce" penwidth="1.5" ]
"(*github.com/VaalaCat/frp-panel/services/rpcclient.ClientRPC).Stop" [ fillcolor="moccasin" label="(*ClientRPC).Stop" penwidth="1.5" tooltip="(*github.com/VaalaCat/frp-panel/services/rpcclient.ClientRPC).Stop | defined in rpc_service.go:62" ]
}
subgraph "cluster_github.com/VaalaCat/frp-panel/services/server" {
tooltip="package: github.com/VaalaCat/frp-panel/services/server";
fontsize="16";
style="filled";
fontname="Tahoma bold";
label="server";
penwidth="0.8";
fillcolor="lightyellow";
rank="sink";
URL="/?f=github.com/VaalaCat/frp-panel/services/server";
"github.com/VaalaCat/frp-panel/services/server.GetServerSerivce" [ penwidth="1.5" tooltip="github.com/VaalaCat/frp-panel/services/server.GetServerSerivce | defined in frps_service.go:45" fillcolor="moccasin" label="GetServerSerivce" ]
}
subgraph "cluster_github.com/VaalaCat/frp-panel/utils" {
penwidth="0.8";
fontsize="16";
style="filled";
fillcolor="lightyellow";
URL="/?f=github.com/VaalaCat/frp-panel/utils";
fontname="Tahoma bold";
rank="sink";
label="utils";
tooltip="package: github.com/VaalaCat/frp-panel/utils";
"github.com/VaalaCat/frp-panel/utils.NewBaseFRPServerUserAuthConfig" [ penwidth="1.5" tooltip="github.com/VaalaCat/frp-panel/utils.NewBaseFRPServerUserAuthConfig | defined in frp_config.go:19" fillcolor="moccasin" label="NewBaseFRPServerUserAuthConfig" ]
"github.com/VaalaCat/frp-panel/utils.MD5" [ label="MD5" penwidth="1.5" tooltip="github.com/VaalaCat/frp-panel/utils.MD5 | defined in hash.go:12" fillcolor="moccasin" ]
}
subgraph "cluster_github.com/VaalaCat/frp-panel/watcher" {
style="filled";
fillcolor="lightyellow";
fontname="Tahoma bold";
rank="sink";
label="watcher";
penwidth="0.8";
URL="/?f=github.com/VaalaCat/frp-panel/watcher";
tooltip="package: github.com/VaalaCat/frp-panel/watcher";
fontsize="16";
"github.com/VaalaCat/frp-panel/watcher.NewClient" [ fillcolor="moccasin" label="NewClient" penwidth="1.5" tooltip="github.com/VaalaCat/frp-panel/watcher.NewClient | defined in client.go:17" ]
"(*github.com/VaalaCat/frp-panel/watcher.client).Stop" [ fillcolor="moccasin" label="(*client).Stop" penwidth="1.5" tooltip="(*github.com/VaalaCat/frp-panel/watcher.client).Stop | defined in client.go:40" ]
}
}
"github.com/VaalaCat/frp-panel/cmd.runClient" -> "github.com/VaalaCat/frp-panel/watcher.NewClient" [ color="saddlebrown" tooltip="at client.go:31: calling [github.com/VaalaCat/frp-panel/watcher.NewClient]" ]
"github.com/VaalaCat/frp-panel/cmd.initClientOnce" -> "github.com/VaalaCat/frp-panel/biz/client.PullConfig" [ color="saddlebrown" tooltip="at client.go:43: calling [github.com/VaalaCat/frp-panel/biz/client.PullConfig]" ]
"github.com/VaalaCat/frp-panel/cmd.runServer" -> "(*github.com/VaalaCat/frp-panel/watcher.client).Stop" [ color="saddlebrown" tooltip="at server.go:38: calling [(*github.com/VaalaCat/frp-panel/watcher.client).Stop]" style="dashed" arrowhead="normalnoneodiamond" ]
"github.com/VaalaCat/frp-panel/cmd.runMaster" -> "github.com/VaalaCat/frp-panel/conf.FRPsAuthOption" [ color="saddlebrown" tooltip="at master.go:34: calling [github.com/VaalaCat/frp-panel/conf.FRPsAuthOption]" ]
"github.com/VaalaCat/frp-panel/cmd.runClient" -> "github.com/VaalaCat/frp-panel/cmd.initClientOnce" [ tooltip="at client.go:34: calling [github.com/VaalaCat/frp-panel/cmd.initClientOnce]" ]
"github.com/VaalaCat/frp-panel/cmd.runServer" -> "github.com/VaalaCat/frp-panel/watcher.NewClient" [ color="saddlebrown" tooltip="at server.go:37: calling [github.com/VaalaCat/frp-panel/watcher.NewClient]" ]
"github.com/VaalaCat/frp-panel/cmd.initCommand$2" -> "github.com/VaalaCat/frp-panel/cmd.runServer" [ tooltip="at cmd.go:38: calling [github.com/VaalaCat/frp-panel/cmd.runServer]" ]
"github.com/VaalaCat/frp-panel/cmd.runMaster" -> "github.com/VaalaCat/frp-panel/biz/master/auth.InitAuth" [ color="saddlebrown" tooltip="at master.go:28: calling [github.com/VaalaCat/frp-panel/biz/master/auth.InitAuth]" ]
"github.com/VaalaCat/frp-panel/cmd.main" -> "github.com/VaalaCat/frp-panel/utils.MD5" [ color="saddlebrown" tooltip="at main.go:16: calling [github.com/VaalaCat/frp-panel/utils.MD5]" ]
"github.com/VaalaCat/frp-panel/cmd.runMaster" -> "github.com/VaalaCat/frp-panel/services/server.GetServerSerivce" [ color="saddlebrown" tooltip="at master.go:37: calling [github.com/VaalaCat/frp-panel/services/server.GetServerSerivce]" ]
"github.com/VaalaCat/frp-panel/cmd.main" -> "github.com/VaalaCat/frp-panel/conf.InitConfig" [ color="saddlebrown" tooltip="at main.go:13: calling [github.com/VaalaCat/frp-panel/conf.InitConfig]" ]
"github.com/VaalaCat/frp-panel/cmd.runClient" -> "github.com/VaalaCat/frp-panel/services/rpcclient.GetClientRPCSerivce" [ color="saddlebrown" tooltip="at client.go:28: calling [github.com/VaalaCat/frp-panel/services/rpcclient.GetClientRPCSerivce]" ]
"github.com/VaalaCat/frp-panel/cmd.runClient" -> "(*github.com/VaalaCat/frp-panel/services/rpcclient.ClientRPC).Stop" [ style="dashed" arrowhead="normalnoneodiamond" color="saddlebrown" tooltip="at client.go:29: calling [(*github.com/VaalaCat/frp-panel/services/rpcclient.ClientRPC).Stop]" ]
"github.com/VaalaCat/frp-panel/cmd.runServer" -> "(*github.com/VaalaCat/frp-panel/services/rpcclient.ClientRPC).Stop" [ style="dashed" arrowhead="normalnoneodiamond" color="saddlebrown" tooltip="at server.go:35: calling [(*github.com/VaalaCat/frp-panel/services/rpcclient.ClientRPC).Stop]" ]
"github.com/VaalaCat/frp-panel/cmd.runMaster" -> "github.com/VaalaCat/frp-panel/biz/master.NewRouter" [ color="saddlebrown" tooltip="at master.go:23: calling [github.com/VaalaCat/frp-panel/biz/master.NewRouter]" ]
"github.com/VaalaCat/frp-panel/cmd.initDatabase" -> "github.com/VaalaCat/frp-panel/conf.Get" [ tooltip="at master.go:48: calling [github.com/VaalaCat/frp-panel/conf.Get]\nat master.go:49: calling [github.com/VaalaCat/frp-panel/conf.Get]\nat master.go:51: calling [github.com/VaalaCat/frp-panel/conf.Get]\nat master.go:53: calling [github.com/VaalaCat/frp-panel/conf.Get]\nat master.go:60: calling [github.com/VaalaCat/frp-panel/conf.Get]\nat master.go:57: calling [github.com/VaalaCat/frp-panel/conf.Get]" color="saddlebrown" ]
"github.com/VaalaCat/frp-panel/cmd.initDatabase" -> "github.com/VaalaCat/frp-panel/models.GetDBManager" [ color="saddlebrown" tooltip="at master.go:63: calling [github.com/VaalaCat/frp-panel/models.GetDBManager]\nat master.go:56: calling [github.com/VaalaCat/frp-panel/models.GetDBManager]" ]
"github.com/VaalaCat/frp-panel/cmd.main" -> "github.com/VaalaCat/frp-panel/rpc.InitRPCClients" [ color="saddlebrown" tooltip="at main.go:14: calling [github.com/VaalaCat/frp-panel/rpc.InitRPCClients]" ]
"github.com/VaalaCat/frp-panel/cmd.main" -> "github.com/VaalaCat/frp-panel/conf.Get" [ tooltip="at main.go:16: calling [github.com/VaalaCat/frp-panel/conf.Get]" color="saddlebrown" ]
"github.com/VaalaCat/frp-panel/cmd.runMaster" -> "github.com/VaalaCat/frp-panel/utils.NewBaseFRPServerUserAuthConfig" [ color="saddlebrown" tooltip="at master.go:32: calling [github.com/VaalaCat/frp-panel/utils.NewBaseFRPServerUserAuthConfig]" ]
"github.com/VaalaCat/frp-panel/cmd.runClient" -> "github.com/VaalaCat/frp-panel/services/rpcclient.MustInitClientRPCSerivce" [ color="saddlebrown" tooltip="at client.go:22: calling [github.com/VaalaCat/frp-panel/services/rpcclient.MustInitClientRPCSerivce]" ]
"github.com/VaalaCat/frp-panel/cmd.runMaster" -> "github.com/VaalaCat/frp-panel/services/master.MustInitMasterService" [ color="saddlebrown" tooltip="at master.go:21: calling [github.com/VaalaCat/frp-panel/services/master.MustInitMasterService]" ]
"github.com/VaalaCat/frp-panel/cmd.runMaster" -> "github.com/VaalaCat/frp-panel/services/api.MustInitApiService" [ color="saddlebrown" tooltip="at master.go:24: calling [github.com/VaalaCat/frp-panel/services/api.MustInitApiService]" ]
"github.com/VaalaCat/frp-panel/cmd.initDatabase" -> "github.com/VaalaCat/frp-panel/models.MustInitDBManager" [ tooltip="at master.go:49: calling [github.com/VaalaCat/frp-panel/models.MustInitDBManager]" color="saddlebrown" ]
"github.com/VaalaCat/frp-panel/cmd.runMaster" -> "github.com/VaalaCat/frp-panel/cmd.initDatabase" [ tooltip="at master.go:26: calling [github.com/VaalaCat/frp-panel/cmd.initDatabase]" ]
"github.com/VaalaCat/frp-panel/cmd.runMaster" -> "github.com/VaalaCat/frp-panel/conf.Get" [ color="saddlebrown" tooltip="at master.go:33: calling [github.com/VaalaCat/frp-panel/conf.Get]" ]
"github.com/VaalaCat/frp-panel/cmd.initCommand$3" -> "github.com/VaalaCat/frp-panel/cmd.runMaster" [ tooltip="at cmd.go:45: calling [github.com/VaalaCat/frp-panel/cmd.runMaster]" ]
"github.com/VaalaCat/frp-panel/cmd.main" -> "github.com/VaalaCat/frp-panel/cmd.initCommand" [ tooltip="at main.go:12: calling [github.com/VaalaCat/frp-panel/cmd.initCommand]" ]
"github.com/VaalaCat/frp-panel/cmd.runServer" -> "github.com/VaalaCat/frp-panel/conf.ServerAPIListenAddr" [ color="saddlebrown" tooltip="at server.go:22: calling [github.com/VaalaCat/frp-panel/conf.ServerAPIListenAddr]" ]
"github.com/VaalaCat/frp-panel/cmd.runServer" -> "github.com/VaalaCat/frp-panel/services/api.GetAPIService" [ color="saddlebrown" tooltip="at server.go:24: calling [github.com/VaalaCat/frp-panel/services/api.GetAPIService]" ]
"github.com/VaalaCat/frp-panel/cmd.initServerOnce" -> "github.com/VaalaCat/frp-panel/biz/server.PullConfig" [ color="saddlebrown" tooltip="at server.go:50: calling [github.com/VaalaCat/frp-panel/biz/server.PullConfig]" ]
"github.com/VaalaCat/frp-panel/cmd.runServer" -> "(*github.com/VaalaCat/frp-panel/services/api.server).Stop" [ color="saddlebrown" tooltip="at server.go:25: calling [(*github.com/VaalaCat/frp-panel/services/api.server).Stop]" style="dashed" arrowhead="normalnoneodiamond" ]
"github.com/VaalaCat/frp-panel/cmd.initDatabase" -> "(*github.com/VaalaCat/frp-panel/models.dbManagerImpl).SetDB" [ style="dashed" color="saddlebrown" tooltip="at master.go:56: calling [(*github.com/VaalaCat/frp-panel/models.dbManagerImpl).SetDB]" ]
"github.com/VaalaCat/frp-panel/cmd.runMaster" -> "github.com/VaalaCat/frp-panel/cache.InitCache" [ color="saddlebrown" tooltip="at master.go:27: calling [github.com/VaalaCat/frp-panel/cache.InitCache]" ]
"github.com/VaalaCat/frp-panel/cmd.runClient" -> "(*github.com/VaalaCat/frp-panel/watcher.client).Stop" [ tooltip="at client.go:32: calling [(*github.com/VaalaCat/frp-panel/watcher.client).Stop]" style="dashed" arrowhead="normalnoneodiamond" color="saddlebrown" ]
"github.com/VaalaCat/frp-panel/cmd.runServer" -> "github.com/VaalaCat/frp-panel/biz/server.NewRouter" [ color="saddlebrown" tooltip="at server.go:21: calling [github.com/VaalaCat/frp-panel/biz/server.NewRouter]" ]
"github.com/VaalaCat/frp-panel/cmd.runServer" -> "github.com/VaalaCat/frp-panel/services/api.MustInitApiService" [ color="saddlebrown" tooltip="at server.go:22: calling [github.com/VaalaCat/frp-panel/services/api.MustInitApiService]" ]
"github.com/VaalaCat/frp-panel/cmd.initDatabase" -> "(*github.com/VaalaCat/frp-panel/models.dbManagerImpl).Init" [ tooltip="at master.go:63: calling [(*github.com/VaalaCat/frp-panel/models.dbManagerImpl).Init]" style="dashed" color="saddlebrown" ]
"github.com/VaalaCat/frp-panel/cmd.initCommand$1" -> "github.com/VaalaCat/frp-panel/cmd.runClient" [ tooltip="at cmd.go:31: calling [github.com/VaalaCat/frp-panel/cmd.runClient]" ]
"github.com/VaalaCat/frp-panel/cmd.runServer" -> "github.com/VaalaCat/frp-panel/cmd.initServerOnce" [ tooltip="at server.go:40: calling [github.com/VaalaCat/frp-panel/cmd.initServerOnce]" ]
"github.com/VaalaCat/frp-panel/cmd.runMaster" -> "github.com/VaalaCat/frp-panel/conf.MasterAPIListenAddr" [ color="saddlebrown" tooltip="at master.go:24: calling [github.com/VaalaCat/frp-panel/conf.MasterAPIListenAddr]" ]
"github.com/VaalaCat/frp-panel/cmd.main" -> "github.com/VaalaCat/frp-panel/cmd.initLogger" [ tooltip="at main.go:11: calling [github.com/VaalaCat/frp-panel/cmd.initLogger]" ]
"github.com/VaalaCat/frp-panel/cmd.runServer" -> "github.com/VaalaCat/frp-panel/services/rpcclient.MustInitClientRPCSerivce" [ color="saddlebrown" tooltip="at server.go:27: calling [github.com/VaalaCat/frp-panel/services/rpcclient.MustInitClientRPCSerivce]" ]
"github.com/VaalaCat/frp-panel/cmd.runServer" -> "github.com/VaalaCat/frp-panel/services/rpcclient.GetClientRPCSerivce" [ color="saddlebrown" tooltip="at server.go:34: calling [github.com/VaalaCat/frp-panel/services/rpcclient.GetClientRPCSerivce]" ]
"github.com/VaalaCat/frp-panel/cmd.runMaster" -> "github.com/VaalaCat/frp-panel/services/master.GetMasterSerivce" [ color="saddlebrown" tooltip="at master.go:31: calling [github.com/VaalaCat/frp-panel/services/master.GetMasterSerivce]" ]
"github.com/VaalaCat/frp-panel/cmd.runMaster" -> "github.com/VaalaCat/frp-panel/services/api.GetAPIService" [ color="saddlebrown" tooltip="at master.go:38: calling [github.com/VaalaCat/frp-panel/services/api.GetAPIService]" ]
}

924
doc/callvis.svg Normal file
View File

@@ -0,0 +1,924 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by graphviz version 2.40.1 (20161225.0304)
-->
<!-- Title: gocallvis Pages: 1 -->
<svg width="799pt" height="1498pt"
viewBox="0.00 0.00 798.80 1497.80" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(0 1497.8)">
<title>gocallvis</title>
<polygon fill="#d3d3d3" stroke="transparent" points="0,0 0,-1497.8 798.7968,-1497.8 798.7968,0 0,0"/>
<text text-anchor="middle" x="117.6893" y="-8.2" font-family="Arial" font-size="14.00" fill="#000000">github.com/VaalaCat/frp&#45;panel/cmd</text>
<g id="clust1" class="cluster">
<title>cluster_focus</title>
<polygon fill="#e6ecfa" stroke="#000000" stroke-width=".5" points="8,-32.8 8,-1489.8 790.7968,-1489.8 790.7968,-32.8 8,-32.8"/>
<text text-anchor="middle" x="399.3984" y="-1469.6" font-family="Arial" font-size="18.00" fill="#000000">main</text>
</g>
<g id="clust15" class="cluster">
<title>cluster_github.com/VaalaCat/frp&#45;panel/watcher</title>
<g id="a_clust15"><a xlink:href="/?f=github.com/VaalaCat/frp-panel/watcher" xlink:title="package: github.com/VaalaCat/frp&#45;panel/watcher">
<polygon fill="#ffffe0" stroke="#000000" stroke-width=".8" points="355.6757,-1267.8 355.6757,-1407.8 456.2711,-1407.8 456.2711,-1267.8 355.6757,-1267.8"/>
<text text-anchor="middle" x="405.9734" y="-1389.4" font-family="Tahoma bold" font-size="16.00" fill="#000000">watcher</text>
</a>
</g>
</g>
<g id="clust14" class="cluster">
<title>cluster_github.com/VaalaCat/frp&#45;panel/utils</title>
<g id="a_clust14"><a xlink:href="/?f=github.com/VaalaCat/frp-panel/utils" xlink:title="package: github.com/VaalaCat/frp&#45;panel/utils">
<polygon fill="#ffffe0" stroke="#000000" stroke-width=".8" points="550.4124,-241.8 550.4124,-381.8 782.7968,-381.8 782.7968,-241.8 550.4124,-241.8"/>
<text text-anchor="middle" x="666.6046" y="-363.4" font-family="Tahoma bold" font-size="16.00" fill="#000000">utils</text>
</a>
</g>
</g>
<g id="clust13" class="cluster">
<title>cluster_github.com/VaalaCat/frp&#45;panel/services/server</title>
<g id="a_clust13"><a xlink:href="/?f=github.com/VaalaCat/frp-panel/services/server" xlink:title="package: github.com/VaalaCat/frp&#45;panel/services/server">
<polygon fill="#ffffe0" stroke="#000000" stroke-width=".8" points="344.6122,-93.8 344.6122,-172.8 467.3346,-172.8 467.3346,-93.8 344.6122,-93.8"/>
<text text-anchor="middle" x="405.9734" y="-154.4" font-family="Tahoma bold" font-size="16.00" fill="#000000">server</text>
</a>
</g>
</g>
<g id="clust12" class="cluster">
<title>cluster_github.com/VaalaCat/frp&#45;panel/services/rpcclient</title>
<g id="a_clust12"><a xlink:href="/?f=github.com/VaalaCat/frp-panel/services/rpcclient" xlink:title="package: github.com/VaalaCat/frp&#45;panel/services/rpcclient">
<polygon fill="#ffffe0" stroke="#000000" stroke-width=".8" points="318.5344,-1058.8 318.5344,-1259.8 493.4124,-1259.8 493.4124,-1058.8 318.5344,-1058.8"/>
<text text-anchor="middle" x="405.9734" y="-1241.4" font-family="Tahoma bold" font-size="16.00" fill="#000000">rpcclient</text>
</a>
</g>
</g>
<g id="clust11" class="cluster">
<title>cluster_github.com/VaalaCat/frp&#45;panel/services/master</title>
<g id="a_clust11"><a xlink:href="/?f=github.com/VaalaCat/frp-panel/services/master" xlink:title="package: github.com/VaalaCat/frp&#45;panel/services/master">
<polygon fill="#ffffe0" stroke="#000000" stroke-width=".8" points="329.439,-533.8 329.439,-673.8 482.5078,-673.8 482.5078,-533.8 329.439,-533.8"/>
<text text-anchor="middle" x="405.9734" y="-655.4" font-family="Tahoma bold" font-size="16.00" fill="#000000">master</text>
</a>
</g>
</g>
<g id="clust10" class="cluster">
<title>cluster_github.com/VaalaCat/frp&#45;panel/services/api</title>
<g id="a_clust10"><a xlink:href="/?f=github.com/VaalaCat/frp-panel/services/api" xlink:title="package: github.com/VaalaCat/frp&#45;panel/services/api">
<polygon fill="#ffffe0" stroke="#000000" stroke-width=".8" points="338.3752,-849.8 338.3752,-1050.8 473.5716,-1050.8 473.5716,-849.8 338.3752,-849.8"/>
<text text-anchor="middle" x="405.9734" y="-1032.4" font-family="Tahoma bold" font-size="16.00" fill="#000000">api</text>
</a>
</g>
</g>
<g id="clust9" class="cluster">
<title>cluster_github.com/VaalaCat/frp&#45;panel/rpc</title>
<g id="a_clust9"><a xlink:href="/?f=github.com/VaalaCat/frp-panel/rpc" xlink:title="package: github.com/VaalaCat/frp&#45;panel/rpc">
<polygon fill="#ffffe0" stroke="#000000" stroke-width=".8" points="611.822,-40.8 611.822,-119.8 721.3872,-119.8 721.3872,-40.8 611.822,-40.8"/>
<text text-anchor="middle" x="666.6046" y="-101.4" font-family="Tahoma bold" font-size="16.00" fill="#000000">rpc</text>
</a>
</g>
</g>
<g id="clust8" class="cluster">
<title>cluster_github.com/VaalaCat/frp&#45;panel/models</title>
<g id="a_clust8"><a xlink:href="/?f=github.com/VaalaCat/frp-panel/models" xlink:title="package: github.com/VaalaCat/frp&#45;panel/models">
<polygon fill="#ffffe0" stroke="#000000" stroke-width=".8" points="580.9331,-720.8 580.9331,-982.8 752.2761,-982.8 752.2761,-720.8 580.9331,-720.8"/>
<text text-anchor="middle" x="666.6046" y="-964.4" font-family="Tahoma bold" font-size="16.00" fill="#000000">models</text>
</a>
</g>
</g>
<g id="clust7" class="cluster">
<title>cluster_github.com/VaalaCat/frp&#45;panel/conf</title>
<g id="a_clust7"><a xlink:href="/?f=github.com/VaalaCat/frp-panel/conf" xlink:title="package: github.com/VaalaCat/frp&#45;panel/conf">
<polygon fill="#ffffe0" stroke="#000000" stroke-width=".8" points="592.0148,-389.8 592.0148,-712.8 741.1944,-712.8 741.1944,-389.8 592.0148,-389.8"/>
<text text-anchor="middle" x="666.6046" y="-694.4" font-family="Tahoma bold" font-size="16.00" fill="#000000">conf</text>
</a>
</g>
</g>
<g id="clust6" class="cluster">
<title>cluster_github.com/VaalaCat/frp&#45;panel/cache</title>
<g id="a_clust6"><a xlink:href="/?f=github.com/VaalaCat/frp-panel/cache" xlink:title="package: github.com/VaalaCat/frp&#45;panel/cache">
<polygon fill="#ffffe0" stroke="#000000" stroke-width=".8" points="366.7623,-400.8 366.7623,-479.8 445.1845,-479.8 445.1845,-400.8 366.7623,-400.8"/>
<text text-anchor="middle" x="405.9734" y="-461.4" font-family="Tahoma bold" font-size="16.00" fill="#000000">cache</text>
</a>
</g>
</g>
<g id="clust5" class="cluster">
<title>cluster_github.com/VaalaCat/frp&#45;panel/biz/server</title>
<g id="a_clust5"><a xlink:href="/?f=github.com/VaalaCat/frp-panel/biz/server" xlink:title="package: github.com/VaalaCat/frp&#45;panel/biz/server">
<polygon fill="#ffffe0" stroke="#000000" stroke-width=".8" points="622.3395,-990.8 622.3395,-1130.8 710.8697,-1130.8 710.8697,-990.8 622.3395,-990.8"/>
<text text-anchor="middle" x="666.6046" y="-1112.4" font-family="Tahoma bold" font-size="16.00" fill="#000000">server</text>
</a>
</g>
</g>
<g id="clust4" class="cluster">
<title>cluster_github.com/VaalaCat/frp&#45;panel/biz/master/auth</title>
<g id="a_clust4"><a xlink:href="/?f=github.com/VaalaCat/frp-panel/biz/master/auth" xlink:title="package: github.com/VaalaCat/frp&#45;panel/biz/master/auth">
<polygon fill="#ffffe0" stroke="#000000" stroke-width=".8" points="370.2539,-313.8 370.2539,-392.8 441.6929,-392.8 441.6929,-313.8 370.2539,-313.8"/>
<text text-anchor="middle" x="405.9734" y="-374.4" font-family="Tahoma bold" font-size="16.00" fill="#000000">auth</text>
</a>
</g>
</g>
<g id="clust3" class="cluster">
<title>cluster_github.com/VaalaCat/frp&#45;panel/biz/master</title>
<g id="a_clust3"><a xlink:href="/?f=github.com/VaalaCat/frp-panel/biz/master" xlink:title="package: github.com/VaalaCat/frp&#45;panel/biz/master">
<polygon fill="#ffffe0" stroke="#000000" stroke-width=".8" points="361.7083,-226.8 361.7083,-305.8 450.2385,-305.8 450.2385,-226.8 361.7083,-226.8"/>
<text text-anchor="middle" x="405.9734" y="-287.4" font-family="Tahoma bold" font-size="16.00" fill="#000000">master</text>
</a>
</g>
</g>
<g id="clust2" class="cluster">
<title>cluster_github.com/VaalaCat/frp&#45;panel/biz/client</title>
<g id="a_clust2"><a xlink:href="/?f=github.com/VaalaCat/frp-panel/biz/client" xlink:title="package: github.com/VaalaCat/frp&#45;panel/biz/client">
<polygon fill="#ffffe0" stroke="#000000" stroke-width=".8" points="623.8788,-1372.8 623.8788,-1451.8 709.3304,-1451.8 709.3304,-1372.8 623.8788,-1372.8"/>
<text text-anchor="middle" x="666.6046" y="-1433.4" font-family="Tahoma bold" font-size="16.00" fill="#000000">client</text>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.runClient -->
<g id="node1" class="node">
<title>github.com/VaalaCat/frp&#45;panel/cmd.runClient</title>
<g id="a_node1"><a xlink:title="github.com/VaalaCat/frp&#45;panel/cmd.runClient | defined in client.go:12&#10;at client.go:31: calling [github.com/VaalaCat/frp&#45;panel/watcher.NewClient]&#10;at client.go:34: calling [github.com/VaalaCat/frp&#45;panel/cmd.initClientOnce]&#10;at client.go:28: calling [github.com/VaalaCat/frp&#45;panel/services/rpcclient.GetClientRPCSerivce]&#10;at client.go:29: calling [(*github.com/VaalaCat/frp&#45;panel/services/rpcclient.ClientRPC).Stop]&#10;at client.go:22: calling [github.com/VaalaCat/frp&#45;panel/services/rpcclient.MustInitClientRPCSerivce]&#10;at client.go:32: calling [(*github.com/VaalaCat/frp&#45;panel/watcher.client).Stop]">
<path fill="#add8e6" stroke="#000000" stroke-width=".5" d="M239.153,-1265.8C239.153,-1265.8 202.3856,-1265.8 202.3856,-1265.8 196.3856,-1265.8 190.3856,-1259.8 190.3856,-1253.8 190.3856,-1253.8 190.3856,-1241.8 190.3856,-1241.8 190.3856,-1235.8 196.3856,-1229.8 202.3856,-1229.8 202.3856,-1229.8 239.153,-1229.8 239.153,-1229.8 245.153,-1229.8 251.153,-1235.8 251.153,-1241.8 251.153,-1241.8 251.153,-1253.8 251.153,-1253.8 251.153,-1259.8 245.153,-1265.8 239.153,-1265.8"/>
<text text-anchor="middle" x="220.7693" y="-1243.6" font-family="Verdana" font-size="14.00" fill="#000000">runClient</text>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.initClientOnce -->
<g id="node2" class="node">
<title>github.com/VaalaCat/frp&#45;panel/cmd.initClientOnce</title>
<g id="a_node2"><a xlink:title="github.com/VaalaCat/frp&#45;panel/cmd.initClientOnce | defined in client.go:42&#10;at client.go:43: calling [github.com/VaalaCat/frp&#45;panel/biz/client.PullConfig]">
<path fill="#add8e6" stroke="#000000" stroke-width=".5" d="M439.405,-1451.8C439.405,-1451.8 372.5418,-1451.8 372.5418,-1451.8 366.5418,-1451.8 360.5418,-1445.8 360.5418,-1439.8 360.5418,-1439.8 360.5418,-1427.8 360.5418,-1427.8 360.5418,-1421.8 366.5418,-1415.8 372.5418,-1415.8 372.5418,-1415.8 439.405,-1415.8 439.405,-1415.8 445.405,-1415.8 451.405,-1421.8 451.405,-1427.8 451.405,-1427.8 451.405,-1439.8 451.405,-1439.8 451.405,-1445.8 445.405,-1451.8 439.405,-1451.8"/>
<text text-anchor="middle" x="405.9734" y="-1429.6" font-family="Verdana" font-size="14.00" fill="#000000">initClientOnce</text>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.runClient&#45;&gt;github.com/VaalaCat/frp&#45;panel/cmd.initClientOnce -->
<g id="edge5" class="edge">
<title>github.com/VaalaCat/frp&#45;panel/cmd.runClient&#45;&gt;github.com/VaalaCat/frp&#45;panel/cmd.initClientOnce</title>
<g id="a_edge5"><a xlink:title="at client.go:34: calling [github.com/VaalaCat/frp&#45;panel/cmd.initClientOnce]">
<path fill="none" stroke="#000000" d="M226.3828,-1266.0332C237.8616,-1300.1682 267.3482,-1373.7009 318.5344,-1411.8 327.8579,-1418.7397 339.1287,-1423.5046 350.4328,-1426.7723"/>
<polygon fill="#000000" stroke="#000000" points="349.7742,-1430.2159 360.3272,-1429.2757 351.4912,-1423.4297 349.7742,-1430.2159"/>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/services/rpcclient.MustInitClientRPCSerivce -->
<g id="node34" class="node">
<title>github.com/VaalaCat/frp&#45;panel/services/rpcclient.MustInitClientRPCSerivce</title>
<g id="a_node34"><a xlink:title="github.com/VaalaCat/frp&#45;panel/services/rpcclient.MustInitClientRPCSerivce | defined in rpc_service.go:27">
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M473.3514,-1224.8C473.3514,-1224.8 338.5954,-1224.8 338.5954,-1224.8 332.5954,-1224.8 326.5954,-1218.8 326.5954,-1212.8 326.5954,-1212.8 326.5954,-1200.8 326.5954,-1200.8 326.5954,-1194.8 332.5954,-1188.8 338.5954,-1188.8 338.5954,-1188.8 473.3514,-1188.8 473.3514,-1188.8 479.3514,-1188.8 485.3514,-1194.8 485.3514,-1200.8 485.3514,-1200.8 485.3514,-1212.8 485.3514,-1212.8 485.3514,-1218.8 479.3514,-1224.8 473.3514,-1224.8"/>
<text text-anchor="middle" x="405.9734" y="-1202.6" font-family="Verdana" font-size="14.00" fill="#000000">MustInitClientRPCSerivce</text>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.runClient&#45;&gt;github.com/VaalaCat/frp&#45;panel/services/rpcclient.MustInitClientRPCSerivce -->
<g id="edge21" class="edge">
<title>github.com/VaalaCat/frp&#45;panel/cmd.runClient&#45;&gt;github.com/VaalaCat/frp&#45;panel/services/rpcclient.MustInitClientRPCSerivce</title>
<g id="a_edge21"><a xlink:title="at client.go:22: calling [github.com/VaalaCat/frp&#45;panel/services/rpcclient.MustInitClientRPCSerivce]">
<path fill="none" stroke="#8b4513" d="M251.352,-1241.0297C269.3316,-1237.0494 293.0841,-1231.7911 316.5627,-1226.5935"/>
<polygon fill="#8b4513" stroke="#8b4513" points="317.5835,-1229.9523 326.5906,-1224.3736 316.0705,-1223.1178 317.5835,-1229.9523"/>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/services/rpcclient.GetClientRPCSerivce -->
<g id="node35" class="node">
<title>github.com/VaalaCat/frp&#45;panel/services/rpcclient.GetClientRPCSerivce</title>
<g id="a_node35"><a xlink:title="github.com/VaalaCat/frp&#45;panel/services/rpcclient.GetClientRPCSerivce | defined in rpc_service.go:35">
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M459.3417,-1102.8C459.3417,-1102.8 352.6051,-1102.8 352.6051,-1102.8 346.6051,-1102.8 340.6051,-1096.8 340.6051,-1090.8 340.6051,-1090.8 340.6051,-1078.8 340.6051,-1078.8 340.6051,-1072.8 346.6051,-1066.8 352.6051,-1066.8 352.6051,-1066.8 459.3417,-1066.8 459.3417,-1066.8 465.3417,-1066.8 471.3417,-1072.8 471.3417,-1078.8 471.3417,-1078.8 471.3417,-1090.8 471.3417,-1090.8 471.3417,-1096.8 465.3417,-1102.8 459.3417,-1102.8"/>
<text text-anchor="middle" x="405.9734" y="-1080.6" font-family="Verdana" font-size="14.00" fill="#000000">GetClientRPCSerivce</text>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.runClient&#45;&gt;github.com/VaalaCat/frp&#45;panel/services/rpcclient.GetClientRPCSerivce -->
<g id="edge12" class="edge">
<title>github.com/VaalaCat/frp&#45;panel/cmd.runClient&#45;&gt;github.com/VaalaCat/frp&#45;panel/services/rpcclient.GetClientRPCSerivce</title>
<g id="a_edge12"><a xlink:title="at client.go:28: calling [github.com/VaalaCat/frp&#45;panel/services/rpcclient.GetClientRPCSerivce]">
<path fill="none" stroke="#8b4513" d="M229.6095,-1229.7554C244.3016,-1201.5472 276.3528,-1147.0103 318.5344,-1115.8 322.6371,-1112.7644 327.0638,-1110.0053 331.6715,-1107.5008"/>
<polygon fill="#8b4513" stroke="#8b4513" points="333.3288,-1110.5855 340.7178,-1102.9925 330.2065,-1104.3204 333.3288,-1110.5855"/>
</a>
</g>
</g>
<!-- (*github.com/VaalaCat/frp&#45;panel/services/rpcclient.ClientRPC).Stop -->
<g id="node36" class="node">
<title>(*github.com/VaalaCat/frp&#45;panel/services/rpcclient.ClientRPC).Stop</title>
<g id="a_node36"><a xlink:title="(*github.com/VaalaCat/frp&#45;panel/services/rpcclient.ClientRPC).Stop | defined in rpc_service.go:62">
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M451.1467,-1163.8C451.1467,-1163.8 360.8001,-1163.8 360.8001,-1163.8 354.8001,-1163.8 348.8001,-1157.8 348.8001,-1151.8 348.8001,-1151.8 348.8001,-1139.8 348.8001,-1139.8 348.8001,-1133.8 354.8001,-1127.8 360.8001,-1127.8 360.8001,-1127.8 451.1467,-1127.8 451.1467,-1127.8 457.1467,-1127.8 463.1467,-1133.8 463.1467,-1139.8 463.1467,-1139.8 463.1467,-1151.8 463.1467,-1151.8 463.1467,-1157.8 457.1467,-1163.8 451.1467,-1163.8"/>
<text text-anchor="middle" x="405.9734" y="-1141.6" font-family="Verdana" font-size="14.00" fill="#000000">(*ClientRPC).Stop</text>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.runClient&#45;&gt;(*github.com/VaalaCat/frp&#45;panel/services/rpcclient.ClientRPC).Stop -->
<g id="edge13" class="edge">
<title>github.com/VaalaCat/frp&#45;panel/cmd.runClient&#45;&gt;(*github.com/VaalaCat/frp&#45;panel/services/rpcclient.ClientRPC).Stop</title>
<g id="a_edge13"><a xlink:title="at client.go:29: calling [(*github.com/VaalaCat/frp&#45;panel/services/rpcclient.ClientRPC).Stop]">
<path fill="none" stroke="#8b4513" stroke-dasharray="5,2" d="M242.0943,-1229.519C261.1426,-1213.8945 290.318,-1191.6483 318.5344,-1176.8 320.1512,-1175.9492 321.7965,-1175.1129 323.4644,-1174.2915"/>
<polygon fill="#8b4513" stroke="#8b4513" points="340.7188,-1170.6708 348.5186,-1163.5005 337.9498,-1164.2417 340.7188,-1170.6708"/>
<polyline fill="none" stroke="#8b4513" points="339.3343,-1167.4563 334.7421,-1169.4341 "/>
<polygon fill="none" stroke="#8b4513" points="323.7209,-1174.1811 327.6492,-1168.1339 334.7421,-1169.4341 330.8138,-1175.4813 323.7209,-1174.1811"/>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/watcher.NewClient -->
<g id="node40" class="node">
<title>github.com/VaalaCat/frp&#45;panel/watcher.NewClient</title>
<g id="a_node40"><a xlink:title="github.com/VaalaCat/frp&#45;panel/watcher.NewClient | defined in client.go:17">
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M428.1251,-1372.8C428.1251,-1372.8 383.8217,-1372.8 383.8217,-1372.8 377.8217,-1372.8 371.8217,-1366.8 371.8217,-1360.8 371.8217,-1360.8 371.8217,-1348.8 371.8217,-1348.8 371.8217,-1342.8 377.8217,-1336.8 383.8217,-1336.8 383.8217,-1336.8 428.1251,-1336.8 428.1251,-1336.8 434.1251,-1336.8 440.1251,-1342.8 440.1251,-1348.8 440.1251,-1348.8 440.1251,-1360.8 440.1251,-1360.8 440.1251,-1366.8 434.1251,-1372.8 428.1251,-1372.8"/>
<text text-anchor="middle" x="405.9734" y="-1350.6" font-family="Verdana" font-size="14.00" fill="#000000">NewClient</text>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.runClient&#45;&gt;github.com/VaalaCat/frp&#45;panel/watcher.NewClient -->
<g id="edge1" class="edge">
<title>github.com/VaalaCat/frp&#45;panel/cmd.runClient&#45;&gt;github.com/VaalaCat/frp&#45;panel/watcher.NewClient</title>
<g id="a_edge1"><a xlink:title="at client.go:31: calling [github.com/VaalaCat/frp&#45;panel/watcher.NewClient]">
<path fill="none" stroke="#8b4513" d="M231.2107,-1265.9485C242.9557,-1284.668 263.7959,-1313.2559 289.5344,-1328.8 311.214,-1341.8928 338.7473,-1348.41 361.5966,-1351.6461"/>
<polygon fill="#8b4513" stroke="#8b4513" points="361.3703,-1355.145 371.7275,-1352.9139 362.2396,-1348.1992 361.3703,-1355.145"/>
</a>
</g>
</g>
<!-- (*github.com/VaalaCat/frp&#45;panel/watcher.client).Stop -->
<g id="node41" class="node">
<title>(*github.com/VaalaCat/frp&#45;panel/watcher.client).Stop</title>
<g id="a_node41"><a xlink:title="(*github.com/VaalaCat/frp&#45;panel/watcher.client).Stop | defined in client.go:40">
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M436.0698,-1311.8C436.0698,-1311.8 375.877,-1311.8 375.877,-1311.8 369.877,-1311.8 363.877,-1305.8 363.877,-1299.8 363.877,-1299.8 363.877,-1287.8 363.877,-1287.8 363.877,-1281.8 369.877,-1275.8 375.877,-1275.8 375.877,-1275.8 436.0698,-1275.8 436.0698,-1275.8 442.0698,-1275.8 448.0698,-1281.8 448.0698,-1287.8 448.0698,-1287.8 448.0698,-1299.8 448.0698,-1299.8 448.0698,-1305.8 442.0698,-1311.8 436.0698,-1311.8"/>
<text text-anchor="middle" x="405.9734" y="-1289.6" font-family="Verdana" font-size="14.00" fill="#000000">(*client).Stop</text>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.runClient&#45;&gt;(*github.com/VaalaCat/frp&#45;panel/watcher.client).Stop -->
<g id="edge35" class="edge">
<title>github.com/VaalaCat/frp&#45;panel/cmd.runClient&#45;&gt;(*github.com/VaalaCat/frp&#45;panel/watcher.client).Stop</title>
<g id="a_edge35"><a xlink:title="at client.go:32: calling [(*github.com/VaalaCat/frp&#45;panel/watcher.client).Stop]">
<path fill="none" stroke="#8b4513" stroke-dasharray="5,2" d="M251.352,-1255.396C274.6733,-1261.1884 307.7073,-1269.3932 337.258,-1276.7328"/>
<polygon fill="#8b4513" stroke="#8b4513" points="353.0149,-1284.2528 363.5637,-1283.2665 354.7022,-1277.4592 353.0149,-1284.2528"/>
<polyline fill="none" stroke="#8b4513" points="353.8586,-1280.856 349.006,-1279.6507 "/>
<polygon fill="none" stroke="#8b4513" points="337.3598,-1276.7581 344.1471,-1274.3223 349.006,-1279.6507 342.2187,-1282.0864 337.3598,-1276.7581"/>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/biz/client.PullConfig -->
<g id="node13" class="node">
<title>github.com/VaalaCat/frp&#45;panel/biz/client.PullConfig</title>
<g id="a_node13"><a xlink:title="github.com/VaalaCat/frp&#45;panel/biz/client.PullConfig | defined in rpc_pull_config.go:15">
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M689.5577,-1416.8C689.5577,-1416.8 643.6515,-1416.8 643.6515,-1416.8 637.6515,-1416.8 631.6515,-1410.8 631.6515,-1404.8 631.6515,-1404.8 631.6515,-1392.8 631.6515,-1392.8 631.6515,-1386.8 637.6515,-1380.8 643.6515,-1380.8 643.6515,-1380.8 689.5577,-1380.8 689.5577,-1380.8 695.5577,-1380.8 701.5577,-1386.8 701.5577,-1392.8 701.5577,-1392.8 701.5577,-1404.8 701.5577,-1404.8 701.5577,-1410.8 695.5577,-1416.8 689.5577,-1416.8"/>
<text text-anchor="middle" x="666.6046" y="-1394.6" font-family="Verdana" font-size="14.00" fill="#000000">PullConfig</text>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.initClientOnce&#45;&gt;github.com/VaalaCat/frp&#45;panel/biz/client.PullConfig -->
<g id="edge2" class="edge">
<title>github.com/VaalaCat/frp&#45;panel/cmd.initClientOnce&#45;&gt;github.com/VaalaCat/frp&#45;panel/biz/client.PullConfig</title>
<g id="a_edge2"><a xlink:title="at client.go:43: calling [github.com/VaalaCat/frp&#45;panel/biz/client.PullConfig]">
<path fill="none" stroke="#8b4513" d="M451.3719,-1427.7035C499.1999,-1421.2807 574.0579,-1411.228 621.6991,-1404.8303"/>
<polygon fill="#8b4513" stroke="#8b4513" points="622.28,-1408.2838 631.7252,-1403.4839 621.3483,-1401.3461 622.28,-1408.2838"/>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.initCommand$1 -->
<g id="node3" class="node">
<title>github.com/VaalaCat/frp&#45;panel/cmd.initCommand$1</title>
<g id="a_node3"><a xlink:title="github.com/VaalaCat/frp&#45;panel/cmd.initCommand$1 | defined in cmd.go:30&#10;at cmd.go:31: calling [github.com/VaalaCat/frp&#45;panel/cmd.runClient]">
<polygon fill="#add8e6" stroke="#000000" stroke-dasharray="1,5" points="115.0063,-1265.8 15.9979,-1265.8 15.9979,-1229.8 115.0063,-1229.8 115.0063,-1265.8"/>
<text text-anchor="middle" x="65.5021" y="-1243.6" font-family="Verdana" font-size="14.00" fill="#000000">initCommand$1</text>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.initCommand$1&#45;&gt;github.com/VaalaCat/frp&#45;panel/cmd.runClient -->
<g id="edge39" class="edge">
<title>github.com/VaalaCat/frp&#45;panel/cmd.initCommand$1&#45;&gt;github.com/VaalaCat/frp&#45;panel/cmd.runClient</title>
<g id="a_edge39"><a xlink:title="at cmd.go:31: calling [github.com/VaalaCat/frp&#45;panel/cmd.runClient]">
<path fill="none" stroke="#000000" d="M115.0565,-1247.8C135.9703,-1247.8 160.0262,-1247.8 179.9016,-1247.8"/>
<polygon fill="#000000" stroke="#000000" points="180.1703,-1251.3001 190.1703,-1247.8 180.1702,-1244.3001 180.1703,-1251.3001"/>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.runServer -->
<g id="node4" class="node">
<title>github.com/VaalaCat/frp&#45;panel/cmd.runServer</title>
<g id="a_node4"><a xlink:title="github.com/VaalaCat/frp&#45;panel/cmd.runServer | defined in server.go:14&#10;at server.go:38: calling [(*github.com/VaalaCat/frp&#45;panel/watcher.client).Stop]&#10;at server.go:37: calling [github.com/VaalaCat/frp&#45;panel/watcher.NewClient]&#10;at server.go:35: calling [(*github.com/VaalaCat/frp&#45;panel/services/rpcclient.ClientRPC).Stop]&#10;at server.go:22: calling [github.com/VaalaCat/frp&#45;panel/conf.ServerAPIListenAddr]&#10;at server.go:24: calling [github.com/VaalaCat/frp&#45;panel/services/api.GetAPIService]&#10;at server.go:25: calling [(*github.com/VaalaCat/frp&#45;panel/services/api.server).Stop]&#10;at server.go:21: calling [github.com/VaalaCat/frp&#45;panel/biz/server.NewRouter]&#10;at server.go:22: calling [github.com/VaalaCat/frp&#45;panel/services/api.MustInitApiService]&#10;at server.go:40: calling [github.com/VaalaCat/frp&#45;panel/cmd.initServerOnce]&#10;at server.go:27: calling [github.com/VaalaCat/frp&#45;panel/services/rpcclient.MustInitClientRPCSerivce]&#10;at server.go:34: calling [github.com/VaalaCat/frp&#45;panel/services/rpcclient.GetClientRPCSerivce]">
<path fill="#add8e6" stroke="#000000" stroke-width=".5" d="M240.4632,-1015.8C240.4632,-1015.8 201.0754,-1015.8 201.0754,-1015.8 195.0754,-1015.8 189.0754,-1009.8 189.0754,-1003.8 189.0754,-1003.8 189.0754,-991.8 189.0754,-991.8 189.0754,-985.8 195.0754,-979.8 201.0754,-979.8 201.0754,-979.8 240.4632,-979.8 240.4632,-979.8 246.4632,-979.8 252.4632,-985.8 252.4632,-991.8 252.4632,-991.8 252.4632,-1003.8 252.4632,-1003.8 252.4632,-1009.8 246.4632,-1015.8 240.4632,-1015.8"/>
<text text-anchor="middle" x="220.7693" y="-993.6" font-family="Verdana" font-size="14.00" fill="#000000">runServer</text>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.initServerOnce -->
<g id="node5" class="node">
<title>github.com/VaalaCat/frp&#45;panel/cmd.initServerOnce</title>
<g id="a_node5"><a xlink:title="github.com/VaalaCat/frp&#45;panel/cmd.initServerOnce | defined in server.go:49&#10;at server.go:50: calling [github.com/VaalaCat/frp&#45;panel/biz/server.PullConfig]">
<path fill="#add8e6" stroke="#000000" stroke-width=".5" d="M440.2144,-805.8C440.2144,-805.8 371.7324,-805.8 371.7324,-805.8 365.7324,-805.8 359.7324,-799.8 359.7324,-793.8 359.7324,-793.8 359.7324,-781.8 359.7324,-781.8 359.7324,-775.8 365.7324,-769.8 371.7324,-769.8 371.7324,-769.8 440.2144,-769.8 440.2144,-769.8 446.2144,-769.8 452.2144,-775.8 452.2144,-781.8 452.2144,-781.8 452.2144,-793.8 452.2144,-793.8 452.2144,-799.8 446.2144,-805.8 440.2144,-805.8"/>
<text text-anchor="middle" x="405.9734" y="-783.6" font-family="Verdana" font-size="14.00" fill="#000000">initServerOnce</text>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.runServer&#45;&gt;github.com/VaalaCat/frp&#45;panel/cmd.initServerOnce -->
<g id="edge40" class="edge">
<title>github.com/VaalaCat/frp&#45;panel/cmd.runServer&#45;&gt;github.com/VaalaCat/frp&#45;panel/cmd.initServerOnce</title>
<g id="a_edge40"><a xlink:title="at server.go:40: calling [github.com/VaalaCat/frp&#45;panel/cmd.initServerOnce]">
<path fill="none" stroke="#000000" d="M222.8434,-979.7945C227.8232,-944.854 243.6591,-867.5429 289.5344,-824.8 305.9461,-809.5089 328.6685,-800.5372 349.6873,-795.2733"/>
<polygon fill="#000000" stroke="#000000" points="350.5374,-798.6694 359.5135,-793.0409 348.9866,-791.8434 350.5374,-798.6694"/>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/biz/server.NewRouter -->
<g id="node16" class="node">
<title>github.com/VaalaCat/frp&#45;panel/biz/server.NewRouter</title>
<g id="a_node16"><a xlink:title="github.com/VaalaCat/frp&#45;panel/biz/server.NewRouter | defined in auth_handler.go:13">
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M690.6363,-1095.8C690.6363,-1095.8 642.5729,-1095.8 642.5729,-1095.8 636.5729,-1095.8 630.5729,-1089.8 630.5729,-1083.8 630.5729,-1083.8 630.5729,-1071.8 630.5729,-1071.8 630.5729,-1065.8 636.5729,-1059.8 642.5729,-1059.8 642.5729,-1059.8 690.6363,-1059.8 690.6363,-1059.8 696.6363,-1059.8 702.6363,-1065.8 702.6363,-1071.8 702.6363,-1071.8 702.6363,-1083.8 702.6363,-1083.8 702.6363,-1089.8 696.6363,-1095.8 690.6363,-1095.8"/>
<text text-anchor="middle" x="666.6046" y="-1073.6" font-family="Verdana" font-size="14.00" fill="#000000">NewRouter</text>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.runServer&#45;&gt;github.com/VaalaCat/frp&#45;panel/biz/server.NewRouter -->
<g id="edge36" class="edge">
<title>github.com/VaalaCat/frp&#45;panel/cmd.runServer&#45;&gt;github.com/VaalaCat/frp&#45;panel/biz/server.NewRouter</title>
<g id="a_edge36"><a xlink:title="at server.go:21: calling [github.com/VaalaCat/frp&#45;panel/biz/server.NewRouter]">
<path fill="none" stroke="#8b4513" d="M225.8861,-979.7597C236.6043,-945.8201 264.9717,-873.2409 318.5344,-843.8 352.5907,-825.0809 462.4556,-820.3072 493.4124,-843.8 568.4027,-900.7094 483.1905,-981.8953 550.4124,-1047.8 568.8142,-1065.8413 596.5602,-1073.452 620.3242,-1076.4999"/>
<polygon fill="#8b4513" stroke="#8b4513" points="620.2593,-1080.0122 630.5693,-1077.5723 620.9881,-1073.0502 620.2593,-1080.0122"/>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/conf.ServerAPIListenAddr -->
<g id="node19" class="node">
<title>github.com/VaalaCat/frp&#45;panel/conf.ServerAPIListenAddr</title>
<g id="a_node19"><a xlink:title="github.com/VaalaCat/frp&#45;panel/conf.ServerAPIListenAddr | defined in helper.go:42">
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M719.9477,-677.8C719.9477,-677.8 613.2615,-677.8 613.2615,-677.8 607.2615,-677.8 601.2615,-671.8 601.2615,-665.8 601.2615,-665.8 601.2615,-653.8 601.2615,-653.8 601.2615,-647.8 607.2615,-641.8 613.2615,-641.8 613.2615,-641.8 719.9477,-641.8 719.9477,-641.8 725.9477,-641.8 731.9477,-647.8 731.9477,-653.8 731.9477,-653.8 731.9477,-665.8 731.9477,-665.8 731.9477,-671.8 725.9477,-677.8 719.9477,-677.8"/>
<text text-anchor="middle" x="666.6046" y="-655.6" font-family="Verdana" font-size="14.00" fill="#000000">ServerAPIListenAddr</text>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.runServer&#45;&gt;github.com/VaalaCat/frp&#45;panel/conf.ServerAPIListenAddr -->
<g id="edge29" class="edge">
<title>github.com/VaalaCat/frp&#45;panel/cmd.runServer&#45;&gt;github.com/VaalaCat/frp&#45;panel/conf.ServerAPIListenAddr</title>
<g id="a_edge29"><a xlink:title="at server.go:22: calling [github.com/VaalaCat/frp&#45;panel/conf.ServerAPIListenAddr]">
<path fill="none" stroke="#8b4513" d="M224.0354,-979.5603C235.0574,-920.1533 272.7629,-733.914 318.5344,-696.8 319.1937,-696.2654 488.7186,-678.4292 590.9084,-667.7198"/>
<polygon fill="#8b4513" stroke="#8b4513" points="591.3036,-671.1976 600.8844,-666.6745 590.5741,-664.2357 591.3036,-671.1976"/>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/services/api.MustInitApiService -->
<g id="node29" class="node">
<title>github.com/VaalaCat/frp&#45;panel/services/api.MustInitApiService</title>
<g id="a_node29"><a xlink:title="github.com/VaalaCat/frp&#45;panel/services/api.MustInitApiService | defined in service.go:29">
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M453.67,-893.8C453.67,-893.8 358.2768,-893.8 358.2768,-893.8 352.2768,-893.8 346.2768,-887.8 346.2768,-881.8 346.2768,-881.8 346.2768,-869.8 346.2768,-869.8 346.2768,-863.8 352.2768,-857.8 358.2768,-857.8 358.2768,-857.8 453.67,-857.8 453.67,-857.8 459.67,-857.8 465.67,-863.8 465.67,-869.8 465.67,-869.8 465.67,-881.8 465.67,-881.8 465.67,-887.8 459.67,-893.8 453.67,-893.8"/>
<text text-anchor="middle" x="405.9734" y="-871.6" font-family="Verdana" font-size="14.00" fill="#000000">MustInitApiService</text>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.runServer&#45;&gt;github.com/VaalaCat/frp&#45;panel/services/api.MustInitApiService -->
<g id="edge37" class="edge">
<title>github.com/VaalaCat/frp&#45;panel/cmd.runServer&#45;&gt;github.com/VaalaCat/frp&#45;panel/services/api.MustInitApiService</title>
<g id="a_edge37"><a xlink:title="at server.go:22: calling [github.com/VaalaCat/frp&#45;panel/services/api.MustInitApiService]">
<path fill="none" stroke="#8b4513" d="M235.9964,-979.7323C253.9077,-959.487 285.4233,-926.8799 318.5344,-906.8 324.2712,-903.321 330.4561,-900.1534 336.7916,-897.288"/>
<polygon fill="#8b4513" stroke="#8b4513" points="338.317,-900.4426 346.1467,-893.3049 335.5748,-894.002 338.317,-900.4426"/>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/services/api.GetAPIService -->
<g id="node30" class="node">
<title>github.com/VaalaCat/frp&#45;panel/services/api.GetAPIService</title>
<g id="a_node30"><a xlink:title="github.com/VaalaCat/frp&#45;panel/services/api.GetAPIService | defined in service.go:33">
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M440.213,-954.8C440.213,-954.8 371.7338,-954.8 371.7338,-954.8 365.7338,-954.8 359.7338,-948.8 359.7338,-942.8 359.7338,-942.8 359.7338,-930.8 359.7338,-930.8 359.7338,-924.8 365.7338,-918.8 371.7338,-918.8 371.7338,-918.8 440.213,-918.8 440.213,-918.8 446.213,-918.8 452.213,-924.8 452.213,-930.8 452.213,-930.8 452.213,-942.8 452.213,-942.8 452.213,-948.8 446.213,-954.8 440.213,-954.8"/>
<text text-anchor="middle" x="405.9734" y="-932.6" font-family="Verdana" font-size="14.00" fill="#000000">GetAPIService</text>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.runServer&#45;&gt;github.com/VaalaCat/frp&#45;panel/services/api.GetAPIService -->
<g id="edge30" class="edge">
<title>github.com/VaalaCat/frp&#45;panel/cmd.runServer&#45;&gt;github.com/VaalaCat/frp&#45;panel/services/api.GetAPIService</title>
<g id="a_edge30"><a xlink:title="at server.go:24: calling [github.com/VaalaCat/frp&#45;panel/services/api.GetAPIService]">
<path fill="none" stroke="#8b4513" d="M252.607,-987.3137C279.3192,-978.5156 318.1092,-965.7395 349.9939,-955.2378"/>
<polygon fill="#8b4513" stroke="#8b4513" points="351.2433,-958.5113 359.6464,-952.0585 349.0534,-951.8626 351.2433,-958.5113"/>
</a>
</g>
</g>
<!-- (*github.com/VaalaCat/frp&#45;panel/services/api.server).Stop -->
<g id="node31" class="node">
<title>(*github.com/VaalaCat/frp&#45;panel/services/api.server).Stop</title>
<g id="a_node31"><a xlink:title="(*github.com/VaalaCat/frp&#45;panel/services/api.server).Stop | defined in service.go:41">
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M437.6633,-1015.8C437.6633,-1015.8 374.2835,-1015.8 374.2835,-1015.8 368.2835,-1015.8 362.2835,-1009.8 362.2835,-1003.8 362.2835,-1003.8 362.2835,-991.8 362.2835,-991.8 362.2835,-985.8 368.2835,-979.8 374.2835,-979.8 374.2835,-979.8 437.6633,-979.8 437.6633,-979.8 443.6633,-979.8 449.6633,-985.8 449.6633,-991.8 449.6633,-991.8 449.6633,-1003.8 449.6633,-1003.8 449.6633,-1009.8 443.6633,-1015.8 437.6633,-1015.8"/>
<text text-anchor="middle" x="405.9734" y="-993.6" font-family="Verdana" font-size="14.00" fill="#000000">(*server).Stop</text>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.runServer&#45;&gt;(*github.com/VaalaCat/frp&#45;panel/services/api.server).Stop -->
<g id="edge32" class="edge">
<title>github.com/VaalaCat/frp&#45;panel/cmd.runServer&#45;&gt;(*github.com/VaalaCat/frp&#45;panel/services/api.server).Stop</title>
<g id="a_edge32"><a xlink:title="at server.go:25: calling [(*github.com/VaalaCat/frp&#45;panel/services/api.server).Stop]">
<path fill="none" stroke="#8b4513" stroke-dasharray="5,2" d="M252.607,-997.8C275.2567,-997.8 306.5896,-997.8 335.0337,-997.8"/>
<polygon fill="#8b4513" stroke="#8b4513" points="352.0863,-1001.3 362.0863,-997.8 352.0863,-994.3 352.0863,-1001.3"/>
<polyline fill="none" stroke="#8b4513" points="352.0863,-997.8 347.0863,-997.8001 "/>
<polygon fill="none" stroke="#8b4513" points="335.0863,-997.8001 341.0863,-993.8001 347.0863,-997.8001 341.0863,-1001.8001 335.0863,-997.8001"/>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.runServer&#45;&gt;github.com/VaalaCat/frp&#45;panel/services/rpcclient.MustInitClientRPCSerivce -->
<g id="edge43" class="edge">
<title>github.com/VaalaCat/frp&#45;panel/cmd.runServer&#45;&gt;github.com/VaalaCat/frp&#45;panel/services/rpcclient.MustInitClientRPCSerivce</title>
<g id="a_edge43"><a xlink:title="at server.go:27: calling [github.com/VaalaCat/frp&#45;panel/services/rpcclient.MustInitClientRPCSerivce]">
<path fill="none" stroke="#8b4513" d="M225.7865,-1015.8632C236.6567,-1051.7252 265.7546,-1132.2807 318.5344,-1176.8 321.5534,-1179.3465 324.8,-1181.6806 328.2025,-1183.8197"/>
<polygon fill="#8b4513" stroke="#8b4513" points="326.5106,-1186.8837 336.9406,-1188.7449 329.9477,-1180.7857 326.5106,-1186.8837"/>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.runServer&#45;&gt;github.com/VaalaCat/frp&#45;panel/services/rpcclient.GetClientRPCSerivce -->
<g id="edge44" class="edge">
<title>github.com/VaalaCat/frp&#45;panel/cmd.runServer&#45;&gt;github.com/VaalaCat/frp&#45;panel/services/rpcclient.GetClientRPCSerivce</title>
<g id="a_edge44"><a xlink:title="at server.go:34: calling [github.com/VaalaCat/frp&#45;panel/services/rpcclient.GetClientRPCSerivce]">
<path fill="none" stroke="#8b4513" d="M246.8238,-1015.8217C266.012,-1028.514 293.0853,-1045.2379 318.5344,-1056.8 323.4323,-1059.0252 328.5585,-1061.1504 333.7676,-1063.1631"/>
<polygon fill="#8b4513" stroke="#8b4513" points="332.6094,-1066.4665 343.2024,-1066.6622 335.0435,-1059.9033 332.6094,-1066.4665"/>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.runServer&#45;&gt;(*github.com/VaalaCat/frp&#45;panel/services/rpcclient.ClientRPC).Stop -->
<g id="edge14" class="edge">
<title>github.com/VaalaCat/frp&#45;panel/cmd.runServer&#45;&gt;(*github.com/VaalaCat/frp&#45;panel/services/rpcclient.ClientRPC).Stop</title>
<g id="a_edge14"><a xlink:title="at server.go:35: calling [(*github.com/VaalaCat/frp&#45;panel/services/rpcclient.ClientRPC).Stop]">
<path fill="none" stroke="#8b4513" stroke-dasharray="5,2" d="M231.3501,-1016.0562C247.1694,-1041.8225 279.3582,-1088.7264 318.5344,-1115.8 320.3849,-1117.0788 322.2948,-1118.3075 324.2522,-1119.4878"/>
<polygon fill="#8b4513" stroke="#8b4513" points="338.2197,-1130.0711 348.7497,-1131.2413 341.2477,-1123.76 338.2197,-1130.0711"/>
<polyline fill="none" stroke="#8b4513" points="339.7337,-1126.9155 335.2257,-1124.7527 "/>
<polygon fill="none" stroke="#8b4513" points="324.4065,-1119.5618 331.5464,-1118.5508 335.2257,-1124.7527 328.0858,-1125.7636 324.4065,-1119.5618"/>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.runServer&#45;&gt;github.com/VaalaCat/frp&#45;panel/watcher.NewClient -->
<g id="edge6" class="edge">
<title>github.com/VaalaCat/frp&#45;panel/cmd.runServer&#45;&gt;github.com/VaalaCat/frp&#45;panel/watcher.NewClient</title>
<g id="a_edge6"><a xlink:title="at server.go:37: calling [github.com/VaalaCat/frp&#45;panel/watcher.NewClient]">
<path fill="none" stroke="#8b4513" d="M223.8784,-1015.9324C234.8306,-1077.826 273.4033,-1279.4301 318.5344,-1324.8 330.0473,-1336.3738 346.2159,-1343.4865 361.5227,-1347.856"/>
<polygon fill="#8b4513" stroke="#8b4513" points="360.8468,-1351.2952 371.3995,-1350.3506 362.561,-1344.5083 360.8468,-1351.2952"/>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.runServer&#45;&gt;(*github.com/VaalaCat/frp&#45;panel/watcher.client).Stop -->
<g id="edge3" class="edge">
<title>github.com/VaalaCat/frp&#45;panel/cmd.runServer&#45;&gt;(*github.com/VaalaCat/frp&#45;panel/watcher.client).Stop</title>
<g id="a_edge3"><a xlink:title="at server.go:38: calling [(*github.com/VaalaCat/frp&#45;panel/watcher.client).Stop]">
<path fill="none" stroke="#8b4513" stroke-dasharray="5,2" d="M222.0498,-1016.0369C226.4027,-1064.0172 244.7885,-1194.9386 318.5344,-1265.8 324.1501,-1271.1961 330.8073,-1275.5523 337.9039,-1279.0691"/>
<polygon fill="#8b4513" stroke="#8b4513" points="353.0472,-1288.2082 363.6418,-1288.2837 355.4067,-1281.6178 353.0472,-1288.2082"/>
<polyline fill="none" stroke="#8b4513" points="354.227,-1284.913 349.5196,-1283.2277 "/>
<polygon fill="none" stroke="#8b4513" points="338.2218,-1279.1828 345.219,-1277.4393 349.5196,-1283.2277 342.5224,-1284.9712 338.2218,-1279.1828"/>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/biz/server.PullConfig -->
<g id="node17" class="node">
<title>github.com/VaalaCat/frp&#45;panel/biz/server.PullConfig</title>
<g id="a_node17"><a xlink:title="github.com/VaalaCat/frp&#45;panel/biz/server.PullConfig | defined in rpc_pull_config.go:15">
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M689.5577,-1034.8C689.5577,-1034.8 643.6515,-1034.8 643.6515,-1034.8 637.6515,-1034.8 631.6515,-1028.8 631.6515,-1022.8 631.6515,-1022.8 631.6515,-1010.8 631.6515,-1010.8 631.6515,-1004.8 637.6515,-998.8 643.6515,-998.8 643.6515,-998.8 689.5577,-998.8 689.5577,-998.8 695.5577,-998.8 701.5577,-1004.8 701.5577,-1010.8 701.5577,-1010.8 701.5577,-1022.8 701.5577,-1022.8 701.5577,-1028.8 695.5577,-1034.8 689.5577,-1034.8"/>
<text text-anchor="middle" x="666.6046" y="-1012.6" font-family="Verdana" font-size="14.00" fill="#000000">PullConfig</text>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.initServerOnce&#45;&gt;github.com/VaalaCat/frp&#45;panel/biz/server.PullConfig -->
<g id="edge31" class="edge">
<title>github.com/VaalaCat/frp&#45;panel/cmd.initServerOnce&#45;&gt;github.com/VaalaCat/frp&#45;panel/biz/server.PullConfig</title>
<g id="a_edge31"><a xlink:title="at server.go:50: calling [github.com/VaalaCat/frp&#45;panel/biz/server.PullConfig]">
<path fill="none" stroke="#8b4513" d="M452.3016,-796.5286C476.8029,-803.557 505.2778,-816.0099 522.4124,-837.8 564.603,-891.4537 503.4476,-939.2715 550.4124,-988.8 568.5269,-1007.9033 597.2258,-1014.9487 621.5683,-1017.1958"/>
<polygon fill="#8b4513" stroke="#8b4513" points="621.4755,-1020.6976 631.6906,-1017.8863 621.952,-1013.7138 621.4755,-1020.6976"/>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.initCommand$2 -->
<g id="node6" class="node">
<title>github.com/VaalaCat/frp&#45;panel/cmd.initCommand$2</title>
<g id="a_node6"><a xlink:title="github.com/VaalaCat/frp&#45;panel/cmd.initCommand$2 | defined in cmd.go:37&#10;at cmd.go:38: calling [github.com/VaalaCat/frp&#45;panel/cmd.runServer]">
<polygon fill="#add8e6" stroke="#000000" stroke-dasharray="1,5" points="115.0063,-1015.8 15.9979,-1015.8 15.9979,-979.8 115.0063,-979.8 115.0063,-1015.8"/>
<text text-anchor="middle" x="65.5021" y="-993.6" font-family="Verdana" font-size="14.00" fill="#000000">initCommand$2</text>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.initCommand$2&#45;&gt;github.com/VaalaCat/frp&#45;panel/cmd.runServer -->
<g id="edge7" class="edge">
<title>github.com/VaalaCat/frp&#45;panel/cmd.initCommand$2&#45;&gt;github.com/VaalaCat/frp&#45;panel/cmd.runServer</title>
<g id="a_edge7"><a xlink:title="at cmd.go:38: calling [github.com/VaalaCat/frp&#45;panel/cmd.runServer]">
<path fill="none" stroke="#000000" d="M115.0565,-997.8C135.5189,-997.8 158.9892,-997.8 178.6089,-997.8"/>
<polygon fill="#000000" stroke="#000000" points="178.7744,-1001.3001 188.7743,-997.8 178.7743,-994.3001 178.7744,-1001.3001"/>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.runMaster -->
<g id="node7" class="node">
<title>github.com/VaalaCat/frp&#45;panel/cmd.runMaster</title>
<g id="a_node7"><a xlink:title="github.com/VaalaCat/frp&#45;panel/cmd.runMaster | defined in master.go:20&#10;at master.go:34: calling [github.com/VaalaCat/frp&#45;panel/conf.FRPsAuthOption]&#10;at master.go:28: calling [github.com/VaalaCat/frp&#45;panel/biz/master/auth.InitAuth]&#10;at master.go:37: calling [github.com/VaalaCat/frp&#45;panel/services/server.GetServerSerivce]&#10;at master.go:23: calling [github.com/VaalaCat/frp&#45;panel/biz/master.NewRouter]&#10;at master.go:32: calling [github.com/VaalaCat/frp&#45;panel/utils.NewBaseFRPServerUserAuthConfig]&#10;at master.go:21: calling [github.com/VaalaCat/frp&#45;panel/services/master.MustInitMasterService]&#10;at master.go:24: calling [github.com/VaalaCat/frp&#45;panel/services/api.MustInitApiService]&#10;at master.go:26: calling [github.com/VaalaCat/frp&#45;panel/cmd.initDatabase]&#10;at master.go:33: calling [github.com/VaalaCat/frp&#45;panel/conf.Get]&#10;at master.go:27: calling [github.com/VaalaCat/frp&#45;panel/cache.InitCache]&#10;at master.go:24: calling [github.com/VaalaCat/frp&#45;panel/conf.MasterAPIListenAddr]&#10;at master.go:31: calling [github.com/VaalaCat/frp&#45;panel/services/master.GetMasterSerivce]&#10;at master.go:38: calling [github.com/VaalaCat/frp&#45;panel/services/api.GetAPIService]">
<path fill="#add8e6" stroke="#000000" stroke-width=".5" d="M241.3012,-506.8C241.3012,-506.8 200.2374,-506.8 200.2374,-506.8 194.2374,-506.8 188.2374,-500.8 188.2374,-494.8 188.2374,-494.8 188.2374,-482.8 188.2374,-482.8 188.2374,-476.8 194.2374,-470.8 200.2374,-470.8 200.2374,-470.8 241.3012,-470.8 241.3012,-470.8 247.3012,-470.8 253.3012,-476.8 253.3012,-482.8 253.3012,-482.8 253.3012,-494.8 253.3012,-494.8 253.3012,-500.8 247.3012,-506.8 241.3012,-506.8"/>
<text text-anchor="middle" x="220.7693" y="-484.6" font-family="Verdana" font-size="14.00" fill="#000000">runMaster</text>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.initDatabase -->
<g id="node8" class="node">
<title>github.com/VaalaCat/frp&#45;panel/cmd.initDatabase</title>
<g id="a_node8"><a xlink:title="github.com/VaalaCat/frp&#45;panel/cmd.initDatabase | defined in master.go:47&#10;at master.go:48: calling [github.com/VaalaCat/frp&#45;panel/conf.Get]&#10;at master.go:49: calling [github.com/VaalaCat/frp&#45;panel/conf.Get]&#10;at master.go:51: calling [github.com/VaalaCat/frp&#45;panel/conf.Get]&#10;at master.go:53: calling [github.com/VaalaCat/frp&#45;panel/conf.Get]&#10;at master.go:60: calling [github.com/VaalaCat/frp&#45;panel/conf.Get]&#10;at master.go:57: calling [github.com/VaalaCat/frp&#45;panel/conf.Get]&#10;at master.go:63: calling [github.com/VaalaCat/frp&#45;panel/models.GetDBManager]&#10;at master.go:56: calling [github.com/VaalaCat/frp&#45;panel/models.GetDBManager]&#10;at master.go:49: calling [github.com/VaalaCat/frp&#45;panel/models.MustInitDBManager]&#10;at master.go:56: calling [(*github.com/VaalaCat/frp&#45;panel/models.dbManagerImpl).SetDB]&#10;at master.go:63: calling [(*github.com/VaalaCat/frp&#45;panel/models.dbManagerImpl).Init]">
<path fill="#add8e6" stroke="#000000" stroke-width=".5" d="M432.9454,-744.8C432.9454,-744.8 379.0014,-744.8 379.0014,-744.8 373.0014,-744.8 367.0014,-738.8 367.0014,-732.8 367.0014,-732.8 367.0014,-720.8 367.0014,-720.8 367.0014,-714.8 373.0014,-708.8 379.0014,-708.8 379.0014,-708.8 432.9454,-708.8 432.9454,-708.8 438.9454,-708.8 444.9454,-714.8 444.9454,-720.8 444.9454,-720.8 444.9454,-732.8 444.9454,-732.8 444.9454,-738.8 438.9454,-744.8 432.9454,-744.8"/>
<text text-anchor="middle" x="405.9734" y="-722.6" font-family="Verdana" font-size="14.00" fill="#000000">initDatabase</text>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.runMaster&#45;&gt;github.com/VaalaCat/frp&#45;panel/cmd.initDatabase -->
<g id="edge25" class="edge">
<title>github.com/VaalaCat/frp&#45;panel/cmd.runMaster&#45;&gt;github.com/VaalaCat/frp&#45;panel/cmd.initDatabase</title>
<g id="a_edge25"><a xlink:title="at master.go:26: calling [github.com/VaalaCat/frp&#45;panel/cmd.initDatabase]">
<path fill="none" stroke="#000000" d="M226.0282,-507.0459C237.4245,-543.8264 267.5592,-627.7887 318.5344,-679.8 329.6176,-691.1085 344.0077,-700.3536 357.9036,-707.5599"/>
<polygon fill="#000000" stroke="#000000" points="356.4066,-710.724 366.9241,-712.0022 359.4992,-704.4442 356.4066,-710.724"/>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/biz/master.NewRouter -->
<g id="node14" class="node">
<title>github.com/VaalaCat/frp&#45;panel/biz/master.NewRouter</title>
<g id="a_node14"><a xlink:title="github.com/VaalaCat/frp&#45;panel/biz/master.NewRouter | defined in handler.go:13">
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M430.0051,-270.8C430.0051,-270.8 381.9417,-270.8 381.9417,-270.8 375.9417,-270.8 369.9417,-264.8 369.9417,-258.8 369.9417,-258.8 369.9417,-246.8 369.9417,-246.8 369.9417,-240.8 375.9417,-234.8 381.9417,-234.8 381.9417,-234.8 430.0051,-234.8 430.0051,-234.8 436.0051,-234.8 442.0051,-240.8 442.0051,-246.8 442.0051,-246.8 442.0051,-258.8 442.0051,-258.8 442.0051,-264.8 436.0051,-270.8 430.0051,-270.8"/>
<text text-anchor="middle" x="405.9734" y="-248.6" font-family="Verdana" font-size="14.00" fill="#000000">NewRouter</text>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.runMaster&#45;&gt;github.com/VaalaCat/frp&#45;panel/biz/master.NewRouter -->
<g id="edge15" class="edge">
<title>github.com/VaalaCat/frp&#45;panel/cmd.runMaster&#45;&gt;github.com/VaalaCat/frp&#45;panel/biz/master.NewRouter</title>
<g id="a_edge15"><a xlink:title="at master.go:23: calling [github.com/VaalaCat/frp&#45;panel/biz/master.NewRouter]">
<path fill="none" stroke="#8b4513" d="M226.9618,-470.725C239.6215,-435.8471 271.3128,-358.2578 318.5344,-307.8 330.5091,-295.0047 346.0823,-283.9639 360.7621,-275.2024"/>
<polygon fill="#8b4513" stroke="#8b4513" points="362.8154,-278.0595 369.7467,-270.0465 359.3313,-271.9882 362.8154,-278.0595"/>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/biz/master/auth.InitAuth -->
<g id="node15" class="node">
<title>github.com/VaalaCat/frp&#45;panel/biz/master/auth.InitAuth</title>
<g id="a_node15"><a xlink:title="github.com/VaalaCat/frp&#45;panel/biz/master/auth.InitAuth | defined in init.go:11">
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M421.9142,-357.8C421.9142,-357.8 390.0326,-357.8 390.0326,-357.8 384.0326,-357.8 378.0326,-351.8 378.0326,-345.8 378.0326,-345.8 378.0326,-333.8 378.0326,-333.8 378.0326,-327.8 384.0326,-321.8 390.0326,-321.8 390.0326,-321.8 421.9142,-321.8 421.9142,-321.8 427.9142,-321.8 433.9142,-327.8 433.9142,-333.8 433.9142,-333.8 433.9142,-345.8 433.9142,-345.8 433.9142,-351.8 427.9142,-357.8 421.9142,-357.8"/>
<text text-anchor="middle" x="405.9734" y="-335.6" font-family="Verdana" font-size="14.00" fill="#000000">InitAuth</text>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.runMaster&#45;&gt;github.com/VaalaCat/frp&#45;panel/biz/master/auth.InitAuth -->
<g id="edge8" class="edge">
<title>github.com/VaalaCat/frp&#45;panel/cmd.runMaster&#45;&gt;github.com/VaalaCat/frp&#45;panel/biz/master/auth.InitAuth</title>
<g id="a_edge8"><a xlink:title="at master.go:28: calling [github.com/VaalaCat/frp&#45;panel/biz/master/auth.InitAuth]">
<path fill="none" stroke="#8b4513" d="M237.4453,-470.683C256.1623,-450.863 287.9291,-418.7311 318.5344,-394.8 334.5074,-382.3103 353.4269,-370.1247 369.5746,-360.4108"/>
<polygon fill="#8b4513" stroke="#8b4513" points="371.4075,-363.3931 378.224,-355.2823 367.8373,-357.3719 371.4075,-363.3931"/>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cache.InitCache -->
<g id="node18" class="node">
<title>github.com/VaalaCat/frp&#45;panel/cache.InitCache</title>
<g id="a_node18"><a xlink:title="github.com/VaalaCat/frp&#45;panel/cache.InitCache | defined in freecache.go:13">
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M425.397,-444.8C425.397,-444.8 386.5498,-444.8 386.5498,-444.8 380.5498,-444.8 374.5498,-438.8 374.5498,-432.8 374.5498,-432.8 374.5498,-420.8 374.5498,-420.8 374.5498,-414.8 380.5498,-408.8 386.5498,-408.8 386.5498,-408.8 425.397,-408.8 425.397,-408.8 431.397,-408.8 437.397,-414.8 437.397,-420.8 437.397,-420.8 437.397,-432.8 437.397,-432.8 437.397,-438.8 431.397,-444.8 425.397,-444.8"/>
<text text-anchor="middle" x="405.9734" y="-422.6" font-family="Verdana" font-size="14.00" fill="#000000">InitCache</text>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.runMaster&#45;&gt;github.com/VaalaCat/frp&#45;panel/cache.InitCache -->
<g id="edge34" class="edge">
<title>github.com/VaalaCat/frp&#45;panel/cmd.runMaster&#45;&gt;github.com/VaalaCat/frp&#45;panel/cache.InitCache</title>
<g id="a_edge34"><a xlink:title="at master.go:27: calling [github.com/VaalaCat/frp&#45;panel/cache.InitCache]">
<path fill="none" stroke="#8b4513" d="M253.3693,-474.1032C272.1739,-465.9706 296.4077,-456.0694 318.5344,-448.8 333.3966,-443.9172 349.9804,-439.494 364.6767,-435.9157"/>
<polygon fill="#8b4513" stroke="#8b4513" points="365.5864,-439.297 374.5052,-433.578 363.9667,-432.487 365.5864,-439.297"/>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/conf.MasterAPIListenAddr -->
<g id="node20" class="node">
<title>github.com/VaalaCat/frp&#45;panel/conf.MasterAPIListenAddr</title>
<g id="a_node20"><a xlink:title="github.com/VaalaCat/frp&#45;panel/conf.MasterAPIListenAddr | defined in helper.go:37">
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M721.2843,-616.8C721.2843,-616.8 611.9249,-616.8 611.9249,-616.8 605.9249,-616.8 599.9249,-610.8 599.9249,-604.8 599.9249,-604.8 599.9249,-592.8 599.9249,-592.8 599.9249,-586.8 605.9249,-580.8 611.9249,-580.8 611.9249,-580.8 721.2843,-580.8 721.2843,-580.8 727.2843,-580.8 733.2843,-586.8 733.2843,-592.8 733.2843,-592.8 733.2843,-604.8 733.2843,-604.8 733.2843,-610.8 727.2843,-616.8 721.2843,-616.8"/>
<text text-anchor="middle" x="666.6046" y="-594.6" font-family="Verdana" font-size="14.00" fill="#000000">MasterAPIListenAddr</text>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.runMaster&#45;&gt;github.com/VaalaCat/frp&#45;panel/conf.MasterAPIListenAddr -->
<g id="edge41" class="edge">
<title>github.com/VaalaCat/frp&#45;panel/cmd.runMaster&#45;&gt;github.com/VaalaCat/frp&#45;panel/conf.MasterAPIListenAddr</title>
<g id="a_edge41"><a xlink:title="at master.go:24: calling [github.com/VaalaCat/frp&#45;panel/conf.MasterAPIListenAddr]">
<path fill="none" stroke="#8b4513" d="M253.3177,-494.3899C272.3143,-497.5865 296.7556,-501.5865 318.5344,-504.8 396.0876,-516.2431 420.5296,-498.929 493.4124,-527.8 522.4252,-539.2928 522.1536,-555.5612 550.4124,-568.8 562.8611,-574.632 576.6117,-579.4506 590.1662,-583.3909"/>
<polygon fill="#8b4513" stroke="#8b4513" points="589.4085,-586.8127 599.9798,-586.1067 591.2756,-580.0663 589.4085,-586.8127"/>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/conf.Get -->
<g id="node21" class="node">
<title>github.com/VaalaCat/frp&#45;panel/conf.Get</title>
<g id="a_node21"><a xlink:title="github.com/VaalaCat/frp&#45;panel/conf.Get | defined in settings.go:44">
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M681.6046,-494.8C681.6046,-494.8 651.6046,-494.8 651.6046,-494.8 645.6046,-494.8 639.6046,-488.8 639.6046,-482.8 639.6046,-482.8 639.6046,-470.8 639.6046,-470.8 639.6046,-464.8 645.6046,-458.8 651.6046,-458.8 651.6046,-458.8 681.6046,-458.8 681.6046,-458.8 687.6046,-458.8 693.6046,-464.8 693.6046,-470.8 693.6046,-470.8 693.6046,-482.8 693.6046,-482.8 693.6046,-488.8 687.6046,-494.8 681.6046,-494.8"/>
<text text-anchor="middle" x="666.6046" y="-472.6" font-family="Verdana" font-size="14.00" fill="#000000">Get</text>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.runMaster&#45;&gt;github.com/VaalaCat/frp&#45;panel/conf.Get -->
<g id="edge26" class="edge">
<title>github.com/VaalaCat/frp&#45;panel/cmd.runMaster&#45;&gt;github.com/VaalaCat/frp&#45;panel/conf.Get</title>
<g id="a_edge26"><a xlink:title="at master.go:33: calling [github.com/VaalaCat/frp&#45;panel/conf.Get]">
<path fill="none" stroke="#8b4513" d="M224.6286,-470.4377C236.7015,-414.9376 275.5191,-250.8963 318.5344,-220.8 350.3762,-198.5214 462.7565,-196.9159 493.4124,-220.8 534.2706,-252.6327 513.8908,-410.0728 550.4124,-446.8 570.9415,-467.4447 603.6816,-474.4899 629.1836,-476.6311"/>
<polygon fill="#8b4513" stroke="#8b4513" points="629.0629,-480.1303 639.2614,-477.2597 629.4987,-473.1439 629.0629,-480.1303"/>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/conf.FRPsAuthOption -->
<g id="node22" class="node">
<title>github.com/VaalaCat/frp&#45;panel/conf.FRPsAuthOption</title>
<g id="a_node22"><a xlink:title="github.com/VaalaCat/frp&#45;panel/conf.FRPsAuthOption | defined in helper.go:47">
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M707.3363,-555.8C707.3363,-555.8 625.8729,-555.8 625.8729,-555.8 619.8729,-555.8 613.8729,-549.8 613.8729,-543.8 613.8729,-543.8 613.8729,-531.8 613.8729,-531.8 613.8729,-525.8 619.8729,-519.8 625.8729,-519.8 625.8729,-519.8 707.3363,-519.8 707.3363,-519.8 713.3363,-519.8 719.3363,-525.8 719.3363,-531.8 719.3363,-531.8 719.3363,-543.8 719.3363,-543.8 719.3363,-549.8 713.3363,-555.8 707.3363,-555.8"/>
<text text-anchor="middle" x="666.6046" y="-533.6" font-family="Verdana" font-size="14.00" fill="#000000">FRPsAuthOption</text>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.runMaster&#45;&gt;github.com/VaalaCat/frp&#45;panel/conf.FRPsAuthOption -->
<g id="edge4" class="edge">
<title>github.com/VaalaCat/frp&#45;panel/cmd.runMaster&#45;&gt;github.com/VaalaCat/frp&#45;panel/conf.FRPsAuthOption</title>
<g id="a_edge4"><a xlink:title="at master.go:34: calling [github.com/VaalaCat/frp&#45;panel/conf.FRPsAuthOption]">
<path fill="none" stroke="#8b4513" d="M253.4944,-489.5532C309.017,-491.1472 425.1263,-495.8495 522.4124,-508.8 549.3384,-512.3843 578.785,-517.9974 604.008,-523.3342"/>
<polygon fill="#8b4513" stroke="#8b4513" points="603.3016,-526.7622 613.8135,-525.4394 604.7711,-519.9181 603.3016,-526.7622"/>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.runMaster&#45;&gt;github.com/VaalaCat/frp&#45;panel/services/api.MustInitApiService -->
<g id="edge23" class="edge">
<title>github.com/VaalaCat/frp&#45;panel/cmd.runMaster&#45;&gt;github.com/VaalaCat/frp&#45;panel/services/api.MustInitApiService</title>
<g id="a_edge23"><a xlink:title="at master.go:24: calling [github.com/VaalaCat/frp&#45;panel/services/api.MustInitApiService]">
<path fill="none" stroke="#8b4513" d="M223.2246,-507.2226C232.5147,-574.221 267.5888,-803.6239 318.5344,-853.8 323.7482,-858.9351 329.9738,-862.9283 336.6677,-866.0256"/>
<polygon fill="#8b4513" stroke="#8b4513" points="335.4481,-869.3069 346.035,-869.7167 338.0144,-862.7942 335.4481,-869.3069"/>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.runMaster&#45;&gt;github.com/VaalaCat/frp&#45;panel/services/api.GetAPIService -->
<g id="edge46" class="edge">
<title>github.com/VaalaCat/frp&#45;panel/cmd.runMaster&#45;&gt;github.com/VaalaCat/frp&#45;panel/services/api.GetAPIService</title>
<g id="a_edge46"><a xlink:title="at master.go:38: calling [github.com/VaalaCat/frp&#45;panel/services/api.GetAPIService]">
<path fill="none" stroke="#8b4513" d="M222.594,-507.2763C230.1681,-580.3042 261.4365,-847.7132 318.5344,-906.8 327.073,-915.636 338.3252,-921.8702 349.9041,-926.2684"/>
<polygon fill="#8b4513" stroke="#8b4513" points="349.0609,-929.6774 359.6549,-929.5479 351.2924,-923.0426 349.0609,-929.6774"/>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/services/master.MustInitMasterService -->
<g id="node32" class="node">
<title>github.com/VaalaCat/frp&#45;panel/services/master.MustInitMasterService</title>
<g id="a_node32"><a xlink:title="github.com/VaalaCat/frp&#45;panel/services/master.MustInitMasterService | defined in grpc_service.go:21">
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M462.5422,-638.8C462.5422,-638.8 349.4046,-638.8 349.4046,-638.8 343.4046,-638.8 337.4046,-632.8 337.4046,-626.8 337.4046,-626.8 337.4046,-614.8 337.4046,-614.8 337.4046,-608.8 343.4046,-602.8 349.4046,-602.8 349.4046,-602.8 462.5422,-602.8 462.5422,-602.8 468.5422,-602.8 474.5422,-608.8 474.5422,-614.8 474.5422,-614.8 474.5422,-626.8 474.5422,-626.8 474.5422,-632.8 468.5422,-638.8 462.5422,-638.8"/>
<text text-anchor="middle" x="405.9734" y="-616.6" font-family="Verdana" font-size="14.00" fill="#000000">MustInitMasterService</text>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.runMaster&#45;&gt;github.com/VaalaCat/frp&#45;panel/services/master.MustInitMasterService -->
<g id="edge22" class="edge">
<title>github.com/VaalaCat/frp&#45;panel/cmd.runMaster&#45;&gt;github.com/VaalaCat/frp&#45;panel/services/master.MustInitMasterService</title>
<g id="a_edge22"><a xlink:title="at master.go:21: calling [github.com/VaalaCat/frp&#45;panel/services/master.MustInitMasterService]">
<path fill="none" stroke="#8b4513" d="M233.6591,-506.8084C250.6993,-529.4033 282.7751,-567.9524 318.5344,-590.8 322.9023,-593.5908 327.5598,-596.1549 332.3643,-598.5051"/>
<polygon fill="#8b4513" stroke="#8b4513" points="331.1949,-601.8179 341.7474,-602.7643 334.0883,-595.4439 331.1949,-601.8179"/>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/services/master.GetMasterSerivce -->
<g id="node33" class="node">
<title>github.com/VaalaCat/frp&#45;panel/services/master.GetMasterSerivce</title>
<g id="a_node33"><a xlink:title="github.com/VaalaCat/frp&#45;panel/services/master.GetMasterSerivce | defined in grpc_service.go:29">
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M448.5324,-577.8C448.5324,-577.8 363.4144,-577.8 363.4144,-577.8 357.4144,-577.8 351.4144,-571.8 351.4144,-565.8 351.4144,-565.8 351.4144,-553.8 351.4144,-553.8 351.4144,-547.8 357.4144,-541.8 363.4144,-541.8 363.4144,-541.8 448.5324,-541.8 448.5324,-541.8 454.5324,-541.8 460.5324,-547.8 460.5324,-553.8 460.5324,-553.8 460.5324,-565.8 460.5324,-565.8 460.5324,-571.8 454.5324,-577.8 448.5324,-577.8"/>
<text text-anchor="middle" x="405.9734" y="-555.6" font-family="Verdana" font-size="14.00" fill="#000000">GetMasterSerivce</text>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.runMaster&#45;&gt;github.com/VaalaCat/frp&#45;panel/services/master.GetMasterSerivce -->
<g id="edge45" class="edge">
<title>github.com/VaalaCat/frp&#45;panel/cmd.runMaster&#45;&gt;github.com/VaalaCat/frp&#45;panel/services/master.GetMasterSerivce</title>
<g id="a_edge45"><a xlink:title="at master.go:31: calling [github.com/VaalaCat/frp&#45;panel/services/master.GetMasterSerivce]">
<path fill="none" stroke="#8b4513" d="M252.5656,-506.9554C271.3114,-517.0905 295.7527,-529.3405 318.5344,-537.8 325.8602,-540.5203 333.6539,-543.0162 341.4545,-545.2719"/>
<polygon fill="#8b4513" stroke="#8b4513" points="340.7328,-548.7037 351.3042,-547.9993 342.6009,-541.9575 340.7328,-548.7037"/>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/services/server.GetServerSerivce -->
<g id="node37" class="node">
<title>github.com/VaalaCat/frp&#45;panel/services/server.GetServerSerivce</title>
<g id="a_node37"><a xlink:title="github.com/VaalaCat/frp&#45;panel/services/server.GetServerSerivce | defined in frps_service.go:45">
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M447.1962,-137.8C447.1962,-137.8 364.7506,-137.8 364.7506,-137.8 358.7506,-137.8 352.7506,-131.8 352.7506,-125.8 352.7506,-125.8 352.7506,-113.8 352.7506,-113.8 352.7506,-107.8 358.7506,-101.8 364.7506,-101.8 364.7506,-101.8 447.1962,-101.8 447.1962,-101.8 453.1962,-101.8 459.1962,-107.8 459.1962,-113.8 459.1962,-113.8 459.1962,-125.8 459.1962,-125.8 459.1962,-131.8 453.1962,-137.8 447.1962,-137.8"/>
<text text-anchor="middle" x="405.9734" y="-115.6" font-family="Verdana" font-size="14.00" fill="#000000">GetServerSerivce</text>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.runMaster&#45;&gt;github.com/VaalaCat/frp&#45;panel/services/server.GetServerSerivce -->
<g id="edge10" class="edge">
<title>github.com/VaalaCat/frp&#45;panel/cmd.runMaster&#45;&gt;github.com/VaalaCat/frp&#45;panel/services/server.GetServerSerivce</title>
<g id="a_edge10"><a xlink:title="at master.go:37: calling [github.com/VaalaCat/frp&#45;panel/services/server.GetServerSerivce]">
<path fill="none" stroke="#8b4513" d="M221.5896,-470.7469C224.4919,-420.9315 237.143,-278.3799 289.5344,-174.8 298.3472,-157.3768 301.8699,-151.9749 318.5344,-141.8 326.0087,-137.2364 334.3922,-133.6167 342.9304,-130.7464"/>
<polygon fill="#8b4513" stroke="#8b4513" points="344.0429,-134.0665 352.5959,-127.8137 342.0104,-127.368 344.0429,-134.0665"/>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/utils.NewBaseFRPServerUserAuthConfig -->
<g id="node38" class="node">
<title>github.com/VaalaCat/frp&#45;panel/utils.NewBaseFRPServerUserAuthConfig</title>
<g id="a_node38"><a xlink:title="github.com/VaalaCat/frp&#45;panel/utils.NewBaseFRPServerUserAuthConfig | defined in frp_config.go:19">
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M762.9893,-346.8C762.9893,-346.8 570.2199,-346.8 570.2199,-346.8 564.2199,-346.8 558.2199,-340.8 558.2199,-334.8 558.2199,-334.8 558.2199,-322.8 558.2199,-322.8 558.2199,-316.8 564.2199,-310.8 570.2199,-310.8 570.2199,-310.8 762.9893,-310.8 762.9893,-310.8 768.9893,-310.8 774.9893,-316.8 774.9893,-322.8 774.9893,-322.8 774.9893,-334.8 774.9893,-334.8 774.9893,-340.8 768.9893,-346.8 762.9893,-346.8"/>
<text text-anchor="middle" x="666.6046" y="-324.6" font-family="Verdana" font-size="14.00" fill="#000000">NewBaseFRPServerUserAuthConfig</text>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.runMaster&#45;&gt;github.com/VaalaCat/frp&#45;panel/utils.NewBaseFRPServerUserAuthConfig -->
<g id="edge20" class="edge">
<title>github.com/VaalaCat/frp&#45;panel/cmd.runMaster&#45;&gt;github.com/VaalaCat/frp&#45;panel/utils.NewBaseFRPServerUserAuthConfig</title>
<g id="a_edge20"><a xlink:title="at master.go:32: calling [github.com/VaalaCat/frp&#45;panel/utils.NewBaseFRPServerUserAuthConfig]">
<path fill="none" stroke="#8b4513" d="M223.782,-470.6163C234.0153,-411.4624 269.5487,-226.5968 318.5344,-196.8 351.7363,-176.6041 459.894,-177.1339 493.4124,-196.8 538.2035,-223.0801 509.2896,-267.0856 550.4124,-298.8 553.7996,-301.4122 557.3908,-303.7984 561.1315,-305.978"/>
<polygon fill="#8b4513" stroke="#8b4513" points="559.6259,-309.1406 570.1057,-310.6979 562.8844,-302.9453 559.6259,-309.1406"/>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.initDatabase&#45;&gt;github.com/VaalaCat/frp&#45;panel/conf.Get -->
<g id="edge16" class="edge">
<title>github.com/VaalaCat/frp&#45;panel/cmd.initDatabase&#45;&gt;github.com/VaalaCat/frp&#45;panel/conf.Get</title>
<g id="a_edge16"><a xlink:title="at master.go:48: calling [github.com/VaalaCat/frp&#45;panel/conf.Get]&#10;at master.go:49: calling [github.com/VaalaCat/frp&#45;panel/conf.Get]&#10;at master.go:51: calling [github.com/VaalaCat/frp&#45;panel/conf.Get]&#10;at master.go:53: calling [github.com/VaalaCat/frp&#45;panel/conf.Get]&#10;at master.go:60: calling [github.com/VaalaCat/frp&#45;panel/conf.Get]&#10;at master.go:57: calling [github.com/VaalaCat/frp&#45;panel/conf.Get]">
<path fill="none" stroke="#8b4513" d="M445.1708,-713.3444C462.0516,-705.8078 480.7734,-694.8423 493.4124,-679.8 545.2189,-618.1427 491.8045,-563.0327 550.4124,-507.8 571.5117,-487.9158 603.9102,-480.4821 629.1408,-477.8424"/>
<polygon fill="#8b4513" stroke="#8b4513" points="629.4413,-481.3296 639.113,-477.0043 628.855,-474.3542 629.4413,-481.3296"/>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/models.MustInitDBManager -->
<g id="node24" class="node">
<title>github.com/VaalaCat/frp&#45;panel/models.MustInitDBManager</title>
<g id="a_node24"><a xlink:title="github.com/VaalaCat/frp&#45;panel/models.MustInitDBManager | defined in db.go:39">
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M717.5191,-764.8C717.5191,-764.8 615.6901,-764.8 615.6901,-764.8 609.6901,-764.8 603.6901,-758.8 603.6901,-752.8 603.6901,-752.8 603.6901,-740.8 603.6901,-740.8 603.6901,-734.8 609.6901,-728.8 615.6901,-728.8 615.6901,-728.8 717.5191,-728.8 717.5191,-728.8 723.5191,-728.8 729.5191,-734.8 729.5191,-740.8 729.5191,-740.8 729.5191,-752.8 729.5191,-752.8 729.5191,-758.8 723.5191,-764.8 717.5191,-764.8"/>
<text text-anchor="middle" x="666.6046" y="-742.6" font-family="Verdana" font-size="14.00" fill="#000000">MustInitDBManager</text>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.initDatabase&#45;&gt;github.com/VaalaCat/frp&#45;panel/models.MustInitDBManager -->
<g id="edge24" class="edge">
<title>github.com/VaalaCat/frp&#45;panel/cmd.initDatabase&#45;&gt;github.com/VaalaCat/frp&#45;panel/models.MustInitDBManager</title>
<g id="a_edge24"><a xlink:title="at master.go:49: calling [github.com/VaalaCat/frp&#45;panel/models.MustInitDBManager]">
<path fill="none" stroke="#8b4513" d="M445.0954,-726.9154C467.7123,-727.2053 496.6956,-727.9566 522.4124,-729.8 545.6277,-731.4641 570.8548,-734.1393 593.6223,-736.8799"/>
<polygon fill="#8b4513" stroke="#8b4513" points="593.202,-740.3545 603.5537,-738.0978 594.0541,-733.4065 593.202,-740.3545"/>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/models.GetDBManager -->
<g id="node25" class="node">
<title>github.com/VaalaCat/frp&#45;panel/models.GetDBManager</title>
<g id="a_node25"><a xlink:title="github.com/VaalaCat/frp&#45;panel/models.GetDBManager | defined in db.go:55">
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M703.5094,-825.8C703.5094,-825.8 629.6998,-825.8 629.6998,-825.8 623.6998,-825.8 617.6998,-819.8 617.6998,-813.8 617.6998,-813.8 617.6998,-801.8 617.6998,-801.8 617.6998,-795.8 623.6998,-789.8 629.6998,-789.8 629.6998,-789.8 703.5094,-789.8 703.5094,-789.8 709.5094,-789.8 715.5094,-795.8 715.5094,-801.8 715.5094,-801.8 715.5094,-813.8 715.5094,-813.8 715.5094,-819.8 709.5094,-825.8 703.5094,-825.8"/>
<text text-anchor="middle" x="666.6046" y="-803.6" font-family="Verdana" font-size="14.00" fill="#000000">GetDBManager</text>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.initDatabase&#45;&gt;github.com/VaalaCat/frp&#45;panel/models.GetDBManager -->
<g id="edge17" class="edge">
<title>github.com/VaalaCat/frp&#45;panel/cmd.initDatabase&#45;&gt;github.com/VaalaCat/frp&#45;panel/models.GetDBManager</title>
<g id="a_edge17"><a xlink:title="at master.go:63: calling [github.com/VaalaCat/frp&#45;panel/models.GetDBManager]&#10;at master.go:56: calling [github.com/VaalaCat/frp&#45;panel/models.GetDBManager]">
<path fill="none" stroke="#8b4513" d="M445.051,-732.9085C468.3063,-737.4964 497.9507,-745.049 522.4124,-756.8 536.434,-763.5357 536.3925,-771.0607 550.4124,-777.8 568.2388,-786.3691 588.8233,-792.7084 607.6684,-797.2933"/>
<polygon fill="#8b4513" stroke="#8b4513" points="607.103,-800.7548 617.6345,-799.598 608.6803,-793.9348 607.103,-800.7548"/>
</a>
</g>
</g>
<!-- (*github.com/VaalaCat/frp&#45;panel/models.dbManagerImpl).Init -->
<g id="node26" class="node">
<title>(*github.com/VaalaCat/frp&#45;panel/models.dbManagerImpl).Init</title>
<g id="a_node26"><a xlink:title="(*github.com/VaalaCat/frp&#45;panel/models.dbManagerImpl).Init | defined in db.go:21">
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M723.5592,-886.8C723.5592,-886.8 609.65,-886.8 609.65,-886.8 603.65,-886.8 597.65,-880.8 597.65,-874.8 597.65,-874.8 597.65,-862.8 597.65,-862.8 597.65,-856.8 603.65,-850.8 609.65,-850.8 609.65,-850.8 723.5592,-850.8 723.5592,-850.8 729.5592,-850.8 735.5592,-856.8 735.5592,-862.8 735.5592,-862.8 735.5592,-874.8 735.5592,-874.8 735.5592,-880.8 729.5592,-886.8 723.5592,-886.8"/>
<text text-anchor="middle" x="666.6046" y="-864.6" font-family="Verdana" font-size="14.00" fill="#000000">(*dbManagerImpl).Init</text>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.initDatabase&#45;&gt;(*github.com/VaalaCat/frp&#45;panel/models.dbManagerImpl).Init -->
<g id="edge38" class="edge">
<title>github.com/VaalaCat/frp&#45;panel/cmd.initDatabase&#45;&gt;(*github.com/VaalaCat/frp&#45;panel/models.dbManagerImpl).Init</title>
<g id="a_edge38"><a xlink:title="at master.go:63: calling [(*github.com/VaalaCat/frp&#45;panel/models.dbManagerImpl).Init]">
<path fill="none" stroke="#8b4513" stroke-dasharray="5,2" d="M445.2958,-737.1386C460.8874,-742.1425 478.594,-749.0016 493.4124,-757.8 508.297,-766.6376 511.8622,-770.0761 522.4124,-783.8 539.13,-805.5466 529.0199,-821.6316 550.4124,-838.8 561.2645,-847.5092 574.3628,-853.7161 587.7967,-858.1334"/>
<polygon fill="#8b4513" stroke="#8b4513" points="587.0281,-861.5561 597.6106,-861.0439 589.0184,-854.845 587.0281,-861.5561"/>
</a>
</g>
</g>
<!-- (*github.com/VaalaCat/frp&#45;panel/models.dbManagerImpl).SetDB -->
<g id="node27" class="node">
<title>(*github.com/VaalaCat/frp&#45;panel/models.dbManagerImpl).SetDB</title>
<g id="a_node27"><a xlink:title="(*github.com/VaalaCat/frp&#45;panel/models.dbManagerImpl).SetDB | defined in db.go:66">
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M732.448,-947.8C732.448,-947.8 600.7612,-947.8 600.7612,-947.8 594.7612,-947.8 588.7612,-941.8 588.7612,-935.8 588.7612,-935.8 588.7612,-923.8 588.7612,-923.8 588.7612,-917.8 594.7612,-911.8 600.7612,-911.8 600.7612,-911.8 732.448,-911.8 732.448,-911.8 738.448,-911.8 744.448,-917.8 744.448,-923.8 744.448,-923.8 744.448,-935.8 744.448,-935.8 744.448,-941.8 738.448,-947.8 732.448,-947.8"/>
<text text-anchor="middle" x="666.6046" y="-925.6" font-family="Verdana" font-size="14.00" fill="#000000">(*dbManagerImpl).SetDB</text>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.initDatabase&#45;&gt;(*github.com/VaalaCat/frp&#45;panel/models.dbManagerImpl).SetDB -->
<g id="edge33" class="edge">
<title>github.com/VaalaCat/frp&#45;panel/cmd.initDatabase&#45;&gt;(*github.com/VaalaCat/frp&#45;panel/models.dbManagerImpl).SetDB</title>
<g id="a_edge33"><a xlink:title="at master.go:56: calling [(*github.com/VaalaCat/frp&#45;panel/models.dbManagerImpl).SetDB]">
<path fill="none" stroke="#8b4513" stroke-dasharray="5,2" d="M445.2514,-734.2139C461.5547,-738.8413 479.8013,-746.2088 493.4124,-757.8 513.8553,-775.209 511.8884,-786.0971 522.4124,-810.8 538.6648,-848.9493 520.3367,-871.2526 550.4124,-899.8 558.6518,-907.6207 568.6527,-913.4709 579.2908,-917.8352"/>
<polygon fill="#8b4513" stroke="#8b4513" points="578.1814,-921.1561 588.7753,-921.3001 580.5835,-914.5811 578.1814,-921.1561"/>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.initCommand$3 -->
<g id="node9" class="node">
<title>github.com/VaalaCat/frp&#45;panel/cmd.initCommand$3</title>
<g id="a_node9"><a xlink:title="github.com/VaalaCat/frp&#45;panel/cmd.initCommand$3 | defined in cmd.go:44&#10;at cmd.go:45: calling [github.com/VaalaCat/frp&#45;panel/cmd.runMaster]">
<polygon fill="#add8e6" stroke="#000000" stroke-dasharray="1,5" points="115.0063,-506.8 15.9979,-506.8 15.9979,-470.8 115.0063,-470.8 115.0063,-506.8"/>
<text text-anchor="middle" x="65.5021" y="-484.6" font-family="Verdana" font-size="14.00" fill="#000000">initCommand$3</text>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.initCommand$3&#45;&gt;github.com/VaalaCat/frp&#45;panel/cmd.runMaster -->
<g id="edge27" class="edge">
<title>github.com/VaalaCat/frp&#45;panel/cmd.initCommand$3&#45;&gt;github.com/VaalaCat/frp&#45;panel/cmd.runMaster</title>
<g id="a_edge27"><a xlink:title="at cmd.go:45: calling [github.com/VaalaCat/frp&#45;panel/cmd.runMaster]">
<path fill="none" stroke="#000000" d="M115.0565,-488.8C135.218,-488.8 158.2996,-488.8 177.7409,-488.8"/>
<polygon fill="#000000" stroke="#000000" points="177.8323,-492.3001 187.8322,-488.8 177.8322,-485.3001 177.8323,-492.3001"/>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.main -->
<g id="node10" class="node">
<title>github.com/VaalaCat/frp&#45;panel/cmd.main</title>
<g id="a_node10"><a xlink:title="github.com/VaalaCat/frp&#45;panel/cmd.main | defined in main.go:10&#10;at main.go:16: calling [github.com/VaalaCat/frp&#45;panel/utils.MD5]&#10;at main.go:13: calling [github.com/VaalaCat/frp&#45;panel/conf.InitConfig]&#10;at main.go:14: calling [github.com/VaalaCat/frp&#45;panel/rpc.InitRPCClients]&#10;at main.go:16: calling [github.com/VaalaCat/frp&#45;panel/conf.Get]&#10;at main.go:12: calling [github.com/VaalaCat/frp&#45;panel/cmd.initCommand]&#10;at main.go:11: calling [github.com/VaalaCat/frp&#45;panel/cmd.initLogger]">
<path fill="#add8e6" stroke="#000000" stroke-width=".5" d="M420.9734,-76.8C420.9734,-76.8 390.9734,-76.8 390.9734,-76.8 384.9734,-76.8 378.9734,-70.8 378.9734,-64.8 378.9734,-64.8 378.9734,-52.8 378.9734,-52.8 378.9734,-46.8 384.9734,-40.8 390.9734,-40.8 390.9734,-40.8 420.9734,-40.8 420.9734,-40.8 426.9734,-40.8 432.9734,-46.8 432.9734,-52.8 432.9734,-52.8 432.9734,-64.8 432.9734,-64.8 432.9734,-70.8 426.9734,-76.8 420.9734,-76.8"/>
<text text-anchor="middle" x="405.9734" y="-54.6" font-family="Verdana" font-size="14.00" fill="#000000">main</text>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.initLogger -->
<g id="node11" class="node">
<title>github.com/VaalaCat/frp&#45;panel/cmd.initLogger</title>
<g id="a_node11"><a xlink:title="github.com/VaalaCat/frp&#45;panel/cmd.initLogger | defined in cmd.go:59">
<path fill="#add8e6" stroke="#000000" stroke-width=".5" d="M688.2043,-163.8C688.2043,-163.8 645.0049,-163.8 645.0049,-163.8 639.0049,-163.8 633.0049,-157.8 633.0049,-151.8 633.0049,-151.8 633.0049,-139.8 633.0049,-139.8 633.0049,-133.8 639.0049,-127.8 645.0049,-127.8 645.0049,-127.8 688.2043,-127.8 688.2043,-127.8 694.2043,-127.8 700.2043,-133.8 700.2043,-139.8 700.2043,-139.8 700.2043,-151.8 700.2043,-151.8 700.2043,-157.8 694.2043,-163.8 688.2043,-163.8"/>
<text text-anchor="middle" x="666.6046" y="-141.6" font-family="Verdana" font-size="14.00" fill="#000000">initLogger</text>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.main&#45;&gt;github.com/VaalaCat/frp&#45;panel/cmd.initLogger -->
<g id="edge42" class="edge">
<title>github.com/VaalaCat/frp&#45;panel/cmd.main&#45;&gt;github.com/VaalaCat/frp&#45;panel/cmd.initLogger</title>
<g id="a_edge42"><a xlink:title="at main.go:11: calling [github.com/VaalaCat/frp&#45;panel/cmd.initLogger]">
<path fill="none" stroke="#000000" d="M433.0287,-65.9248C450.6455,-71.0089 473.8941,-78.5687 493.4124,-87.8 520.4987,-100.6106 522.5341,-112.8192 550.4124,-123.8 573.4168,-132.861 600.4906,-138.2656 622.7143,-141.4486"/>
<polygon fill="#000000" stroke="#000000" points="622.4985,-144.9507 632.8727,-142.7995 623.4213,-138.0118 622.4985,-144.9507"/>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.initCommand -->
<g id="node12" class="node">
<title>github.com/VaalaCat/frp&#45;panel/cmd.initCommand</title>
<g id="a_node12"><a xlink:title="github.com/VaalaCat/frp&#45;panel/cmd.initCommand | defined in cmd.go:20">
<path fill="#add8e6" stroke="#000000" stroke-width=".5" d="M697.1088,-224.8C697.1088,-224.8 636.1004,-224.8 636.1004,-224.8 630.1004,-224.8 624.1004,-218.8 624.1004,-212.8 624.1004,-212.8 624.1004,-200.8 624.1004,-200.8 624.1004,-194.8 630.1004,-188.8 636.1004,-188.8 636.1004,-188.8 697.1088,-188.8 697.1088,-188.8 703.1088,-188.8 709.1088,-194.8 709.1088,-200.8 709.1088,-200.8 709.1088,-212.8 709.1088,-212.8 709.1088,-218.8 703.1088,-224.8 697.1088,-224.8"/>
<text text-anchor="middle" x="666.6046" y="-202.6" font-family="Verdana" font-size="14.00" fill="#000000">initCommand</text>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.main&#45;&gt;github.com/VaalaCat/frp&#45;panel/cmd.initCommand -->
<g id="edge28" class="edge">
<title>github.com/VaalaCat/frp&#45;panel/cmd.main&#45;&gt;github.com/VaalaCat/frp&#45;panel/cmd.initCommand</title>
<g id="a_edge28"><a xlink:title="at main.go:12: calling [github.com/VaalaCat/frp&#45;panel/cmd.initCommand]">
<path fill="none" stroke="#000000" d="M433.072,-62.8866C451.5898,-66.7802 475.8597,-74.1575 493.4124,-87.8 530.5001,-116.6258 512.3722,-149.2434 550.4124,-176.8 568.8375,-190.1473 592.6867,-197.5663 613.9796,-201.686"/>
<polygon fill="#000000" stroke="#000000" points="613.4203,-205.1412 623.872,-203.4055 614.6192,-198.2446 613.4203,-205.1412"/>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.main&#45;&gt;github.com/VaalaCat/frp&#45;panel/conf.Get -->
<g id="edge19" class="edge">
<title>github.com/VaalaCat/frp&#45;panel/cmd.main&#45;&gt;github.com/VaalaCat/frp&#45;panel/conf.Get</title>
<g id="a_edge19"><a xlink:title="at main.go:16: calling [github.com/VaalaCat/frp&#45;panel/conf.Get]">
<path fill="none" stroke="#8b4513" d="M433.3215,-60.6313C452.9568,-63.4493 478.4916,-70.4668 493.4124,-87.8 518.1288,-116.5125 516.4421,-218.3879 522.4124,-255.8 529.1726,-298.1621 521.7462,-414.8862 550.4124,-446.8 569.9902,-468.5958 603.12,-475.4984 629.0056,-477.2932"/>
<polygon fill="#8b4513" stroke="#8b4513" points="629.086,-480.8007 639.238,-477.7698 629.4117,-473.8082 629.086,-480.8007"/>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/conf.InitConfig -->
<g id="node23" class="node">
<title>github.com/VaalaCat/frp&#45;panel/conf.InitConfig</title>
<g id="a_node23"><a xlink:title="github.com/VaalaCat/frp&#45;panel/conf.InitConfig | defined in settings.go:48">
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M687.935,-433.8C687.935,-433.8 645.2742,-433.8 645.2742,-433.8 639.2742,-433.8 633.2742,-427.8 633.2742,-421.8 633.2742,-421.8 633.2742,-409.8 633.2742,-409.8 633.2742,-403.8 639.2742,-397.8 645.2742,-397.8 645.2742,-397.8 687.935,-397.8 687.935,-397.8 693.935,-397.8 699.935,-403.8 699.935,-409.8 699.935,-409.8 699.935,-421.8 699.935,-421.8 699.935,-427.8 693.935,-433.8 687.935,-433.8"/>
<text text-anchor="middle" x="666.6046" y="-411.6" font-family="Verdana" font-size="14.00" fill="#000000">InitConfig</text>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.main&#45;&gt;github.com/VaalaCat/frp&#45;panel/conf.InitConfig -->
<g id="edge11" class="edge">
<title>github.com/VaalaCat/frp&#45;panel/cmd.main&#45;&gt;github.com/VaalaCat/frp&#45;panel/conf.InitConfig</title>
<g id="a_edge11"><a xlink:title="at main.go:13: calling [github.com/VaalaCat/frp&#45;panel/conf.InitConfig]">
<path fill="none" stroke="#8b4513" d="M433.161,-60.7717C452.7143,-63.6614 478.217,-70.7071 493.4124,-87.8 535.92,-135.6156 510.4188,-165.9558 522.4124,-228.8 535.8637,-299.282 501.2758,-335.5101 550.4124,-387.8 568.8134,-407.3818 598.3306,-414.3174 623.0088,-416.3903"/>
<polygon fill="#8b4513" stroke="#8b4513" points="623.0509,-419.899 633.2425,-417.0036 623.4698,-412.9115 623.0509,-419.899"/>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/rpc.InitRPCClients -->
<g id="node28" class="node">
<title>github.com/VaalaCat/frp&#45;panel/rpc.InitRPCClients</title>
<g id="a_node28"><a xlink:title="github.com/VaalaCat/frp&#45;panel/rpc.InitRPCClients | defined in init.go:3">
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M701.1708,-84.8C701.1708,-84.8 632.0384,-84.8 632.0384,-84.8 626.0384,-84.8 620.0384,-78.8 620.0384,-72.8 620.0384,-72.8 620.0384,-60.8 620.0384,-60.8 620.0384,-54.8 626.0384,-48.8 632.0384,-48.8 632.0384,-48.8 701.1708,-48.8 701.1708,-48.8 707.1708,-48.8 713.1708,-54.8 713.1708,-60.8 713.1708,-60.8 713.1708,-72.8 713.1708,-72.8 713.1708,-78.8 707.1708,-84.8 701.1708,-84.8"/>
<text text-anchor="middle" x="666.6046" y="-62.6" font-family="Verdana" font-size="14.00" fill="#000000">InitRPCClients</text>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.main&#45;&gt;github.com/VaalaCat/frp&#45;panel/rpc.InitRPCClients -->
<g id="edge18" class="edge">
<title>github.com/VaalaCat/frp&#45;panel/cmd.main&#45;&gt;github.com/VaalaCat/frp&#45;panel/rpc.InitRPCClients</title>
<g id="a_edge18"><a xlink:title="at main.go:14: calling [github.com/VaalaCat/frp&#45;panel/rpc.InitRPCClients]">
<path fill="none" stroke="#8b4513" d="M433.3729,-59.641C474.9961,-60.9186 555.0779,-63.3767 609.6698,-65.0524"/>
<polygon fill="#8b4513" stroke="#8b4513" points="609.7876,-68.5576 619.8903,-65.3661 610.0024,-61.5609 609.7876,-68.5576"/>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/utils.MD5 -->
<g id="node39" class="node">
<title>github.com/VaalaCat/frp&#45;panel/utils.MD5</title>
<g id="a_node39"><a xlink:title="github.com/VaalaCat/frp&#45;panel/utils.MD5 | defined in hash.go:12">
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M681.6046,-285.8C681.6046,-285.8 651.6046,-285.8 651.6046,-285.8 645.6046,-285.8 639.6046,-279.8 639.6046,-273.8 639.6046,-273.8 639.6046,-261.8 639.6046,-261.8 639.6046,-255.8 645.6046,-249.8 651.6046,-249.8 651.6046,-249.8 681.6046,-249.8 681.6046,-249.8 687.6046,-249.8 693.6046,-255.8 693.6046,-261.8 693.6046,-261.8 693.6046,-273.8 693.6046,-273.8 693.6046,-279.8 687.6046,-285.8 681.6046,-285.8"/>
<text text-anchor="middle" x="666.6046" y="-263.6" font-family="Verdana" font-size="14.00" fill="#000000">MD5</text>
</a>
</g>
</g>
<!-- github.com/VaalaCat/frp&#45;panel/cmd.main&#45;&gt;github.com/VaalaCat/frp&#45;panel/utils.MD5 -->
<g id="edge9" class="edge">
<title>github.com/VaalaCat/frp&#45;panel/cmd.main&#45;&gt;github.com/VaalaCat/frp&#45;panel/utils.MD5</title>
<g id="a_edge9"><a xlink:title="at main.go:16: calling [github.com/VaalaCat/frp&#45;panel/utils.MD5]">
<path fill="none" stroke="#8b4513" d="M433.2773,-61.5713C452.3756,-64.8635 477.2607,-72.0626 493.4124,-87.8 520.1466,-113.8484 522.005,-221.5874 550.4124,-245.8 572.0141,-264.2119 604.1708,-269.1536 629.1824,-269.8043"/>
<polygon fill="#8b4513" stroke="#8b4513" points="629.3979,-273.3052 639.4125,-269.8473 629.4273,-266.3052 629.3979,-273.3052"/>
</a>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 82 KiB

112
go.mod Normal file
View File

@@ -0,0 +1,112 @@
module github.com/VaalaCat/frp-panel
go 1.21.5
require (
github.com/coocood/freecache v1.2.4
github.com/fatedier/frp v0.53.2
github.com/fatedier/golib v0.1.1-0.20230725122706-dcbaee8eef40
github.com/gin-gonic/gin v1.9.1
github.com/glebarez/sqlite v1.10.0
github.com/go-co-op/gocron/v2 v2.1.2
github.com/golang-jwt/jwt/v5 v5.2.0
github.com/google/uuid v1.5.0
github.com/ilyakaznacheev/cleanenv v1.5.0
github.com/joho/godotenv v1.5.1
github.com/samber/lo v1.38.1
github.com/sirupsen/logrus v1.9.3
github.com/sourcegraph/conc v0.3.0
github.com/spf13/cobra v1.8.0
golang.org/x/crypto v0.16.0
google.golang.org/grpc v1.60.1
google.golang.org/protobuf v1.31.0
gorm.io/gorm v1.25.5
k8s.io/apimachinery v0.27.4
)
require (
github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c // indirect
github.com/BurntSushi/toml v1.3.2 // indirect
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/bytedance/sonic v1.9.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
github.com/coreos/go-oidc/v3 v3.6.0 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/fatedier/beego v0.0.0-20171024143340-6c6a4f5bd5eb // indirect
github.com/fatedier/kcp-go v2.0.4-0.20190803094908-fe8645b0a904+incompatible // indirect
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/glebarez/go-sqlite v1.21.2 // indirect
github.com/go-jose/go-jose/v3 v3.0.0 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.14.0 // indirect
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/golang/mock v1.6.0 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 // indirect
github.com/gorilla/mux v1.8.0 // indirect
github.com/hashicorp/yamux v0.1.1 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/jonboulle/clockwork v0.4.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
github.com/klauspost/reedsolomon v1.9.15 // indirect
github.com/leodido/go-urn v1.2.4 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/onsi/ginkgo/v2 v2.11.0 // indirect
github.com/pelletier/go-toml/v2 v2.1.0 // indirect
github.com/pion/dtls/v2 v2.2.7 // indirect
github.com/pion/logging v0.2.2 // indirect
github.com/pion/stun v0.6.1 // indirect
github.com/pion/transport/v2 v2.2.1 // indirect
github.com/pires/go-proxyproto v0.7.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/client_golang v1.16.0 // indirect
github.com/prometheus/client_model v0.3.0 // indirect
github.com/prometheus/common v0.42.0 // indirect
github.com/prometheus/procfs v0.10.1 // indirect
github.com/quic-go/qtls-go1-20 v0.3.1 // indirect
github.com/quic-go/quic-go v0.37.4 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/robfig/cron/v3 v3.0.1 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161 // indirect
github.com/templexxx/xor v0.0.0-20191217153810-f85b25db303b // indirect
github.com/tjfoc/gmsm v1.4.1 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.11 // indirect
golang.org/x/arch v0.3.0 // indirect
golang.org/x/exp v0.0.0-20231219180239-dc181d75b848 // indirect
golang.org/x/mod v0.14.0 // indirect
golang.org/x/net v0.19.0 // indirect
golang.org/x/oauth2 v0.15.0 // indirect
golang.org/x/sync v0.5.0 // indirect
golang.org/x/sys v0.15.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/time v0.5.0 // indirect
golang.org/x/tools v0.16.0 // indirect
google.golang.org/appengine v1.6.8 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20231002182017-d307bd883b97 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
modernc.org/libc v1.22.5 // indirect
modernc.org/mathutil v1.5.0 // indirect
modernc.org/memory v1.5.0 // indirect
modernc.org/sqlite v1.23.1 // indirect
olympos.io/encoding/edn v0.0.0-20201019073823-d3554ca0b0a3 // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/yaml v1.3.0 // indirect
)

380
go.sum Normal file
View File

@@ -0,0 +1,380 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c h1:/IBSNwUN8+eKzUzbJPqhK839ygXJ82sde8x3ogr6R28=
github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s=
github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams=
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/coocood/freecache v1.2.4 h1:UdR6Yz/X1HW4fZOuH0Z94KwG851GWOSknua5VUbb/5M=
github.com/coocood/freecache v1.2.4/go.mod h1:RBUWa/Cy+OHdfTGFEhEuE1pMCMX51Ncizj7rthiQ3vk=
github.com/coreos/go-oidc/v3 v3.6.0 h1:AKVxfYw1Gmkn/w96z0DbT/B/xFnzTd3MkZvWLjF4n/o=
github.com/coreos/go-oidc/v3 v3.6.0/go.mod h1:ZpHUsHBucTUj6WOkrP4E20UPynbLZzhTQ1XKCXkxyPc=
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/fatedier/beego v0.0.0-20171024143340-6c6a4f5bd5eb h1:wCrNShQidLmvVWn/0PikGmpdP0vtQmnvyRg3ZBEhczw=
github.com/fatedier/beego v0.0.0-20171024143340-6c6a4f5bd5eb/go.mod h1:wx3gB6dbIfBRcucp94PI9Bt3I0F2c/MyNEWuhzpWiwk=
github.com/fatedier/frp v0.53.2 h1:rbNcXJyKLrEnvurRfGDhSG3BERH7cfv1XRjIs6MSY4s=
github.com/fatedier/frp v0.53.2/go.mod h1:BNJZ9il1aazwhaLeiO2cQCBhY/c9Lq+HP73144bNUkk=
github.com/fatedier/golib v0.1.1-0.20230725122706-dcbaee8eef40 h1:BVdpWT6viE/mpuRa6txNyRNjtHa1Efrii9Du6/gHfJ0=
github.com/fatedier/golib v0.1.1-0.20230725122706-dcbaee8eef40/go.mod h1:Lmi9U4VfvdRvonSMh1FgXVy1hCXycVyJk4E9ktokknE=
github.com/fatedier/kcp-go v2.0.4-0.20190803094908-fe8645b0a904+incompatible h1:ssXat9YXFvigNge/IkkZvFMn8yeYKFX+uI6wn2mLJ74=
github.com/fatedier/kcp-go v2.0.4-0.20190803094908-fe8645b0a904+incompatible/go.mod h1:YpCOaxj7vvMThhIQ9AfTOPW2sfztQR5WDfs7AflSy4s=
github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=
github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU=
github.com/glebarez/go-sqlite v1.21.2 h1:3a6LFC4sKahUunAmynQKLZceZCOzUthkRkEAl9gAXWo=
github.com/glebarez/go-sqlite v1.21.2/go.mod h1:sfxdZyhQjTM2Wry3gVYWaW072Ri1WMdWJi0k6+3382k=
github.com/glebarez/sqlite v1.10.0 h1:u4gt8y7OND/cCei/NMHmfbLxF6xP2wgKcT/BJf2pYkc=
github.com/glebarez/sqlite v1.10.0/go.mod h1:IJ+lfSOmiekhQsFTJRx/lHtGYmCdtAiTaf5wI9u5uHA=
github.com/go-co-op/gocron/v2 v2.1.2 h1:+6tTOA9aBaKXpDWExw07hYoGEBzT+4CkGSVAiJ7WSXs=
github.com/go-co-op/gocron/v2 v2.1.2/go.mod h1:0MfNAXEchzeSH1vtkZrTAcSMWqyL435kL6CA4b0bjrg=
github.com/go-jose/go-jose/v3 v3.0.0 h1:s6rrhirfEP/CGIoc6p+PZAeogN2SxKav6Wp7+dyMWVo=
github.com/go-jose/go-jose/v3 v3.0.0/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8=
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js=
github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/golang-jwt/jwt/v5 v5.2.0 h1:d/ix8ftRUorsN+5eMIlF4T6J8CAt9rch3My2winC1Jw=
github.com/golang-jwt/jwt/v5 v5.2.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ=
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo=
github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU=
github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE=
github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ=
github.com/ilyakaznacheev/cleanenv v1.5.0 h1:0VNZXggJE2OYdXE87bfSSwGxeiGt9moSR2lOrsHHvr4=
github.com/ilyakaznacheev/cleanenv v1.5.0/go.mod h1:a5aDzaJrLCQZsazHol1w8InnDcOX0OColm64SlIi6gk=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4=
github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/klauspost/cpuid/v2 v2.0.6/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk=
github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
github.com/klauspost/reedsolomon v1.9.15 h1:g2erWKD2M6rgnPf89fCji6jNlhMKMdXcuNHMW1SYCIo=
github.com/klauspost/reedsolomon v1.9.15/go.mod h1:eqPAcE7xar5CIzcdfwydOEdcmchAKAP/qs14y4GCBOk=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU=
github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM=
github.com/onsi/gomega v1.27.8 h1:gegWiwZjBsf2DgiSbf5hpokZ98JVDMcWkUiigk6/KXc=
github.com/onsi/gomega v1.27.8/go.mod h1:2J8vzI/s+2shY9XHRApDkdgPo1TKT7P2u6fXeJKFnNQ=
github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4=
github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
github.com/pion/dtls/v2 v2.2.7 h1:cSUBsETxepsCSFSxC3mc/aDo14qQLMSL+O6IjG28yV8=
github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s=
github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY=
github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms=
github.com/pion/stun v0.6.1 h1:8lp6YejULeHBF8NmV8e2787BogQhduZugh5PdhDyyN4=
github.com/pion/stun v0.6.1/go.mod h1:/hO7APkX4hZKu/D0f2lHzNyvdkTGtIy3NDmLR7kSz/8=
github.com/pion/transport/v2 v2.2.1 h1:7qYnCBlpgSJNYMbLCKuSY9KbQdBFoETvPNETv0y4N7c=
github.com/pion/transport/v2 v2.2.1/go.mod h1:cXXWavvCnFF6McHTft3DWS9iic2Mftcz1Aq29pGcU5g=
github.com/pires/go-proxyproto v0.7.0 h1:IukmRewDQFWC7kfnb66CSomk2q/seBuilHBYFwyq0Hs=
github.com/pires/go-proxyproto v0.7.0/go.mod h1:Vz/1JPY/OACxWGQNIRY2BeyDmpoaWmEP40O9LbuiFR4=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8=
github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4=
github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=
github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM=
github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc=
github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg=
github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM=
github.com/quic-go/qtls-go1-20 v0.3.1 h1:O4BLOM3hwfVF3AcktIylQXyl7Yi2iBNVy5QsV+ySxbg=
github.com/quic-go/qtls-go1-20 v0.3.1/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k=
github.com/quic-go/quic-go v0.37.4 h1:ke8B73yMCWGq9MfrCCAw0Uzdm7GaViC3i39dsIdDlH4=
github.com/quic-go/quic-go v0.37.4/go.mod h1:YsbH1r4mSHPJcLF4k4zruUkLBqctEMBDR6VPvcYjIsU=
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/samber/lo v1.38.1 h1:j2XEAqXKb09Am4ebOg31SpvzUTTs6EN3VfgeLUhPdXM=
github.com/samber/lo v1.38.1/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161 h1:89CEmDvlq/F7SJEOqkIdNDGJXrQIhuIx9D2DBXjavSU=
github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161/go.mod h1:wM7WEvslTq+iOEAMDLSzhVuOt5BRZ05WirO+b09GHQU=
github.com/templexxx/xor v0.0.0-20191217153810-f85b25db303b h1:fj5tQ8acgNUr6O8LEplsxDhUIe2573iLkJc+PqnzZTI=
github.com/templexxx/xor v0.0.0-20191217153810-f85b25db303b/go.mod h1:5XA7W9S6mni3h5uvOC75dA3m9CCCaS83lltmc0ukdi4=
github.com/tjfoc/gmsm v1.4.1 h1:aMe1GlZb+0bLjn+cKTPEvvn9oUEBlJitaZiiBwsbgho=
github.com/tjfoc/gmsm v1.4.1/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVcTE=
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
github.com/xtaci/lossyconn v0.0.0-20200209145036-adba10fffc37 h1:EWU6Pktpas0n8lLQwDsRyZfmkPeRbdgPtW609es+/9E=
github.com/xtaci/lossyconn v0.0.0-20200209145036-adba10fffc37/go.mod h1:HpMP7DB2CyokmAh4lp0EQnnWhmycP/TvwBGzvuie+H0=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k=
golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE=
golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY=
golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20231219180239-dc181d75b848 h1:+iq7lrkxmFNBM7xx+Rae2W6uyPfhPeDWD+n+JgppptE=
golang.org/x/exp v0.0.0-20231219180239-dc181d75b848/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=
golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c=
golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.15.0 h1:s8pnnxNVzjWyrvYdFUQq5llS1PX2zhPXmccZv99h7uQ=
golang.org/x/oauth2 v0.15.0/go.mod h1:q48ptWNTY5XWf+JNten23lcvHpLJ0ZSxF5ttTHKVCAM=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=
golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4=
golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.16.0 h1:GO788SKMRunPIBCXiQyo2AaexLstOrVhuAL5YwsckQM=
golang.org/x/tools v0.16.0/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto/googleapis/rpc v0.0.0-20231002182017-d307bd883b97 h1:6GQBEOdGkX6MMTLT9V+TjtIRZCw9VPD5Z+yHY9wMgS0=
google.golang.org/genproto/googleapis/rpc v0.0.0-20231002182017-d307bd883b97/go.mod h1:v7nGkzlmW8P3n/bKmWBn2WpBjpOEx8Q6gMueudAmKfY=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.60.1 h1:26+wFr+cNqSGFcOXcabYC0lUVJVRa2Sb2ortSK7VrEU=
google.golang.org/grpc v1.60.1/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gorm.io/gorm v1.25.5 h1:zR9lOiiYf09VNh5Q1gphfyia1JpiClIWG9hQaxB/mls=
gorm.io/gorm v1.25.5/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
k8s.io/apimachinery v0.27.4 h1:CdxflD4AF61yewuid0fLl6bM4a3q04jWel0IlP+aYjs=
k8s.io/apimachinery v0.27.4/go.mod h1:XNfZ6xklnMCOGGFNqXG7bUrQCoR04dh/E7FprV6pb+E=
modernc.org/libc v1.22.5 h1:91BNch/e5B0uPbJFgqbxXuOnxBQjlS//icfQEGmvyjE=
modernc.org/libc v1.22.5/go.mod h1:jj+Z7dTNX8fBScMVNRAYZ/jF91K8fdT2hYMThc3YjBY=
modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ=
modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
modernc.org/memory v1.5.0 h1:N+/8c5rE6EqugZwHii4IFsaJ7MUhoWX07J5tC/iI5Ds=
modernc.org/memory v1.5.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
modernc.org/sqlite v1.23.1 h1:nrSBg4aRQQwq59JpvGEQ15tNxoO5pX/kUjcRNwSAGQM=
modernc.org/sqlite v1.23.1/go.mod h1:OrDj17Mggn6MhE+iPbBNf7RGKODDE9NFT0f3EwDzJqk=
olympos.io/encoding/edn v0.0.0-20201019073823-d3554ca0b0a3 h1:slmdOY3vp8a7KQbHkL+FLbvbkgMqmXojpFUO/jENuqQ=
olympos.io/encoding/edn v0.0.0-20201019073823-d3554ca0b0a3/go.mod h1:oVgVk4OWVDi43qWBEyGhXgYxt7+ED4iYNpTngSLX2Iw=
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=

25
idl/api_auth.proto Normal file
View File

@@ -0,0 +1,25 @@
syntax = "proto3";
package api_auth;
import "common.proto";
option go_package="../pb";
message LoginRequest {
optional string username = 1;
optional string password = 2;
}
message LoginResponse {
optional common.Status status = 1;
optional string token = 2;
}
message RegisterRequest {
optional string username = 1;
optional string password = 2;
optional string email = 3;
}
message RegisterResponse {
optional common.Status status = 1;
}

61
idl/api_client.proto Normal file
View File

@@ -0,0 +1,61 @@
syntax = "proto3";
package api_client;
import "common.proto";
option go_package="../pb";
message InitClientRequest {
optional string client_id = 1;
}
message InitClientResponse {
optional common.Status status = 1;
optional string client_id = 2;
}
message ListClientsRequest {
optional int32 page = 1;
optional int32 page_size = 2;
}
message ListClientsResponse {
optional common.Status status = 1;
optional int32 total = 2;
repeated common.Client clients = 3;
}
message GetClientRequest {
optional string client_id = 1;
}
message GetClientResponse {
optional common.Status status = 1;
optional common.Client client = 2;
}
message DeleteClientRequest {
optional string client_id = 1;
}
message DeleteClientResponse {
optional common.Status status = 1;
}
message UpdateFRPCRequest {
optional string client_id = 1;
optional string server_id = 2;
optional bytes config = 3;
}
message UpdateFRPCResponse {
optional common.Status status = 1;
}
message RemoveFRPCRequest {
optional string client_id = 1;
}
message RemoveFRPCResponse {
optional common.Status status = 1;
}

60
idl/api_server.proto Normal file
View File

@@ -0,0 +1,60 @@
syntax = "proto3";
package api_server;
import "common.proto";
option go_package="../pb";
message InitServerRequest {
optional string server_id = 1;
optional string server_ip = 2;
}
message InitServerResponse {
optional common.Status status = 1;
optional string server_id = 2;
}
message ListServersRequest {
optional int32 page = 1;
optional int32 page_size = 2;
}
message ListServersResponse {
optional common.Status status = 1;
optional int32 total = 2;
repeated common.Server servers = 3;
}
message GetServerRequest {
optional string server_id = 1;
}
message GetServerResponse {
optional common.Status status = 1;
optional common.Server server = 2;
}
message DeleteServerRequest {
optional string server_id = 1;
}
message DeleteServerResponse {
optional common.Status status = 1;
}
message UpdateFRPSRequest {
optional string server_id = 1;
optional bytes config = 2;
}
message UpdateFRPSResponse {
optional common.Status status = 1;
}
message RemoveFRPSRequest {
optional string server_id = 1;
}
message RemoveFRPSResponse {
optional common.Status status = 1;
}

20
idl/api_user.proto Normal file
View File

@@ -0,0 +1,20 @@
syntax = "proto3";
package api_user;
import "common.proto";
option go_package="../pb";
message GetUserInfoRequest {}
message GetUserInfoResponse {
optional common.Status status = 1;
optional common.User user_info = 2;
}
message UpdateUserInfoRequest {
optional common.User user_info = 1;
}
message UpdateUserInfoResponse {
optional common.Status status = 1;
}

47
idl/common.proto Normal file
View File

@@ -0,0 +1,47 @@
syntax = "proto3";
package common;
option go_package="../pb";
enum RespCode {
RESP_CODE_UNSPECIFIED = 0;
RESP_CODE_SUCCESS = 1;
RESP_CODE_NOT_FOUND = 2;
RESP_CODE_ALREADY_EXISTS = 3;
RESP_CODE_INVALID = 4;
RESP_CODE_FINISH = 5;
RESP_CODE_UNAUTHORIZED = 6;
}
message Status {
RespCode code = 1;
string message = 2;
}
message CommonResponse {
optional Status status = 1;
}
message Client {
optional string id = 1;
optional string secret = 2;
optional string config = 3;
}
message Server {
optional string id = 1;
optional string secret = 2;
optional string ip = 3;
optional string config = 4; // 在定义上ip和port只是为了方便使用
}
message User {
optional int64 UserID = 1;
optional int64 TenantID = 2;
optional string UserName = 3;
optional string Email = 4;
optional string Status = 5;
optional string Role = 6;
optional string Token = 7;
optional string RawPassword = 8;
}

79
idl/rpc_master.proto Normal file
View File

@@ -0,0 +1,79 @@
syntax = "proto3";
package master;
import "common.proto";
option go_package="../pb";
enum Event {
EVENT_UNSPECIFIED = 0;
EVENT_REGISTER_CLIENT = 1;
EVENT_REGISTER_SERVER = 2;
EVENT_ERROR = 3;
EVENT_DATA = 4;
EVENT_UPDATE_FRPC = 5;
EVENT_REMOVE_FRPC = 6;
EVENT_UPDATE_FRPS = 7;
EVENT_REMOVE_FRPS = 8;
}
message ServerBase {
string server_id = 1;
string server_secret = 2;
}
message ClientBase {
string client_id = 1;
string client_secret = 2;
}
message ServerMessage {
Event event = 1;
string client_id = 2;
string session_id = 3;
bytes data = 4;
}
message ClientMessage {
Event event = 1;
string client_id = 2;
string session_id = 3;
string secret = 4;
bytes data = 5;
}
message PullClientConfigReq {
ClientBase base = 255;
}
message PullClientConfigResp {
common.Status status = 1;
common.Client client = 2;
}
message PullServerConfigReq {
ServerBase base = 255;
}
message PullServerConfigResp {
common.Status status = 1;
common.Server server = 2;
}
message FRPAuthRequest {
string user = 1;
string token = 2;
ServerBase base = 255;
}
message FRPAuthResponse {
common.Status status = 1;
bool ok = 2;
}
service Master {
rpc ServerSend(stream ClientMessage) returns(stream ServerMessage);
rpc PullClientConfig(PullClientConfigReq) returns(PullClientConfigResp);
rpc PullServerConfig(PullServerConfigReq) returns(PullServerConfigResp);
rpc FRPCAuth(FRPAuthRequest) returns(FRPAuthResponse);
}

65
middleware/auth.go Normal file
View File

@@ -0,0 +1,65 @@
package middleware
import (
"github.com/VaalaCat/frp-panel/common"
"github.com/VaalaCat/frp-panel/dao"
"github.com/VaalaCat/frp-panel/models"
"github.com/VaalaCat/frp-panel/utils"
"github.com/gin-gonic/gin"
"github.com/sirupsen/logrus"
)
func AuthCtx(c *gin.Context) {
var uid int64
var err error
var u *models.UserEntity
defer func() {
logrus.WithContext(c).Info("finish auth user middleware")
}()
userID, ok := utils.GetValue[int](c, common.UserIDKey)
if !ok {
logrus.WithContext(c).Errorf("invalid user id")
common.ErrUnAuthorized(c, "token invalid")
c.Abort()
return
}
u, err = dao.GetUserByUserID(userID)
if err != nil {
logrus.WithContext(c).Errorf("get user by user id failed: %v", err)
common.ErrUnAuthorized(c, "token invalid")
c.Abort()
return
}
logrus.WithContext(c).Infof("auth middleware authed user is: [%+v]", u)
if u.Valid() {
logrus.WithContext(c).Infof("set auth user to context, login success")
c.Set(common.UserInfoKey, u)
c.Next()
return
} else {
if uid == 1 {
logrus.WithContext(c).Infof("seems to be admin assign token login")
c.Next()
return
}
logrus.WithContext(c).Errorf("invalid authorization, auth ctx middleware login failed")
common.ErrUnAuthorized(c, "token invalid")
c.Abort()
return
}
}
func AuthAdmin(c *gin.Context) {
u := common.GetUserInfo(c)
if u != nil && u.GetRole() == models.ROLE_ADMIN {
common.ErrUnAuthorized(c, "permission denied")
c.Abort()
return
}
c.Next()
}

157
middleware/jwt.go Normal file
View File

@@ -0,0 +1,157 @@
package middleware
import (
"errors"
"strings"
"time"
"github.com/VaalaCat/frp-panel/common"
"github.com/VaalaCat/frp-panel/conf"
"github.com/VaalaCat/frp-panel/utils"
"github.com/gin-gonic/gin"
"github.com/golang-jwt/jwt/v5"
"github.com/sirupsen/logrus"
)
// JWTMAuth check if authed and set uid to context
func JWTAuth(c *gin.Context) {
defer func() {
logrus.WithContext(c).Info("finish jwt middleware")
}()
var tokenStr string
if tokenStr = c.Copy().Query(common.TokenKey); len(tokenStr) != 0 {
if t, err := utils.ParseToken(conf.JWTSecret(), tokenStr); err == nil {
for k, v := range t {
c.Set(k, v)
}
logrus.WithContext(c).Infof("query auth success")
if err = resignAndPatchCtxJWT(c, t, tokenStr); err != nil {
logrus.WithContext(c).WithError(err).Errorf("resign jwt error")
common.ErrUnAuthorized(c, "resign jwt error")
c.Abort()
return
}
c.Next()
SetToken(c, utils.ToStr(t[common.UserIDKey]))
return
}
logrus.WithContext(c).Infof("query auth failed")
}
cookieToken, err := c.Cookie(conf.Get().App.CookieName)
if err == nil {
if t, err := utils.ParseToken(conf.JWTSecret(), cookieToken); err == nil {
for k, v := range t {
c.Set(k, v)
}
logrus.WithContext(c).Infof("cookie auth success")
if err = resignAndPatchCtxJWT(c, t, cookieToken); err != nil {
logrus.WithContext(c).WithError(err).Errorf("resign jwt error")
common.ErrUnAuthorized(c, "resign jwt error")
c.Abort()
return
}
c.Next()
return
} else {
logrus.WithContext(c).WithError(err).Errorf("jwt middleware parse token error")
common.ErrUnAuthorized(c, "invalid authorization")
c.Abort()
return
}
}
tokenStr = c.Request.Header.Get(common.AuthorizationKey)
tokenStr = strings.TrimPrefix(tokenStr, "Bearer ")
if tokenStr == "" || tokenStr == "null" {
logrus.WithContext(c).WithError(errors.New("authorization is empty")).Infof("authorization is empty")
common.ErrUnAuthorized(c, "invalid authorization")
c.Abort()
return
}
if t, err := utils.ParseToken(conf.JWTSecret(), tokenStr); err == nil {
for k, v := range t {
c.Set(k, v)
}
logrus.WithContext(c).Infof("header auth success")
if err = resignAndPatchCtxJWT(c, t, tokenStr); err != nil {
logrus.WithContext(c).WithError(err).Errorf("resign jwt error")
common.ErrUnAuthorized(c, "resign jwt error")
c.Abort()
return
}
c.Next()
return
} else {
logrus.WithContext(c).WithError(err).Errorf("jwt middleware parse token error")
}
}
func resignAndPatchCtxJWT(c *gin.Context, t jwt.MapClaims, tokenStr string) error {
tokenExpire, _ := t.GetExpirationTime()
now := time.Now().Add(time.Duration(conf.Get().App.CookieAge/2) * time.Second)
if now.Before(tokenExpire.Time) {
logrus.WithContext(c).Infof("jwt not going to expire, continue to use old one")
c.Set(common.TokenKey, tokenStr)
return nil
}
token, err := utils.GetJwtTokenFromMap(conf.JWTSecret(),
time.Now().Unix(),
int64(conf.Get().App.CookieAge),
map[string]string{common.UserIDKey: utils.ToStr(t[common.UserIDKey])})
if err != nil {
c.Set(common.TokenKey, tokenStr)
logrus.WithContext(c).WithError(err).Errorf("resign jwt error")
return err
}
logrus.WithContext(c).Infof("jwt going to expire, resigning token")
c.Header(common.SetAuthorizationKey, token)
c.SetCookie(conf.Get().App.CookieName,
token,
conf.Get().App.CookieAge,
conf.Get().App.CookiePath,
conf.Get().App.CookieDomain,
conf.Get().App.CookieSecure,
conf.Get().App.CookieHTTPOnly)
c.Set(common.TokenKey, token)
return nil
}
func SetToken(c *gin.Context, uid string) (string, error) {
logrus.WithContext(c).Infof("set token for uid:[%s]", uid)
token, err := utils.GetJwtTokenFromMap(conf.JWTSecret(),
time.Now().Unix(),
int64(conf.Get().App.CookieAge),
map[string]string{common.UserIDKey: uid})
if err != nil {
return "", err
}
c.SetCookie(conf.Get().App.CookieName,
token,
conf.Get().App.CookieAge,
conf.Get().App.CookiePath,
conf.Get().App.CookieDomain,
conf.Get().App.CookieSecure,
conf.Get().App.CookieHTTPOnly)
c.Set(common.TokenKey, token)
c.Header(common.SetAuthorizationKey, token)
return token, nil
}
// PushTokenStr 推送token到客户端
func PushTokenStr(c *gin.Context, tokenStr string) {
logrus.WithContext(c).Infof("push new token to client")
c.SetCookie(conf.Get().App.CookieName,
tokenStr,
conf.Get().App.CookieAge,
conf.Get().App.CookiePath,
conf.Get().App.CookieDomain,
conf.Get().App.CookieSecure,
conf.Get().App.CookieHTTPOnly)
c.Header(common.SetAuthorizationKey, tokenStr)
}

60
models/client.go Normal file
View File

@@ -0,0 +1,60 @@
package models
import (
"encoding/json"
"time"
"github.com/VaalaCat/frp-panel/utils"
v1 "github.com/fatedier/frp/pkg/config/v1"
"github.com/samber/lo"
"gorm.io/gorm"
)
type Client struct {
*ClientEntity
}
type ClientEntity struct {
ClientID string `json:"client_id" gorm:"uniqueIndex;not null;primaryKey"`
TenantID int `json:"tenant_id" gorm:"not null"`
UserID int `json:"user_id" gorm:"not null"`
ConfigContent []byte `json:"config_content"`
ConnectSecret string `json:"connect_secret" gorm:"not null"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`
}
func (*Client) TableName() string {
return "clients"
}
func (c *ClientEntity) SetConfigContent(cfg v1.ClientConfig) error {
newCfg := struct {
v1.ClientCommonConfig
Proxies []v1.ProxyConfigurer `json:"proxies,omitempty"`
Visitors []v1.VisitorBaseConfig `json:"visitors,omitempty"`
}{
ClientCommonConfig: cfg.ClientCommonConfig,
Proxies: lo.Map(cfg.Proxies, func(item v1.TypedProxyConfig, _ int) v1.ProxyConfigurer {
return item.ProxyConfigurer
}),
Visitors: lo.Map(cfg.Visitors, func(item v1.TypedVisitorConfig, _ int) v1.VisitorBaseConfig {
return *item.GetBaseConfig()
}),
}
raw, err := json.Marshal(newCfg)
if err != nil {
return err
}
c.ConfigContent = raw
return nil
}
func (c *ClientEntity) GetConfigContent() (*v1.ClientConfig, error) {
cliCfg, err := utils.LoadClientConfigNormal(c.ConfigContent, true)
if err != nil {
return nil, err
}
return cliCfg, err
}

76
models/db.go Normal file
View File

@@ -0,0 +1,76 @@
package models
import (
"github.com/sirupsen/logrus"
"gorm.io/gorm"
)
type DBManager interface {
GetDB(dbType string) *gorm.DB
GetDefaultDB() *gorm.DB
SetDB(dbType string, db *gorm.DB)
RemoveDB(dbType string)
Init()
}
type dbManagerImpl struct {
DBs map[string]*gorm.DB // key: db type
defaultDBType string
}
func (dbm *dbManagerImpl) Init() {
for _, db := range dbm.DBs {
if err := db.AutoMigrate(&Client{}); err != nil {
logrus.WithError(err).Fatalf("cannot init db table [%s]", (&Client{}).TableName())
}
if err := db.AutoMigrate(&User{}); err != nil {
logrus.WithError(err).Fatalf("cannot init db table [%s]", (&User{}).TableName())
}
if err := db.AutoMigrate(&Server{}); err != nil {
logrus.WithError(err).Fatalf("cannot init db table [%s]", (&Server{}).TableName())
}
}
}
var (
dbm *dbManagerImpl
)
func MustInitDBManager(dbs map[string]*gorm.DB, defaultDBType string) {
if dbm == nil {
dbm = NewDBManager(dbs, defaultDBType)
}
}
func NewDBManager(dbs map[string]*gorm.DB, defaultDBType string) *dbManagerImpl {
if dbs == nil {
dbs = make(map[string]*gorm.DB)
}
return &dbManagerImpl{
DBs: dbs,
defaultDBType: defaultDBType,
}
}
func GetDBManager() DBManager {
if dbm == nil {
dbm = NewDBManager(nil, "")
}
return dbm
}
func (dbm *dbManagerImpl) GetDB(dbType string) *gorm.DB {
return dbm.DBs[dbType]
}
func (dbm *dbManagerImpl) SetDB(dbType string, db *gorm.DB) {
dbm.DBs[dbType] = db
}
func (dbm *dbManagerImpl) RemoveDB(dbType string) {
delete(dbm.DBs, dbType)
}
func (dbm *dbManagerImpl) GetDefaultDB() *gorm.DB {
return dbm.DBs[dbm.defaultDBType]
}

12
models/enums.go Normal file
View File

@@ -0,0 +1,12 @@
package models
const (
ROLE_ADMIN = "admin"
ROLE_NORMAL = "normal"
)
const (
STATUS_UNKNOWN = iota
STATUS_NORMAL
STATUS_BANED
)

2
models/init.go Normal file
View File

@@ -0,0 +1,2 @@
package models

49
models/server.go Normal file
View File

@@ -0,0 +1,49 @@
package models
import (
"encoding/json"
"fmt"
"time"
v1 "github.com/fatedier/frp/pkg/config/v1"
"gorm.io/gorm"
)
type Server struct {
*ServerEntity
}
type ServerEntity struct {
ServerID string `json:"client_id" gorm:"uniqueIndex;not null;primaryKey"`
TenantID int `json:"tenant_id" gorm:"not null"`
UserID int `json:"user_id" gorm:"not null"`
ServerIP string `json:"server_ip"`
ConfigContent []byte `json:"config_content"`
ConnectSecret string `json:"connect_secret" gorm:"not null"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`
}
func (*Server) TableName() string {
return "servers"
}
func (s *ServerEntity) GetConfigContent() (*v1.ServerConfig, error) {
if len(s.ConfigContent) == 0 {
return nil, fmt.Errorf("config content is empty")
}
var cfg v1.ServerConfig
err := json.Unmarshal(s.ConfigContent, &cfg)
return &cfg, err
}
func (s *ServerEntity) SetConfigContent(cfg *v1.ServerConfig) error {
raw, err := json.Marshal(cfg)
if err != nil {
return err
}
s.ConfigContent = raw
return nil
}

107
models/user.go Normal file
View File

@@ -0,0 +1,107 @@
package models
import (
"fmt"
"time"
"gorm.io/gorm"
)
type User struct {
*UserEntity
}
type UserInfo interface {
GetUserID() int
GetUserIDStr() string
GetUserName() string
GetEmail() string
GetHashedPassword() string
GetStatus() int
GetRole() string
GetToken() string
GetTenantID() int
GetSafeUserInfo() UserEntity
IsAdmin() bool
Valid() bool
}
var _ UserInfo = (*UserEntity)(nil)
type UserEntity struct {
UserID int `json:"user_id" gorm:"primaryKey"`
UserName string `json:"user_name" gorm:"uniqueIndex;not null"`
Password string `json:"password"`
Email string `json:"email" gorm:"uniqueIndex;not null"`
Status int `json:"status"`
Role string `json:"role"`
TenantID int `json:"tenant_id"`
Token string `json:"token"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`
}
func (u *UserEntity) GetUserID() int {
return u.UserID
}
func (u *UserEntity) GetUserIDStr() string {
return fmt.Sprint(u.UserID)
}
func (u *UserEntity) GetUserName() string {
return u.UserName
}
func (u *UserEntity) GetEmail() string {
return u.Email
}
func (u *UserEntity) GetHashedPassword() string {
return u.Password
}
func (u *UserEntity) GetStatus() int {
return u.Status
}
func (u *UserEntity) GetRole() string {
return u.Role
}
func (u *UserEntity) GetTenantID() int {
return u.TenantID
}
func (u *UserEntity) GetToken() string {
return u.Token
}
func (u *UserEntity) GetSafeUserInfo() UserEntity {
return UserEntity{
UserID: u.UserID,
UserName: u.UserName,
Email: u.Email,
Status: u.Status,
Role: u.Role,
}
}
func (u *UserEntity) Valid() bool {
if u == nil {
return false
}
if u.Status == STATUS_BANED {
return false
}
return true
}
func (u *UserEntity) IsAdmin() bool {
return u.Role == ROLE_ADMIN
}
func (u *User) TableName() string {
return "users"
}

388
pb/api_auth.pb.go Normal file
View File

@@ -0,0 +1,388 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.32.0
// protoc v4.25.1
// source: api_auth.proto
package pb
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type LoginRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Username *string `protobuf:"bytes,1,opt,name=username,proto3,oneof" json:"username,omitempty"`
Password *string `protobuf:"bytes,2,opt,name=password,proto3,oneof" json:"password,omitempty"`
}
func (x *LoginRequest) Reset() {
*x = LoginRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_api_auth_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *LoginRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*LoginRequest) ProtoMessage() {}
func (x *LoginRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_auth_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use LoginRequest.ProtoReflect.Descriptor instead.
func (*LoginRequest) Descriptor() ([]byte, []int) {
return file_api_auth_proto_rawDescGZIP(), []int{0}
}
func (x *LoginRequest) GetUsername() string {
if x != nil && x.Username != nil {
return *x.Username
}
return ""
}
func (x *LoginRequest) GetPassword() string {
if x != nil && x.Password != nil {
return *x.Password
}
return ""
}
type LoginResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Status *Status `protobuf:"bytes,1,opt,name=status,proto3,oneof" json:"status,omitempty"`
Token *string `protobuf:"bytes,2,opt,name=token,proto3,oneof" json:"token,omitempty"`
}
func (x *LoginResponse) Reset() {
*x = LoginResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_api_auth_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *LoginResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*LoginResponse) ProtoMessage() {}
func (x *LoginResponse) ProtoReflect() protoreflect.Message {
mi := &file_api_auth_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use LoginResponse.ProtoReflect.Descriptor instead.
func (*LoginResponse) Descriptor() ([]byte, []int) {
return file_api_auth_proto_rawDescGZIP(), []int{1}
}
func (x *LoginResponse) GetStatus() *Status {
if x != nil {
return x.Status
}
return nil
}
func (x *LoginResponse) GetToken() string {
if x != nil && x.Token != nil {
return *x.Token
}
return ""
}
type RegisterRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Username *string `protobuf:"bytes,1,opt,name=username,proto3,oneof" json:"username,omitempty"`
Password *string `protobuf:"bytes,2,opt,name=password,proto3,oneof" json:"password,omitempty"`
Email *string `protobuf:"bytes,3,opt,name=email,proto3,oneof" json:"email,omitempty"`
}
func (x *RegisterRequest) Reset() {
*x = RegisterRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_api_auth_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *RegisterRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*RegisterRequest) ProtoMessage() {}
func (x *RegisterRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_auth_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use RegisterRequest.ProtoReflect.Descriptor instead.
func (*RegisterRequest) Descriptor() ([]byte, []int) {
return file_api_auth_proto_rawDescGZIP(), []int{2}
}
func (x *RegisterRequest) GetUsername() string {
if x != nil && x.Username != nil {
return *x.Username
}
return ""
}
func (x *RegisterRequest) GetPassword() string {
if x != nil && x.Password != nil {
return *x.Password
}
return ""
}
func (x *RegisterRequest) GetEmail() string {
if x != nil && x.Email != nil {
return *x.Email
}
return ""
}
type RegisterResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Status *Status `protobuf:"bytes,1,opt,name=status,proto3,oneof" json:"status,omitempty"`
}
func (x *RegisterResponse) Reset() {
*x = RegisterResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_api_auth_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *RegisterResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*RegisterResponse) ProtoMessage() {}
func (x *RegisterResponse) ProtoReflect() protoreflect.Message {
mi := &file_api_auth_proto_msgTypes[3]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use RegisterResponse.ProtoReflect.Descriptor instead.
func (*RegisterResponse) Descriptor() ([]byte, []int) {
return file_api_auth_proto_rawDescGZIP(), []int{3}
}
func (x *RegisterResponse) GetStatus() *Status {
if x != nil {
return x.Status
}
return nil
}
var File_api_auth_proto protoreflect.FileDescriptor
var file_api_auth_proto_rawDesc = []byte{
0x0a, 0x0e, 0x61, 0x70, 0x69, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x12, 0x08, 0x61, 0x70, 0x69, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x1a, 0x0c, 0x63, 0x6f, 0x6d, 0x6d,
0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x6a, 0x0a, 0x0c, 0x4c, 0x6f, 0x67, 0x69,
0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72,
0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x08, 0x75, 0x73,
0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x88, 0x01, 0x01, 0x12, 0x1f, 0x0a, 0x08, 0x70, 0x61, 0x73,
0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x08, 0x70,
0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x88, 0x01, 0x01, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x75,
0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x70, 0x61, 0x73, 0x73,
0x77, 0x6f, 0x72, 0x64, 0x22, 0x6c, 0x0a, 0x0d, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18,
0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53,
0x74, 0x61, 0x74, 0x75, 0x73, 0x48, 0x00, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x88,
0x01, 0x01, 0x12, 0x19, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28,
0x09, 0x48, 0x01, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x88, 0x01, 0x01, 0x42, 0x09, 0x0a,
0x07, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x74, 0x6f, 0x6b,
0x65, 0x6e, 0x22, 0x92, 0x01, 0x0a, 0x0f, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61,
0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72,
0x6e, 0x61, 0x6d, 0x65, 0x88, 0x01, 0x01, 0x12, 0x1f, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77,
0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x08, 0x70, 0x61, 0x73,
0x73, 0x77, 0x6f, 0x72, 0x64, 0x88, 0x01, 0x01, 0x12, 0x19, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69,
0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x02, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c,
0x88, 0x01, 0x01, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65,
0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x42, 0x08, 0x0a,
0x06, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x22, 0x4a, 0x0a, 0x10, 0x52, 0x65, 0x67, 0x69, 0x73,
0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, 0x0a, 0x06, 0x73,
0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x6f,
0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x48, 0x00, 0x52, 0x06, 0x73,
0x74, 0x61, 0x74, 0x75, 0x73, 0x88, 0x01, 0x01, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x73, 0x74, 0x61,
0x74, 0x75, 0x73, 0x42, 0x07, 0x5a, 0x05, 0x2e, 0x2e, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x33,
}
var (
file_api_auth_proto_rawDescOnce sync.Once
file_api_auth_proto_rawDescData = file_api_auth_proto_rawDesc
)
func file_api_auth_proto_rawDescGZIP() []byte {
file_api_auth_proto_rawDescOnce.Do(func() {
file_api_auth_proto_rawDescData = protoimpl.X.CompressGZIP(file_api_auth_proto_rawDescData)
})
return file_api_auth_proto_rawDescData
}
var file_api_auth_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
var file_api_auth_proto_goTypes = []interface{}{
(*LoginRequest)(nil), // 0: api_auth.LoginRequest
(*LoginResponse)(nil), // 1: api_auth.LoginResponse
(*RegisterRequest)(nil), // 2: api_auth.RegisterRequest
(*RegisterResponse)(nil), // 3: api_auth.RegisterResponse
(*Status)(nil), // 4: common.Status
}
var file_api_auth_proto_depIdxs = []int32{
4, // 0: api_auth.LoginResponse.status:type_name -> common.Status
4, // 1: api_auth.RegisterResponse.status:type_name -> common.Status
2, // [2:2] is the sub-list for method output_type
2, // [2:2] is the sub-list for method input_type
2, // [2:2] is the sub-list for extension type_name
2, // [2:2] is the sub-list for extension extendee
0, // [0:2] is the sub-list for field type_name
}
func init() { file_api_auth_proto_init() }
func file_api_auth_proto_init() {
if File_api_auth_proto != nil {
return
}
file_common_proto_init()
if !protoimpl.UnsafeEnabled {
file_api_auth_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*LoginRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_api_auth_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*LoginResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_api_auth_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*RegisterRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_api_auth_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*RegisterResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
file_api_auth_proto_msgTypes[0].OneofWrappers = []interface{}{}
file_api_auth_proto_msgTypes[1].OneofWrappers = []interface{}{}
file_api_auth_proto_msgTypes[2].OneofWrappers = []interface{}{}
file_api_auth_proto_msgTypes[3].OneofWrappers = []interface{}{}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_api_auth_proto_rawDesc,
NumEnums: 0,
NumMessages: 4,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_api_auth_proto_goTypes,
DependencyIndexes: file_api_auth_proto_depIdxs,
MessageInfos: file_api_auth_proto_msgTypes,
}.Build()
File_api_auth_proto = out.File
file_api_auth_proto_rawDesc = nil
file_api_auth_proto_goTypes = nil
file_api_auth_proto_depIdxs = nil
}

954
pb/api_client.pb.go Normal file
View File

@@ -0,0 +1,954 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.32.0
// protoc v4.25.1
// source: api_client.proto
package pb
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type InitClientRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
ClientId *string `protobuf:"bytes,1,opt,name=client_id,json=clientId,proto3,oneof" json:"client_id,omitempty"`
}
func (x *InitClientRequest) Reset() {
*x = InitClientRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_api_client_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *InitClientRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*InitClientRequest) ProtoMessage() {}
func (x *InitClientRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_client_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use InitClientRequest.ProtoReflect.Descriptor instead.
func (*InitClientRequest) Descriptor() ([]byte, []int) {
return file_api_client_proto_rawDescGZIP(), []int{0}
}
func (x *InitClientRequest) GetClientId() string {
if x != nil && x.ClientId != nil {
return *x.ClientId
}
return ""
}
type InitClientResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Status *Status `protobuf:"bytes,1,opt,name=status,proto3,oneof" json:"status,omitempty"`
ClientId *string `protobuf:"bytes,2,opt,name=client_id,json=clientId,proto3,oneof" json:"client_id,omitempty"`
}
func (x *InitClientResponse) Reset() {
*x = InitClientResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_api_client_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *InitClientResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*InitClientResponse) ProtoMessage() {}
func (x *InitClientResponse) ProtoReflect() protoreflect.Message {
mi := &file_api_client_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use InitClientResponse.ProtoReflect.Descriptor instead.
func (*InitClientResponse) Descriptor() ([]byte, []int) {
return file_api_client_proto_rawDescGZIP(), []int{1}
}
func (x *InitClientResponse) GetStatus() *Status {
if x != nil {
return x.Status
}
return nil
}
func (x *InitClientResponse) GetClientId() string {
if x != nil && x.ClientId != nil {
return *x.ClientId
}
return ""
}
type ListClientsRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Page *int32 `protobuf:"varint,1,opt,name=page,proto3,oneof" json:"page,omitempty"`
PageSize *int32 `protobuf:"varint,2,opt,name=page_size,json=pageSize,proto3,oneof" json:"page_size,omitempty"`
}
func (x *ListClientsRequest) Reset() {
*x = ListClientsRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_api_client_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ListClientsRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ListClientsRequest) ProtoMessage() {}
func (x *ListClientsRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_client_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ListClientsRequest.ProtoReflect.Descriptor instead.
func (*ListClientsRequest) Descriptor() ([]byte, []int) {
return file_api_client_proto_rawDescGZIP(), []int{2}
}
func (x *ListClientsRequest) GetPage() int32 {
if x != nil && x.Page != nil {
return *x.Page
}
return 0
}
func (x *ListClientsRequest) GetPageSize() int32 {
if x != nil && x.PageSize != nil {
return *x.PageSize
}
return 0
}
type ListClientsResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Status *Status `protobuf:"bytes,1,opt,name=status,proto3,oneof" json:"status,omitempty"`
Total *int32 `protobuf:"varint,2,opt,name=total,proto3,oneof" json:"total,omitempty"`
Clients []*Client `protobuf:"bytes,3,rep,name=clients,proto3" json:"clients,omitempty"`
}
func (x *ListClientsResponse) Reset() {
*x = ListClientsResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_api_client_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ListClientsResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ListClientsResponse) ProtoMessage() {}
func (x *ListClientsResponse) ProtoReflect() protoreflect.Message {
mi := &file_api_client_proto_msgTypes[3]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ListClientsResponse.ProtoReflect.Descriptor instead.
func (*ListClientsResponse) Descriptor() ([]byte, []int) {
return file_api_client_proto_rawDescGZIP(), []int{3}
}
func (x *ListClientsResponse) GetStatus() *Status {
if x != nil {
return x.Status
}
return nil
}
func (x *ListClientsResponse) GetTotal() int32 {
if x != nil && x.Total != nil {
return *x.Total
}
return 0
}
func (x *ListClientsResponse) GetClients() []*Client {
if x != nil {
return x.Clients
}
return nil
}
type GetClientRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
ClientId *string `protobuf:"bytes,1,opt,name=client_id,json=clientId,proto3,oneof" json:"client_id,omitempty"`
}
func (x *GetClientRequest) Reset() {
*x = GetClientRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_api_client_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *GetClientRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GetClientRequest) ProtoMessage() {}
func (x *GetClientRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_client_proto_msgTypes[4]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use GetClientRequest.ProtoReflect.Descriptor instead.
func (*GetClientRequest) Descriptor() ([]byte, []int) {
return file_api_client_proto_rawDescGZIP(), []int{4}
}
func (x *GetClientRequest) GetClientId() string {
if x != nil && x.ClientId != nil {
return *x.ClientId
}
return ""
}
type GetClientResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Status *Status `protobuf:"bytes,1,opt,name=status,proto3,oneof" json:"status,omitempty"`
Client *Client `protobuf:"bytes,2,opt,name=client,proto3,oneof" json:"client,omitempty"`
}
func (x *GetClientResponse) Reset() {
*x = GetClientResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_api_client_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *GetClientResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GetClientResponse) ProtoMessage() {}
func (x *GetClientResponse) ProtoReflect() protoreflect.Message {
mi := &file_api_client_proto_msgTypes[5]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use GetClientResponse.ProtoReflect.Descriptor instead.
func (*GetClientResponse) Descriptor() ([]byte, []int) {
return file_api_client_proto_rawDescGZIP(), []int{5}
}
func (x *GetClientResponse) GetStatus() *Status {
if x != nil {
return x.Status
}
return nil
}
func (x *GetClientResponse) GetClient() *Client {
if x != nil {
return x.Client
}
return nil
}
type DeleteClientRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
ClientId *string `protobuf:"bytes,1,opt,name=client_id,json=clientId,proto3,oneof" json:"client_id,omitempty"`
}
func (x *DeleteClientRequest) Reset() {
*x = DeleteClientRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_api_client_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *DeleteClientRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*DeleteClientRequest) ProtoMessage() {}
func (x *DeleteClientRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_client_proto_msgTypes[6]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use DeleteClientRequest.ProtoReflect.Descriptor instead.
func (*DeleteClientRequest) Descriptor() ([]byte, []int) {
return file_api_client_proto_rawDescGZIP(), []int{6}
}
func (x *DeleteClientRequest) GetClientId() string {
if x != nil && x.ClientId != nil {
return *x.ClientId
}
return ""
}
type DeleteClientResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Status *Status `protobuf:"bytes,1,opt,name=status,proto3,oneof" json:"status,omitempty"`
}
func (x *DeleteClientResponse) Reset() {
*x = DeleteClientResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_api_client_proto_msgTypes[7]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *DeleteClientResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*DeleteClientResponse) ProtoMessage() {}
func (x *DeleteClientResponse) ProtoReflect() protoreflect.Message {
mi := &file_api_client_proto_msgTypes[7]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use DeleteClientResponse.ProtoReflect.Descriptor instead.
func (*DeleteClientResponse) Descriptor() ([]byte, []int) {
return file_api_client_proto_rawDescGZIP(), []int{7}
}
func (x *DeleteClientResponse) GetStatus() *Status {
if x != nil {
return x.Status
}
return nil
}
type UpdateFRPCRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
ClientId *string `protobuf:"bytes,1,opt,name=client_id,json=clientId,proto3,oneof" json:"client_id,omitempty"`
ServerId *string `protobuf:"bytes,2,opt,name=server_id,json=serverId,proto3,oneof" json:"server_id,omitempty"`
Config []byte `protobuf:"bytes,3,opt,name=config,proto3,oneof" json:"config,omitempty"`
}
func (x *UpdateFRPCRequest) Reset() {
*x = UpdateFRPCRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_api_client_proto_msgTypes[8]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *UpdateFRPCRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*UpdateFRPCRequest) ProtoMessage() {}
func (x *UpdateFRPCRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_client_proto_msgTypes[8]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use UpdateFRPCRequest.ProtoReflect.Descriptor instead.
func (*UpdateFRPCRequest) Descriptor() ([]byte, []int) {
return file_api_client_proto_rawDescGZIP(), []int{8}
}
func (x *UpdateFRPCRequest) GetClientId() string {
if x != nil && x.ClientId != nil {
return *x.ClientId
}
return ""
}
func (x *UpdateFRPCRequest) GetServerId() string {
if x != nil && x.ServerId != nil {
return *x.ServerId
}
return ""
}
func (x *UpdateFRPCRequest) GetConfig() []byte {
if x != nil {
return x.Config
}
return nil
}
type UpdateFRPCResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Status *Status `protobuf:"bytes,1,opt,name=status,proto3,oneof" json:"status,omitempty"`
}
func (x *UpdateFRPCResponse) Reset() {
*x = UpdateFRPCResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_api_client_proto_msgTypes[9]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *UpdateFRPCResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*UpdateFRPCResponse) ProtoMessage() {}
func (x *UpdateFRPCResponse) ProtoReflect() protoreflect.Message {
mi := &file_api_client_proto_msgTypes[9]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use UpdateFRPCResponse.ProtoReflect.Descriptor instead.
func (*UpdateFRPCResponse) Descriptor() ([]byte, []int) {
return file_api_client_proto_rawDescGZIP(), []int{9}
}
func (x *UpdateFRPCResponse) GetStatus() *Status {
if x != nil {
return x.Status
}
return nil
}
type RemoveFRPCRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
ClientId *string `protobuf:"bytes,1,opt,name=client_id,json=clientId,proto3,oneof" json:"client_id,omitempty"`
}
func (x *RemoveFRPCRequest) Reset() {
*x = RemoveFRPCRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_api_client_proto_msgTypes[10]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *RemoveFRPCRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*RemoveFRPCRequest) ProtoMessage() {}
func (x *RemoveFRPCRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_client_proto_msgTypes[10]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use RemoveFRPCRequest.ProtoReflect.Descriptor instead.
func (*RemoveFRPCRequest) Descriptor() ([]byte, []int) {
return file_api_client_proto_rawDescGZIP(), []int{10}
}
func (x *RemoveFRPCRequest) GetClientId() string {
if x != nil && x.ClientId != nil {
return *x.ClientId
}
return ""
}
type RemoveFRPCResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Status *Status `protobuf:"bytes,1,opt,name=status,proto3,oneof" json:"status,omitempty"`
}
func (x *RemoveFRPCResponse) Reset() {
*x = RemoveFRPCResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_api_client_proto_msgTypes[11]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *RemoveFRPCResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*RemoveFRPCResponse) ProtoMessage() {}
func (x *RemoveFRPCResponse) ProtoReflect() protoreflect.Message {
mi := &file_api_client_proto_msgTypes[11]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use RemoveFRPCResponse.ProtoReflect.Descriptor instead.
func (*RemoveFRPCResponse) Descriptor() ([]byte, []int) {
return file_api_client_proto_rawDescGZIP(), []int{11}
}
func (x *RemoveFRPCResponse) GetStatus() *Status {
if x != nil {
return x.Status
}
return nil
}
var File_api_client_proto protoreflect.FileDescriptor
var file_api_client_proto_rawDesc = []byte{
0x0a, 0x10, 0x61, 0x70, 0x69, 0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x12, 0x0a, 0x61, 0x70, 0x69, 0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x1a, 0x0c,
0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x43, 0x0a, 0x11,
0x49, 0x6e, 0x69, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x12, 0x20, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01,
0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64,
0x88, 0x01, 0x01, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69,
0x64, 0x22, 0x7c, 0x0a, 0x12, 0x49, 0x6e, 0x69, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75,
0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e,
0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x48, 0x00, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75,
0x73, 0x88, 0x01, 0x01, 0x12, 0x20, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69,
0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e,
0x74, 0x49, 0x64, 0x88, 0x01, 0x01, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75,
0x73, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x22,
0x66, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x04, 0x70, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20,
0x01, 0x28, 0x05, 0x48, 0x00, 0x52, 0x04, 0x70, 0x61, 0x67, 0x65, 0x88, 0x01, 0x01, 0x12, 0x20,
0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
0x05, 0x48, 0x01, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x88, 0x01, 0x01,
0x42, 0x07, 0x0a, 0x05, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x70, 0x61,
0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x22, 0x9c, 0x01, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74,
0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
0x2b, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x0e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x48,
0x00, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x88, 0x01, 0x01, 0x12, 0x19, 0x0a, 0x05,
0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x48, 0x01, 0x52, 0x05, 0x74,
0x6f, 0x74, 0x61, 0x6c, 0x88, 0x01, 0x01, 0x12, 0x28, 0x0a, 0x07, 0x63, 0x6c, 0x69, 0x65, 0x6e,
0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f,
0x6e, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x07, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
0x73, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x08, 0x0a, 0x06,
0x5f, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x22, 0x42, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x43, 0x6c, 0x69,
0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x09, 0x63, 0x6c,
0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52,
0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x88, 0x01, 0x01, 0x42, 0x0c, 0x0a, 0x0a,
0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x22, 0x83, 0x01, 0x0a, 0x11, 0x47,
0x65, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x12, 0x2b, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x0e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
0x48, 0x00, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x88, 0x01, 0x01, 0x12, 0x2b, 0x0a,
0x06, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e,
0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x48, 0x01, 0x52,
0x06, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x88, 0x01, 0x01, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x73,
0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
0x22, 0x45, 0x0a, 0x13, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e,
0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x08, 0x63, 0x6c,
0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x88, 0x01, 0x01, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x63, 0x6c,
0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x22, 0x4e, 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74,
0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
0x2b, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x0e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x48,
0x00, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x88, 0x01, 0x01, 0x42, 0x09, 0x0a, 0x07,
0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x9b, 0x01, 0x0a, 0x11, 0x55, 0x70, 0x64, 0x61,
0x74, 0x65, 0x46, 0x52, 0x50, 0x43, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a,
0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
0x48, 0x00, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x88, 0x01, 0x01, 0x12,
0x20, 0x0a, 0x09, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01,
0x28, 0x09, 0x48, 0x01, 0x52, 0x08, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x49, 0x64, 0x88, 0x01,
0x01, 0x12, 0x1b, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28,
0x0c, 0x48, 0x02, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x88, 0x01, 0x01, 0x42, 0x0c,
0x0a, 0x0a, 0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x42, 0x0c, 0x0a, 0x0a,
0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x63,
0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x4c, 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x46,
0x52, 0x50, 0x43, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, 0x0a, 0x06, 0x73,
0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x6f,
0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x48, 0x00, 0x52, 0x06, 0x73,
0x74, 0x61, 0x74, 0x75, 0x73, 0x88, 0x01, 0x01, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x73, 0x74, 0x61,
0x74, 0x75, 0x73, 0x22, 0x43, 0x0a, 0x11, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x46, 0x52, 0x50,
0x43, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65,
0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x08, 0x63,
0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x88, 0x01, 0x01, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x63,
0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x22, 0x4c, 0x0a, 0x12, 0x52, 0x65, 0x6d, 0x6f,
0x76, 0x65, 0x46, 0x52, 0x50, 0x43, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b,
0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e,
0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x48, 0x00,
0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x88, 0x01, 0x01, 0x42, 0x09, 0x0a, 0x07, 0x5f,
0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x07, 0x5a, 0x05, 0x2e, 0x2e, 0x2f, 0x70, 0x62, 0x62,
0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_api_client_proto_rawDescOnce sync.Once
file_api_client_proto_rawDescData = file_api_client_proto_rawDesc
)
func file_api_client_proto_rawDescGZIP() []byte {
file_api_client_proto_rawDescOnce.Do(func() {
file_api_client_proto_rawDescData = protoimpl.X.CompressGZIP(file_api_client_proto_rawDescData)
})
return file_api_client_proto_rawDescData
}
var file_api_client_proto_msgTypes = make([]protoimpl.MessageInfo, 12)
var file_api_client_proto_goTypes = []interface{}{
(*InitClientRequest)(nil), // 0: api_client.InitClientRequest
(*InitClientResponse)(nil), // 1: api_client.InitClientResponse
(*ListClientsRequest)(nil), // 2: api_client.ListClientsRequest
(*ListClientsResponse)(nil), // 3: api_client.ListClientsResponse
(*GetClientRequest)(nil), // 4: api_client.GetClientRequest
(*GetClientResponse)(nil), // 5: api_client.GetClientResponse
(*DeleteClientRequest)(nil), // 6: api_client.DeleteClientRequest
(*DeleteClientResponse)(nil), // 7: api_client.DeleteClientResponse
(*UpdateFRPCRequest)(nil), // 8: api_client.UpdateFRPCRequest
(*UpdateFRPCResponse)(nil), // 9: api_client.UpdateFRPCResponse
(*RemoveFRPCRequest)(nil), // 10: api_client.RemoveFRPCRequest
(*RemoveFRPCResponse)(nil), // 11: api_client.RemoveFRPCResponse
(*Status)(nil), // 12: common.Status
(*Client)(nil), // 13: common.Client
}
var file_api_client_proto_depIdxs = []int32{
12, // 0: api_client.InitClientResponse.status:type_name -> common.Status
12, // 1: api_client.ListClientsResponse.status:type_name -> common.Status
13, // 2: api_client.ListClientsResponse.clients:type_name -> common.Client
12, // 3: api_client.GetClientResponse.status:type_name -> common.Status
13, // 4: api_client.GetClientResponse.client:type_name -> common.Client
12, // 5: api_client.DeleteClientResponse.status:type_name -> common.Status
12, // 6: api_client.UpdateFRPCResponse.status:type_name -> common.Status
12, // 7: api_client.RemoveFRPCResponse.status:type_name -> common.Status
8, // [8:8] is the sub-list for method output_type
8, // [8:8] is the sub-list for method input_type
8, // [8:8] is the sub-list for extension type_name
8, // [8:8] is the sub-list for extension extendee
0, // [0:8] is the sub-list for field type_name
}
func init() { file_api_client_proto_init() }
func file_api_client_proto_init() {
if File_api_client_proto != nil {
return
}
file_common_proto_init()
if !protoimpl.UnsafeEnabled {
file_api_client_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*InitClientRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_api_client_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*InitClientResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_api_client_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ListClientsRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_api_client_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ListClientsResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_api_client_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*GetClientRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_api_client_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*GetClientResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_api_client_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*DeleteClientRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_api_client_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*DeleteClientResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_api_client_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*UpdateFRPCRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_api_client_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*UpdateFRPCResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_api_client_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*RemoveFRPCRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_api_client_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*RemoveFRPCResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
file_api_client_proto_msgTypes[0].OneofWrappers = []interface{}{}
file_api_client_proto_msgTypes[1].OneofWrappers = []interface{}{}
file_api_client_proto_msgTypes[2].OneofWrappers = []interface{}{}
file_api_client_proto_msgTypes[3].OneofWrappers = []interface{}{}
file_api_client_proto_msgTypes[4].OneofWrappers = []interface{}{}
file_api_client_proto_msgTypes[5].OneofWrappers = []interface{}{}
file_api_client_proto_msgTypes[6].OneofWrappers = []interface{}{}
file_api_client_proto_msgTypes[7].OneofWrappers = []interface{}{}
file_api_client_proto_msgTypes[8].OneofWrappers = []interface{}{}
file_api_client_proto_msgTypes[9].OneofWrappers = []interface{}{}
file_api_client_proto_msgTypes[10].OneofWrappers = []interface{}{}
file_api_client_proto_msgTypes[11].OneofWrappers = []interface{}{}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_api_client_proto_rawDesc,
NumEnums: 0,
NumMessages: 12,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_api_client_proto_goTypes,
DependencyIndexes: file_api_client_proto_depIdxs,
MessageInfos: file_api_client_proto_msgTypes,
}.Build()
File_api_client_proto = out.File
file_api_client_proto_rawDesc = nil
file_api_client_proto_goTypes = nil
file_api_client_proto_depIdxs = nil
}

954
pb/api_server.pb.go Normal file
View File

@@ -0,0 +1,954 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.32.0
// protoc v4.25.1
// source: api_server.proto
package pb
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type InitServerRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
ServerId *string `protobuf:"bytes,1,opt,name=server_id,json=serverId,proto3,oneof" json:"server_id,omitempty"`
ServerIp *string `protobuf:"bytes,2,opt,name=server_ip,json=serverIp,proto3,oneof" json:"server_ip,omitempty"`
}
func (x *InitServerRequest) Reset() {
*x = InitServerRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_api_server_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *InitServerRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*InitServerRequest) ProtoMessage() {}
func (x *InitServerRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_server_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use InitServerRequest.ProtoReflect.Descriptor instead.
func (*InitServerRequest) Descriptor() ([]byte, []int) {
return file_api_server_proto_rawDescGZIP(), []int{0}
}
func (x *InitServerRequest) GetServerId() string {
if x != nil && x.ServerId != nil {
return *x.ServerId
}
return ""
}
func (x *InitServerRequest) GetServerIp() string {
if x != nil && x.ServerIp != nil {
return *x.ServerIp
}
return ""
}
type InitServerResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Status *Status `protobuf:"bytes,1,opt,name=status,proto3,oneof" json:"status,omitempty"`
ServerId *string `protobuf:"bytes,2,opt,name=server_id,json=serverId,proto3,oneof" json:"server_id,omitempty"`
}
func (x *InitServerResponse) Reset() {
*x = InitServerResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_api_server_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *InitServerResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*InitServerResponse) ProtoMessage() {}
func (x *InitServerResponse) ProtoReflect() protoreflect.Message {
mi := &file_api_server_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use InitServerResponse.ProtoReflect.Descriptor instead.
func (*InitServerResponse) Descriptor() ([]byte, []int) {
return file_api_server_proto_rawDescGZIP(), []int{1}
}
func (x *InitServerResponse) GetStatus() *Status {
if x != nil {
return x.Status
}
return nil
}
func (x *InitServerResponse) GetServerId() string {
if x != nil && x.ServerId != nil {
return *x.ServerId
}
return ""
}
type ListServersRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Page *int32 `protobuf:"varint,1,opt,name=page,proto3,oneof" json:"page,omitempty"`
PageSize *int32 `protobuf:"varint,2,opt,name=page_size,json=pageSize,proto3,oneof" json:"page_size,omitempty"`
}
func (x *ListServersRequest) Reset() {
*x = ListServersRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_api_server_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ListServersRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ListServersRequest) ProtoMessage() {}
func (x *ListServersRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_server_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ListServersRequest.ProtoReflect.Descriptor instead.
func (*ListServersRequest) Descriptor() ([]byte, []int) {
return file_api_server_proto_rawDescGZIP(), []int{2}
}
func (x *ListServersRequest) GetPage() int32 {
if x != nil && x.Page != nil {
return *x.Page
}
return 0
}
func (x *ListServersRequest) GetPageSize() int32 {
if x != nil && x.PageSize != nil {
return *x.PageSize
}
return 0
}
type ListServersResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Status *Status `protobuf:"bytes,1,opt,name=status,proto3,oneof" json:"status,omitempty"`
Total *int32 `protobuf:"varint,2,opt,name=total,proto3,oneof" json:"total,omitempty"`
Servers []*Server `protobuf:"bytes,3,rep,name=servers,proto3" json:"servers,omitempty"`
}
func (x *ListServersResponse) Reset() {
*x = ListServersResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_api_server_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ListServersResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ListServersResponse) ProtoMessage() {}
func (x *ListServersResponse) ProtoReflect() protoreflect.Message {
mi := &file_api_server_proto_msgTypes[3]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ListServersResponse.ProtoReflect.Descriptor instead.
func (*ListServersResponse) Descriptor() ([]byte, []int) {
return file_api_server_proto_rawDescGZIP(), []int{3}
}
func (x *ListServersResponse) GetStatus() *Status {
if x != nil {
return x.Status
}
return nil
}
func (x *ListServersResponse) GetTotal() int32 {
if x != nil && x.Total != nil {
return *x.Total
}
return 0
}
func (x *ListServersResponse) GetServers() []*Server {
if x != nil {
return x.Servers
}
return nil
}
type GetServerRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
ServerId *string `protobuf:"bytes,1,opt,name=server_id,json=serverId,proto3,oneof" json:"server_id,omitempty"`
}
func (x *GetServerRequest) Reset() {
*x = GetServerRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_api_server_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *GetServerRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GetServerRequest) ProtoMessage() {}
func (x *GetServerRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_server_proto_msgTypes[4]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use GetServerRequest.ProtoReflect.Descriptor instead.
func (*GetServerRequest) Descriptor() ([]byte, []int) {
return file_api_server_proto_rawDescGZIP(), []int{4}
}
func (x *GetServerRequest) GetServerId() string {
if x != nil && x.ServerId != nil {
return *x.ServerId
}
return ""
}
type GetServerResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Status *Status `protobuf:"bytes,1,opt,name=status,proto3,oneof" json:"status,omitempty"`
Server *Server `protobuf:"bytes,2,opt,name=server,proto3,oneof" json:"server,omitempty"`
}
func (x *GetServerResponse) Reset() {
*x = GetServerResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_api_server_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *GetServerResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GetServerResponse) ProtoMessage() {}
func (x *GetServerResponse) ProtoReflect() protoreflect.Message {
mi := &file_api_server_proto_msgTypes[5]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use GetServerResponse.ProtoReflect.Descriptor instead.
func (*GetServerResponse) Descriptor() ([]byte, []int) {
return file_api_server_proto_rawDescGZIP(), []int{5}
}
func (x *GetServerResponse) GetStatus() *Status {
if x != nil {
return x.Status
}
return nil
}
func (x *GetServerResponse) GetServer() *Server {
if x != nil {
return x.Server
}
return nil
}
type DeleteServerRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
ServerId *string `protobuf:"bytes,1,opt,name=server_id,json=serverId,proto3,oneof" json:"server_id,omitempty"`
}
func (x *DeleteServerRequest) Reset() {
*x = DeleteServerRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_api_server_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *DeleteServerRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*DeleteServerRequest) ProtoMessage() {}
func (x *DeleteServerRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_server_proto_msgTypes[6]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use DeleteServerRequest.ProtoReflect.Descriptor instead.
func (*DeleteServerRequest) Descriptor() ([]byte, []int) {
return file_api_server_proto_rawDescGZIP(), []int{6}
}
func (x *DeleteServerRequest) GetServerId() string {
if x != nil && x.ServerId != nil {
return *x.ServerId
}
return ""
}
type DeleteServerResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Status *Status `protobuf:"bytes,1,opt,name=status,proto3,oneof" json:"status,omitempty"`
}
func (x *DeleteServerResponse) Reset() {
*x = DeleteServerResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_api_server_proto_msgTypes[7]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *DeleteServerResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*DeleteServerResponse) ProtoMessage() {}
func (x *DeleteServerResponse) ProtoReflect() protoreflect.Message {
mi := &file_api_server_proto_msgTypes[7]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use DeleteServerResponse.ProtoReflect.Descriptor instead.
func (*DeleteServerResponse) Descriptor() ([]byte, []int) {
return file_api_server_proto_rawDescGZIP(), []int{7}
}
func (x *DeleteServerResponse) GetStatus() *Status {
if x != nil {
return x.Status
}
return nil
}
type UpdateFRPSRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
ServerId *string `protobuf:"bytes,1,opt,name=server_id,json=serverId,proto3,oneof" json:"server_id,omitempty"`
Config []byte `protobuf:"bytes,2,opt,name=config,proto3,oneof" json:"config,omitempty"`
}
func (x *UpdateFRPSRequest) Reset() {
*x = UpdateFRPSRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_api_server_proto_msgTypes[8]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *UpdateFRPSRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*UpdateFRPSRequest) ProtoMessage() {}
func (x *UpdateFRPSRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_server_proto_msgTypes[8]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use UpdateFRPSRequest.ProtoReflect.Descriptor instead.
func (*UpdateFRPSRequest) Descriptor() ([]byte, []int) {
return file_api_server_proto_rawDescGZIP(), []int{8}
}
func (x *UpdateFRPSRequest) GetServerId() string {
if x != nil && x.ServerId != nil {
return *x.ServerId
}
return ""
}
func (x *UpdateFRPSRequest) GetConfig() []byte {
if x != nil {
return x.Config
}
return nil
}
type UpdateFRPSResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Status *Status `protobuf:"bytes,1,opt,name=status,proto3,oneof" json:"status,omitempty"`
}
func (x *UpdateFRPSResponse) Reset() {
*x = UpdateFRPSResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_api_server_proto_msgTypes[9]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *UpdateFRPSResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*UpdateFRPSResponse) ProtoMessage() {}
func (x *UpdateFRPSResponse) ProtoReflect() protoreflect.Message {
mi := &file_api_server_proto_msgTypes[9]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use UpdateFRPSResponse.ProtoReflect.Descriptor instead.
func (*UpdateFRPSResponse) Descriptor() ([]byte, []int) {
return file_api_server_proto_rawDescGZIP(), []int{9}
}
func (x *UpdateFRPSResponse) GetStatus() *Status {
if x != nil {
return x.Status
}
return nil
}
type RemoveFRPSRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
ServerId *string `protobuf:"bytes,1,opt,name=server_id,json=serverId,proto3,oneof" json:"server_id,omitempty"`
}
func (x *RemoveFRPSRequest) Reset() {
*x = RemoveFRPSRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_api_server_proto_msgTypes[10]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *RemoveFRPSRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*RemoveFRPSRequest) ProtoMessage() {}
func (x *RemoveFRPSRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_server_proto_msgTypes[10]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use RemoveFRPSRequest.ProtoReflect.Descriptor instead.
func (*RemoveFRPSRequest) Descriptor() ([]byte, []int) {
return file_api_server_proto_rawDescGZIP(), []int{10}
}
func (x *RemoveFRPSRequest) GetServerId() string {
if x != nil && x.ServerId != nil {
return *x.ServerId
}
return ""
}
type RemoveFRPSResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Status *Status `protobuf:"bytes,1,opt,name=status,proto3,oneof" json:"status,omitempty"`
}
func (x *RemoveFRPSResponse) Reset() {
*x = RemoveFRPSResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_api_server_proto_msgTypes[11]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *RemoveFRPSResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*RemoveFRPSResponse) ProtoMessage() {}
func (x *RemoveFRPSResponse) ProtoReflect() protoreflect.Message {
mi := &file_api_server_proto_msgTypes[11]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use RemoveFRPSResponse.ProtoReflect.Descriptor instead.
func (*RemoveFRPSResponse) Descriptor() ([]byte, []int) {
return file_api_server_proto_rawDescGZIP(), []int{11}
}
func (x *RemoveFRPSResponse) GetStatus() *Status {
if x != nil {
return x.Status
}
return nil
}
var File_api_server_proto protoreflect.FileDescriptor
var file_api_server_proto_rawDesc = []byte{
0x0a, 0x10, 0x61, 0x70, 0x69, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x12, 0x0a, 0x61, 0x70, 0x69, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x1a, 0x0c,
0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x73, 0x0a, 0x11,
0x49, 0x6e, 0x69, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x12, 0x20, 0x0a, 0x09, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01,
0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x08, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x49, 0x64,
0x88, 0x01, 0x01, 0x12, 0x20, 0x0a, 0x09, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x69, 0x70,
0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x08, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72,
0x49, 0x70, 0x88, 0x01, 0x01, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72,
0x5f, 0x69, 0x64, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x69,
0x70, 0x22, 0x7c, 0x0a, 0x12, 0x49, 0x6e, 0x69, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75,
0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e,
0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x48, 0x00, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75,
0x73, 0x88, 0x01, 0x01, 0x12, 0x20, 0x0a, 0x09, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x69,
0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x08, 0x73, 0x65, 0x72, 0x76, 0x65,
0x72, 0x49, 0x64, 0x88, 0x01, 0x01, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75,
0x73, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x22,
0x66, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x04, 0x70, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20,
0x01, 0x28, 0x05, 0x48, 0x00, 0x52, 0x04, 0x70, 0x61, 0x67, 0x65, 0x88, 0x01, 0x01, 0x12, 0x20,
0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
0x05, 0x48, 0x01, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x88, 0x01, 0x01,
0x42, 0x07, 0x0a, 0x05, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x70, 0x61,
0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x22, 0x9c, 0x01, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74,
0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
0x2b, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x0e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x48,
0x00, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x88, 0x01, 0x01, 0x12, 0x19, 0x0a, 0x05,
0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x48, 0x01, 0x52, 0x05, 0x74,
0x6f, 0x74, 0x61, 0x6c, 0x88, 0x01, 0x01, 0x12, 0x28, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x65,
0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f,
0x6e, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72,
0x73, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x08, 0x0a, 0x06,
0x5f, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x22, 0x42, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72,
0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x09, 0x73, 0x65,
0x72, 0x76, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52,
0x08, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x49, 0x64, 0x88, 0x01, 0x01, 0x42, 0x0c, 0x0a, 0x0a,
0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x22, 0x83, 0x01, 0x0a, 0x11, 0x47,
0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x12, 0x2b, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x0e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
0x48, 0x00, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x88, 0x01, 0x01, 0x12, 0x2b, 0x0a,
0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e,
0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x48, 0x01, 0x52,
0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x88, 0x01, 0x01, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x73,
0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72,
0x22, 0x45, 0x0a, 0x13, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x09, 0x73, 0x65, 0x72, 0x76, 0x65,
0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x08, 0x73, 0x65,
0x72, 0x76, 0x65, 0x72, 0x49, 0x64, 0x88, 0x01, 0x01, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x73, 0x65,
0x72, 0x76, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x22, 0x4e, 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74,
0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
0x2b, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x0e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x48,
0x00, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x88, 0x01, 0x01, 0x42, 0x09, 0x0a, 0x07,
0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x6b, 0x0a, 0x11, 0x55, 0x70, 0x64, 0x61, 0x74,
0x65, 0x46, 0x52, 0x50, 0x53, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x09,
0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48,
0x00, 0x52, 0x08, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x49, 0x64, 0x88, 0x01, 0x01, 0x12, 0x1b,
0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x01,
0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x88, 0x01, 0x01, 0x42, 0x0c, 0x0a, 0x0a, 0x5f,
0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x63, 0x6f,
0x6e, 0x66, 0x69, 0x67, 0x22, 0x4c, 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x46, 0x52,
0x50, 0x53, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, 0x0a, 0x06, 0x73, 0x74,
0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x6f, 0x6d,
0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x48, 0x00, 0x52, 0x06, 0x73, 0x74,
0x61, 0x74, 0x75, 0x73, 0x88, 0x01, 0x01, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x73, 0x74, 0x61, 0x74,
0x75, 0x73, 0x22, 0x43, 0x0a, 0x11, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x46, 0x52, 0x50, 0x53,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x09, 0x73, 0x65, 0x72, 0x76, 0x65,
0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x08, 0x73, 0x65,
0x72, 0x76, 0x65, 0x72, 0x49, 0x64, 0x88, 0x01, 0x01, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x73, 0x65,
0x72, 0x76, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x22, 0x4c, 0x0a, 0x12, 0x52, 0x65, 0x6d, 0x6f, 0x76,
0x65, 0x46, 0x52, 0x50, 0x53, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, 0x0a,
0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e,
0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x48, 0x00, 0x52,
0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x88, 0x01, 0x01, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x73,
0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x07, 0x5a, 0x05, 0x2e, 0x2e, 0x2f, 0x70, 0x62, 0x62, 0x06,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_api_server_proto_rawDescOnce sync.Once
file_api_server_proto_rawDescData = file_api_server_proto_rawDesc
)
func file_api_server_proto_rawDescGZIP() []byte {
file_api_server_proto_rawDescOnce.Do(func() {
file_api_server_proto_rawDescData = protoimpl.X.CompressGZIP(file_api_server_proto_rawDescData)
})
return file_api_server_proto_rawDescData
}
var file_api_server_proto_msgTypes = make([]protoimpl.MessageInfo, 12)
var file_api_server_proto_goTypes = []interface{}{
(*InitServerRequest)(nil), // 0: api_server.InitServerRequest
(*InitServerResponse)(nil), // 1: api_server.InitServerResponse
(*ListServersRequest)(nil), // 2: api_server.ListServersRequest
(*ListServersResponse)(nil), // 3: api_server.ListServersResponse
(*GetServerRequest)(nil), // 4: api_server.GetServerRequest
(*GetServerResponse)(nil), // 5: api_server.GetServerResponse
(*DeleteServerRequest)(nil), // 6: api_server.DeleteServerRequest
(*DeleteServerResponse)(nil), // 7: api_server.DeleteServerResponse
(*UpdateFRPSRequest)(nil), // 8: api_server.UpdateFRPSRequest
(*UpdateFRPSResponse)(nil), // 9: api_server.UpdateFRPSResponse
(*RemoveFRPSRequest)(nil), // 10: api_server.RemoveFRPSRequest
(*RemoveFRPSResponse)(nil), // 11: api_server.RemoveFRPSResponse
(*Status)(nil), // 12: common.Status
(*Server)(nil), // 13: common.Server
}
var file_api_server_proto_depIdxs = []int32{
12, // 0: api_server.InitServerResponse.status:type_name -> common.Status
12, // 1: api_server.ListServersResponse.status:type_name -> common.Status
13, // 2: api_server.ListServersResponse.servers:type_name -> common.Server
12, // 3: api_server.GetServerResponse.status:type_name -> common.Status
13, // 4: api_server.GetServerResponse.server:type_name -> common.Server
12, // 5: api_server.DeleteServerResponse.status:type_name -> common.Status
12, // 6: api_server.UpdateFRPSResponse.status:type_name -> common.Status
12, // 7: api_server.RemoveFRPSResponse.status:type_name -> common.Status
8, // [8:8] is the sub-list for method output_type
8, // [8:8] is the sub-list for method input_type
8, // [8:8] is the sub-list for extension type_name
8, // [8:8] is the sub-list for extension extendee
0, // [0:8] is the sub-list for field type_name
}
func init() { file_api_server_proto_init() }
func file_api_server_proto_init() {
if File_api_server_proto != nil {
return
}
file_common_proto_init()
if !protoimpl.UnsafeEnabled {
file_api_server_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*InitServerRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_api_server_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*InitServerResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_api_server_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ListServersRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_api_server_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ListServersResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_api_server_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*GetServerRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_api_server_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*GetServerResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_api_server_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*DeleteServerRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_api_server_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*DeleteServerResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_api_server_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*UpdateFRPSRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_api_server_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*UpdateFRPSResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_api_server_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*RemoveFRPSRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_api_server_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*RemoveFRPSResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
file_api_server_proto_msgTypes[0].OneofWrappers = []interface{}{}
file_api_server_proto_msgTypes[1].OneofWrappers = []interface{}{}
file_api_server_proto_msgTypes[2].OneofWrappers = []interface{}{}
file_api_server_proto_msgTypes[3].OneofWrappers = []interface{}{}
file_api_server_proto_msgTypes[4].OneofWrappers = []interface{}{}
file_api_server_proto_msgTypes[5].OneofWrappers = []interface{}{}
file_api_server_proto_msgTypes[6].OneofWrappers = []interface{}{}
file_api_server_proto_msgTypes[7].OneofWrappers = []interface{}{}
file_api_server_proto_msgTypes[8].OneofWrappers = []interface{}{}
file_api_server_proto_msgTypes[9].OneofWrappers = []interface{}{}
file_api_server_proto_msgTypes[10].OneofWrappers = []interface{}{}
file_api_server_proto_msgTypes[11].OneofWrappers = []interface{}{}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_api_server_proto_rawDesc,
NumEnums: 0,
NumMessages: 12,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_api_server_proto_goTypes,
DependencyIndexes: file_api_server_proto_depIdxs,
MessageInfos: file_api_server_proto_msgTypes,
}.Build()
File_api_server_proto = out.File
file_api_server_proto_rawDesc = nil
file_api_server_proto_goTypes = nil
file_api_server_proto_depIdxs = nil
}

350
pb/api_user.pb.go Normal file
View File

@@ -0,0 +1,350 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.32.0
// protoc v4.25.1
// source: api_user.proto
package pb
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type GetUserInfoRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
}
func (x *GetUserInfoRequest) Reset() {
*x = GetUserInfoRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_api_user_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *GetUserInfoRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GetUserInfoRequest) ProtoMessage() {}
func (x *GetUserInfoRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_user_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use GetUserInfoRequest.ProtoReflect.Descriptor instead.
func (*GetUserInfoRequest) Descriptor() ([]byte, []int) {
return file_api_user_proto_rawDescGZIP(), []int{0}
}
type GetUserInfoResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Status *Status `protobuf:"bytes,1,opt,name=status,proto3,oneof" json:"status,omitempty"`
UserInfo *User `protobuf:"bytes,2,opt,name=user_info,json=userInfo,proto3,oneof" json:"user_info,omitempty"`
}
func (x *GetUserInfoResponse) Reset() {
*x = GetUserInfoResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_api_user_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *GetUserInfoResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GetUserInfoResponse) ProtoMessage() {}
func (x *GetUserInfoResponse) ProtoReflect() protoreflect.Message {
mi := &file_api_user_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use GetUserInfoResponse.ProtoReflect.Descriptor instead.
func (*GetUserInfoResponse) Descriptor() ([]byte, []int) {
return file_api_user_proto_rawDescGZIP(), []int{1}
}
func (x *GetUserInfoResponse) GetStatus() *Status {
if x != nil {
return x.Status
}
return nil
}
func (x *GetUserInfoResponse) GetUserInfo() *User {
if x != nil {
return x.UserInfo
}
return nil
}
type UpdateUserInfoRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
UserInfo *User `protobuf:"bytes,1,opt,name=user_info,json=userInfo,proto3,oneof" json:"user_info,omitempty"`
}
func (x *UpdateUserInfoRequest) Reset() {
*x = UpdateUserInfoRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_api_user_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *UpdateUserInfoRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*UpdateUserInfoRequest) ProtoMessage() {}
func (x *UpdateUserInfoRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_user_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use UpdateUserInfoRequest.ProtoReflect.Descriptor instead.
func (*UpdateUserInfoRequest) Descriptor() ([]byte, []int) {
return file_api_user_proto_rawDescGZIP(), []int{2}
}
func (x *UpdateUserInfoRequest) GetUserInfo() *User {
if x != nil {
return x.UserInfo
}
return nil
}
type UpdateUserInfoResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Status *Status `protobuf:"bytes,1,opt,name=status,proto3,oneof" json:"status,omitempty"`
}
func (x *UpdateUserInfoResponse) Reset() {
*x = UpdateUserInfoResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_api_user_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *UpdateUserInfoResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*UpdateUserInfoResponse) ProtoMessage() {}
func (x *UpdateUserInfoResponse) ProtoReflect() protoreflect.Message {
mi := &file_api_user_proto_msgTypes[3]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use UpdateUserInfoResponse.ProtoReflect.Descriptor instead.
func (*UpdateUserInfoResponse) Descriptor() ([]byte, []int) {
return file_api_user_proto_rawDescGZIP(), []int{3}
}
func (x *UpdateUserInfoResponse) GetStatus() *Status {
if x != nil {
return x.Status
}
return nil
}
var File_api_user_proto protoreflect.FileDescriptor
var file_api_user_proto_rawDesc = []byte{
0x0a, 0x0e, 0x61, 0x70, 0x69, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x12, 0x08, 0x61, 0x70, 0x69, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x1a, 0x0c, 0x63, 0x6f, 0x6d, 0x6d,
0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x14, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x55,
0x73, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x8b,
0x01, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73,
0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e,
0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x48, 0x00, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73,
0x88, 0x01, 0x01, 0x12, 0x2e, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x66, 0x6f,
0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e,
0x55, 0x73, 0x65, 0x72, 0x48, 0x01, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f,
0x88, 0x01, 0x01, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x0c,
0x0a, 0x0a, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x22, 0x55, 0x0a, 0x15,
0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2e, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x6e,
0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f,
0x6e, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x48, 0x00, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x49, 0x6e,
0x66, 0x6f, 0x88, 0x01, 0x01, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69,
0x6e, 0x66, 0x6f, 0x22, 0x50, 0x0a, 0x16, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65,
0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, 0x0a,
0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e,
0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x48, 0x00, 0x52,
0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x88, 0x01, 0x01, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x73,
0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x07, 0x5a, 0x05, 0x2e, 0x2e, 0x2f, 0x70, 0x62, 0x62, 0x06,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_api_user_proto_rawDescOnce sync.Once
file_api_user_proto_rawDescData = file_api_user_proto_rawDesc
)
func file_api_user_proto_rawDescGZIP() []byte {
file_api_user_proto_rawDescOnce.Do(func() {
file_api_user_proto_rawDescData = protoimpl.X.CompressGZIP(file_api_user_proto_rawDescData)
})
return file_api_user_proto_rawDescData
}
var file_api_user_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
var file_api_user_proto_goTypes = []interface{}{
(*GetUserInfoRequest)(nil), // 0: api_user.GetUserInfoRequest
(*GetUserInfoResponse)(nil), // 1: api_user.GetUserInfoResponse
(*UpdateUserInfoRequest)(nil), // 2: api_user.UpdateUserInfoRequest
(*UpdateUserInfoResponse)(nil), // 3: api_user.UpdateUserInfoResponse
(*Status)(nil), // 4: common.Status
(*User)(nil), // 5: common.User
}
var file_api_user_proto_depIdxs = []int32{
4, // 0: api_user.GetUserInfoResponse.status:type_name -> common.Status
5, // 1: api_user.GetUserInfoResponse.user_info:type_name -> common.User
5, // 2: api_user.UpdateUserInfoRequest.user_info:type_name -> common.User
4, // 3: api_user.UpdateUserInfoResponse.status:type_name -> common.Status
4, // [4:4] is the sub-list for method output_type
4, // [4:4] is the sub-list for method input_type
4, // [4:4] is the sub-list for extension type_name
4, // [4:4] is the sub-list for extension extendee
0, // [0:4] is the sub-list for field type_name
}
func init() { file_api_user_proto_init() }
func file_api_user_proto_init() {
if File_api_user_proto != nil {
return
}
file_common_proto_init()
if !protoimpl.UnsafeEnabled {
file_api_user_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*GetUserInfoRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_api_user_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*GetUserInfoResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_api_user_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*UpdateUserInfoRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_api_user_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*UpdateUserInfoResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
file_api_user_proto_msgTypes[1].OneofWrappers = []interface{}{}
file_api_user_proto_msgTypes[2].OneofWrappers = []interface{}{}
file_api_user_proto_msgTypes[3].OneofWrappers = []interface{}{}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_api_user_proto_rawDesc,
NumEnums: 0,
NumMessages: 4,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_api_user_proto_goTypes,
DependencyIndexes: file_api_user_proto_depIdxs,
MessageInfos: file_api_user_proto_msgTypes,
}.Build()
File_api_user_proto = out.File
file_api_user_proto_rawDesc = nil
file_api_user_proto_goTypes = nil
file_api_user_proto_depIdxs = nil
}

612
pb/common.pb.go Normal file
View File

@@ -0,0 +1,612 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.32.0
// protoc v4.25.1
// source: common.proto
package pb
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type RespCode int32
const (
RespCode_RESP_CODE_UNSPECIFIED RespCode = 0
RespCode_RESP_CODE_SUCCESS RespCode = 1
RespCode_RESP_CODE_NOT_FOUND RespCode = 2
RespCode_RESP_CODE_ALREADY_EXISTS RespCode = 3
RespCode_RESP_CODE_INVALID RespCode = 4
RespCode_RESP_CODE_FINISH RespCode = 5
RespCode_RESP_CODE_UNAUTHORIZED RespCode = 6
)
// Enum value maps for RespCode.
var (
RespCode_name = map[int32]string{
0: "RESP_CODE_UNSPECIFIED",
1: "RESP_CODE_SUCCESS",
2: "RESP_CODE_NOT_FOUND",
3: "RESP_CODE_ALREADY_EXISTS",
4: "RESP_CODE_INVALID",
5: "RESP_CODE_FINISH",
6: "RESP_CODE_UNAUTHORIZED",
}
RespCode_value = map[string]int32{
"RESP_CODE_UNSPECIFIED": 0,
"RESP_CODE_SUCCESS": 1,
"RESP_CODE_NOT_FOUND": 2,
"RESP_CODE_ALREADY_EXISTS": 3,
"RESP_CODE_INVALID": 4,
"RESP_CODE_FINISH": 5,
"RESP_CODE_UNAUTHORIZED": 6,
}
)
func (x RespCode) Enum() *RespCode {
p := new(RespCode)
*p = x
return p
}
func (x RespCode) String() string {
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}
func (RespCode) Descriptor() protoreflect.EnumDescriptor {
return file_common_proto_enumTypes[0].Descriptor()
}
func (RespCode) Type() protoreflect.EnumType {
return &file_common_proto_enumTypes[0]
}
func (x RespCode) Number() protoreflect.EnumNumber {
return protoreflect.EnumNumber(x)
}
// Deprecated: Use RespCode.Descriptor instead.
func (RespCode) EnumDescriptor() ([]byte, []int) {
return file_common_proto_rawDescGZIP(), []int{0}
}
type Status struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Code RespCode `protobuf:"varint,1,opt,name=code,proto3,enum=common.RespCode" json:"code,omitempty"`
Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"`
}
func (x *Status) Reset() {
*x = Status{}
if protoimpl.UnsafeEnabled {
mi := &file_common_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Status) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Status) ProtoMessage() {}
func (x *Status) ProtoReflect() protoreflect.Message {
mi := &file_common_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Status.ProtoReflect.Descriptor instead.
func (*Status) Descriptor() ([]byte, []int) {
return file_common_proto_rawDescGZIP(), []int{0}
}
func (x *Status) GetCode() RespCode {
if x != nil {
return x.Code
}
return RespCode_RESP_CODE_UNSPECIFIED
}
func (x *Status) GetMessage() string {
if x != nil {
return x.Message
}
return ""
}
type CommonResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Status *Status `protobuf:"bytes,1,opt,name=status,proto3,oneof" json:"status,omitempty"`
}
func (x *CommonResponse) Reset() {
*x = CommonResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_common_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *CommonResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CommonResponse) ProtoMessage() {}
func (x *CommonResponse) ProtoReflect() protoreflect.Message {
mi := &file_common_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CommonResponse.ProtoReflect.Descriptor instead.
func (*CommonResponse) Descriptor() ([]byte, []int) {
return file_common_proto_rawDescGZIP(), []int{1}
}
func (x *CommonResponse) GetStatus() *Status {
if x != nil {
return x.Status
}
return nil
}
type Client struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Id *string `protobuf:"bytes,1,opt,name=id,proto3,oneof" json:"id,omitempty"`
Secret *string `protobuf:"bytes,2,opt,name=secret,proto3,oneof" json:"secret,omitempty"`
Config *string `protobuf:"bytes,3,opt,name=config,proto3,oneof" json:"config,omitempty"`
}
func (x *Client) Reset() {
*x = Client{}
if protoimpl.UnsafeEnabled {
mi := &file_common_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Client) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Client) ProtoMessage() {}
func (x *Client) ProtoReflect() protoreflect.Message {
mi := &file_common_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Client.ProtoReflect.Descriptor instead.
func (*Client) Descriptor() ([]byte, []int) {
return file_common_proto_rawDescGZIP(), []int{2}
}
func (x *Client) GetId() string {
if x != nil && x.Id != nil {
return *x.Id
}
return ""
}
func (x *Client) GetSecret() string {
if x != nil && x.Secret != nil {
return *x.Secret
}
return ""
}
func (x *Client) GetConfig() string {
if x != nil && x.Config != nil {
return *x.Config
}
return ""
}
type Server struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Id *string `protobuf:"bytes,1,opt,name=id,proto3,oneof" json:"id,omitempty"`
Secret *string `protobuf:"bytes,2,opt,name=secret,proto3,oneof" json:"secret,omitempty"`
Ip *string `protobuf:"bytes,3,opt,name=ip,proto3,oneof" json:"ip,omitempty"`
Config *string `protobuf:"bytes,4,opt,name=config,proto3,oneof" json:"config,omitempty"` // 在定义上ip和port只是为了方便使用
}
func (x *Server) Reset() {
*x = Server{}
if protoimpl.UnsafeEnabled {
mi := &file_common_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Server) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Server) ProtoMessage() {}
func (x *Server) ProtoReflect() protoreflect.Message {
mi := &file_common_proto_msgTypes[3]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Server.ProtoReflect.Descriptor instead.
func (*Server) Descriptor() ([]byte, []int) {
return file_common_proto_rawDescGZIP(), []int{3}
}
func (x *Server) GetId() string {
if x != nil && x.Id != nil {
return *x.Id
}
return ""
}
func (x *Server) GetSecret() string {
if x != nil && x.Secret != nil {
return *x.Secret
}
return ""
}
func (x *Server) GetIp() string {
if x != nil && x.Ip != nil {
return *x.Ip
}
return ""
}
func (x *Server) GetConfig() string {
if x != nil && x.Config != nil {
return *x.Config
}
return ""
}
type User struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
UserID *int64 `protobuf:"varint,1,opt,name=UserID,proto3,oneof" json:"UserID,omitempty"`
TenantID *int64 `protobuf:"varint,2,opt,name=TenantID,proto3,oneof" json:"TenantID,omitempty"`
UserName *string `protobuf:"bytes,3,opt,name=UserName,proto3,oneof" json:"UserName,omitempty"`
Email *string `protobuf:"bytes,4,opt,name=Email,proto3,oneof" json:"Email,omitempty"`
Status *string `protobuf:"bytes,5,opt,name=Status,proto3,oneof" json:"Status,omitempty"`
Role *string `protobuf:"bytes,6,opt,name=Role,proto3,oneof" json:"Role,omitempty"`
Token *string `protobuf:"bytes,7,opt,name=Token,proto3,oneof" json:"Token,omitempty"`
RawPassword *string `protobuf:"bytes,8,opt,name=RawPassword,proto3,oneof" json:"RawPassword,omitempty"`
}
func (x *User) Reset() {
*x = User{}
if protoimpl.UnsafeEnabled {
mi := &file_common_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *User) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*User) ProtoMessage() {}
func (x *User) ProtoReflect() protoreflect.Message {
mi := &file_common_proto_msgTypes[4]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use User.ProtoReflect.Descriptor instead.
func (*User) Descriptor() ([]byte, []int) {
return file_common_proto_rawDescGZIP(), []int{4}
}
func (x *User) GetUserID() int64 {
if x != nil && x.UserID != nil {
return *x.UserID
}
return 0
}
func (x *User) GetTenantID() int64 {
if x != nil && x.TenantID != nil {
return *x.TenantID
}
return 0
}
func (x *User) GetUserName() string {
if x != nil && x.UserName != nil {
return *x.UserName
}
return ""
}
func (x *User) GetEmail() string {
if x != nil && x.Email != nil {
return *x.Email
}
return ""
}
func (x *User) GetStatus() string {
if x != nil && x.Status != nil {
return *x.Status
}
return ""
}
func (x *User) GetRole() string {
if x != nil && x.Role != nil {
return *x.Role
}
return ""
}
func (x *User) GetToken() string {
if x != nil && x.Token != nil {
return *x.Token
}
return ""
}
func (x *User) GetRawPassword() string {
if x != nil && x.RawPassword != nil {
return *x.RawPassword
}
return ""
}
var File_common_proto protoreflect.FileDescriptor
var file_common_proto_rawDesc = []byte{
0x0a, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06,
0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x22, 0x48, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
0x12, 0x24, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x10,
0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x43, 0x6f, 0x64, 0x65,
0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67,
0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
0x22, 0x48, 0x0a, 0x0e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x12, 0x2b, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x74,
0x75, 0x73, 0x48, 0x00, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x88, 0x01, 0x01, 0x42,
0x09, 0x0a, 0x07, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x74, 0x0a, 0x06, 0x43, 0x6c,
0x69, 0x65, 0x6e, 0x74, 0x12, 0x13, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
0x48, 0x00, 0x52, 0x02, 0x69, 0x64, 0x88, 0x01, 0x01, 0x12, 0x1b, 0x0a, 0x06, 0x73, 0x65, 0x63,
0x72, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x06, 0x73, 0x65, 0x63,
0x72, 0x65, 0x74, 0x88, 0x01, 0x01, 0x12, 0x1b, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x02, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
0x88, 0x01, 0x01, 0x42, 0x05, 0x0a, 0x03, 0x5f, 0x69, 0x64, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x73,
0x65, 0x63, 0x72, 0x65, 0x74, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
0x22, 0x90, 0x01, 0x0a, 0x06, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x13, 0x0a, 0x02, 0x69,
0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x02, 0x69, 0x64, 0x88, 0x01, 0x01,
0x12, 0x1b, 0x0a, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
0x48, 0x01, 0x52, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x88, 0x01, 0x01, 0x12, 0x13, 0x0a,
0x02, 0x69, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x02, 0x52, 0x02, 0x69, 0x70, 0x88,
0x01, 0x01, 0x12, 0x1b, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x04, 0x20, 0x01,
0x28, 0x09, 0x48, 0x03, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x88, 0x01, 0x01, 0x42,
0x05, 0x0a, 0x03, 0x5f, 0x69, 0x64, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x73, 0x65, 0x63, 0x72, 0x65,
0x74, 0x42, 0x05, 0x0a, 0x03, 0x5f, 0x69, 0x70, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x63, 0x6f, 0x6e,
0x66, 0x69, 0x67, 0x22, 0xd5, 0x02, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x1b, 0x0a, 0x06,
0x55, 0x73, 0x65, 0x72, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x06,
0x55, 0x73, 0x65, 0x72, 0x49, 0x44, 0x88, 0x01, 0x01, 0x12, 0x1f, 0x0a, 0x08, 0x54, 0x65, 0x6e,
0x61, 0x6e, 0x74, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x48, 0x01, 0x52, 0x08, 0x54,
0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x44, 0x88, 0x01, 0x01, 0x12, 0x1f, 0x0a, 0x08, 0x55, 0x73,
0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x02, 0x52, 0x08,
0x55, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x88, 0x01, 0x01, 0x12, 0x19, 0x0a, 0x05, 0x45,
0x6d, 0x61, 0x69, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x03, 0x52, 0x05, 0x45, 0x6d,
0x61, 0x69, 0x6c, 0x88, 0x01, 0x01, 0x12, 0x1b, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x48, 0x04, 0x52, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
0x88, 0x01, 0x01, 0x12, 0x17, 0x0a, 0x04, 0x52, 0x6f, 0x6c, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28,
0x09, 0x48, 0x05, 0x52, 0x04, 0x52, 0x6f, 0x6c, 0x65, 0x88, 0x01, 0x01, 0x12, 0x19, 0x0a, 0x05,
0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x48, 0x06, 0x52, 0x05, 0x54,
0x6f, 0x6b, 0x65, 0x6e, 0x88, 0x01, 0x01, 0x12, 0x25, 0x0a, 0x0b, 0x52, 0x61, 0x77, 0x50, 0x61,
0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x48, 0x07, 0x52, 0x0b,
0x52, 0x61, 0x77, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x88, 0x01, 0x01, 0x42, 0x09,
0x0a, 0x07, 0x5f, 0x55, 0x73, 0x65, 0x72, 0x49, 0x44, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x54, 0x65,
0x6e, 0x61, 0x6e, 0x74, 0x49, 0x44, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x55, 0x73, 0x65, 0x72, 0x4e,
0x61, 0x6d, 0x65, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x42, 0x09, 0x0a,
0x07, 0x5f, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x52, 0x6f, 0x6c,
0x65, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x42, 0x0e, 0x0a, 0x0c, 0x5f,
0x52, 0x61, 0x77, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x2a, 0xbc, 0x01, 0x0a, 0x08,
0x52, 0x65, 0x73, 0x70, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x19, 0x0a, 0x15, 0x52, 0x45, 0x53, 0x50,
0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45,
0x44, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x52, 0x45, 0x53, 0x50, 0x5f, 0x43, 0x4f, 0x44, 0x45,
0x5f, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, 0x01, 0x12, 0x17, 0x0a, 0x13, 0x52, 0x45,
0x53, 0x50, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x46, 0x4f, 0x55, 0x4e,
0x44, 0x10, 0x02, 0x12, 0x1c, 0x0a, 0x18, 0x52, 0x45, 0x53, 0x50, 0x5f, 0x43, 0x4f, 0x44, 0x45,
0x5f, 0x41, 0x4c, 0x52, 0x45, 0x41, 0x44, 0x59, 0x5f, 0x45, 0x58, 0x49, 0x53, 0x54, 0x53, 0x10,
0x03, 0x12, 0x15, 0x0a, 0x11, 0x52, 0x45, 0x53, 0x50, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x49,
0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, 0x04, 0x12, 0x14, 0x0a, 0x10, 0x52, 0x45, 0x53, 0x50,
0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x46, 0x49, 0x4e, 0x49, 0x53, 0x48, 0x10, 0x05, 0x12, 0x1a,
0x0a, 0x16, 0x52, 0x45, 0x53, 0x50, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x55, 0x4e, 0x41, 0x55,
0x54, 0x48, 0x4f, 0x52, 0x49, 0x5a, 0x45, 0x44, 0x10, 0x06, 0x42, 0x07, 0x5a, 0x05, 0x2e, 0x2e,
0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_common_proto_rawDescOnce sync.Once
file_common_proto_rawDescData = file_common_proto_rawDesc
)
func file_common_proto_rawDescGZIP() []byte {
file_common_proto_rawDescOnce.Do(func() {
file_common_proto_rawDescData = protoimpl.X.CompressGZIP(file_common_proto_rawDescData)
})
return file_common_proto_rawDescData
}
var file_common_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_common_proto_msgTypes = make([]protoimpl.MessageInfo, 5)
var file_common_proto_goTypes = []interface{}{
(RespCode)(0), // 0: common.RespCode
(*Status)(nil), // 1: common.Status
(*CommonResponse)(nil), // 2: common.CommonResponse
(*Client)(nil), // 3: common.Client
(*Server)(nil), // 4: common.Server
(*User)(nil), // 5: common.User
}
var file_common_proto_depIdxs = []int32{
0, // 0: common.Status.code:type_name -> common.RespCode
1, // 1: common.CommonResponse.status:type_name -> common.Status
2, // [2:2] is the sub-list for method output_type
2, // [2:2] is the sub-list for method input_type
2, // [2:2] is the sub-list for extension type_name
2, // [2:2] is the sub-list for extension extendee
0, // [0:2] is the sub-list for field type_name
}
func init() { file_common_proto_init() }
func file_common_proto_init() {
if File_common_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_common_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Status); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_common_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CommonResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_common_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Client); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_common_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Server); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_common_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*User); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
file_common_proto_msgTypes[1].OneofWrappers = []interface{}{}
file_common_proto_msgTypes[2].OneofWrappers = []interface{}{}
file_common_proto_msgTypes[3].OneofWrappers = []interface{}{}
file_common_proto_msgTypes[4].OneofWrappers = []interface{}{}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_common_proto_rawDesc,
NumEnums: 1,
NumMessages: 5,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_common_proto_goTypes,
DependencyIndexes: file_common_proto_depIdxs,
EnumInfos: file_common_proto_enumTypes,
MessageInfos: file_common_proto_msgTypes,
}.Build()
File_common_proto = out.File
file_common_proto_rawDesc = nil
file_common_proto_goTypes = nil
file_common_proto_depIdxs = nil
}

976
pb/rpc_master.pb.go Normal file
View File

@@ -0,0 +1,976 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.32.0
// protoc v4.25.1
// source: rpc_master.proto
package pb
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type Event int32
const (
Event_EVENT_UNSPECIFIED Event = 0
Event_EVENT_REGISTER_CLIENT Event = 1
Event_EVENT_REGISTER_SERVER Event = 2
Event_EVENT_ERROR Event = 3
Event_EVENT_DATA Event = 4
Event_EVENT_UPDATE_FRPC Event = 5
Event_EVENT_REMOVE_FRPC Event = 6
Event_EVENT_UPDATE_FRPS Event = 7
Event_EVENT_REMOVE_FRPS Event = 8
)
// Enum value maps for Event.
var (
Event_name = map[int32]string{
0: "EVENT_UNSPECIFIED",
1: "EVENT_REGISTER_CLIENT",
2: "EVENT_REGISTER_SERVER",
3: "EVENT_ERROR",
4: "EVENT_DATA",
5: "EVENT_UPDATE_FRPC",
6: "EVENT_REMOVE_FRPC",
7: "EVENT_UPDATE_FRPS",
8: "EVENT_REMOVE_FRPS",
}
Event_value = map[string]int32{
"EVENT_UNSPECIFIED": 0,
"EVENT_REGISTER_CLIENT": 1,
"EVENT_REGISTER_SERVER": 2,
"EVENT_ERROR": 3,
"EVENT_DATA": 4,
"EVENT_UPDATE_FRPC": 5,
"EVENT_REMOVE_FRPC": 6,
"EVENT_UPDATE_FRPS": 7,
"EVENT_REMOVE_FRPS": 8,
}
)
func (x Event) Enum() *Event {
p := new(Event)
*p = x
return p
}
func (x Event) String() string {
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}
func (Event) Descriptor() protoreflect.EnumDescriptor {
return file_rpc_master_proto_enumTypes[0].Descriptor()
}
func (Event) Type() protoreflect.EnumType {
return &file_rpc_master_proto_enumTypes[0]
}
func (x Event) Number() protoreflect.EnumNumber {
return protoreflect.EnumNumber(x)
}
// Deprecated: Use Event.Descriptor instead.
func (Event) EnumDescriptor() ([]byte, []int) {
return file_rpc_master_proto_rawDescGZIP(), []int{0}
}
type ServerBase struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
ServerId string `protobuf:"bytes,1,opt,name=server_id,json=serverId,proto3" json:"server_id,omitempty"`
ServerSecret string `protobuf:"bytes,2,opt,name=server_secret,json=serverSecret,proto3" json:"server_secret,omitempty"`
}
func (x *ServerBase) Reset() {
*x = ServerBase{}
if protoimpl.UnsafeEnabled {
mi := &file_rpc_master_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ServerBase) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ServerBase) ProtoMessage() {}
func (x *ServerBase) ProtoReflect() protoreflect.Message {
mi := &file_rpc_master_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ServerBase.ProtoReflect.Descriptor instead.
func (*ServerBase) Descriptor() ([]byte, []int) {
return file_rpc_master_proto_rawDescGZIP(), []int{0}
}
func (x *ServerBase) GetServerId() string {
if x != nil {
return x.ServerId
}
return ""
}
func (x *ServerBase) GetServerSecret() string {
if x != nil {
return x.ServerSecret
}
return ""
}
type ClientBase struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
ClientId string `protobuf:"bytes,1,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty"`
ClientSecret string `protobuf:"bytes,2,opt,name=client_secret,json=clientSecret,proto3" json:"client_secret,omitempty"`
}
func (x *ClientBase) Reset() {
*x = ClientBase{}
if protoimpl.UnsafeEnabled {
mi := &file_rpc_master_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ClientBase) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ClientBase) ProtoMessage() {}
func (x *ClientBase) ProtoReflect() protoreflect.Message {
mi := &file_rpc_master_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ClientBase.ProtoReflect.Descriptor instead.
func (*ClientBase) Descriptor() ([]byte, []int) {
return file_rpc_master_proto_rawDescGZIP(), []int{1}
}
func (x *ClientBase) GetClientId() string {
if x != nil {
return x.ClientId
}
return ""
}
func (x *ClientBase) GetClientSecret() string {
if x != nil {
return x.ClientSecret
}
return ""
}
type ServerMessage struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Event Event `protobuf:"varint,1,opt,name=event,proto3,enum=master.Event" json:"event,omitempty"`
ClientId string `protobuf:"bytes,2,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty"`
SessionId string `protobuf:"bytes,3,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"`
Data []byte `protobuf:"bytes,4,opt,name=data,proto3" json:"data,omitempty"`
}
func (x *ServerMessage) Reset() {
*x = ServerMessage{}
if protoimpl.UnsafeEnabled {
mi := &file_rpc_master_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ServerMessage) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ServerMessage) ProtoMessage() {}
func (x *ServerMessage) ProtoReflect() protoreflect.Message {
mi := &file_rpc_master_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ServerMessage.ProtoReflect.Descriptor instead.
func (*ServerMessage) Descriptor() ([]byte, []int) {
return file_rpc_master_proto_rawDescGZIP(), []int{2}
}
func (x *ServerMessage) GetEvent() Event {
if x != nil {
return x.Event
}
return Event_EVENT_UNSPECIFIED
}
func (x *ServerMessage) GetClientId() string {
if x != nil {
return x.ClientId
}
return ""
}
func (x *ServerMessage) GetSessionId() string {
if x != nil {
return x.SessionId
}
return ""
}
func (x *ServerMessage) GetData() []byte {
if x != nil {
return x.Data
}
return nil
}
type ClientMessage struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Event Event `protobuf:"varint,1,opt,name=event,proto3,enum=master.Event" json:"event,omitempty"`
ClientId string `protobuf:"bytes,2,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty"`
SessionId string `protobuf:"bytes,3,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"`
Secret string `protobuf:"bytes,4,opt,name=secret,proto3" json:"secret,omitempty"`
Data []byte `protobuf:"bytes,5,opt,name=data,proto3" json:"data,omitempty"`
}
func (x *ClientMessage) Reset() {
*x = ClientMessage{}
if protoimpl.UnsafeEnabled {
mi := &file_rpc_master_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ClientMessage) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ClientMessage) ProtoMessage() {}
func (x *ClientMessage) ProtoReflect() protoreflect.Message {
mi := &file_rpc_master_proto_msgTypes[3]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ClientMessage.ProtoReflect.Descriptor instead.
func (*ClientMessage) Descriptor() ([]byte, []int) {
return file_rpc_master_proto_rawDescGZIP(), []int{3}
}
func (x *ClientMessage) GetEvent() Event {
if x != nil {
return x.Event
}
return Event_EVENT_UNSPECIFIED
}
func (x *ClientMessage) GetClientId() string {
if x != nil {
return x.ClientId
}
return ""
}
func (x *ClientMessage) GetSessionId() string {
if x != nil {
return x.SessionId
}
return ""
}
func (x *ClientMessage) GetSecret() string {
if x != nil {
return x.Secret
}
return ""
}
func (x *ClientMessage) GetData() []byte {
if x != nil {
return x.Data
}
return nil
}
type PullClientConfigReq struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Base *ClientBase `protobuf:"bytes,255,opt,name=base,proto3" json:"base,omitempty"`
}
func (x *PullClientConfigReq) Reset() {
*x = PullClientConfigReq{}
if protoimpl.UnsafeEnabled {
mi := &file_rpc_master_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *PullClientConfigReq) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*PullClientConfigReq) ProtoMessage() {}
func (x *PullClientConfigReq) ProtoReflect() protoreflect.Message {
mi := &file_rpc_master_proto_msgTypes[4]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use PullClientConfigReq.ProtoReflect.Descriptor instead.
func (*PullClientConfigReq) Descriptor() ([]byte, []int) {
return file_rpc_master_proto_rawDescGZIP(), []int{4}
}
func (x *PullClientConfigReq) GetBase() *ClientBase {
if x != nil {
return x.Base
}
return nil
}
type PullClientConfigResp struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Status *Status `protobuf:"bytes,1,opt,name=status,proto3" json:"status,omitempty"`
Client *Client `protobuf:"bytes,2,opt,name=client,proto3" json:"client,omitempty"`
}
func (x *PullClientConfigResp) Reset() {
*x = PullClientConfigResp{}
if protoimpl.UnsafeEnabled {
mi := &file_rpc_master_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *PullClientConfigResp) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*PullClientConfigResp) ProtoMessage() {}
func (x *PullClientConfigResp) ProtoReflect() protoreflect.Message {
mi := &file_rpc_master_proto_msgTypes[5]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use PullClientConfigResp.ProtoReflect.Descriptor instead.
func (*PullClientConfigResp) Descriptor() ([]byte, []int) {
return file_rpc_master_proto_rawDescGZIP(), []int{5}
}
func (x *PullClientConfigResp) GetStatus() *Status {
if x != nil {
return x.Status
}
return nil
}
func (x *PullClientConfigResp) GetClient() *Client {
if x != nil {
return x.Client
}
return nil
}
type PullServerConfigReq struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Base *ServerBase `protobuf:"bytes,255,opt,name=base,proto3" json:"base,omitempty"`
}
func (x *PullServerConfigReq) Reset() {
*x = PullServerConfigReq{}
if protoimpl.UnsafeEnabled {
mi := &file_rpc_master_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *PullServerConfigReq) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*PullServerConfigReq) ProtoMessage() {}
func (x *PullServerConfigReq) ProtoReflect() protoreflect.Message {
mi := &file_rpc_master_proto_msgTypes[6]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use PullServerConfigReq.ProtoReflect.Descriptor instead.
func (*PullServerConfigReq) Descriptor() ([]byte, []int) {
return file_rpc_master_proto_rawDescGZIP(), []int{6}
}
func (x *PullServerConfigReq) GetBase() *ServerBase {
if x != nil {
return x.Base
}
return nil
}
type PullServerConfigResp struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Status *Status `protobuf:"bytes,1,opt,name=status,proto3" json:"status,omitempty"`
Server *Server `protobuf:"bytes,2,opt,name=server,proto3" json:"server,omitempty"`
}
func (x *PullServerConfigResp) Reset() {
*x = PullServerConfigResp{}
if protoimpl.UnsafeEnabled {
mi := &file_rpc_master_proto_msgTypes[7]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *PullServerConfigResp) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*PullServerConfigResp) ProtoMessage() {}
func (x *PullServerConfigResp) ProtoReflect() protoreflect.Message {
mi := &file_rpc_master_proto_msgTypes[7]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use PullServerConfigResp.ProtoReflect.Descriptor instead.
func (*PullServerConfigResp) Descriptor() ([]byte, []int) {
return file_rpc_master_proto_rawDescGZIP(), []int{7}
}
func (x *PullServerConfigResp) GetStatus() *Status {
if x != nil {
return x.Status
}
return nil
}
func (x *PullServerConfigResp) GetServer() *Server {
if x != nil {
return x.Server
}
return nil
}
type FRPAuthRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
User string `protobuf:"bytes,1,opt,name=user,proto3" json:"user,omitempty"`
Token string `protobuf:"bytes,2,opt,name=token,proto3" json:"token,omitempty"`
Base *ServerBase `protobuf:"bytes,255,opt,name=base,proto3" json:"base,omitempty"`
}
func (x *FRPAuthRequest) Reset() {
*x = FRPAuthRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_rpc_master_proto_msgTypes[8]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *FRPAuthRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*FRPAuthRequest) ProtoMessage() {}
func (x *FRPAuthRequest) ProtoReflect() protoreflect.Message {
mi := &file_rpc_master_proto_msgTypes[8]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use FRPAuthRequest.ProtoReflect.Descriptor instead.
func (*FRPAuthRequest) Descriptor() ([]byte, []int) {
return file_rpc_master_proto_rawDescGZIP(), []int{8}
}
func (x *FRPAuthRequest) GetUser() string {
if x != nil {
return x.User
}
return ""
}
func (x *FRPAuthRequest) GetToken() string {
if x != nil {
return x.Token
}
return ""
}
func (x *FRPAuthRequest) GetBase() *ServerBase {
if x != nil {
return x.Base
}
return nil
}
type FRPAuthResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Status *Status `protobuf:"bytes,1,opt,name=status,proto3" json:"status,omitempty"`
Ok bool `protobuf:"varint,2,opt,name=ok,proto3" json:"ok,omitempty"`
}
func (x *FRPAuthResponse) Reset() {
*x = FRPAuthResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_rpc_master_proto_msgTypes[9]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *FRPAuthResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*FRPAuthResponse) ProtoMessage() {}
func (x *FRPAuthResponse) ProtoReflect() protoreflect.Message {
mi := &file_rpc_master_proto_msgTypes[9]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use FRPAuthResponse.ProtoReflect.Descriptor instead.
func (*FRPAuthResponse) Descriptor() ([]byte, []int) {
return file_rpc_master_proto_rawDescGZIP(), []int{9}
}
func (x *FRPAuthResponse) GetStatus() *Status {
if x != nil {
return x.Status
}
return nil
}
func (x *FRPAuthResponse) GetOk() bool {
if x != nil {
return x.Ok
}
return false
}
var File_rpc_master_proto protoreflect.FileDescriptor
var file_rpc_master_proto_rawDesc = []byte{
0x0a, 0x10, 0x72, 0x70, 0x63, 0x5f, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x12, 0x06, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x1a, 0x0c, 0x63, 0x6f, 0x6d, 0x6d,
0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x4e, 0x0a, 0x0a, 0x53, 0x65, 0x72, 0x76,
0x65, 0x72, 0x42, 0x61, 0x73, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72,
0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x65, 0x72, 0x76, 0x65,
0x72, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x73, 0x65,
0x63, 0x72, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x73, 0x65, 0x72, 0x76,
0x65, 0x72, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x22, 0x4e, 0x0a, 0x0a, 0x43, 0x6c, 0x69, 0x65,
0x6e, 0x74, 0x42, 0x61, 0x73, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e,
0x74, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x65,
0x63, 0x72, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x6c, 0x69, 0x65,
0x6e, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x22, 0x84, 0x01, 0x0a, 0x0d, 0x53, 0x65, 0x72,
0x76, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x23, 0x0a, 0x05, 0x65, 0x76,
0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0d, 0x2e, 0x6d, 0x61, 0x73, 0x74,
0x65, 0x72, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x12,
0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01,
0x28, 0x09, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a,
0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
0x52, 0x09, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x64,
0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22,
0x9c, 0x01, 0x0a, 0x0d, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67,
0x65, 0x12, 0x23, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e,
0x32, 0x0d, 0x2e, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52,
0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e,
0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69,
0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e,
0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x04, 0x20, 0x01,
0x28, 0x09, 0x52, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61,
0x74, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x3e,
0x0a, 0x13, 0x50, 0x75, 0x6c, 0x6c, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66,
0x69, 0x67, 0x52, 0x65, 0x71, 0x12, 0x27, 0x0a, 0x04, 0x62, 0x61, 0x73, 0x65, 0x18, 0xff, 0x01,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x43, 0x6c,
0x69, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x73, 0x65, 0x52, 0x04, 0x62, 0x61, 0x73, 0x65, 0x22, 0x66,
0x0a, 0x14, 0x50, 0x75, 0x6c, 0x6c, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66,
0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x12, 0x26, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73,
0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e,
0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x26,
0x0a, 0x06, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e,
0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x06,
0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x22, 0x3e, 0x0a, 0x13, 0x50, 0x75, 0x6c, 0x6c, 0x53, 0x65,
0x72, 0x76, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x12, 0x27, 0x0a,
0x04, 0x62, 0x61, 0x73, 0x65, 0x18, 0xff, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d,
0x61, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x42, 0x61, 0x73, 0x65,
0x52, 0x04, 0x62, 0x61, 0x73, 0x65, 0x22, 0x66, 0x0a, 0x14, 0x50, 0x75, 0x6c, 0x6c, 0x53, 0x65,
0x72, 0x76, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x12, 0x26,
0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e,
0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06,
0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x26, 0x0a, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72,
0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e,
0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0x63,
0x0a, 0x0e, 0x46, 0x52, 0x50, 0x41, 0x75, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x12, 0x12, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
0x75, 0x73, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20,
0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x27, 0x0a, 0x04, 0x62, 0x61,
0x73, 0x65, 0x18, 0xff, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x61, 0x73, 0x74,
0x65, 0x72, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x42, 0x61, 0x73, 0x65, 0x52, 0x04, 0x62,
0x61, 0x73, 0x65, 0x22, 0x49, 0x0a, 0x0f, 0x46, 0x52, 0x50, 0x41, 0x75, 0x74, 0x68, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73,
0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e,
0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0e,
0x0a, 0x02, 0x6f, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x02, 0x6f, 0x6b, 0x2a, 0xd1,
0x01, 0x0a, 0x05, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x15, 0x0a, 0x11, 0x45, 0x56, 0x45, 0x4e,
0x54, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12,
0x19, 0x0a, 0x15, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, 0x45,
0x52, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x10, 0x01, 0x12, 0x19, 0x0a, 0x15, 0x45, 0x56,
0x45, 0x4e, 0x54, 0x5f, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, 0x45, 0x52, 0x5f, 0x53, 0x45, 0x52,
0x56, 0x45, 0x52, 0x10, 0x02, 0x12, 0x0f, 0x0a, 0x0b, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x45,
0x52, 0x52, 0x4f, 0x52, 0x10, 0x03, 0x12, 0x0e, 0x0a, 0x0a, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f,
0x44, 0x41, 0x54, 0x41, 0x10, 0x04, 0x12, 0x15, 0x0a, 0x11, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f,
0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x5f, 0x46, 0x52, 0x50, 0x43, 0x10, 0x05, 0x12, 0x15, 0x0a,
0x11, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x52, 0x45, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x46, 0x52,
0x50, 0x43, 0x10, 0x06, 0x12, 0x15, 0x0a, 0x11, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x55, 0x50,
0x44, 0x41, 0x54, 0x45, 0x5f, 0x46, 0x52, 0x50, 0x53, 0x10, 0x07, 0x12, 0x15, 0x0a, 0x11, 0x45,
0x56, 0x45, 0x4e, 0x54, 0x5f, 0x52, 0x45, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x46, 0x52, 0x50, 0x53,
0x10, 0x08, 0x32, 0xa3, 0x02, 0x0a, 0x06, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x12, 0x3e, 0x0a,
0x0a, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x65, 0x6e, 0x64, 0x12, 0x15, 0x2e, 0x6d, 0x61,
0x73, 0x74, 0x65, 0x72, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61,
0x67, 0x65, 0x1a, 0x15, 0x2e, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x53, 0x65, 0x72, 0x76,
0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x28, 0x01, 0x30, 0x01, 0x12, 0x4d, 0x0a,
0x10, 0x50, 0x75, 0x6c, 0x6c, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69,
0x67, 0x12, 0x1b, 0x2e, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x50, 0x75, 0x6c, 0x6c, 0x43,
0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x1a, 0x1c,
0x2e, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x50, 0x75, 0x6c, 0x6c, 0x43, 0x6c, 0x69, 0x65,
0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x12, 0x4d, 0x0a, 0x10,
0x50, 0x75, 0x6c, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
0x12, 0x1b, 0x2e, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x50, 0x75, 0x6c, 0x6c, 0x53, 0x65,
0x72, 0x76, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x1a, 0x1c, 0x2e,
0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x50, 0x75, 0x6c, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x65,
0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x12, 0x3b, 0x0a, 0x08, 0x46,
0x52, 0x50, 0x43, 0x41, 0x75, 0x74, 0x68, 0x12, 0x16, 0x2e, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72,
0x2e, 0x46, 0x52, 0x50, 0x41, 0x75, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
0x17, 0x2e, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x46, 0x52, 0x50, 0x41, 0x75, 0x74, 0x68,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x07, 0x5a, 0x05, 0x2e, 0x2e, 0x2f, 0x70,
0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_rpc_master_proto_rawDescOnce sync.Once
file_rpc_master_proto_rawDescData = file_rpc_master_proto_rawDesc
)
func file_rpc_master_proto_rawDescGZIP() []byte {
file_rpc_master_proto_rawDescOnce.Do(func() {
file_rpc_master_proto_rawDescData = protoimpl.X.CompressGZIP(file_rpc_master_proto_rawDescData)
})
return file_rpc_master_proto_rawDescData
}
var file_rpc_master_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_rpc_master_proto_msgTypes = make([]protoimpl.MessageInfo, 10)
var file_rpc_master_proto_goTypes = []interface{}{
(Event)(0), // 0: master.Event
(*ServerBase)(nil), // 1: master.ServerBase
(*ClientBase)(nil), // 2: master.ClientBase
(*ServerMessage)(nil), // 3: master.ServerMessage
(*ClientMessage)(nil), // 4: master.ClientMessage
(*PullClientConfigReq)(nil), // 5: master.PullClientConfigReq
(*PullClientConfigResp)(nil), // 6: master.PullClientConfigResp
(*PullServerConfigReq)(nil), // 7: master.PullServerConfigReq
(*PullServerConfigResp)(nil), // 8: master.PullServerConfigResp
(*FRPAuthRequest)(nil), // 9: master.FRPAuthRequest
(*FRPAuthResponse)(nil), // 10: master.FRPAuthResponse
(*Status)(nil), // 11: common.Status
(*Client)(nil), // 12: common.Client
(*Server)(nil), // 13: common.Server
}
var file_rpc_master_proto_depIdxs = []int32{
0, // 0: master.ServerMessage.event:type_name -> master.Event
0, // 1: master.ClientMessage.event:type_name -> master.Event
2, // 2: master.PullClientConfigReq.base:type_name -> master.ClientBase
11, // 3: master.PullClientConfigResp.status:type_name -> common.Status
12, // 4: master.PullClientConfigResp.client:type_name -> common.Client
1, // 5: master.PullServerConfigReq.base:type_name -> master.ServerBase
11, // 6: master.PullServerConfigResp.status:type_name -> common.Status
13, // 7: master.PullServerConfigResp.server:type_name -> common.Server
1, // 8: master.FRPAuthRequest.base:type_name -> master.ServerBase
11, // 9: master.FRPAuthResponse.status:type_name -> common.Status
4, // 10: master.Master.ServerSend:input_type -> master.ClientMessage
5, // 11: master.Master.PullClientConfig:input_type -> master.PullClientConfigReq
7, // 12: master.Master.PullServerConfig:input_type -> master.PullServerConfigReq
9, // 13: master.Master.FRPCAuth:input_type -> master.FRPAuthRequest
3, // 14: master.Master.ServerSend:output_type -> master.ServerMessage
6, // 15: master.Master.PullClientConfig:output_type -> master.PullClientConfigResp
8, // 16: master.Master.PullServerConfig:output_type -> master.PullServerConfigResp
10, // 17: master.Master.FRPCAuth:output_type -> master.FRPAuthResponse
14, // [14:18] is the sub-list for method output_type
10, // [10:14] is the sub-list for method input_type
10, // [10:10] is the sub-list for extension type_name
10, // [10:10] is the sub-list for extension extendee
0, // [0:10] is the sub-list for field type_name
}
func init() { file_rpc_master_proto_init() }
func file_rpc_master_proto_init() {
if File_rpc_master_proto != nil {
return
}
file_common_proto_init()
if !protoimpl.UnsafeEnabled {
file_rpc_master_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ServerBase); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_rpc_master_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ClientBase); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_rpc_master_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ServerMessage); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_rpc_master_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ClientMessage); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_rpc_master_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*PullClientConfigReq); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_rpc_master_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*PullClientConfigResp); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_rpc_master_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*PullServerConfigReq); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_rpc_master_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*PullServerConfigResp); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_rpc_master_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*FRPAuthRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_rpc_master_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*FRPAuthResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_rpc_master_proto_rawDesc,
NumEnums: 1,
NumMessages: 10,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_rpc_master_proto_goTypes,
DependencyIndexes: file_rpc_master_proto_depIdxs,
EnumInfos: file_rpc_master_proto_enumTypes,
MessageInfos: file_rpc_master_proto_msgTypes,
}.Build()
File_rpc_master_proto = out.File
file_rpc_master_proto_rawDesc = nil
file_rpc_master_proto_goTypes = nil
file_rpc_master_proto_depIdxs = nil
}

253
pb/rpc_master_grpc.pb.go Normal file
View File

@@ -0,0 +1,253 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.3.0
// - protoc v4.25.1
// source: rpc_master.proto
package pb
import (
context "context"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
)
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
// Requires gRPC-Go v1.32.0 or later.
const _ = grpc.SupportPackageIsVersion7
const (
Master_ServerSend_FullMethodName = "/master.Master/ServerSend"
Master_PullClientConfig_FullMethodName = "/master.Master/PullClientConfig"
Master_PullServerConfig_FullMethodName = "/master.Master/PullServerConfig"
Master_FRPCAuth_FullMethodName = "/master.Master/FRPCAuth"
)
// MasterClient is the client API for Master service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type MasterClient interface {
ServerSend(ctx context.Context, opts ...grpc.CallOption) (Master_ServerSendClient, error)
PullClientConfig(ctx context.Context, in *PullClientConfigReq, opts ...grpc.CallOption) (*PullClientConfigResp, error)
PullServerConfig(ctx context.Context, in *PullServerConfigReq, opts ...grpc.CallOption) (*PullServerConfigResp, error)
FRPCAuth(ctx context.Context, in *FRPAuthRequest, opts ...grpc.CallOption) (*FRPAuthResponse, error)
}
type masterClient struct {
cc grpc.ClientConnInterface
}
func NewMasterClient(cc grpc.ClientConnInterface) MasterClient {
return &masterClient{cc}
}
func (c *masterClient) ServerSend(ctx context.Context, opts ...grpc.CallOption) (Master_ServerSendClient, error) {
stream, err := c.cc.NewStream(ctx, &Master_ServiceDesc.Streams[0], Master_ServerSend_FullMethodName, opts...)
if err != nil {
return nil, err
}
x := &masterServerSendClient{stream}
return x, nil
}
type Master_ServerSendClient interface {
Send(*ClientMessage) error
Recv() (*ServerMessage, error)
grpc.ClientStream
}
type masterServerSendClient struct {
grpc.ClientStream
}
func (x *masterServerSendClient) Send(m *ClientMessage) error {
return x.ClientStream.SendMsg(m)
}
func (x *masterServerSendClient) Recv() (*ServerMessage, error) {
m := new(ServerMessage)
if err := x.ClientStream.RecvMsg(m); err != nil {
return nil, err
}
return m, nil
}
func (c *masterClient) PullClientConfig(ctx context.Context, in *PullClientConfigReq, opts ...grpc.CallOption) (*PullClientConfigResp, error) {
out := new(PullClientConfigResp)
err := c.cc.Invoke(ctx, Master_PullClientConfig_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *masterClient) PullServerConfig(ctx context.Context, in *PullServerConfigReq, opts ...grpc.CallOption) (*PullServerConfigResp, error) {
out := new(PullServerConfigResp)
err := c.cc.Invoke(ctx, Master_PullServerConfig_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *masterClient) FRPCAuth(ctx context.Context, in *FRPAuthRequest, opts ...grpc.CallOption) (*FRPAuthResponse, error) {
out := new(FRPAuthResponse)
err := c.cc.Invoke(ctx, Master_FRPCAuth_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// MasterServer is the server API for Master service.
// All implementations must embed UnimplementedMasterServer
// for forward compatibility
type MasterServer interface {
ServerSend(Master_ServerSendServer) error
PullClientConfig(context.Context, *PullClientConfigReq) (*PullClientConfigResp, error)
PullServerConfig(context.Context, *PullServerConfigReq) (*PullServerConfigResp, error)
FRPCAuth(context.Context, *FRPAuthRequest) (*FRPAuthResponse, error)
mustEmbedUnimplementedMasterServer()
}
// UnimplementedMasterServer must be embedded to have forward compatible implementations.
type UnimplementedMasterServer struct {
}
func (UnimplementedMasterServer) ServerSend(Master_ServerSendServer) error {
return status.Errorf(codes.Unimplemented, "method ServerSend not implemented")
}
func (UnimplementedMasterServer) PullClientConfig(context.Context, *PullClientConfigReq) (*PullClientConfigResp, error) {
return nil, status.Errorf(codes.Unimplemented, "method PullClientConfig not implemented")
}
func (UnimplementedMasterServer) PullServerConfig(context.Context, *PullServerConfigReq) (*PullServerConfigResp, error) {
return nil, status.Errorf(codes.Unimplemented, "method PullServerConfig not implemented")
}
func (UnimplementedMasterServer) FRPCAuth(context.Context, *FRPAuthRequest) (*FRPAuthResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method FRPCAuth not implemented")
}
func (UnimplementedMasterServer) mustEmbedUnimplementedMasterServer() {}
// UnsafeMasterServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to MasterServer will
// result in compilation errors.
type UnsafeMasterServer interface {
mustEmbedUnimplementedMasterServer()
}
func RegisterMasterServer(s grpc.ServiceRegistrar, srv MasterServer) {
s.RegisterService(&Master_ServiceDesc, srv)
}
func _Master_ServerSend_Handler(srv interface{}, stream grpc.ServerStream) error {
return srv.(MasterServer).ServerSend(&masterServerSendServer{stream})
}
type Master_ServerSendServer interface {
Send(*ServerMessage) error
Recv() (*ClientMessage, error)
grpc.ServerStream
}
type masterServerSendServer struct {
grpc.ServerStream
}
func (x *masterServerSendServer) Send(m *ServerMessage) error {
return x.ServerStream.SendMsg(m)
}
func (x *masterServerSendServer) Recv() (*ClientMessage, error) {
m := new(ClientMessage)
if err := x.ServerStream.RecvMsg(m); err != nil {
return nil, err
}
return m, nil
}
func _Master_PullClientConfig_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(PullClientConfigReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(MasterServer).PullClientConfig(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Master_PullClientConfig_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(MasterServer).PullClientConfig(ctx, req.(*PullClientConfigReq))
}
return interceptor(ctx, in, info, handler)
}
func _Master_PullServerConfig_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(PullServerConfigReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(MasterServer).PullServerConfig(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Master_PullServerConfig_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(MasterServer).PullServerConfig(ctx, req.(*PullServerConfigReq))
}
return interceptor(ctx, in, info, handler)
}
func _Master_FRPCAuth_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(FRPAuthRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(MasterServer).FRPCAuth(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Master_FRPCAuth_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(MasterServer).FRPCAuth(ctx, req.(*FRPAuthRequest))
}
return interceptor(ctx, in, info, handler)
}
// Master_ServiceDesc is the grpc.ServiceDesc for Master service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var Master_ServiceDesc = grpc.ServiceDesc{
ServiceName: "master.Master",
HandlerType: (*MasterServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "PullClientConfig",
Handler: _Master_PullClientConfig_Handler,
},
{
MethodName: "PullServerConfig",
Handler: _Master_PullServerConfig_Handler,
},
{
MethodName: "FRPCAuth",
Handler: _Master_FRPCAuth_Handler,
},
},
Streams: []grpc.StreamDesc{
{
StreamName: "ServerSend",
Handler: _Master_ServerSend_Handler,
ServerStreams: true,
ClientStreams: true,
},
},
Metadata: "rpc_master.proto",
}

106
rpc/client.go Normal file
View File

@@ -0,0 +1,106 @@
package rpc
import (
"context"
"fmt"
"io"
"sync"
"github.com/VaalaCat/frp-panel/pb"
"github.com/google/uuid"
"github.com/sirupsen/logrus"
"google.golang.org/protobuf/proto"
)
func CallClient(c context.Context, clientID string, event pb.Event, msg proto.Message) (*pb.ClientMessage, error) {
sender := GetClientsManager().Get(clientID)
if sender == nil {
logrus.Errorf("cannot get client, id: [%s]", clientID)
return nil, fmt.Errorf("cannot get client, id: [%s]", clientID)
}
data, err := proto.Marshal(msg)
if err != nil {
logrus.WithError(err).Errorf("cannot marshal")
return nil, err
}
req := &pb.ServerMessage{
Event: event,
Data: data,
SessionId: uuid.New().String(),
ClientId: clientID,
}
recvMap.Store(req.SessionId, make(chan *pb.ClientMessage))
err = sender.Send(req)
if err != nil {
logrus.WithError(err).Errorf("cannot send")
return nil, err
}
respChAny, ok := recvMap.Load(req.SessionId)
if !ok {
logrus.Fatalf("cannot load")
}
respCh, ok := respChAny.(chan *pb.ClientMessage)
if !ok {
logrus.Fatalf("cannot cast")
}
resp := <-respCh
if resp.Event == pb.Event_EVENT_ERROR {
return nil, fmt.Errorf("client return error: %s", resp.Data)
}
close(respCh)
recvMap.Delete(req.SessionId)
return resp, nil
}
var (
recvMap *sync.Map
)
func init() {
recvMap = &sync.Map{}
}
func Recv(clientID string) chan bool {
done := make(chan bool)
go func() {
for {
reciver := GetClientsManager().Get(clientID)
if reciver == nil {
logrus.Errorf("cannot get client")
continue
}
resp, err := reciver.Recv()
if err == io.EOF {
logrus.Infof("finish client recv")
done <- true
return
}
if err != nil {
logrus.WithError(err).Errorf("cannot recv, usually means client disconnect")
done <- true
return
}
respChAny, ok := recvMap.Load(resp.SessionId)
if !ok {
logrus.Errorf("cannot load")
continue
}
respCh, ok := respChAny.(chan *pb.ClientMessage)
if !ok {
logrus.Errorf("cannot cast")
continue
}
logrus.Infof("recv success, resp: %+v", resp)
respCh <- resp
}
}()
return done
}

63
rpc/client_manager.go Normal file
View File

@@ -0,0 +1,63 @@
package rpc
import (
"sync"
"github.com/VaalaCat/frp-panel/pb"
)
type ClientsManager interface {
Get(cliID string) pb.Master_ServerSendServer
Set(cliID string, sender pb.Master_ServerSendServer)
Remove(cliID string)
}
type ClientsManagerImpl struct {
senders *sync.Map
}
// Get implements ClientsManager.
func (c *ClientsManagerImpl) Get(cliID string) pb.Master_ServerSendServer {
cliAny, ok := c.senders.Load(cliID)
if !ok {
return nil
}
cli, ok := cliAny.(pb.Master_ServerSendServer)
if !ok {
return nil
}
return cli
}
// Set implements ClientsManager.
func (c *ClientsManagerImpl) Set(cliID string, sender pb.Master_ServerSendServer) {
c.senders.Store(cliID, sender)
}
func (c *ClientsManagerImpl) Remove(cliID string) {
c.senders.Delete(cliID)
}
var (
clientsManager *ClientsManagerImpl
)
func NewClientsManager() *ClientsManagerImpl {
return &ClientsManagerImpl{
senders: &sync.Map{},
}
}
func MustInitClientsManager() {
if clientsManager != nil {
return
}
clientsManager = NewClientsManager()
}
func GetClientsManager() ClientsManager {
return clientsManager
}

5
rpc/init.go Normal file
View File

@@ -0,0 +1,5 @@
package rpc
func InitRPCClients() {
MustInitClientsManager()
}

23
rpc/master.go Normal file
View File

@@ -0,0 +1,23 @@
package rpc
import (
"context"
"github.com/VaalaCat/frp-panel/conf"
"github.com/VaalaCat/frp-panel/pb"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
)
func MasterCli(c context.Context) (pb.MasterClient, error) {
conn, err := grpc.Dial(conf.RPCCallAddr(),
grpc.WithTransportCredentials(
insecure.NewCredentials(),
))
if err != nil {
return nil, err
}
client := pb.NewMasterClient(conn)
return client, nil
}

42
services/api/service.go Normal file
View File

@@ -0,0 +1,42 @@
package api
import (
"github.com/gin-gonic/gin"
)
type ApiService interface {
Run()
Stop()
}
type server struct {
srv *gin.Engine
addr string
}
var (
_ ApiService = (*server)(nil)
apiService *server
)
func NewApiService(listenAddr string, router *gin.Engine) *server {
return &server{
srv: router,
addr: listenAddr,
}
}
func MustInitApiService(listenAddr string, router *gin.Engine) {
apiService = NewApiService(listenAddr, router)
}
func GetAPIService() ApiService {
return apiService
}
func (s *server) Run() {
s.srv.Run(s.addr)
}
func (s *server) Stop() {
}

View File

@@ -0,0 +1,179 @@
package client
import (
"context"
"os"
"os/signal"
"syscall"
"time"
"github.com/VaalaCat/frp-panel/utils"
"github.com/fatedier/frp/client"
"github.com/fatedier/frp/client/proxy"
v1 "github.com/fatedier/frp/pkg/config/v1"
"github.com/fatedier/frp/pkg/config/v1/validation"
"github.com/fatedier/frp/pkg/util/log"
"github.com/samber/lo"
"github.com/sirupsen/logrus"
)
type ClientHandler interface {
Run()
Stop()
Wait()
Running() bool
Update([]v1.ProxyConfigurer, []v1.VisitorConfigurer)
AddProxy(v1.ProxyConfigurer)
AddVisitor(v1.VisitorConfigurer)
RemoveProxy(v1.ProxyConfigurer)
RemoveVisitor(v1.VisitorConfigurer)
GetProxyStatus(string) (*proxy.WorkingStatus, error)
GetCommonCfg() *v1.ClientCommonConfig
GetProxyCfgs() map[string]v1.ProxyConfigurer
GetVisitorCfgs() map[string]v1.VisitorConfigurer
}
type Client struct {
cli *client.Service
Common *v1.ClientCommonConfig
ProxyCfgs map[string]v1.ProxyConfigurer
VisitorCfgs map[string]v1.VisitorConfigurer
done chan bool
running bool
}
var (
cli *Client
)
func InitGlobalClientService(commonCfg *v1.ClientCommonConfig,
proxyCfgs []v1.ProxyConfigurer,
visitorCfgs []v1.VisitorConfigurer) {
if cli != nil {
logrus.Warn("client has been initialized")
return
}
cli = NewClientHandler(commonCfg, proxyCfgs, visitorCfgs)
}
func GetGlobalClientSerivce() ClientHandler {
if cli == nil {
logrus.Panic("client has not been initialized")
}
return cli
}
func NewClientHandler(commonCfg *v1.ClientCommonConfig,
proxyCfgs []v1.ProxyConfigurer,
visitorCfgs []v1.VisitorConfigurer) *Client {
warning, err := validation.ValidateAllClientConfig(commonCfg, proxyCfgs, visitorCfgs)
if warning != nil {
logrus.WithError(err).Warnf("validate client config warning: %+v", warning)
}
if err != nil {
logrus.Panic(err)
}
log.InitLog(commonCfg.Log.To, commonCfg.Log.Level, commonCfg.Log.MaxDays, commonCfg.Log.DisablePrintColor)
cli, err := client.NewService(client.ServiceOptions{
Common: commonCfg,
ProxyCfgs: proxyCfgs,
VisitorCfgs: visitorCfgs,
})
if err != nil {
logrus.Panic(err)
}
return &Client{
cli: cli,
Common: commonCfg,
ProxyCfgs: lo.SliceToMap(proxyCfgs, utils.TransformProxyConfigurerToMap),
VisitorCfgs: lo.SliceToMap(visitorCfgs, utils.TransformVisitorConfigurerToMap),
}
}
func (c *Client) Run() {
shouldGracefulClose := c.Common.Transport.Protocol == "kcp" || c.Common.Transport.Protocol == "quic"
if shouldGracefulClose {
go handleTermSignal(c.cli)
}
c.running = true
c.done = make(chan bool)
defer func() {
c.running = false
close(c.done)
}()
if err := c.cli.Run(context.Background()); err != nil {
logrus.Errorf("run client error: %v", err)
}
}
func (c *Client) Stop() {
c.cli.Close()
}
func (c *Client) Update(proxyCfgs []v1.ProxyConfigurer, visitorCfgs []v1.VisitorConfigurer) {
c.ProxyCfgs = lo.SliceToMap(proxyCfgs, utils.TransformProxyConfigurerToMap)
c.VisitorCfgs = lo.SliceToMap(visitorCfgs, utils.TransformVisitorConfigurerToMap)
c.cli.UpdateAllConfigurer(proxyCfgs, visitorCfgs)
}
func (c *Client) AddProxy(proxyCfg v1.ProxyConfigurer) {
c.ProxyCfgs[proxyCfg.GetBaseConfig().Name] = proxyCfg
c.cli.UpdateAllConfigurer(lo.Values(c.ProxyCfgs), lo.Values(c.VisitorCfgs))
}
func (c *Client) AddVisitor(visitorCfg v1.VisitorConfigurer) {
c.VisitorCfgs[visitorCfg.GetBaseConfig().Name] = visitorCfg
c.cli.UpdateAllConfigurer(lo.Values(c.ProxyCfgs), lo.Values(c.VisitorCfgs))
}
func (c *Client) RemoveProxy(proxyCfg v1.ProxyConfigurer) {
old := c.ProxyCfgs
delete(old, proxyCfg.GetBaseConfig().Name)
c.ProxyCfgs = old
c.cli.UpdateAllConfigurer(lo.Values(c.ProxyCfgs), lo.Values(c.VisitorCfgs))
}
func (c *Client) RemoveVisitor(visitorCfg v1.VisitorConfigurer) {
old := c.VisitorCfgs
delete(old, visitorCfg.GetBaseConfig().Name)
c.VisitorCfgs = old
c.cli.UpdateAllConfigurer(lo.Values(c.ProxyCfgs), lo.Values(c.VisitorCfgs))
}
func (c *Client) GetProxyStatus(name string) (*proxy.WorkingStatus, error) {
return c.cli.GetProxyStatus(name)
}
func (c *Client) GetCommonCfg() *v1.ClientCommonConfig {
return c.Common
}
func (c *Client) GetProxyCfgs() map[string]v1.ProxyConfigurer {
return c.ProxyCfgs
}
func (c *Client) GetVisitorCfgs() map[string]v1.VisitorConfigurer {
return c.VisitorCfgs
}
func (c *Client) Running() bool {
return c.running
}
func (c *Client) Wait() {
<-c.done
}
func handleTermSignal(svr *client.Service) {
ch := make(chan os.Signal, 1)
signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM)
<-ch
svr.GracefulClose(500 * time.Millisecond)
}

View File

@@ -0,0 +1,132 @@
package master
import (
"context"
"fmt"
"io"
"net"
"github.com/VaalaCat/frp-panel/biz/master/client"
masterserver "github.com/VaalaCat/frp-panel/biz/master/server"
"github.com/VaalaCat/frp-panel/conf"
"github.com/VaalaCat/frp-panel/dao"
"github.com/VaalaCat/frp-panel/pb"
"github.com/VaalaCat/frp-panel/rpc"
"github.com/sirupsen/logrus"
"google.golang.org/grpc"
)
type server struct {
pb.UnimplementedMasterServer
}
func NewRpcServer() *grpc.Server {
s := grpc.NewServer()
pb.RegisterMasterServer(s, &server{})
return s
}
func RunRpcServer(s *grpc.Server) {
lis, err := net.Listen("tcp", conf.RPCListenAddr())
if err != nil {
logrus.Fatalf("rpc server failed to listen: %v", err)
}
logrus.Infof("start server")
if err := s.Serve(lis); err != nil {
logrus.Fatalf("failed to serve: %v", err)
}
}
// PullClientConfig implements pb.MasterServer.
func (s *server) PullClientConfig(ctx context.Context, req *pb.PullClientConfigReq) (*pb.PullClientConfigResp, error) {
logrus.Infof("pull client config, req: [%+v]", req)
return client.RPCPullConfig(ctx, req)
}
// PullServerConfig implements pb.MasterServer.
func (s *server) PullServerConfig(ctx context.Context, req *pb.PullServerConfigReq) (*pb.PullServerConfigResp, error) {
logrus.Infof("pull server config, req: [%+v]", req)
return masterserver.RPCPullConfig(ctx, req)
}
// FRPCAuth implements pb.MasterServer.
func (*server) FRPCAuth(ctx context.Context, req *pb.FRPAuthRequest) (*pb.FRPAuthResponse, error) {
logrus.Infof("frpc auth, req: [%+v]", req)
return masterserver.FRPAuth(ctx, req)
}
// ServerSend implements pb.MasterServer.
func (s *server) ServerSend(sender pb.Master_ServerSendServer) error {
logrus.Infof("server get a client connected")
var done chan bool
for {
req, err := sender.Recv()
if err == io.EOF {
logrus.Infof("finish server send, client id: [%s]", req.GetClientId())
return nil
}
if err != nil {
logrus.WithError(err).Errorf("cannot recv from client, id: [%s]", req.GetClientId())
return err
}
if req.GetEvent() == pb.Event_EVENT_REGISTER_CLIENT || req.GetEvent() == pb.Event_EVENT_REGISTER_SERVER {
if len(req.GetSecret()) == 0 {
logrus.Errorf("rpc auth token is empty")
sender.Send(&pb.ServerMessage{
Event: req.GetEvent(),
Data: []byte("rpc auth token is invalid"),
})
return fmt.Errorf("rpc auth token is invalid")
}
var secret string
switch req.GetEvent() {
case pb.Event_EVENT_REGISTER_CLIENT:
cli, err := dao.AdminGetClientByClientID(req.GetClientId())
if err != nil {
logrus.WithError(err).Errorf("cannot get client, %s id: [%s]", req.GetEvent().String(), req.GetClientId())
sender.Send(&pb.ServerMessage{
Event: req.GetEvent(),
Data: []byte("rpc auth token is invalid"),
})
return err
}
secret = cli.ConnectSecret
case pb.Event_EVENT_REGISTER_SERVER:
srv, err := dao.AdminGetServerByServerID(req.GetClientId())
if err != nil {
logrus.WithError(err).Errorf("cannot get server, %s id: [%s]", req.GetEvent().String(), req.GetClientId())
sender.Send(&pb.ServerMessage{
Event: req.GetEvent(),
Data: []byte("rpc auth token is invalid"),
})
return err
}
secret = srv.ConnectSecret
}
if secret != req.GetSecret() {
logrus.Errorf("invalid secret, %s id: [%s]", req.GetEvent().String(), req.GetClientId())
sender.Send(&pb.ServerMessage{
Event: req.GetEvent(),
Data: []byte("rpc auth token is invalid"),
})
return fmt.Errorf("invalid secret, %s id: [%s]", req.GetEvent().String(), req.GetClientId())
}
rpc.GetClientsManager().Set(req.GetClientId(), sender)
done = rpc.Recv(req.GetClientId())
sender.Send(&pb.ServerMessage{
Event: req.GetEvent(),
ClientId: req.GetClientId(),
SessionId: req.GetClientId(),
})
logrus.Infof("register success, req: [%+v]", req)
break
}
}
<-done
return nil
}

View File

@@ -0,0 +1,49 @@
package master
import (
"github.com/sirupsen/logrus"
"google.golang.org/grpc"
)
type MasterHandler interface {
Run()
Stop()
}
type Master struct {
grpcServer *grpc.Server
}
var (
cli *Master
)
func MustInitMasterService() {
if cli != nil {
logrus.Warn("server has been initialized")
return
}
cli = NewMasterHandler()
}
func GetMasterSerivce() MasterHandler {
if cli == nil {
logrus.Panic("server has not been initialized")
}
return cli
}
func NewMasterHandler() *Master {
s := NewRpcServer()
return &Master{
grpcServer: s,
}
}
func (s *Master) Run() {
RunRpcServer(s.grpcServer)
}
func (s *Master) Stop() {
s.grpcServer.Stop()
}

View File

@@ -0,0 +1,113 @@
package rpcclient
import (
"context"
"io"
"time"
"github.com/VaalaCat/frp-panel/pb"
"github.com/VaalaCat/frp-panel/rpc"
"github.com/google/uuid"
"github.com/sirupsen/logrus"
)
// func clientHandleServerSend(req *pb.ServerMessage) *pb.ClientMessage {
// logrus.Infof("client get a server message, origin is: [%+v]", req)
// return &pb.ClientMessage{
// Event: pb.Event_EVENT_DATA,
// ClientId: req.ClientId,
// SessionId: req.SessionId,
// Data: req.Data,
// }
// }
func NewMasterCli() (pb.MasterClient, error) {
return rpc.MasterCli(context.Background())
}
func RegistClientToMaster(recvStream pb.Master_ServerSendClient, event pb.Event, clientID, clientSecret string) {
logrus.Infof("start to regist client to master")
for {
err := recvStream.Send(&pb.ClientMessage{
Event: event,
ClientId: clientID,
SessionId: uuid.New().String(),
Secret: clientSecret,
})
if err != nil {
logrus.WithError(err).Warnf("cannot send, sleep 3s and retry")
time.Sleep(3 * time.Second)
continue
}
resp, err := recvStream.Recv()
if err == io.EOF {
break
}
if err != nil {
logrus.Fatalf("cannot receive %v", err)
}
if resp.GetEvent() == event {
logrus.Infof("client get server register envent success, clientID: %s", resp.GetClientId())
break
}
}
}
func RunRPCClient(recvStream pb.Master_ServerSendClient, done chan bool, clientID string,
clientHandleServerSend func(req *pb.ServerMessage) *pb.ClientMessage) {
for {
select {
case <-done:
logrus.Infof("finish rpc client")
recvStream.CloseSend()
return
default:
resp, err := recvStream.Recv()
if err == io.EOF {
break
}
if err != nil {
logrus.WithError(err).Errorf("cannot receive, sleep 3s and return")
time.Sleep(3 * time.Second)
return
}
if resp == nil {
continue
}
go func() {
msg := clientHandleServerSend(resp)
if msg == nil {
return
}
msg.ClientId = clientID
msg.SessionId = resp.SessionId
recvStream.Send(msg)
logrus.Infof("client resp received: %s", resp.GetClientId())
}()
}
}
}
func StartRPCClient(client pb.MasterClient, done chan bool, clientID, clientSecret string, event pb.Event,
clientHandleServerSend func(req *pb.ServerMessage) *pb.ClientMessage) {
logrus.Infof("start to run rpc client")
for {
select {
case <-done:
logrus.Infof("finish rpc client")
return
default:
recvStream, err := client.ServerSend(context.Background())
if err != nil {
logrus.WithError(err).Errorf("cannot recv, sleep 3s and retry")
time.Sleep(3 * time.Second)
continue
}
RegistClientToMaster(recvStream, event, clientID, clientSecret)
RunRPCClient(recvStream, done, clientID, clientHandleServerSend)
}
}
}

View File

@@ -0,0 +1,68 @@
package rpcclient
import (
"github.com/VaalaCat/frp-panel/pb"
"github.com/sirupsen/logrus"
)
type ClientRPCHandler interface {
Run()
Stop()
GetCli() pb.MasterClient
}
type ClientRPC struct {
rpcClient pb.MasterClient
done chan bool
handerFunc func(req *pb.ServerMessage) *pb.ClientMessage
clientID string
clientSecret string
event pb.Event
}
var (
cliRpc *ClientRPC
)
func MustInitClientRPCSerivce(clientID, clientSecret string, event pb.Event, handerFunc func(req *pb.ServerMessage) *pb.ClientMessage) {
if cliRpc != nil {
logrus.Warn("rpc client has been initialized")
return
}
cliRpc = NewClientRPCHandler(clientID, clientSecret, event, handerFunc)
}
func GetClientRPCSerivce() ClientRPCHandler {
if cliRpc == nil {
logrus.Panic("rpc client has not been initialized")
}
return cliRpc
}
func NewClientRPCHandler(clientID, clientSecret string, event pb.Event, handerFunc func(req *pb.ServerMessage) *pb.ClientMessage) *ClientRPC {
rpcCli, err := NewMasterCli()
if err != nil {
logrus.Fatalf("new rpc client failed: %v", err)
}
done := make(chan bool)
return &ClientRPC{
rpcClient: rpcCli,
done: done,
handerFunc: handerFunc,
clientID: clientID,
clientSecret: clientSecret,
event: event,
}
}
func (s *ClientRPC) Run() {
StartRPCClient(s.rpcClient, s.done, s.clientID, s.clientSecret, s.event, s.handerFunc)
}
func (s *ClientRPC) Stop() {
close(s.done)
}
func (s *ClientRPC) GetCli() pb.MasterClient {
return s.rpcClient
}

View File

@@ -0,0 +1,82 @@
package server
import (
"context"
v1 "github.com/fatedier/frp/pkg/config/v1"
"github.com/fatedier/frp/pkg/config/v1/validation"
"github.com/fatedier/frp/pkg/util/log"
"github.com/fatedier/frp/server"
"github.com/sirupsen/logrus"
)
type ServerHandler interface {
Run()
Stop()
GetCommonCfg() *v1.ServerConfig
}
type Server struct {
srv *server.Service
Common *v1.ServerConfig
}
var (
srv *Server
)
func InitGlobalServerService(svrCfg *v1.ServerConfig) {
if srv != nil {
logrus.Warn("server has been initialized")
return
}
svrCfg.Complete()
srv = NewServerHandler(svrCfg)
}
func GetGlobalServerSerivce() ServerHandler {
if srv == nil {
logrus.Panic("server has not been initialized")
}
return srv
}
func GetServerSerivce(svrCfg *v1.ServerConfig) ServerHandler {
svrCfg.Complete()
return NewServerHandler(svrCfg)
}
func NewServerHandler(svrCfg *v1.ServerConfig) *Server {
warning, err := validation.ValidateServerConfig(svrCfg)
if warning != nil {
logrus.WithError(err).Warnf("validate server config warning: %+v", warning)
}
if err != nil {
logrus.Panic(err)
}
log.InitLog(svrCfg.Log.To, svrCfg.Log.Level, svrCfg.Log.MaxDays, svrCfg.Log.DisablePrintColor)
svr, err := server.NewService(svrCfg)
if err != nil {
logrus.Panic(err)
}
return &Server{
srv: svr,
Common: svrCfg,
}
}
func (s *Server) Run() {
s.srv.Run(context.Background())
}
func (s *Server) Stop() {
s.srv.Close()
}
func (s *Server) GetCommonCfg() *v1.ServerConfig {
return s.Common
}

83
tunnel/client.go Normal file
View File

@@ -0,0 +1,83 @@
package tunnel
import (
"sync"
"github.com/VaalaCat/frp-panel/services/client"
)
type ClientController interface {
Add(clientID string, clientHandler client.ClientHandler)
Get(clientID string) client.ClientHandler
Delete(clientID string)
Set(clientID string, clientHandler client.ClientHandler)
Run(clientID string) // 不阻塞
Stop(clientID string)
List() []string
}
type clientController struct {
clients *sync.Map
}
var (
clientControllerInstance *clientController
)
func NewClientController() ClientController {
return &clientController{
clients: &sync.Map{},
}
}
func GetClientController() ClientController {
if clientControllerInstance == nil {
clientControllerInstance = NewClientController().(*clientController)
}
return clientControllerInstance
}
func (c *clientController) Add(clientID string, clientHandler client.ClientHandler) {
c.clients.Store(clientID, clientHandler)
}
func (c *clientController) Get(clientID string) client.ClientHandler {
v, ok := c.clients.Load(clientID)
if !ok {
return nil
}
return v.(client.ClientHandler)
}
func (c *clientController) Delete(clientID string) {
c.clients.Delete(clientID)
}
func (c *clientController) Set(clientID string, clientHandler client.ClientHandler) {
c.clients.Store(clientID, clientHandler)
}
func (c *clientController) Run(clientID string) {
v, ok := c.clients.Load(clientID)
if !ok {
return
}
go v.(client.ClientHandler).Run()
}
func (c *clientController) Stop(clientID string) {
v, ok := c.clients.Load(clientID)
if !ok {
return
}
v.(client.ClientHandler).Stop()
}
func (c *clientController) List() []string {
keys := make([]string, 0)
c.clients.Range(func(key, value interface{}) bool {
keys = append(keys, key.(string))
return true
})
return keys
}

1
tunnel/master.go Normal file
View File

@@ -0,0 +1 @@
package tunnel

83
tunnel/server.go Normal file
View File

@@ -0,0 +1,83 @@
package tunnel
import (
"sync"
"github.com/VaalaCat/frp-panel/services/server"
)
type ServerController interface {
Add(serverID string, serverHandler server.ServerHandler)
Get(serverID string) server.ServerHandler
Delete(serverID string)
Set(serverID string, serverHandler server.ServerHandler)
Run(serverID string) // 不阻塞
Stop(serverID string)
List() []string
}
type serverController struct {
servers *sync.Map
}
var (
serverControllerInstance *serverController
)
func NewServerController() ServerController {
return &serverController{
servers: &sync.Map{},
}
}
func GetServerController() ServerController {
if serverControllerInstance == nil {
serverControllerInstance = NewServerController().(*serverController)
}
return serverControllerInstance
}
func (c *serverController) Add(serverID string, serverHandler server.ServerHandler) {
c.servers.Store(serverID, serverHandler)
}
func (c *serverController) Get(serverID string) server.ServerHandler {
v, ok := c.servers.Load(serverID)
if !ok {
return nil
}
return v.(server.ServerHandler)
}
func (c *serverController) Delete(serverID string) {
c.servers.Delete(serverID)
}
func (c *serverController) Set(serverID string, serverHandler server.ServerHandler) {
c.servers.Store(serverID, serverHandler)
}
func (c *serverController) Run(serverID string) {
v, ok := c.servers.Load(serverID)
if !ok {
return
}
go v.(server.ServerHandler).Run()
}
func (c *serverController) Stop(serverID string) {
v, ok := c.servers.Load(serverID)
if !ok {
return
}
v.(server.ServerHandler).Stop()
}
func (c *serverController) List() []string {
keys := make([]string, 0)
c.servers.Range(func(key, value interface{}) bool {
keys = append(keys, key.(string))
return true
})
return keys
}

38
utils/conv.go Normal file
View File

@@ -0,0 +1,38 @@
package utils
import (
"strconv"
)
func Str2Int64(str string) int64 {
num, err := strconv.ParseInt(str, 10, 64)
if err != nil {
return 0
}
return num
}
func Str2Int64Default(str string, intVal int64) int64 {
num, err := strconv.ParseInt(str, 10, 64)
if err != nil {
return intVal
}
return num
}
func ToStr(any interface{}) string {
if any == nil {
return ""
}
if str, ok := any.(string); ok {
return str
}
return ""
}
func IsInteger(str string) bool {
_, err := strconv.Atoi(str)
return err == nil
}

60
utils/ctx.go Normal file
View File

@@ -0,0 +1,60 @@
package utils
import (
"context"
"reflect"
"strconv"
)
func GetValue[T any](c context.Context, key string) (T, bool) {
val, ok := getValue[T](c, key)
if !ok {
return *new(T), false
}
v, ok := val.(T)
if !ok {
return *new(T), false
}
return v, true
}
func getValue[T any](c context.Context, key string) (interface{}, bool) {
val := c.Value(key)
if val == nil {
return *new(T), false
}
if reflect.TypeOf(*new(T)).Kind() == reflect.Int && reflect.TypeOf(val).Kind() == reflect.String {
strconvInt, err := strconv.Atoi(val.(string))
if err != nil {
return *new(T), false
}
return strconvInt, true
}
v, ok := val.(T)
if !ok {
return *new(T), false
}
return v, true
}
func GetIntValueFromStr(c context.Context, key string) (int, bool) {
val := c.Value(key)
if val == nil {
return 0, false
}
v, ok := val.(string)
if !ok {
return 0, false
}
strconvInt, err := strconv.Atoi(v)
if err != nil {
return 0, false
}
return strconvInt, true
}

64
utils/frp_config.go Normal file
View File

@@ -0,0 +1,64 @@
package utils
import (
v1 "github.com/fatedier/frp/pkg/config/v1"
)
func NewBaseFRPServerConfig(port int, token string) *v1.ServerConfig {
resp := &v1.ServerConfig{
BindPort: port,
Auth: v1.AuthServerConfig{
Method: v1.AuthMethodToken,
Token: token,
},
}
resp.Complete()
return resp
}
func NewBaseFRPServerUserAuthConfig(port int, opts []v1.HTTPPluginOptions) *v1.ServerConfig {
resp := &v1.ServerConfig{
BindPort: port,
HTTPPlugins: opts,
}
resp.Complete()
return resp
}
func NewBaseFRPClientConfig(serverAddr string, serverPort int, token string) *v1.ClientCommonConfig {
resp := &v1.ClientCommonConfig{
Auth: v1.AuthClientConfig{
Method: v1.AuthMethodToken,
Token: token,
},
ServerAddr: serverAddr,
ServerPort: serverPort,
}
resp.Complete()
return resp
}
func NewBaseFRPClientUserAuthConfig(serverAddr string, serverPort int, user, token string) *v1.ClientCommonConfig {
resp := &v1.ClientCommonConfig{
User: user,
Metadatas: map[string]string{
string(v1.AuthMethodToken): token,
},
ServerAddr: serverAddr,
ServerPort: serverPort,
}
resp.Complete()
return resp
}
func TransformProxyConfigurerToMap(origin v1.ProxyConfigurer) (key string, r v1.ProxyConfigurer) {
key = origin.GetBaseConfig().Name
r = origin
return
}
func TransformVisitorConfigurerToMap(origin v1.VisitorConfigurer) (key string, r v1.VisitorConfigurer) {
key = origin.GetBaseConfig().Name
r = origin
return
}

32
utils/hash.go Normal file
View File

@@ -0,0 +1,32 @@
package utils
import (
"crypto/md5"
"crypto/sha1"
"encoding/hex"
"fmt"
"golang.org/x/crypto/bcrypt"
)
func MD5(input string) string {
data := []byte(input)
hash := md5.Sum(data)
hashString := hex.EncodeToString(hash[:])
return hashString
}
func SHA1(input string) string {
hash := sha1.Sum([]byte(input))
return fmt.Sprintf("%x", hash)
}
func HashPassword(password string) (string, error) {
bytes, err := bcrypt.GenerateFromPassword([]byte(password), 14)
return string(bytes), err
}
func CheckPasswordHash(password, hash string) bool {
err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password))
return err == nil
}

65
utils/jwt.go Normal file
View File

@@ -0,0 +1,65 @@
package utils
import (
"errors"
"github.com/golang-jwt/jwt/v5"
)
// @secretKey: JWT 加解密密钥
// @iat: 时间戳
// @seconds: 过期时间,单位秒
// @payload: 数据载体
func GetJwtToken(secretKey string, iat, seconds int64, payload string) (string, error) {
claims := make(jwt.MapClaims)
claims["exp"] = iat + seconds
claims["iat"] = iat
claims["payload"] = payload
token := jwt.New(jwt.SigningMethodHS256)
token.Claims = claims
return token.SignedString([]byte(secretKey))
}
// @secretKey: JWT 加解密密钥
// @iat: 时间戳
// @seconds: 过期时间,单位秒
// @payload: 数据载体
func GetJwtTokenFromMap(secretKey string, iat, seconds int64, payload map[string]string) (string, error) {
claims := make(jwt.MapClaims)
claims["exp"] = iat + seconds
claims["iat"] = iat
for k, v := range payload {
claims[k] = v
}
token := jwt.New(jwt.SigningMethodHS256)
token.Claims = claims
return token.SignedString([]byte(secretKey))
}
// @secretKey: JWT 加解密密钥
// @token: JWT Token 的字符串
func ValidateJwtToken(secretKey, token string) (bool, error) {
t, err := jwt.Parse(token, func(token *jwt.Token) (interface{}, error) {
return []byte(secretKey), nil
})
if err != nil {
return false, err
}
return t.Valid, nil
}
func ParseToken(secretKey, tokenStr string) (u jwt.MapClaims, err error) {
token, err := jwt.Parse(tokenStr, func(token *jwt.Token) (interface{}, error) {
return []byte(secretKey), nil
})
if err != nil {
return nil, errors.New("couldn't handle this token")
}
if t, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
return t, nil
}
return nil, errors.New("couldn't handle this token")
}

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