Compare commits

..

29 Commits

Author SHA1 Message Date
刘祥超
6a9045ba44 提交SQL 2022-07-18 09:13:16 +08:00
刘祥超
bc7ee19962 优化代码 2022-07-17 17:08:28 +08:00
刘祥超
2484cd4ae6 可以通过ID查找服务 2022-07-17 11:43:23 +08:00
刘祥超
57b8a96c6d 增加用户身份认证相关接口 2022-07-17 11:00:14 +08:00
刘祥超
6c8ab7cb94 集群DNS设置增加允许通过CNAME访问网站服务选项 2022-07-14 09:49:09 +08:00
刘祥超
b2c2bd247b 更新SQL 2022-07-12 14:22:20 +08:00
刘祥超
29d9e6db81 域名解析支持DNS.COM(商业版) 2022-07-11 11:51:49 +08:00
刘祥超
24fcb48c75 删除节点的时候同时也删除相关的运行日志 2022-07-07 20:31:12 +08:00
刘祥超
4911198fe7 安全设置中增加禁止搜索引擎、禁止爬虫、允许访问的域名等选项 2022-07-07 19:58:50 +08:00
刘祥超
c2af796992 服务看板增加峰值带宽数据 2022-07-07 17:11:49 +08:00
刘祥超
51c8572e53 用户界面设置中增加流量、带宽相关设置 2022-07-07 12:40:05 +08:00
刘祥超
c15cc6d75c 增加按用户统计带宽/修改其他相关代码 2022-07-07 09:18:08 +08:00
刘祥超
c0a99a4ba3 升级Go版本为1.18 2022-07-06 16:13:52 +08:00
刘祥超
62e26bed5a 增加服务带宽统计 2022-07-05 20:08:58 +08:00
刘祥超
9e68a2915c 增加UAM(5秒盾)集群设置 2022-07-03 22:10:46 +08:00
刘祥超
5b809fda1f 反向代理设置中增加移除回源主机名端口功能 2022-06-30 12:12:41 +08:00
刘祥超
88b782940a 提交SQL 2022-06-29 22:17:32 +08:00
刘祥超
85c596644d 实现源站端口跟随功能 2022-06-29 21:55:57 +08:00
刘祥超
ffa2d884bd 移除386、mips等不常用节点安装文件 2022-06-29 17:11:13 +08:00
刘祥超
813ed18610 优化编译脚本 2022-06-29 16:57:46 +08:00
刘祥超
564b11eae7 优化编译脚本 2022-06-29 14:52:11 +08:00
刘祥超
d2af0307b9 将DNS版本改为0.2.4 2022-06-28 20:31:59 +08:00
刘祥超
4fa6b03238 对于小内存(不大于2G),缩短服务统计导入数据库的时间 2022-06-25 20:57:03 +08:00
刘祥超
4bda78aa8c 限制节点自动升级时的速度和并发数 2022-06-25 20:36:31 +08:00
刘祥超
6002cc96d9 增加修改服务所在分组API 2022-06-25 19:21:46 +08:00
刘祥超
56c09f5be7 指标数据写入改成队列执行 2022-06-22 21:51:44 +08:00
刘祥超
e1fb8e4c74 删除某个IP时更新版本 2022-06-22 18:59:27 +08:00
刘祥超
14f055ce7c fix typo 2022-06-22 14:00:56 +08:00
刘祥超
7b7f2b0a00 修改版本号为v0.4.9 2022-06-20 16:00:27 +08:00
72 changed files with 2555 additions and 473 deletions

View File

@@ -1,76 +1,76 @@
#!/usr/bin/env bash
function build() {
ROOT=$(dirname $0)
ROOT=$(dirname "$0")
NAME="edge-api"
DIST=$ROOT/"../dist/${NAME}"
OS=${1}
ARCH=${2}
TAG=${3}
NODE_ARCHITECTS=("amd64" "386" "arm64" "mips64" "mips64le")
NODE_ARCHITECTS=("amd64" "arm64")
if [ -z $OS ]; then
if [ -z "$OS" ]; then
echo "usage: build.sh OS ARCH"
exit
fi
if [ -z $ARCH ]; then
if [ -z "$ARCH" ]; then
echo "usage: build.sh OS ARCH"
exit
fi
if [ -z $TAG ]; then
if [ -z "$TAG" ]; then
TAG="community"
fi
VERSION=$(lookup-version $ROOT/../internal/const/const.go)
VERSION=$(lookup-version "$ROOT"/../internal/const/const.go)
ZIP="${NAME}-${OS}-${ARCH}-${TAG}-v${VERSION}.zip"
# build edge-node
NodeVersion=$(lookup-version $ROOT"/../../EdgeNode/internal/const/const.go")
NodeVersion=$(lookup-version "$ROOT""/../../EdgeNode/internal/const/const.go")
echo "building edge-node v${NodeVersion} ..."
EDGE_NODE_BUILD_SCRIPT=$ROOT"/../../EdgeNode/build/build.sh"
if [ ! -f $EDGE_NODE_BUILD_SCRIPT ]; then
if [ ! -f "$EDGE_NODE_BUILD_SCRIPT" ]; then
echo "unable to find edge-node build script 'EdgeNode/build/build.sh'"
exit
fi
cd $ROOT"/../../EdgeNode/build"
cd "$ROOT""/../../EdgeNode/build" || exit
echo "=============================="
for arch in "${NODE_ARCHITECTS[@]}"; do
if [ ! -f $ROOT"/../../EdgeNode/dist/edge-node-linux-${arch}-${TAG}-v${NodeVersion}.zip" ]; then
./build.sh linux $arch $TAG
if [ ! -f "$ROOT""/../../EdgeNode/dist/edge-node-linux-${arch}-${TAG}-v${NodeVersion}.zip" ]; then
./build.sh linux "$arch" $TAG
else
echo "use built node linux/$arch/v${NodeVersion}"
fi
done
echo "=============================="
cd -
cd - || exit
rm -f $ROOT/deploy/*.zip
rm -f "$ROOT"/deploy/*.zip
for arch in "${NODE_ARCHITECTS[@]}"; do
cp $ROOT"/../../EdgeNode/dist/edge-node-linux-${arch}-${TAG}-v${NodeVersion}.zip" $ROOT/deploy/edge-node-linux-${arch}-v${NodeVersion}.zip
cp "$ROOT""/../../EdgeNode/dist/edge-node-linux-${arch}-${TAG}-v${NodeVersion}.zip" "$ROOT"/deploy/edge-node-linux-"${arch}"-v"${NodeVersion}".zip
done
# build edge-dns
if [ "$TAG" = "plus" ]; then
DNS_ROOT=$ROOT"/../../EdgeDNS"
if [ -d $DNS_ROOT ]; then
DNSNodeVersion=$(lookup-version $ROOT"/../../EdgeDNS/internal/const/const.go")
if [ -d "$DNS_ROOT" ]; then
DNSNodeVersion=$(lookup-version "$ROOT""/../../EdgeDNS/internal/const/const.go")
echo "building edge-dns ${DNSNodeVersion} ..."
EDGE_DNS_NODE_BUILD_SCRIPT=$ROOT"/../../EdgeDNS/build/build.sh"
if [ ! -f $EDGE_DNS_NODE_BUILD_SCRIPT ]; then
if [ ! -f "$EDGE_DNS_NODE_BUILD_SCRIPT" ]; then
echo "unable to find edge-dns build script 'EdgeDNS/build/build.sh'"
exit
fi
cd $ROOT"/../../EdgeDNS/build"
cd "$ROOT""/../../EdgeDNS/build" || exit
echo "=============================="
architects=("amd64")
architects=("amd64" "arm64")
for arch in "${architects[@]}"; do
./build.sh linux $arch $TAG
./build.sh linux "$arch" $TAG
done
echo "=============================="
cd -
cd - || exit
for arch in "${architects[@]}"; do
cp $ROOT"/../../EdgeDNS/dist/edge-dns-linux-${arch}-v${DNSNodeVersion}.zip" $ROOT/deploy/edge-dns-linux-${arch}-v${DNSNodeVersion}.zip
cp "$ROOT""/../../EdgeDNS/dist/edge-dns-linux-${arch}-v${DNSNodeVersion}.zip" "$ROOT"/deploy/edge-dns-linux-"${arch}"-v"${DNSNodeVersion}".zip
done
fi
fi
@@ -78,48 +78,48 @@ function build() {
# build sql
if [ $TAG = "plus" ]; then
echo "building sql ..."
${ROOT}/sql.sh
"${ROOT}"/sql.sh
fi
# copy files
echo "copying ..."
if [ ! -d $DIST ]; then
mkdir $DIST
mkdir $DIST/bin
mkdir $DIST/configs
mkdir $DIST/logs
if [ ! -d "$DIST" ]; then
mkdir "$DIST"
mkdir "$DIST"/bin
mkdir "$DIST"/configs
mkdir "$DIST"/logs
fi
cp $ROOT/configs/api.template.yaml $DIST/configs/
cp $ROOT/configs/db.template.yaml $DIST/configs/
cp -R $ROOT/deploy $DIST/
rm -f $dist/deploy/.gitignore
cp -R $ROOT/installers $DIST/
cp -R $ROOT/resources $DIST/
rm -f $DIST/resources/ipdata/ip2region/global_region.csv
rm -f $DIST/resources/ipdata/ip2region/ip.merge.txt
cp "$ROOT"/configs/api.template.yaml "$DIST"/configs/
cp "$ROOT"/configs/db.template.yaml "$DIST"/configs/
cp -R "$ROOT"/deploy "$DIST/"
rm -f "$DIST"/deploy/.gitignore
cp -R "$ROOT"/installers "$DIST"/
cp -R "$ROOT"/resources "$DIST"/
rm -f "$DIST"/resources/ipdata/ip2region/global_region.csv
rm -f "$DIST"/resources/ipdata/ip2region/ip.merge.txt
# building edge installer
echo "building node installer ..."
architects=("amd64" "386" "arm64")
architects=("amd64" "arm64")
for arch in "${architects[@]}"; do
# TODO support arm, mips ...
env GOOS=linux GOARCH=${arch} go build -tags $TAG --ldflags="-s -w" -o $ROOT/installers/edge-installer-helper-linux-${arch} $ROOT/../cmd/installer-helper/main.go
env GOOS=linux GOARCH="${arch}" go build -trimpath -tags $TAG --ldflags="-s -w" -o "$ROOT"/installers/edge-installer-helper-linux-"${arch}" "$ROOT"/../cmd/installer-helper/main.go
done
# building edge dns installer
echo "building dns node installer ..."
architects=("amd64" "386" "arm64")
architects=("amd64" "arm64")
for arch in "${architects[@]}"; do
# TODO support arm, mips ...
env GOOS=linux GOARCH=${arch} go build -tags $TAG --ldflags="-s -w" -o $ROOT/installers/edge-installer-dns-helper-linux-${arch} $ROOT/../cmd/installer-dns-helper/main.go
env GOOS=linux GOARCH="${arch}" go build -trimpath -tags $TAG --ldflags="-s -w" -o "$ROOT"/installers/edge-installer-dns-helper-linux-"${arch}" "$ROOT"/../cmd/installer-dns-helper/main.go
done
# building api node
env GOOS=$OS GOARCH=$ARCH go build -tags $TAG --ldflags="-s -w" -o $DIST/bin/edge-api $ROOT/../cmd/edge-api/main.go
env GOOS="$OS" GOARCH="$ARCH" go build -trimpath -tags $TAG --ldflags="-s -w" -o "$DIST"/bin/edge-api "$ROOT"/../cmd/edge-api/main.go
# delete hidden files
find $DIST -name ".DS_Store" -delete
find $DIST -name ".gitignore" -delete
find "$DIST" -name ".DS_Store" -delete
find "$DIST" -name ".gitignore" -delete
echo "zip files"
cd "${DIST}/../" || exit
@@ -135,15 +135,15 @@ function build() {
function lookup-version() {
FILE=$1
VERSION_DATA=$(cat $FILE)
VERSION_DATA=$(cat "$FILE")
re="Version[ ]+=[ ]+\"([0-9.]+)\""
if [[ $VERSION_DATA =~ $re ]]; then
VERSION=${BASH_REMATCH[1]}
echo $VERSION
echo "$VERSION"
else
echo "could not match version"
exit
fi
}
build $1 $2 $3
build "$1" "$2" "$3"

3
dist/.gitignore vendored
View File

@@ -1 +1,2 @@
*.zip
*.zip
edge-api

25
go.mod
View File

@@ -1,6 +1,6 @@
module github.com/TeaOSLab/EdgeAPI
go 1.16
go 1.18
replace github.com/TeaOSLab/EdgeCommon => ../EdgeCommon
@@ -14,7 +14,6 @@ require (
github.com/golang/protobuf v1.5.2
github.com/iwind/TeaGo v0.0.0-20220408111647-f36b9bba3570
github.com/iwind/gosock v0.0.0-20210722083328-12b2d66abec3
github.com/json-iterator/go v1.1.12 // indirect
github.com/mozillazg/go-pinyin v0.18.0
github.com/pkg/sftp v1.12.0
github.com/shirou/gopsutil/v3 v3.22.2
@@ -24,3 +23,25 @@ require (
google.golang.org/protobuf v1.27.1
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
)
require (
github.com/cenkalti/backoff/v4 v4.1.1 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/kr/fs v0.1.0 // indirect
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
github.com/miekg/dns v1.1.43 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
github.com/tklauser/go-sysconf v0.3.9 // indirect
github.com/tklauser/numcpus v0.3.0 // indirect
github.com/yusufpapurcu/wmi v1.2.2 // indirect
golang.org/x/net v0.0.0-20220225172249-27dd8689420f // indirect
golang.org/x/text v0.3.7 // indirect
google.golang.org/genproto v0.0.0-20220317150908-0efb43f6373e // indirect
gopkg.in/ini.v1 v1.62.0 // indirect
gopkg.in/square/go-jose.v2 v2.6.0 // indirect
)

6
go.sum
View File

@@ -66,7 +66,6 @@ github.com/c-bata/go-prompt v0.2.5/go.mod h1:vFnjEGDIIA/Lib7giyE4E9c50Lvl8j0S+7F
github.com/cenkalti/backoff/v4 v4.1.1 h1:G2HAfAmvm/GcKan2oOQpBXOd2tT2G57ZnZGWa1PxPBQ=
github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
@@ -238,10 +237,6 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt
github.com/infobloxopen/infoblox-go-client v1.1.1/go.mod h1:BXiw7S2b9qJoM8MS40vfgCNB2NLHGusk1DtO16BD9zI=
github.com/iwind/TeaGo v0.0.0-20210411134150-ddf57e240c2f/go.mod h1:KU4mS7QNiZ7QWEuDBk1zw0/Q2LrAPZv3tycEFBsuUwc=
github.com/iwind/TeaGo v0.0.0-20220304043459-0dd944a5b475/go.mod h1:HRHK0zoC/og3c9/hKosD9yYVMTnnzm3PgXUdhRYHaLc=
github.com/iwind/TeaGo v0.0.0-20220322141208-22f88d04004d h1:e8fkTKras/RXQWECApM9fKlFWujjYjEClpshkmZmtYg=
github.com/iwind/TeaGo v0.0.0-20220322141208-22f88d04004d/go.mod h1:HRHK0zoC/og3c9/hKosD9yYVMTnnzm3PgXUdhRYHaLc=
github.com/iwind/TeaGo v0.0.0-20220408064305-92be81dc2f7c h1:ugjYZ74FJGWlfDKKraNgMyDTeS4vbXHe89JGUVQIJMo=
github.com/iwind/TeaGo v0.0.0-20220408064305-92be81dc2f7c/go.mod h1:HRHK0zoC/og3c9/hKosD9yYVMTnnzm3PgXUdhRYHaLc=
github.com/iwind/TeaGo v0.0.0-20220408111647-f36b9bba3570 h1:zqz2FiMMkSHXWO1EsTRJDPTwX9xQ4uuyD5GAE4JGlhM=
github.com/iwind/TeaGo v0.0.0-20220408111647-f36b9bba3570/go.mod h1:HRHK0zoC/og3c9/hKosD9yYVMTnnzm3PgXUdhRYHaLc=
github.com/iwind/gosock v0.0.0-20210722083328-12b2d66abec3 h1:aBSonas7vFcgTj9u96/bWGILGv1ZbUSTLiOzcI1ZT6c=
@@ -561,7 +556,6 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=

View File

@@ -1,7 +1,7 @@
package teaconst
const (
Version = "0.4.8"
Version = "0.4.9"
ProductName = "Edge API"
ProcessName = "edge-api"
@@ -18,13 +18,13 @@ const (
// 其他节点版本号,用来检测是否有需要升级的节点
NodeVersion = "0.4.8.1"
UserNodeVersion = "0.3.4"
NodeVersion = "0.4.9"
UserNodeVersion = "0.3.5"
AuthorityNodeVersion = "0.0.2"
MonitorNodeVersion = "0.0.4"
DNSNodeVersion = "0.2.3"
DNSNodeVersion = "0.2.4"
ReportNodeVersion = "0.1.1"
// SQLVersion SQL版本号
SQLVersion = "11"
SQLVersion = "2"
)

View File

@@ -58,15 +58,22 @@ func (this *APINodeDAO) EnableAPINode(tx *dbs.Tx, id int64) error {
}
// DisableAPINode 禁用条目
func (this *APINodeDAO) DisableAPINode(tx *dbs.Tx, id int64) error {
func (this *APINodeDAO) DisableAPINode(tx *dbs.Tx, nodeId int64) error {
_, err := this.Query(tx).
Pk(id).
Pk(nodeId).
Set("state", APINodeStateDisabled).
Update()
if err != nil {
return err
}
return this.NotifyUpdate(tx, id)
err = this.NotifyUpdate(tx, nodeId)
if err != nil {
return err
}
// 删除运行日志
return SharedNodeLogDAO.DeleteNodeLogs(tx, nodeconfigs.NodeRoleAPI, nodeId)
}
// FindEnabledAPINode 查找启用中的条目

View File

@@ -4,6 +4,7 @@ import (
"encoding/base64"
"github.com/TeaOSLab/EdgeAPI/internal/encrypt"
"github.com/TeaOSLab/EdgeAPI/internal/errors"
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
_ "github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/dbs"
@@ -49,12 +50,17 @@ func (this *DBNodeDAO) EnableDBNode(tx *dbs.Tx, id int64) error {
}
// DisableDBNode 禁用条目
func (this *DBNodeDAO) DisableDBNode(tx *dbs.Tx, id int64) error {
func (this *DBNodeDAO) DisableDBNode(tx *dbs.Tx, nodeId int64) error {
_, err := this.Query(tx).
Pk(id).
Pk(nodeId).
Set("state", DBNodeStateDisabled).
Update()
return err
if err != nil {
return err
}
// 删除运行日志
return SharedNodeLogDAO.DeleteNodeLogs(tx, nodeconfigs.NodeRoleDatabase, nodeId)
}
// FindEnabledDBNode 查找启用中的条目

View File

@@ -1,6 +1,7 @@
package models
import (
"github.com/TeaOSLab/EdgeAPI/internal/utils"
_ "github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/dbs"
@@ -33,7 +34,7 @@ func init() {
})
}
// 启用条目
// EnableFile 启用条目
func (this *FileDAO) EnableFile(tx *dbs.Tx, id int64) error {
_, err := this.Query(tx).
Pk(id).
@@ -42,7 +43,7 @@ func (this *FileDAO) EnableFile(tx *dbs.Tx, id int64) error {
return err
}
// 禁用条目
// DisableFile 禁用条目
func (this *FileDAO) DisableFile(tx *dbs.Tx, id int64) error {
_, err := this.Query(tx).
Pk(id).
@@ -51,7 +52,7 @@ func (this *FileDAO) DisableFile(tx *dbs.Tx, id int64) error {
return err
}
// 查找启用中的条目
// FindEnabledFile 查找启用中的条目
func (this *FileDAO) FindEnabledFile(tx *dbs.Tx, id int64) (*File, error) {
result, err := this.Query(tx).
Pk(id).
@@ -63,9 +64,9 @@ func (this *FileDAO) FindEnabledFile(tx *dbs.Tx, id int64) (*File, error) {
return result.(*File), err
}
// 创建文件
// CreateFile 创建文件
func (this *FileDAO) CreateFile(tx *dbs.Tx, adminId int64, userId int64, businessType, description string, filename string, size int64, isPublic bool) (int64, error) {
op := NewFileOperator()
var op = NewFileOperator()
op.AdminId = adminId
op.UserId = userId
op.Type = businessType
@@ -74,6 +75,7 @@ func (this *FileDAO) CreateFile(tx *dbs.Tx, adminId int64, userId int64, busines
op.Size = size
op.Filename = filename
op.IsPublic = isPublic
op.Code = utils.Sha1RandomString()
err := this.Save(tx, op)
if err != nil {
return 0, err
@@ -82,7 +84,7 @@ func (this *FileDAO) CreateFile(tx *dbs.Tx, adminId int64, userId int64, busines
return types.Int64(op.Id), nil
}
// 将文件置为已完成
// UpdateFileIsFinished 将文件置为已完成
func (this *FileDAO) UpdateFileIsFinished(tx *dbs.Tx, fileId int64) error {
_, err := this.Query(tx).
Pk(fileId).

View File

@@ -1,9 +1,10 @@
package models
// 文件管理
// File 文件管理
type File struct {
Id uint32 `field:"id"` // ID
AdminId uint32 `field:"adminId"` // 管理员ID
Code string `field:"code"` // 代号
UserId uint32 `field:"userId"` // 用户ID
Description string `field:"description"` // 文件描述
Filename string `field:"filename"` // 文件名
@@ -19,6 +20,7 @@ type File struct {
type FileOperator struct {
Id interface{} // ID
AdminId interface{} // 管理员ID
Code interface{} // 代号
UserId interface{} // 用户ID
Description interface{} // 文件描述
Filename interface{} // 文件名

View File

@@ -207,14 +207,35 @@ func (this *IPItemDAO) FindEnabledIPItem(tx *dbs.Tx, id int64) (*IPItem, error)
// DeleteOldItem 根据IP删除以前的旧记录
func (this *IPItemDAO) DeleteOldItem(tx *dbs.Tx, listId int64, ipFrom string, ipTo string) error {
_, err := this.Query(tx).
ones, err := this.Query(tx).
ResultPk().
UseIndex("ipFrom").
Attr("listId", listId).
Attr("ipFrom", ipFrom).
Attr("ipTo", ipTo).
Delete()
// 这里不通知更新
return err
Set("state", IPItemStateEnabled).
FindAll()
if err != nil {
return err
}
for _, one := range ones {
var itemId = int64(one.(*IPItem).Id)
version, err := SharedIPListDAO.IncreaseVersion(tx)
if err != nil {
return err
}
err = this.Query(tx).
Pk(itemId).
Set("version", version).
Set("state", IPItemStateDisabled).
UpdateQuickly()
if err != nil {
return err
}
}
return nil
}
// CreateIPItem 创建IP
@@ -267,6 +288,8 @@ func (this *IPItemDAO) CreateIPItem(tx *dbs.Tx,
}
op.State = IPItemStateEnabled
op.UpdatedAt = time.Now().Unix()
err = this.Save(tx, op)
if err != nil {
return 0, err

View File

@@ -691,7 +691,6 @@ func (this *MetricStatDAO) Clean(tx *dbs.Tx) error {
Table(table).
Attr("itemId", item.Id).
Lte("createdDay", expiresDay).
UseIndex("createdDay").
Limit(10_000). // 一次性不要删除太多,防止阻塞其他操作
Delete()
return err

View File

@@ -237,7 +237,6 @@ func (this *MetricSumStatDAO) Clean(tx *dbs.Tx) error {
Attr("itemId", item.Id).
Where("(createdDay IS NULL OR createdDay<:day)").
Param("day", expiresDay).
UseIndex("createdDay").
Limit(10_000). // 一次性不要删除太多,防止阻塞其他操作
Delete()
return err

View File

@@ -47,12 +47,17 @@ func (this *MonitorNodeDAO) EnableMonitorNode(tx *dbs.Tx, id int64) error {
}
// DisableMonitorNode 禁用条目
func (this *MonitorNodeDAO) DisableMonitorNode(tx *dbs.Tx, id int64) error {
func (this *MonitorNodeDAO) DisableMonitorNode(tx *dbs.Tx, nodeId int64) error {
_, err := this.Query(tx).
Pk(id).
Pk(nodeId).
Set("state", MonitorNodeStateDisabled).
Update()
return err
if err != nil {
return err
}
// 删除运行日志
return SharedNodeLogDAO.DeleteNodeLogs(tx, nodeconfigs.NodeRoleMonitor, nodeId)
}
// FindEnabledMonitorNode 查找启用中的条目

View File

@@ -214,7 +214,7 @@ func (this *NSRouteDAO) FindAllEnabledRoutes(tx *dbs.Tx, clusterId int64, domain
State(NSRouteStateEnabled).
Slice(&result).
Desc("order").
DescPk()
AscPk()
if clusterId > 0 {
query.Attr("clusterId", clusterId)
} else {

View File

@@ -142,10 +142,11 @@ func (this *NodeClusterDAO) CreateCluster(tx *dbs.Tx, adminId int64, name string
// DNS设置
op.DnsDomainId = dnsDomainId
op.DnsName = dnsName
dnsConfig := &dnsconfigs.ClusterDNSConfig{
var dnsConfig = &dnsconfigs.ClusterDNSConfig{
NodesAutoSync: true,
ServersAutoSync: true,
CNameRecords: []string{},
CNameAsDomain: true,
TTL: 0,
}
dnsJSON, err := json.Marshal(dnsConfig)
@@ -463,7 +464,7 @@ func (this *NodeClusterDAO) ExistClusterDNSName(tx *dbs.Tx, dnsName string, excl
}
// UpdateClusterDNS 修改集群DNS相关信息
func (this *NodeClusterDAO) UpdateClusterDNS(tx *dbs.Tx, clusterId int64, dnsName string, dnsDomainId int64, nodesAutoSync bool, serversAutoSync bool, cnameRecords []string, ttl int32) error {
func (this *NodeClusterDAO) UpdateClusterDNS(tx *dbs.Tx, clusterId int64, dnsName string, dnsDomainId int64, nodesAutoSync bool, serversAutoSync bool, cnameRecords []string, ttl int32, cnameAsDomain bool) error {
if clusterId <= 0 {
return errors.New("invalid clusterId")
}
@@ -503,6 +504,7 @@ func (this *NodeClusterDAO) UpdateClusterDNS(tx *dbs.Tx, clusterId int64, dnsNam
ServersAutoSync: serversAutoSync,
CNameRecords: cnameRecords,
TTL: ttl,
CNameAsDomain: cnameAsDomain,
}
dnsJSON, err := json.Marshal(dnsConfig)
if err != nil {
@@ -918,7 +920,7 @@ func (this *NodeClusterDAO) FindClusterBasicInfo(tx *dbs.Tx, clusterId int64, ca
cluster, err := this.Query(tx).
Pk(clusterId).
State(NodeClusterStateEnabled).
Result("id", "timeZone", "nodeMaxThreads", "cachePolicyId", "httpFirewallPolicyId", "autoOpenPorts", "webp", "isOn", "ddosProtection").
Result("id", "timeZone", "nodeMaxThreads", "cachePolicyId", "httpFirewallPolicyId", "autoOpenPorts", "webp", "uam", "isOn", "ddosProtection").
Find()
if err != nil || cluster == nil {
return nil, err
@@ -988,6 +990,65 @@ func (this *NodeClusterDAO) FindClusterWebPPolicy(tx *dbs.Tx, clusterId int64, c
return policy, nil
}
// UpdateClusterUAMPolicy 修改UAM设置
func (this *NodeClusterDAO) UpdateClusterUAMPolicy(tx *dbs.Tx, clusterId int64, uamPolicy *nodeconfigs.UAMPolicy) error {
if uamPolicy == nil {
err := this.Query(tx).
Pk(clusterId).
Set("uam", dbs.SQL("null")).
UpdateQuickly()
if err != nil {
return err
}
return this.NotifyUpdate(tx, clusterId)
}
uamPolicyJSON, err := json.Marshal(uamPolicy)
if err != nil {
return err
}
err = this.Query(tx).
Pk(clusterId).
Set("uam", uamPolicyJSON).
UpdateQuickly()
if err != nil {
return err
}
return this.NotifyUpdate(tx, clusterId)
}
// FindClusterUAMPolicy 查询设置
func (this *NodeClusterDAO) FindClusterUAMPolicy(tx *dbs.Tx, clusterId int64, cacheMap *utils.CacheMap) (*nodeconfigs.UAMPolicy, error) {
var cacheKey = this.Table + ":FindClusterUAMPolicy:" + types.String(clusterId)
if cacheMap != nil {
cache, ok := cacheMap.Get(cacheKey)
if ok {
return cache.(*nodeconfigs.UAMPolicy), nil
}
}
uamJSON, err := this.Query(tx).
Pk(clusterId).
Result("uam").
FindJSONCol()
if err != nil {
return nil, err
}
if IsNull(uamJSON) {
return nodeconfigs.DefaultUAMPolicy, nil
}
var policy = &nodeconfigs.UAMPolicy{}
err = json.Unmarshal(uamJSON, policy)
if err != nil {
return nil, err
}
return policy, nil
}
// FindClusterDDoSProtection 获取集群的DDoS设置
func (this *NodeClusterDAO) FindClusterDDoSProtection(tx *dbs.Tx, clusterId int64) (*ddosconfigs.ProtectionConfig, error) {
one, err := this.Query(tx).

View File

@@ -34,6 +34,7 @@ type NodeCluster struct {
AutoOpenPorts uint8 `field:"autoOpenPorts"` // 是否自动尝试开放端口
IsPinned bool `field:"isPinned"` // 是否置顶
Webp dbs.JSON `field:"webp"` // WebP设置
Uam dbs.JSON `field:"uam"` // UAM设置
}
type NodeClusterOperator struct {
@@ -67,6 +68,7 @@ type NodeClusterOperator struct {
AutoOpenPorts interface{} // 是否自动尝试开放端口
IsPinned interface{} // 是否置顶
Webp interface{} // WebP设置
Uam interface{} // UAM设置
}
func NewNodeClusterOperator() *NodeClusterOperator {

View File

@@ -13,9 +13,12 @@ func (this *NodeCluster) DecodeDNSConfig() (*dnsconfigs.ClusterDNSConfig, error)
return &dnsconfigs.ClusterDNSConfig{
NodesAutoSync: false,
ServersAutoSync: false,
CNameAsDomain: true,
}, nil
}
dnsConfig := &dnsconfigs.ClusterDNSConfig{}
var dnsConfig = &dnsconfigs.ClusterDNSConfig{
CNameAsDomain: true,
}
err := json.Unmarshal(this.Dns, &dnsConfig)
if err != nil {
return nil, err

View File

@@ -100,7 +100,8 @@ func (this *NodeDAO) DisableNode(tx *dbs.Tx, nodeId int64) (err error) {
return err
}
return nil
// 删除运行日志
return SharedNodeLogDAO.DeleteNodeLogs(tx, nodeconfigs.NodeRoleNode, nodeId)
}
// FindEnabledNode 查找启用中的条目
@@ -1018,6 +1019,7 @@ func (this *NodeDAO) ComposeNodeConfig(tx *dbs.Tx, nodeId int64, cacheMap *utils
clusterIds = append(clusterIds, node.DecodeSecondaryClusterIds()...)
var clusterIndex = 0
config.WebPImagePolicies = map[int64]*nodeconfigs.WebPImagePolicy{}
config.UAMPolicies = map[int64]*nodeconfigs.UAMPolicy{}
var allowIPMaps = map[string]bool{}
for _, clusterId := range clusterIds {
nodeCluster, err := SharedNodeClusterDAO.FindClusterBasicInfo(tx, clusterId, cacheMap)
@@ -1077,7 +1079,7 @@ func (this *NodeDAO) ComposeNodeConfig(tx *dbs.Tx, nodeId int64, cacheMap *utils
// 最大线程数、TCP连接数
if clusterIndex == 0 {
config.MaxThreads = int(nodeCluster.NodeMaxThreads)
config.DDOSProtection = nodeCluster.DecodeDDoSProtection()
config.DDoSProtection = nodeCluster.DecodeDDoSProtection()
config.AutoOpenPorts = nodeCluster.AutoOpenPorts == 1
}
@@ -1091,6 +1093,16 @@ func (this *NodeDAO) ComposeNodeConfig(tx *dbs.Tx, nodeId int64, cacheMap *utils
config.WebPImagePolicies[clusterId] = webpPolicy
}
// UAM
if IsNotNull(nodeCluster.Uam) {
var uamPolicy = &nodeconfigs.UAMPolicy{}
err = json.Unmarshal(nodeCluster.Uam, uamPolicy)
if err != nil {
return nil, err
}
config.UAMPolicies[clusterId] = uamPolicy
}
clusterIndex++
}
@@ -1212,10 +1224,10 @@ func (this *NodeDAO) ComposeNodeConfig(tx *dbs.Tx, nodeId int64, cacheMap *utils
// DDOS Protection
var ddosProtection = node.DecodeDDoSProtection()
if ddosProtection != nil {
if config.DDOSProtection == nil {
config.DDOSProtection = ddosProtection
if config.DDoSProtection == nil {
config.DDoSProtection = ddosProtection
} else {
config.DDOSProtection.Merge(ddosProtection)
config.DDoSProtection.Merge(ddosProtection)
}
}

View File

@@ -360,3 +360,12 @@ func (this *NodeLogDAO) UpdateAllNodeLogsRead(tx *dbs.Tx) error {
Set("isRead", true).
UpdateQuickly()
}
// DeleteNodeLogs 删除某个节点上的日志
func (this *NodeLogDAO) DeleteNodeLogs(tx *dbs.Tx, role nodeconfigs.NodeRole, nodeId int64) error {
_, err := this.Query(tx).
Attr("nodeId", nodeId).
Attr("role", role).
Delete()
return err
}

View File

@@ -52,16 +52,23 @@ func (this *NSNodeDAO) EnableNSNode(tx *dbs.Tx, id int64) error {
}
// DisableNSNode 禁用条目
func (this *NSNodeDAO) DisableNSNode(tx *dbs.Tx, id int64) error {
func (this *NSNodeDAO) DisableNSNode(tx *dbs.Tx, nodeId int64) error {
_, err := this.Query(tx).
Pk(id).
Pk(nodeId).
Set("state", NSNodeStateDisabled).
Update()
if err != nil {
return err
}
return this.NotifyUpdate(tx, id)
err = this.NotifyUpdate(tx, nodeId)
if err != nil {
return err
}
// 删除运行日志
return SharedNodeLogDAO.DeleteNodeLogs(tx, nodeconfigs.NodeRoleDNS, nodeId)
}
// FindEnabledNSNode 查找启用中的条目

View File

@@ -101,7 +101,8 @@ func (this *OriginDAO) CreateOrigin(tx *dbs.Tx,
maxIdleConns int32,
certRef *sslconfigs.SSLCertRef,
domains []string,
host string) (originId int64, err error) {
host string,
followPort bool) (originId int64, err error) {
var op = NewOriginOperator()
op.AdminId = adminId
op.UserId = userId
@@ -167,6 +168,7 @@ func (this *OriginDAO) CreateOrigin(tx *dbs.Tx,
}
op.Host = host
op.FollowPort = followPort
op.State = OriginStateEnabled
err = this.Save(tx, op)
@@ -191,7 +193,8 @@ func (this *OriginDAO) UpdateOrigin(tx *dbs.Tx,
maxIdleConns int32,
certRef *sslconfigs.SSLCertRef,
domains []string,
host string) error {
host string,
followPort bool) error {
if originId <= 0 {
return errors.New("invalid originId")
}
@@ -262,6 +265,7 @@ func (this *OriginDAO) UpdateOrigin(tx *dbs.Tx,
}
op.Host = host
op.FollowPort = followPort
err := this.Save(tx, op)
if err != nil {
@@ -304,10 +308,11 @@ func (this *OriginDAO) ComposeOriginConfig(tx *dbs.Tx, originId int64, cacheMap
RequestURI: origin.HttpRequestURI,
RequestHost: origin.Host,
Domains: origin.DecodeDomains(),
FollowPort: origin.FollowPort,
}
if IsNotNull(origin.Addr) {
addr := &serverconfigs.NetworkAddressConfig{}
var addr = &serverconfigs.NetworkAddressConfig{}
err = json.Unmarshal(origin.Addr, addr)
if err != nil {
return nil, err
@@ -316,7 +321,7 @@ func (this *OriginDAO) ComposeOriginConfig(tx *dbs.Tx, originId int64, cacheMap
}
if IsNotNull(origin.ConnTimeout) {
connTimeout := &shared.TimeDuration{}
var connTimeout = &shared.TimeDuration{}
err = json.Unmarshal(origin.ConnTimeout, &connTimeout)
if err != nil {
return nil, err
@@ -325,7 +330,7 @@ func (this *OriginDAO) ComposeOriginConfig(tx *dbs.Tx, originId int64, cacheMap
}
if IsNotNull(origin.ReadTimeout) {
readTimeout := &shared.TimeDuration{}
var readTimeout = &shared.TimeDuration{}
err = json.Unmarshal(origin.ReadTimeout, &readTimeout)
if err != nil {
return nil, err
@@ -334,7 +339,7 @@ func (this *OriginDAO) ComposeOriginConfig(tx *dbs.Tx, originId int64, cacheMap
}
if IsNotNull(origin.IdleTimeout) {
idleTimeout := &shared.TimeDuration{}
var idleTimeout = &shared.TimeDuration{}
err = json.Unmarshal(origin.IdleTimeout, &idleTimeout)
if err != nil {
return nil, err
@@ -363,7 +368,7 @@ func (this *OriginDAO) ComposeOriginConfig(tx *dbs.Tx, originId int64, cacheMap
}
if IsNotNull(origin.HttpResponseHeader) {
ref := &shared.HTTPHeaderPolicyRef{}
var ref = &shared.HTTPHeaderPolicyRef{}
err = json.Unmarshal(origin.HttpResponseHeader, ref)
if err != nil {
return nil, err
@@ -382,7 +387,7 @@ func (this *OriginDAO) ComposeOriginConfig(tx *dbs.Tx, originId int64, cacheMap
}
if IsNotNull(origin.HealthCheck) {
healthCheck := &serverconfigs.HealthCheckConfig{}
var healthCheck = &serverconfigs.HealthCheckConfig{}
err = json.Unmarshal(origin.HealthCheck, healthCheck)
if err != nil {
return nil, err
@@ -391,7 +396,7 @@ func (this *OriginDAO) ComposeOriginConfig(tx *dbs.Tx, originId int64, cacheMap
}
if IsNotNull(origin.Cert) {
ref := &sslconfigs.SSLCertRef{}
var ref = &sslconfigs.SSLCertRef{}
err = json.Unmarshal(origin.Cert, ref)
if err != nil {
return nil, err
@@ -417,6 +422,19 @@ func (this *OriginDAO) ComposeOriginConfig(tx *dbs.Tx, originId int64, cacheMap
return config, nil
}
// CheckUserOrigin 检查源站权限
func (this *OriginDAO) CheckUserOrigin(tx *dbs.Tx, userId int64, originId int64) error {
reverseProxyId, err := SharedReverseProxyDAO.FindReverseProxyContainsOriginId(tx, originId)
if err != nil {
return err
}
if reverseProxyId == 0 {
// 这里我们不允许源站没有被使用
return ErrNotFound
}
return SharedReverseProxyDAO.CheckUserReverseProxy(tx, userId, reverseProxyId)
}
// NotifyUpdate 通知更新
func (this *OriginDAO) NotifyUpdate(tx *dbs.Tx, originId int64) error {
reverseProxyId, err := SharedReverseProxyDAO.FindReverseProxyContainsOriginId(tx, originId)

View File

@@ -29,6 +29,7 @@ type Origin struct {
Ftp dbs.JSON `field:"ftp"` // FTP相关设置
CreatedAt uint64 `field:"createdAt"` // 创建时间
Domains dbs.JSON `field:"domains"` // 所属域名
FollowPort bool `field:"followPort"` // 端口跟随
State uint8 `field:"state"` // 状态
}
@@ -58,6 +59,7 @@ type OriginOperator struct {
Ftp interface{} // FTP相关设置
CreatedAt interface{} // 创建时间
Domains interface{} // 所属域名
FollowPort interface{} // 端口跟随
State interface{} // 状态
}

View File

@@ -217,7 +217,7 @@ func (this *PlanDAO) ListEnabledPlans(tx *dbs.Tx, offset int64, size int64) (res
Limit(size).
Slice(&result).
Desc("order").
DescPk().
AscPk().
FindAll()
return
}

View File

@@ -50,12 +50,17 @@ func (this *ReportNodeDAO) EnableReportNode(tx *dbs.Tx, id int64) error {
}
// DisableReportNode 禁用条目
func (this *ReportNodeDAO) DisableReportNode(tx *dbs.Tx, id int64) error {
func (this *ReportNodeDAO) DisableReportNode(tx *dbs.Tx, nodeId int64) error {
_, err := this.Query(tx).
Pk(id).
Pk(nodeId).
Set("state", ReportNodeStateDisabled).
Update()
return err
if err != nil {
return err
}
// 删除运行日志
return SharedNodeLogDAO.DeleteNodeLogs(tx, nodeconfigs.NodeRoleReport, nodeId)
}
// FindEnabledReportNode 查找启用中的条目

View File

@@ -99,17 +99,18 @@ func (this *ReverseProxyDAO) ComposeReverseProxyConfig(tx *dbs.Tx, reverseProxyI
return nil, nil
}
config := &serverconfigs.ReverseProxyConfig{}
var config = &serverconfigs.ReverseProxyConfig{}
config.Id = int64(reverseProxy.Id)
config.IsOn = reverseProxy.IsOn
config.RequestHostType = types.Int8(reverseProxy.RequestHostType)
config.RequestHost = reverseProxy.RequestHost
config.RequestHostExcludingPort = reverseProxy.RequestHostExcludingPort
config.RequestURI = reverseProxy.RequestURI
config.StripPrefix = reverseProxy.StripPrefix
config.AutoFlush = reverseProxy.AutoFlush == 1
config.FollowRedirects = reverseProxy.FollowRedirects == 1
schedulingConfig := &serverconfigs.SchedulingConfig{}
var schedulingConfig = &serverconfigs.SchedulingConfig{}
if IsNotNull(reverseProxy.Scheduling) {
err = json.Unmarshal(reverseProxy.Scheduling, schedulingConfig)
if err != nil {
@@ -118,7 +119,7 @@ func (this *ReverseProxyDAO) ComposeReverseProxyConfig(tx *dbs.Tx, reverseProxyI
config.Scheduling = schedulingConfig
}
if IsNotNull(reverseProxy.PrimaryOrigins) {
originRefs := []*serverconfigs.OriginRef{}
var originRefs = []*serverconfigs.OriginRef{}
err = json.Unmarshal(reverseProxy.PrimaryOrigins, &originRefs)
if err != nil {
return nil, err
@@ -135,13 +136,13 @@ func (this *ReverseProxyDAO) ComposeReverseProxyConfig(tx *dbs.Tx, reverseProxyI
}
if IsNotNull(reverseProxy.BackupOrigins) {
originRefs := []*serverconfigs.OriginRef{}
var originRefs = []*serverconfigs.OriginRef{}
err = json.Unmarshal(reverseProxy.BackupOrigins, &originRefs)
if err != nil {
return nil, err
}
for _, originConfig := range originRefs {
originConfig, err := SharedOriginDAO.ComposeOriginConfig(tx, originConfig.OriginId, cacheMap)
for _, ref := range originRefs {
originConfig, err := SharedOriginDAO.ComposeOriginConfig(tx, ref.OriginId, cacheMap)
if err != nil {
return nil, err
}
@@ -153,7 +154,7 @@ func (this *ReverseProxyDAO) ComposeReverseProxyConfig(tx *dbs.Tx, reverseProxyI
// add headers
if IsNotNull(reverseProxy.AddHeaders) {
addHeaders := []string{}
var addHeaders = []string{}
err = json.Unmarshal(reverseProxy.AddHeaders, &addHeaders)
if err != nil {
return nil, err
@@ -166,7 +167,7 @@ func (this *ReverseProxyDAO) ComposeReverseProxyConfig(tx *dbs.Tx, reverseProxyI
config.MaxIdleConns = int(reverseProxy.MaxIdleConns)
if IsNotNull(reverseProxy.ConnTimeout) {
connTimeout := &shared.TimeDuration{}
var connTimeout = &shared.TimeDuration{}
err = json.Unmarshal(reverseProxy.ConnTimeout, &connTimeout)
if err != nil {
return nil, err
@@ -175,7 +176,7 @@ func (this *ReverseProxyDAO) ComposeReverseProxyConfig(tx *dbs.Tx, reverseProxyI
}
if IsNotNull(reverseProxy.ReadTimeout) {
readTimeout := &shared.TimeDuration{}
var readTimeout = &shared.TimeDuration{}
err = json.Unmarshal(reverseProxy.ReadTimeout, &readTimeout)
if err != nil {
return nil, err
@@ -184,7 +185,7 @@ func (this *ReverseProxyDAO) ComposeReverseProxyConfig(tx *dbs.Tx, reverseProxyI
}
if IsNotNull(reverseProxy.IdleTimeout) {
idleTimeout := &shared.TimeDuration{}
var idleTimeout = &shared.TimeDuration{}
err = json.Unmarshal(reverseProxy.IdleTimeout, &idleTimeout)
if err != nil {
return nil, err
@@ -304,6 +305,7 @@ func (this *ReverseProxyDAO) UpdateReverseProxy(tx *dbs.Tx,
reverseProxyId int64,
requestHostType int8,
requestHost string,
requestHostExcludingPort bool,
requestURI string,
stripPrefix string,
autoFlush bool,
@@ -328,6 +330,7 @@ func (this *ReverseProxyDAO) UpdateReverseProxy(tx *dbs.Tx,
op.RequestHostType = requestHostType
op.RequestHost = requestHost
op.RequestHostExcludingPort = requestHostExcludingPort
op.RequestURI = requestURI
op.StripPrefix = stripPrefix
op.AutoFlush = autoFlush

View File

@@ -4,55 +4,57 @@ import "github.com/iwind/TeaGo/dbs"
// ReverseProxy 反向代理配置
type ReverseProxy struct {
Id uint32 `field:"id"` // ID
AdminId uint32 `field:"adminId"` // 管理员ID
UserId uint32 `field:"userId"` // 用户ID
TemplateId uint32 `field:"templateId"` // 模版ID
IsOn bool `field:"isOn"` // 是否启用
Scheduling dbs.JSON `field:"scheduling"` // 调度算法
PrimaryOrigins dbs.JSON `field:"primaryOrigins"` // 主要源站
BackupOrigins dbs.JSON `field:"backupOrigins"` // 备用源站
StripPrefix string `field:"stripPrefix"` // 去除URL前缀
RequestHostType uint8 `field:"requestHostType"` // 请求Host类型
RequestHost string `field:"requestHost"` // 请求Host
RequestURI string `field:"requestURI"` // 请求URI
AutoFlush uint8 `field:"autoFlush"` // 是否自动刷新缓冲区
AddHeaders dbs.JSON `field:"addHeaders"` // 自动添加的Header列表
State uint8 `field:"state"` // 状态
CreatedAt uint64 `field:"createdAt"` // 创建时间
ConnTimeout dbs.JSON `field:"connTimeout"` // 连接超时时间
ReadTimeout dbs.JSON `field:"readTimeout"` // 读取超时时间
IdleTimeout dbs.JSON `field:"idleTimeout"` // 空闲超时时间
MaxConns uint32 `field:"maxConns"` // 最大并发连接数
MaxIdleConns uint32 `field:"maxIdleConns"` // 最大空闲连接数
ProxyProtocol dbs.JSON `field:"proxyProtocol"` // Proxy Protocol配置
FollowRedirects uint8 `field:"followRedirects"` // 回源跟随
Id uint32 `field:"id"` // ID
AdminId uint32 `field:"adminId"` // 管理员ID
UserId uint32 `field:"userId"` // 用户ID
TemplateId uint32 `field:"templateId"` // 模版ID
IsOn bool `field:"isOn"` // 是否启用
Scheduling dbs.JSON `field:"scheduling"` // 调度算法
PrimaryOrigins dbs.JSON `field:"primaryOrigins"` // 主要源站
BackupOrigins dbs.JSON `field:"backupOrigins"` // 备用源站
StripPrefix string `field:"stripPrefix"` // 去除URL前缀
RequestHostType uint8 `field:"requestHostType"` // 请求Host类型
RequestHost string `field:"requestHost"` // 请求Host
RequestHostExcludingPort bool `field:"requestHostExcludingPort"` // 移除请求Host中的域名
RequestURI string `field:"requestURI"` // 请求URI
AutoFlush uint8 `field:"autoFlush"` // 是否自动刷新缓冲区
AddHeaders dbs.JSON `field:"addHeaders"` // 自动添加的Header列表
State uint8 `field:"state"` // 状态
CreatedAt uint64 `field:"createdAt"` // 创建时间
ConnTimeout dbs.JSON `field:"connTimeout"` // 连接超时时间
ReadTimeout dbs.JSON `field:"readTimeout"` // 读取超时时间
IdleTimeout dbs.JSON `field:"idleTimeout"` // 空闲超时时间
MaxConns uint32 `field:"maxConns"` // 最大并发连接数
MaxIdleConns uint32 `field:"maxIdleConns"` // 最大空闲连接数
ProxyProtocol dbs.JSON `field:"proxyProtocol"` // Proxy Protocol配置
FollowRedirects uint8 `field:"followRedirects"` // 回源跟随
}
type ReverseProxyOperator struct {
Id interface{} // ID
AdminId interface{} // 管理员ID
UserId interface{} // 用户ID
TemplateId interface{} // 模版ID
IsOn interface{} // 是否启用
Scheduling interface{} // 调度算法
PrimaryOrigins interface{} // 主要源站
BackupOrigins interface{} // 备用源站
StripPrefix interface{} // 去除URL前缀
RequestHostType interface{} // 请求Host类型
RequestHost interface{} // 请求Host
RequestURI interface{} // 请求URI
AutoFlush interface{} // 是否自动刷新缓冲区
AddHeaders interface{} // 自动添加的Header列表
State interface{} // 状态
CreatedAt interface{} // 创建时间
ConnTimeout interface{} // 连接超时时间
ReadTimeout interface{} // 读取超时时间
IdleTimeout interface{} // 空闲超时时间
MaxConns interface{} // 最大并发连接数
MaxIdleConns interface{} // 最大空闲连接数
ProxyProtocol interface{} // Proxy Protocol配置
FollowRedirects interface{} // 回源跟随
Id interface{} // ID
AdminId interface{} // 管理员ID
UserId interface{} // 用户ID
TemplateId interface{} // 模版ID
IsOn interface{} // 是否启用
Scheduling interface{} // 调度算法
PrimaryOrigins interface{} // 主要源站
BackupOrigins interface{} // 备用源站
StripPrefix interface{} // 去除URL前缀
RequestHostType interface{} // 请求Host类型
RequestHost interface{} // 请求Host
RequestHostExcludingPort interface{} // 移除请求Host中的域名
RequestURI interface{} // 请求URI
AutoFlush interface{} // 是否自动刷新缓冲区
AddHeaders interface{} // 自动添加的Header列表
State interface{} // 状态
CreatedAt interface{} // 创建时间
ConnTimeout interface{} // 连接超时时间
ReadTimeout interface{} // 读取超时时间
IdleTimeout interface{} // 空闲超时时间
MaxConns interface{} // 最大并发连接数
MaxIdleConns interface{} // 最大空闲连接数
ProxyProtocol interface{} // Proxy Protocol配置
FollowRedirects interface{} // 回源跟随
}
func NewReverseProxyOperator() *ReverseProxyOperator {

View File

@@ -0,0 +1,215 @@
package models
import (
"github.com/TeaOSLab/EdgeAPI/internal/errors"
"github.com/TeaOSLab/EdgeAPI/internal/goman"
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
_ "github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/dbs"
"github.com/iwind/TeaGo/maps"
"github.com/iwind/TeaGo/rands"
"github.com/iwind/TeaGo/types"
timeutil "github.com/iwind/TeaGo/utils/time"
"math"
"sync"
"time"
)
type ServerBandwidthStatDAO dbs.DAO
const (
ServerBandwidthStatTablePartials = 20 // 分表数量
)
func init() {
dbs.OnReadyDone(func() {
// 清理数据任务
var ticker = time.NewTicker(time.Duration(rands.Int(24, 48)) * time.Hour)
goman.New(func() {
for range ticker.C {
err := SharedServerBandwidthStatDAO.Clean(nil)
if err != nil {
remotelogs.Error("SharedServerBandwidthStatDAO", "clean expired data failed: "+err.Error())
}
}
})
})
}
func NewServerBandwidthStatDAO() *ServerBandwidthStatDAO {
return dbs.NewDAO(&ServerBandwidthStatDAO{
DAOObject: dbs.DAOObject{
DB: Tea.Env,
Table: "edgeServerBandwidthStats",
Model: new(ServerBandwidthStat),
PkName: "id",
},
}).(*ServerBandwidthStatDAO)
}
var SharedServerBandwidthStatDAO *ServerBandwidthStatDAO
func init() {
dbs.OnReady(func() {
SharedServerBandwidthStatDAO = NewServerBandwidthStatDAO()
})
}
// UpdateServerBandwidth 写入数据
func (this *ServerBandwidthStatDAO) UpdateServerBandwidth(tx *dbs.Tx, userId int64, serverId int64, day string, timeAt string, bytes int64) error {
if serverId <= 0 {
return errors.New("invalid server id '" + types.String(serverId) + "'")
}
return this.Query(tx).
Table(this.partialTable(serverId)).
Param("bytes", bytes).
InsertOrUpdateQuickly(maps.Map{
"userId": userId,
"serverId": serverId,
"day": day,
"timeAt": timeAt,
"bytes": bytes,
}, maps.Map{
"bytes": dbs.SQL("bytes+:bytes"),
})
}
// FindMinutelyPeekBandwidthBytes 获取某分钟的带宽峰值
// day YYYYMMDD
// minute HHII
func (this *ServerBandwidthStatDAO) FindMinutelyPeekBandwidthBytes(tx *dbs.Tx, serverId int64, day string, minute string) (int64, error) {
return this.Query(tx).
Table(this.partialTable(serverId)).
Result("bytes").
Attr("serverId", serverId).
Attr("day", day).
Attr("timeAt", minute).
FindInt64Col(0)
}
// FindDailyPeekBandwidthBytes 获取某天的带宽峰值
// day YYYYMMDD
func (this *ServerBandwidthStatDAO) FindDailyPeekBandwidthBytes(tx *dbs.Tx, serverId int64, day string) (int64, error) {
return this.Query(tx).
Table(this.partialTable(serverId)).
Attr("day", day).
Result("MAX(bytes)").
FindInt64Col(0)
}
// FindMonthlyPeekBandwidthBytes 获取某月的带宽峰值
// month YYYYMM
func (this *ServerBandwidthStatDAO) FindMonthlyPeekBandwidthBytes(tx *dbs.Tx, serverId int64, month string) (int64, error) {
return this.Query(tx).
Table(this.partialTable(serverId)).
Between("day", month+"01", month+"31").
Result("MAX(bytes)").
FindInt64Col(0)
}
// FindServerStats 查找某个时间段的带宽统计
// 参数:
// - day YYYYMMDD
// - timeAt HHII
func (this *ServerBandwidthStatDAO) FindServerStats(tx *dbs.Tx, serverId int64, day string, timeFrom string, timeTo string) (result []*ServerBandwidthStat, err error) {
_, err = this.Query(tx).
Table(this.partialTable(serverId)).
Attr("serverId", serverId).
Attr("day", day).
Between("timeAt", timeFrom, timeTo).
Slice(&result).
FindAll()
return
}
// FindMonthlyPercentile 获取某月内百分位
func (this *ServerBandwidthStatDAO) FindMonthlyPercentile(tx *dbs.Tx, serverId int64, month string, percentile int) (result int64, err error) {
if percentile <= 0 {
percentile = 95
}
// 如果是100%以上,则快速返回
if percentile >= 100 {
result, err = this.Query(tx).
Table(this.partialTable(serverId)).
Result("bytes").
Attr("serverId", serverId).
Between("day", month+"01", month+"31").
Desc("bytes").
Limit(1).
FindInt64Col(0)
return
}
// 总数量
total, err := this.Query(tx).
Table(this.partialTable(serverId)).
Attr("serverId", serverId).
Between("day", month+"01", month+"31").
Count()
if err != nil {
return 0, err
}
if total == 0 {
return 0, nil
}
var offset int64
if total > 1 {
offset = int64(math.Ceil(float64(total) * float64(100-percentile) / 100))
}
// 查询 nth 位置
result, err = this.Query(tx).
Table(this.partialTable(serverId)).
Result("bytes").
Attr("serverId", serverId).
Between("day", month+"01", month+"31").
Desc("bytes").
Offset(offset).
Limit(1).
FindInt64Col(0)
return
}
// Clean 清理过期数据
func (this *ServerBandwidthStatDAO) Clean(tx *dbs.Tx) error {
var day = timeutil.Format("Ymd", time.Now().AddDate(0, 0, -62)) // 保留大约2个月的数据
return this.runBatch(func(table string, locker *sync.Mutex) error {
_, err := this.Query(tx).
Table(table).
Lt("day", day).
Delete()
return err
})
}
// 批量执行
func (this *ServerBandwidthStatDAO) runBatch(f func(table string, locker *sync.Mutex) error) error {
var locker = &sync.Mutex{}
var wg = sync.WaitGroup{}
wg.Add(ServerBandwidthStatTablePartials)
var resultErr error
for i := 0; i < ServerBandwidthStatTablePartials; i++ {
var table = this.partialTable(int64(i))
go func(table string) {
defer wg.Done()
err := f(table, locker)
if err != nil {
resultErr = err
}
}(table)
}
wg.Wait()
return resultErr
}
// 获取分区表
func (this *ServerBandwidthStatDAO) partialTable(serverId int64) string {
return this.Table + "_" + types.String(serverId%int64(ServerBandwidthStatTablePartials))
}

View File

@@ -0,0 +1,55 @@
package models_test
import (
"fmt"
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
_ "github.com/go-sql-driver/mysql"
_ "github.com/iwind/TeaGo/bootstrap"
"github.com/iwind/TeaGo/dbs"
"github.com/iwind/TeaGo/rands"
timeutil "github.com/iwind/TeaGo/utils/time"
"testing"
"time"
)
func TestServerBandwidthStatDAO_UpdateServerBandwidth(t *testing.T) {
var dao = models.NewServerBandwidthStatDAO()
var tx *dbs.Tx
err := dao.UpdateServerBandwidth(tx, 1, 1, timeutil.Format("Ymd"), timeutil.Format("Hi"), 1024)
if err != nil {
t.Fatal(err)
}
t.Log("ok")
}
func TestSeverBandwidthStatDAO_InsertManyStats(t *testing.T) {
var dao = models.NewServerBandwidthStatDAO()
var tx *dbs.Tx
var count = 1 // 测试时将此值设为一个比较大的数字
for i := 0; i < count; i++ {
var day = timeutil.Format("Ymd", time.Now().AddDate(0, 0, -rands.Int(0, 200)))
var minute = fmt.Sprintf("%02d%02d", rands.Int(0, 23), rands.Int(0, 59))
err := dao.UpdateServerBandwidth(tx, 1, 1, day, minute, 1024)
if err != nil {
t.Fatal(err)
}
}
t.Log("ok")
}
func TestServerBandwidthStatDAO_FindMonthlyPercentile(t *testing.T) {
var dao = models.NewServerBandwidthStatDAO()
var tx *dbs.Tx
t.Log(dao.FindMonthlyPercentile(tx, 23, timeutil.Format("Ym"), 95))
}
func TestServerBandwidthStatDAO_Clean(t *testing.T) {
var dao = models.NewServerBandwidthStatDAO()
var tx *dbs.Tx
var before = time.Now()
err := dao.Clean(tx)
if err != nil {
t.Fatal(err)
}
t.Log("ok", time.Since(before).Seconds()*1000, "ms")
}

View File

@@ -0,0 +1,24 @@
package models
// ServerBandwidthStat 服务峰值带宽统计
type ServerBandwidthStat struct {
Id uint64 `field:"id"` // ID
UserId uint64 `field:"userId"` // 用户ID
ServerId uint64 `field:"serverId"` // 服务ID
Day string `field:"day"` // 日期YYYYMMDD
TimeAt string `field:"timeAt"` // 时间点HHMM
Bytes uint64 `field:"bytes"` // 带宽字节
}
type ServerBandwidthStatOperator struct {
Id interface{} // ID
UserId interface{} // 用户ID
ServerId interface{} // 服务ID
Day interface{} // 日期YYYYMMDD
TimeAt interface{} // 时间点HHMM
Bytes interface{} // 带宽字节
}
func NewServerBandwidthStatOperator() *ServerBandwidthStatOperator {
return &ServerBandwidthStatOperator{}
}

View File

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

View File

@@ -12,7 +12,6 @@ import (
"github.com/iwind/TeaGo/maps"
"github.com/iwind/TeaGo/rands"
timeutil "github.com/iwind/TeaGo/utils/time"
"math"
"regexp"
"strings"
"time"
@@ -405,45 +404,6 @@ func (this *ServerDailyStatDAO) SumMonthlyBytes(tx *dbs.Tx, serverId int64, mont
FindInt64Col(0)
}
// FindMonthlyPercentile 获取某月内百分位
func (this *ServerDailyStatDAO) FindMonthlyPercentile(tx *dbs.Tx, serverId int64, month string, percentile int) (result int64, err error) {
if percentile <= 0 {
percentile = 95
}
if percentile > 100 {
percentile = 100
}
total, err := this.Query(tx).
Attr("serverId", serverId).
Between("day", month+"01", month+"31").
Count()
if err != nil {
return 0, err
}
if total == 0 {
return 0, nil
}
var offset int64
if total > 1 {
offset = int64(math.Ceil(float64(total) * float64(100-percentile) / 100))
}
result, err = this.Query(tx).
Result("bytes").
Attr("serverId", serverId).
Between("day", month+"01", month+"31").
Desc("bytes").
Offset(offset).
Limit(1).
FindInt64Col(0)
// 因为是5分钟统计所以需要除以300
result = result / 300
return
}
// FindDailyStats 按天统计
func (this *ServerDailyStatDAO) FindDailyStats(tx *dbs.Tx, serverId int64, dayFrom string, dayTo string) (result []*ServerDailyStat, err error) {
ones, err := this.Query(tx).

View File

@@ -83,13 +83,3 @@ func TestServerDailyStatDAO_FindDistinctPlanServerIdsBetweenDay(t *testing.T) {
}
t.Log(serverIds)
}
func TestServerDailyStatDAO_FindMonthlyPercentile(t *testing.T) {
var tx *dbs.Tx
var dao = NewServerDailyStatDAO()
result, err := dao.FindMonthlyPercentile(tx, 23, timeutil.Format("Ym"), 95)
if err != nil {
t.Fatal(err)
}
t.Log("result:", result)
}

View File

@@ -338,12 +338,31 @@ func (this *ServerDAO) UpdateServerBasic(tx *dbs.Tx, serverId int64, name string
return nil
}
// UpdateServerGroupIds 修改服务所在分组
func (this *ServerDAO) UpdateServerGroupIds(tx *dbs.Tx, serverId int64, groupIds []int64) error {
if groupIds == nil {
groupIds = []int64{}
}
groupIdsJSON, err := json.Marshal(groupIds)
if err != nil {
return err
}
err = this.Query(tx).
Pk(serverId).
Set("groupIds", groupIdsJSON).
UpdateQuickly()
if err != nil {
return err
}
return this.NotifyUpdate(tx, serverId)
}
// UpdateUserServerBasic 设置用户相关的基本信息
func (this *ServerDAO) UpdateUserServerBasic(tx *dbs.Tx, serverId int64, name string) error {
if serverId <= 0 {
return errors.New("serverId should not be smaller than 0")
}
op := NewServerOperator()
var op = NewServerOperator()
op.Id = serverId
op.Name = name
@@ -752,8 +771,9 @@ func (this *ServerDAO) CountAllEnabledServersMatch(tx *dbs.Tx, groupId int64, ke
}
if len(keyword) > 0 {
if regexp.MustCompile(`^\d+$`).MatchString(keyword) {
query.Where("(name LIKE :keyword OR serverNames LIKE :keyword OR JSON_CONTAINS(http, :portRange, '$.listen') OR JSON_CONTAINS(https, :portRange, '$.listen') OR JSON_CONTAINS(tcp, :portRange, '$.listen') OR JSON_CONTAINS(tls, :portRange, '$.listen'))").
query.Where("(id=:serverId OR name LIKE :keyword OR serverNames LIKE :keyword OR JSON_CONTAINS(http, :portRange, '$.listen') OR JSON_CONTAINS(https, :portRange, '$.listen') OR JSON_CONTAINS(tcp, :portRange, '$.listen') OR JSON_CONTAINS(tls, :portRange, '$.listen'))").
Param("portRange", maps.Map{"portRange": keyword}.AsJSON()).
Param("serverId", keyword).
Param("keyword", dbutils.QuoteLike(keyword))
} else {
query.Where("(name LIKE :keyword OR serverNames LIKE :keyword)").
@@ -806,8 +826,9 @@ func (this *ServerDAO) ListEnabledServersMatch(tx *dbs.Tx, offset int64, size in
}
if len(keyword) > 0 {
if regexp.MustCompile(`^\d+$`).MatchString(keyword) {
query.Where("(name LIKE :keyword OR serverNames LIKE :keyword OR JSON_CONTAINS(http, :portRange, '$.listen') OR JSON_CONTAINS(https, :portRange, '$.listen') OR JSON_CONTAINS(tcp, :portRange, '$.listen') OR JSON_CONTAINS(tls, :portRange, '$.listen'))").
query.Where("(id=:serverId OR name LIKE :keyword OR serverNames LIKE :keyword OR JSON_CONTAINS(http, :portRange, '$.listen') OR JSON_CONTAINS(https, :portRange, '$.listen') OR JSON_CONTAINS(tcp, :portRange, '$.listen') OR JSON_CONTAINS(tls, :portRange, '$.listen'))").
Param("portRange", string(maps.Map{"portRange": keyword}.AsJSON())).
Param("serverId", keyword).
Param("keyword", dbutils.QuoteLike(keyword))
} else {
query.Where("(name LIKE :keyword OR serverNames LIKE :keyword)").
@@ -1020,9 +1041,10 @@ func (this *ServerDAO) ComposeServerConfig(tx *dbs.Tx, server *Server, cacheMap
return cache.(*serverconfigs.ServerConfig), nil
}
config := &serverconfigs.ServerConfig{}
var config = &serverconfigs.ServerConfig{}
config.Id = int64(server.Id)
config.ClusterId = int64(server.ClusterId)
config.UserId = int64(server.UserId)
config.Type = server.Type
config.IsOn = server.IsOn
config.Name = server.Name
@@ -1044,7 +1066,7 @@ func (this *ServerDAO) ComposeServerConfig(tx *dbs.Tx, server *Server, cacheMap
// ServerNames
if IsNotNull(server.ServerNames) {
serverNames := []*serverconfigs.ServerNameConfig{}
var serverNames = []*serverconfigs.ServerNameConfig{}
err := json.Unmarshal(server.ServerNames, &serverNames)
if err != nil {
return nil, err
@@ -1060,20 +1082,29 @@ func (this *ServerDAO) ComposeServerConfig(tx *dbs.Tx, server *Server, cacheMap
return nil, err
}
if clusterDNS != nil && clusterDNS.DnsDomainId > 0 {
clusterDNSConfig, err := clusterDNS.DecodeDNSConfig()
if err != nil {
return nil, err
}
domain, err := dns.SharedDNSDomainDAO.FindEnabledDNSDomain(tx, int64(clusterDNS.DnsDomainId), cacheMap)
if err != nil {
return nil, err
}
if domain != nil {
cname := server.DnsName + "." + domain.Name
config.AliasServerNames = append(config.AliasServerNames, cname)
var cname = server.DnsName + "." + domain.Name
config.CNameDomain = cname
if clusterDNSConfig.CNameAsDomain {
config.CNameAsDomain = true
config.AliasServerNames = append(config.AliasServerNames, cname)
}
}
}
}
// HTTP
if IsNotNull(server.Http) {
httpConfig := &serverconfigs.HTTPProtocolConfig{}
var httpConfig = &serverconfigs.HTTPProtocolConfig{}
err := json.Unmarshal(server.Http, httpConfig)
if err != nil {
return nil, err
@@ -1083,7 +1114,7 @@ func (this *ServerDAO) ComposeServerConfig(tx *dbs.Tx, server *Server, cacheMap
// HTTPS
if IsNotNull(server.Https) {
httpsConfig := &serverconfigs.HTTPSProtocolConfig{}
var httpsConfig = &serverconfigs.HTTPSProtocolConfig{}
err := json.Unmarshal(server.Https, httpsConfig)
if err != nil {
return nil, err
@@ -1105,7 +1136,7 @@ func (this *ServerDAO) ComposeServerConfig(tx *dbs.Tx, server *Server, cacheMap
// TCP
if IsNotNull(server.Tcp) {
tcpConfig := &serverconfigs.TCPProtocolConfig{}
var tcpConfig = &serverconfigs.TCPProtocolConfig{}
err := json.Unmarshal(server.Tcp, tcpConfig)
if err != nil {
return nil, err
@@ -1115,7 +1146,7 @@ func (this *ServerDAO) ComposeServerConfig(tx *dbs.Tx, server *Server, cacheMap
// TLS
if IsNotNull(server.Tls) {
tlsConfig := &serverconfigs.TLSProtocolConfig{}
var tlsConfig = &serverconfigs.TLSProtocolConfig{}
err := json.Unmarshal(server.Tls, tlsConfig)
if err != nil {
return nil, err
@@ -1137,7 +1168,7 @@ func (this *ServerDAO) ComposeServerConfig(tx *dbs.Tx, server *Server, cacheMap
// Unix
if IsNotNull(server.Unix) {
unixConfig := &serverconfigs.UnixProtocolConfig{}
var unixConfig = &serverconfigs.UnixProtocolConfig{}
err := json.Unmarshal(server.Unix, unixConfig)
if err != nil {
return nil, err
@@ -1147,7 +1178,7 @@ func (this *ServerDAO) ComposeServerConfig(tx *dbs.Tx, server *Server, cacheMap
// UDP
if IsNotNull(server.Udp) {
udpConfig := &serverconfigs.UDPProtocolConfig{}
var udpConfig = &serverconfigs.UDPProtocolConfig{}
err := json.Unmarshal(server.Udp, udpConfig)
if err != nil {
return nil, err
@@ -1168,7 +1199,7 @@ func (this *ServerDAO) ComposeServerConfig(tx *dbs.Tx, server *Server, cacheMap
// ReverseProxy
if IsNotNull(server.ReverseProxy) {
reverseProxyRef := &serverconfigs.ReverseProxyRef{}
var reverseProxyRef = &serverconfigs.ReverseProxyRef{}
err := json.Unmarshal(server.ReverseProxy, reverseProxyRef)
if err != nil {
return nil, err
@@ -1185,7 +1216,7 @@ func (this *ServerDAO) ComposeServerConfig(tx *dbs.Tx, server *Server, cacheMap
}
// WAF策略
clusterId := int64(server.ClusterId)
var clusterId = int64(server.ClusterId)
httpFirewallPolicyId, err := SharedNodeClusterDAO.FindClusterHTTPFirewallPolicyId(tx, clusterId, cacheMap)
if err != nil {
return nil, err

View File

@@ -410,6 +410,17 @@ func (this *ServerGroupDAO) CheckUserGroup(tx *dbs.Tx, userId int64, groupId int
return nil
}
// ExistsGroup 检查分组ID是否存在
func (this *ServerGroupDAO) ExistsGroup(tx *dbs.Tx, groupId int64) (bool, error) {
if groupId <= 0 {
return false, nil
}
return this.Query(tx).
Pk(groupId).
State(ServerGroupStateEnabled).
Exist()
}
// NotifyUpdate 通知更新
func (this *ServerGroupDAO) NotifyUpdate(tx *dbs.Tx, groupId int64) error {
serverIds, err := SharedServerDAO.FindAllEnabledServerIdsWithGroupId(tx, groupId)

View File

@@ -0,0 +1,143 @@
package models
import (
"github.com/TeaOSLab/EdgeAPI/internal/goman"
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
_ "github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/dbs"
"github.com/iwind/TeaGo/maps"
"github.com/iwind/TeaGo/rands"
"github.com/iwind/TeaGo/types"
timeutil "github.com/iwind/TeaGo/utils/time"
"sync"
"time"
)
type UserBandwidthStatDAO dbs.DAO
const (
UserBandwidthStatTablePartials = 20
)
func init() {
dbs.OnReadyDone(func() {
// 清理数据任务
var ticker = time.NewTicker(time.Duration(rands.Int(24, 48)) * time.Hour)
goman.New(func() {
for range ticker.C {
err := SharedUserBandwidthStatDAO.Clean(nil)
if err != nil {
remotelogs.Error("SharedUserBandwidthStatDAO", "clean expired data failed: "+err.Error())
}
}
})
})
}
func NewUserBandwidthStatDAO() *UserBandwidthStatDAO {
return dbs.NewDAO(&UserBandwidthStatDAO{
DAOObject: dbs.DAOObject{
DB: Tea.Env,
Table: "edgeUserBandwidthStats",
Model: new(UserBandwidthStat),
PkName: "id",
},
}).(*UserBandwidthStatDAO)
}
var SharedUserBandwidthStatDAO *UserBandwidthStatDAO
func init() {
dbs.OnReady(func() {
SharedUserBandwidthStatDAO = NewUserBandwidthStatDAO()
})
}
// UpdateUserBandwidth 写入数据
func (this *UserBandwidthStatDAO) UpdateUserBandwidth(tx *dbs.Tx, userId int64, day string, timeAt string, bytes int64) error {
if userId <= 0 {
// 如果用户ID不大于0则说明服务不属于任何用户此时不需要处理
return nil
}
return this.Query(tx).
Table(this.partialTable(userId)).
Param("bytes", bytes).
InsertOrUpdateQuickly(maps.Map{
"userId": userId,
"day": day,
"timeAt": timeAt,
"bytes": bytes,
}, maps.Map{
"bytes": dbs.SQL("bytes+:bytes"),
})
}
// FindUserPeekBandwidthInMonth 读取某月带宽峰值
// month YYYYMM
func (this *UserBandwidthStatDAO) FindUserPeekBandwidthInMonth(tx *dbs.Tx, userId int64, month string) (*UserBandwidthStat, error) {
one, err := this.Query(tx).
Table(this.partialTable(userId)).
Attr("userId", userId).
Between("day", month+"01", month+"31").
Desc("bytes").
Find()
if err != nil || one == nil {
return nil, err
}
return one.(*UserBandwidthStat), nil
}
// FindUserPeekBandwidthInDay 读取某日带宽峰值
// day YYYYMMDD
func (this *UserBandwidthStatDAO) FindUserPeekBandwidthInDay(tx *dbs.Tx, userId int64, day string) (*UserBandwidthStat, error) {
one, err := this.Query(tx).
Table(this.partialTable(userId)).
Attr("userId", userId).
Attr("day", day).
Desc("bytes").
Find()
if err != nil || one == nil {
return nil, err
}
return one.(*UserBandwidthStat), nil
}
// Clean 清理过期数据
func (this *UserBandwidthStatDAO) Clean(tx *dbs.Tx) error {
var day = timeutil.Format("Ymd", time.Now().AddDate(0, 0, -62)) // 保留大约2个月的数据
return this.runBatch(func(table string, locker *sync.Mutex) error {
_, err := this.Query(tx).
Table(table).
Lt("day", day).
Delete()
return err
})
}
// 批量执行
func (this *UserBandwidthStatDAO) runBatch(f func(table string, locker *sync.Mutex) error) error {
var locker = &sync.Mutex{}
var wg = sync.WaitGroup{}
wg.Add(UserBandwidthStatTablePartials)
var resultErr error
for i := 0; i < UserBandwidthStatTablePartials; i++ {
var table = this.partialTable(int64(i))
go func(table string) {
defer wg.Done()
err := f(table, locker)
if err != nil {
resultErr = err
}
}(table)
}
wg.Wait()
return resultErr
}
// 获取分区表
func (this *UserBandwidthStatDAO) partialTable(userId int64) string {
return this.Table + "_" + types.String(userId%int64(UserBandwidthStatTablePartials))
}

View File

@@ -0,0 +1,30 @@
package models_test
import (
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
_ "github.com/go-sql-driver/mysql"
_ "github.com/iwind/TeaGo/bootstrap"
"github.com/iwind/TeaGo/dbs"
timeutil "github.com/iwind/TeaGo/utils/time"
"testing"
)
func TestUserBandwidthStatDAO_UpdateServerBandwidth(t *testing.T) {
var dao = models.NewUserBandwidthStatDAO()
var tx *dbs.Tx
err := dao.UpdateUserBandwidth(tx, 1, timeutil.Format("Ymd"), timeutil.Format("Hi"), 1024)
if err != nil {
t.Fatal(err)
}
t.Log("ok")
}
func TestUserBandwidthStatDAO_Clean(t *testing.T) {
var dao = models.NewUserBandwidthStatDAO()
var tx *dbs.Tx
err := dao.Clean(tx)
if err != nil {
t.Fatal(err)
}
t.Log("ok")
}

View File

@@ -0,0 +1,22 @@
package models
// UserBandwidthStat 用户月带宽峰值
type UserBandwidthStat struct {
Id uint64 `field:"id"` // ID
UserId uint64 `field:"userId"` // 用户ID
Day string `field:"day"` // 日期YYYYMMDD
TimeAt string `field:"timeAt"` // 时间点HHII
Bytes uint64 `field:"bytes"` // 带宽
}
type UserBandwidthStatOperator struct {
Id interface{} // ID
UserId interface{} // 用户ID
Day interface{} // 日期YYYYMMDD
TimeAt interface{} // 时间点HHII
Bytes interface{} // 带宽
}
func NewUserBandwidthStatOperator() *UserBandwidthStatOperator {
return &UserBandwidthStatOperator{}
}

View File

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

View File

@@ -236,7 +236,7 @@ func (this *UserBillDAO) GenerateBills(tx *dbs.Tx, month string) error {
// 百分位
var percentile = 95
percentileBytes, err := SharedServerDailyStatDAO.FindMonthlyPercentile(tx, serverId, month, percentile)
percentileBytes, err := SharedServerBandwidthStatDAO.FindMonthlyPercentile(tx, serverId, month, percentile)
if err != nil {
return err
}
@@ -257,7 +257,7 @@ func (this *UserBillDAO) GenerateBills(tx *dbs.Tx, month string) error {
percentile = 100
}
}
percentileBytes, err := SharedServerDailyStatDAO.FindMonthlyPercentile(tx, serverId, month, percentile)
percentileBytes, err := SharedServerBandwidthStatDAO.FindMonthlyPercentile(tx, serverId, month, percentile)
if err != nil {
return err
}
@@ -306,7 +306,7 @@ func (this *UserBillDAO) GenerateBills(tx *dbs.Tx, month string) error {
// 百分位
var percentile = 95
percentileBytes, err := SharedServerDailyStatDAO.FindMonthlyPercentile(tx, serverId, month, percentile)
percentileBytes, err := SharedServerBandwidthStatDAO.FindMonthlyPercentile(tx, serverId, month, percentile)
if err != nil {
return err
}
@@ -343,7 +343,7 @@ func (this *UserBillDAO) GenerateBills(tx *dbs.Tx, month string) error {
// 百分位
var percentile = 95
percentileBytes, err := SharedServerDailyStatDAO.FindMonthlyPercentile(tx, serverId, month, percentile)
percentileBytes, err := SharedServerBandwidthStatDAO.FindMonthlyPercentile(tx, serverId, month, percentile)
if err != nil {
return err
}
@@ -361,7 +361,7 @@ func (this *UserBillDAO) GenerateBills(tx *dbs.Tx, month string) error {
// 百分位
var percentile = 95
percentileBytes, err := SharedServerDailyStatDAO.FindMonthlyPercentile(tx, serverId, month, percentile)
percentileBytes, err := SharedServerBandwidthStatDAO.FindMonthlyPercentile(tx, serverId, month, percentile)
if err != nil {
return err
}
@@ -382,7 +382,7 @@ func (this *UserBillDAO) GenerateBills(tx *dbs.Tx, month string) error {
percentile = 100
}
}
percentileBytes, err := SharedServerDailyStatDAO.FindMonthlyPercentile(tx, serverId, month, percentile)
percentileBytes, err := SharedServerBandwidthStatDAO.FindMonthlyPercentile(tx, serverId, month, percentile)
if err != nil {
return err
}

View File

@@ -0,0 +1,184 @@
package models
import (
"encoding/json"
"github.com/TeaOSLab/EdgeCommon/pkg/userconfigs"
_ "github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/dbs"
"time"
)
const (
UserIdentityStateEnabled = 1 // 已启用
UserIdentityStateDisabled = 0 // 已禁用
)
type UserIdentityDAO dbs.DAO
func NewUserIdentityDAO() *UserIdentityDAO {
return dbs.NewDAO(&UserIdentityDAO{
DAOObject: dbs.DAOObject{
DB: Tea.Env,
Table: "edgeUserIdentities",
Model: new(UserIdentity),
PkName: "id",
},
}).(*UserIdentityDAO)
}
var SharedUserIdentityDAO *UserIdentityDAO
func init() {
dbs.OnReady(func() {
SharedUserIdentityDAO = NewUserIdentityDAO()
})
}
// EnableUserIdentity 启用条目
func (this *UserIdentityDAO) EnableUserIdentity(tx *dbs.Tx, id uint64) error {
_, err := this.Query(tx).
Pk(id).
Set("state", UserIdentityStateEnabled).
Update()
return err
}
// DisableUserIdentity 禁用条目
func (this *UserIdentityDAO) DisableUserIdentity(tx *dbs.Tx, id uint64) error {
_, err := this.Query(tx).
Pk(id).
Set("state", UserIdentityStateDisabled).
Update()
return err
}
// FindEnabledUserIdentity 查找启用中的条目
func (this *UserIdentityDAO) FindEnabledUserIdentity(tx *dbs.Tx, id int64) (*UserIdentity, error) {
result, err := this.Query(tx).
Pk(id).
Attr("state", UserIdentityStateEnabled).
Find()
if result == nil {
return nil, err
}
return result.(*UserIdentity), err
}
// CreateUserIdentity 创建
func (this *UserIdentityDAO) CreateUserIdentity(tx *dbs.Tx, userId int64, idType userconfigs.UserIdentityType, realName string, number string, fileIds []int64) (int64, error) {
var op = NewUserIdentityOperator()
op.UserId = userId
op.Type = idType
op.RealName = realName
op.Number = number
if fileIds == nil {
fileIds = []int64{}
}
fileIdsJSON, err := json.Marshal(fileIds)
if err != nil {
return 0, err
}
op.FileIds = fileIdsJSON
op.Status = userconfigs.UserIdentityStatusNone
op.State = UserIdentityStateEnabled
return this.SaveInt64(tx, op)
}
// UpdateUserIdentity 修改
func (this *UserIdentityDAO) UpdateUserIdentity(tx *dbs.Tx, identityId int64, idType userconfigs.UserIdentityType, realName string, number string, fileIds []int64) error {
if identityId <= 0 {
return nil
}
var op = NewUserIdentityOperator()
op.Id = identityId
op.Type = idType
op.Number = number
if fileIds == nil {
fileIds = []int64{}
}
fileIdsJSON, err := json.Marshal(fileIds)
if err != nil {
return err
}
op.FileIds = fileIdsJSON
return this.Save(tx, op)
}
// SubmitUserIdentity 提交审核
func (this *UserIdentityDAO) SubmitUserIdentity(tx *dbs.Tx, identityId int64) error {
return this.Query(tx).
Pk(identityId).
Set("status", userconfigs.UserIdentityStatusSubmitted).
Set("submittedAt", time.Now().Unix()).
UpdateQuickly()
}
// CancelUserIdentity 取消提交审核
func (this *UserIdentityDAO) CancelUserIdentity(tx *dbs.Tx, identityId int64) error {
return this.Query(tx).
Pk(identityId).
Set("status", userconfigs.UserIdentityStatusNone).
Set("updatedAt", time.Now().Unix()).
UpdateQuickly()
}
// RejectUserIdentity 拒绝
func (this *UserIdentityDAO) RejectUserIdentity(tx *dbs.Tx, identityId int64) error {
return this.Query(tx).
Pk(identityId).
Set("status", userconfigs.UserIdentityStatusRejected).
Set("rejectedAt", time.Now().Unix()).
UpdateQuickly()
}
// VerifyUserIdentity 通过
func (this *UserIdentityDAO) VerifyUserIdentity(tx *dbs.Tx, identityId int64) error {
return this.Query(tx).
Pk(identityId).
Set("status", userconfigs.UserIdentityStatusVerified).
Set("verifiedAt", time.Now().Unix()).
UpdateQuickly()
}
// CheckUserIdentity 检查用户认证
func (this *UserIdentityDAO) CheckUserIdentity(tx *dbs.Tx, userId int64, identityId int64) error {
b, err := this.Query(tx).
Pk(identityId).
Attr("userId", userId).
State(UserIdentityStateEnabled).
Exist()
if err != nil {
return err
}
if !b {
return ErrNotFound
}
return nil
}
// FindUserIdentityStatus 查找认证信息当前状态
func (this *UserIdentityDAO) FindUserIdentityStatus(tx *dbs.Tx, identityId int64) (userconfigs.UserIdentityStatus, error) {
return this.Query(tx).
Pk(identityId).
Result("status").
FindStringCol("")
}
// FindEnabledUserIdentityWithType 查找某个类型的认证信息
func (this *UserIdentityDAO) FindEnabledUserIdentityWithType(tx *dbs.Tx, userId int64, idType userconfigs.UserIdentityType) (*UserIdentity, error) {
one, err := this.Query(tx).
Attr("userId", userId).
Attr("type", idType).
State(UserIdentityStateEnabled).
Find()
if err != nil || one == nil {
return nil, err
}
return one.(*UserIdentity), nil
}

View File

@@ -0,0 +1,6 @@
package models_test
import (
_ "github.com/go-sql-driver/mysql"
_ "github.com/iwind/TeaGo/bootstrap"
)

View File

@@ -0,0 +1,40 @@
package models
import "github.com/iwind/TeaGo/dbs"
// UserIdentity 用户实名认证信息
type UserIdentity struct {
Id uint64 `field:"id"` // ID
UserId uint64 `field:"userId"` // 用户ID
Type string `field:"type"` // 类型
RealName string `field:"realName"` // 真实姓名
Number string `field:"number"` // 编号
FileIds dbs.JSON `field:"fileIds"` // 文件ID
Status string `field:"status"` // 状态none,submitted,verified,rejected
State uint8 `field:"state"` // 状态
CreatedAt uint64 `field:"createdAt"` // 创建时间
UpdatedAt uint64 `field:"updatedAt"` // 修改时间
SubmittedAt uint64 `field:"submittedAt"` // 提交时间
RejectedAt uint64 `field:"rejectedAt"` // 拒绝时间
VerifiedAt uint64 `field:"verifiedAt"` // 认证时间
}
type UserIdentityOperator struct {
Id interface{} // ID
UserId interface{} // 用户ID
Type interface{} // 类型
RealName interface{} // 真实姓名
Number interface{} // 编号
FileIds interface{} // 文件ID
Status interface{} // 状态none,submitted,verified,rejected
State interface{} // 状态
CreatedAt interface{} // 创建时间
UpdatedAt interface{} // 修改时间
SubmittedAt interface{} // 提交时间
RejectedAt interface{} // 拒绝时间
VerifiedAt interface{} // 认证时间
}
func NewUserIdentityOperator() *UserIdentityOperator {
return &UserIdentityOperator{}
}

View File

@@ -0,0 +1,16 @@
package models
import "encoding/json"
func (this *UserIdentity) DecodeFileIds() []int64 {
if len(this.FileIds) == 0 {
return []int64{}
}
var result = []int64{}
err := json.Unmarshal(this.FileIds, &result)
if err != nil {
// ignore error
}
return result
}

View File

@@ -51,12 +51,17 @@ func (this *UserNodeDAO) EnableUserNode(tx *dbs.Tx, id uint32) error {
}
// DisableUserNode 禁用条目
func (this *UserNodeDAO) DisableUserNode(tx *dbs.Tx, id int64) error {
func (this *UserNodeDAO) DisableUserNode(tx *dbs.Tx, nodeId int64) error {
_, err := this.Query(tx).
Pk(id).
Pk(nodeId).
Set("state", UserNodeStateDisabled).
Update()
return err
if err != nil {
return err
}
// 删除运行日志
return SharedNodeLogDAO.DeleteNodeLogs(tx, nodeconfigs.NodeRoleUser, nodeId)
}
// FindEnabledUserNode 查找启用中的条目

View File

@@ -11,7 +11,6 @@ const (
ProviderTypeDNSPod ProviderType = "dnspod" // DNSPod
ProviderTypeAliDNS ProviderType = "alidns" // 阿里云DNS
ProviderTypeHuaweiDNS ProviderType = "huaweiDNS" // 华为DNS
ProviderTypeDNSCom ProviderType = "dnscom" // dns.com
ProviderTypeCloudFlare ProviderType = "cloudFlare" // CloudFlare DNS
ProviderTypeLocalEdgeDNS ProviderType = "localEdgeDNS" // 和当前系统集成的EdgeDNS
ProviderTypeUserEdgeDNS ProviderType = "userEdgeDNS" // 通过API连接的EdgeDNS
@@ -36,11 +35,6 @@ func FindAllProviderTypes() []maps.Map {
"code": ProviderTypeHuaweiDNS,
"description": "华为云解析DNS。",
},
/**{
"name": "帝恩思DNS.COM",
"code": ProviderTypeDNSCom,
"description": "DNS.com提供的DNS服务。",
},**/
{
"name": "CloudFlare DNS",
"code": ProviderTypeCloudFlare,

View File

@@ -0,0 +1,90 @@
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
package installers
import (
"github.com/TeaOSLab/EdgeAPI/internal/utils/sizes"
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
"github.com/iwind/TeaGo/types"
"sync"
"time"
)
const (
UpgradeLimiterDuration = 10 // node key expire time, by seconds
UpgradeLimiterConcurrent = 10 // 10 nodes
UpgradeLimiterMaxBytesPerSecond = 5 * sizes.M // max bytes per second
)
var SharedUpgradeLimiter = NewUpgradeLimiter()
// UpgradeLimiter 升级流量管理器
type UpgradeLimiter struct {
nodeMap map[string]int64 // key => timestamp
rateTimestamp int64
rateBytes int64
locker sync.Mutex
}
func NewUpgradeLimiter() *UpgradeLimiter {
return &UpgradeLimiter{
nodeMap: map[string]int64{},
}
}
// UpdateNodeBytes 添加正在下载的节点流量
func (this *UpgradeLimiter) UpdateNodeBytes(nodeType nodeconfigs.NodeRole, nodeId int64, bytes int64) {
this.locker.Lock()
defer this.locker.Unlock()
// 先清理
var nowTime = time.Now().Unix()
this.gc(nowTime)
// 添加
var key = nodeType + "_" + types.String(nodeId)
this.nodeMap[key] = nowTime
// 流量
if this.rateTimestamp == nowTime {
this.rateBytes += bytes
} else {
this.rateTimestamp = nowTime
this.rateBytes = bytes
}
}
// CanUpgrade 检查是否有新的升级
func (this *UpgradeLimiter) CanUpgrade() bool {
this.locker.Lock()
defer this.locker.Unlock()
var nowTime = time.Now().Unix()
this.gc(nowTime)
// 限制并发节点数
if len(this.nodeMap) >= UpgradeLimiterConcurrent {
return false
}
if this.rateTimestamp != nowTime {
return true
}
// 限制下载速度
if this.rateBytes >= UpgradeLimiterMaxBytesPerSecond {
return false
}
return true
}
func (this *UpgradeLimiter) gc(nowTime int64) {
for nodeKey, timestamp := range this.nodeMap {
if timestamp < nowTime-UpgradeLimiterDuration {
delete(this.nodeMap, nodeKey)
}
}
}

View File

@@ -0,0 +1,27 @@
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
package installers_test
import (
"github.com/TeaOSLab/EdgeAPI/internal/installers"
"github.com/TeaOSLab/EdgeAPI/internal/utils/sizes"
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
"testing"
"time"
)
func TestNewUpgradeLimiter(t *testing.T) {
var limiter = installers.NewUpgradeLimiter()
limiter.UpdateNodeBytes(nodeconfigs.NodeRoleNode, 1, 1)
limiter.UpdateNodeBytes(nodeconfigs.NodeRoleNode, 2, 5*sizes.M)
t.Log("limiter:", limiter)
t.Log("canUpgrade:", limiter.CanUpgrade())
time.Sleep(1 * time.Second)
t.Log("canUpgrade:", limiter.CanUpgrade())
t.Log("limiter:", limiter)
limiter.UpdateNodeBytes(nodeconfigs.NodeRoleNode, 2, 4*sizes.M)
t.Log("canUpgrade:", limiter.CanUpgrade())
t.Log("limiter:", limiter)
}

View File

@@ -14,579 +14,590 @@ import (
// 注册服务
func (this *APINode) registerServices(server *grpc.Server) {
{
instance := this.serviceInstance(&services.APITokenService{}).(*services.APITokenService)
var instance = this.serviceInstance(&services.APITokenService{}).(*services.APITokenService)
pb.RegisterAPITokenServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.AdminService{}).(*services.AdminService)
var instance = this.serviceInstance(&services.AdminService{}).(*services.AdminService)
pb.RegisterAdminServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.NodeGrantService{}).(*services.NodeGrantService)
var instance = this.serviceInstance(&services.NodeGrantService{}).(*services.NodeGrantService)
pb.RegisterNodeGrantServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.ServerService{}).(*services.ServerService)
var instance = this.serviceInstance(&services.ServerService{}).(*services.ServerService)
pb.RegisterServerServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.NodeService{}).(*services.NodeService)
var instance = this.serviceInstance(&services.NodeService{}).(*services.NodeService)
pb.RegisterNodeServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.NodeClusterService{}).(*services.NodeClusterService)
var instance = this.serviceInstance(&services.NodeClusterService{}).(*services.NodeClusterService)
pb.RegisterNodeClusterServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.NodeIPAddressService{}).(*services.NodeIPAddressService)
var instance = this.serviceInstance(&services.NodeIPAddressService{}).(*services.NodeIPAddressService)
pb.RegisterNodeIPAddressServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.NodeIPAddressLogService{}).(*services.NodeIPAddressLogService)
var instance = this.serviceInstance(&services.NodeIPAddressLogService{}).(*services.NodeIPAddressLogService)
pb.RegisterNodeIPAddressLogServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.NodeIPAddressThresholdService{}).(*services.NodeIPAddressThresholdService)
var instance = this.serviceInstance(&services.NodeIPAddressThresholdService{}).(*services.NodeIPAddressThresholdService)
pb.RegisterNodeIPAddressThresholdServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.APINodeService{}).(*services.APINodeService)
var instance = this.serviceInstance(&services.APINodeService{}).(*services.APINodeService)
pb.RegisterAPINodeServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.APIMethodStatService{}).(*services.APIMethodStatService)
var instance = this.serviceInstance(&services.APIMethodStatService{}).(*services.APIMethodStatService)
pb.RegisterAPIMethodStatServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.OriginService{}).(*services.OriginService)
var instance = this.serviceInstance(&services.OriginService{}).(*services.OriginService)
pb.RegisterOriginServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.HTTPWebService{}).(*services.HTTPWebService)
var instance = this.serviceInstance(&services.HTTPWebService{}).(*services.HTTPWebService)
pb.RegisterHTTPWebServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.ReverseProxyService{}).(*services.ReverseProxyService)
var instance = this.serviceInstance(&services.ReverseProxyService{}).(*services.ReverseProxyService)
pb.RegisterReverseProxyServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.HTTPGzipService{}).(*services.HTTPGzipService)
var instance = this.serviceInstance(&services.HTTPGzipService{}).(*services.HTTPGzipService)
pb.RegisterHTTPGzipServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.HTTPHeaderPolicyService{}).(*services.HTTPHeaderPolicyService)
var instance = this.serviceInstance(&services.HTTPHeaderPolicyService{}).(*services.HTTPHeaderPolicyService)
pb.RegisterHTTPHeaderPolicyServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.HTTPHeaderService{}).(*services.HTTPHeaderService)
var instance = this.serviceInstance(&services.HTTPHeaderService{}).(*services.HTTPHeaderService)
pb.RegisterHTTPHeaderServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.HTTPPageService{}).(*services.HTTPPageService)
var instance = this.serviceInstance(&services.HTTPPageService{}).(*services.HTTPPageService)
pb.RegisterHTTPPageServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.HTTPAccessLogPolicyService{}).(*services.HTTPAccessLogPolicyService)
var instance = this.serviceInstance(&services.HTTPAccessLogPolicyService{}).(*services.HTTPAccessLogPolicyService)
pb.RegisterHTTPAccessLogPolicyServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.HTTPCachePolicyService{}).(*services.HTTPCachePolicyService)
var instance = this.serviceInstance(&services.HTTPCachePolicyService{}).(*services.HTTPCachePolicyService)
pb.RegisterHTTPCachePolicyServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.HTTPFirewallPolicyService{}).(*services.HTTPFirewallPolicyService)
var instance = this.serviceInstance(&services.HTTPFirewallPolicyService{}).(*services.HTTPFirewallPolicyService)
pb.RegisterHTTPFirewallPolicyServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.FirewallService{}).(*services.FirewallService)
var instance = this.serviceInstance(&services.FirewallService{}).(*services.FirewallService)
pb.RegisterFirewallServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.HTTPLocationService{}).(*services.HTTPLocationService)
var instance = this.serviceInstance(&services.HTTPLocationService{}).(*services.HTTPLocationService)
pb.RegisterHTTPLocationServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.HTTPWebsocketService{}).(*services.HTTPWebsocketService)
var instance = this.serviceInstance(&services.HTTPWebsocketService{}).(*services.HTTPWebsocketService)
pb.RegisterHTTPWebsocketServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.HTTPRewriteRuleService{}).(*services.HTTPRewriteRuleService)
var instance = this.serviceInstance(&services.HTTPRewriteRuleService{}).(*services.HTTPRewriteRuleService)
pb.RegisterHTTPRewriteRuleServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.SSLCertService{}).(*services.SSLCertService)
var instance = this.serviceInstance(&services.SSLCertService{}).(*services.SSLCertService)
pb.RegisterSSLCertServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.SSLPolicyService{}).(*services.SSLPolicyService)
var instance = this.serviceInstance(&services.SSLPolicyService{}).(*services.SSLPolicyService)
pb.RegisterSSLPolicyServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.SysSettingService{}).(*services.SysSettingService)
var instance = this.serviceInstance(&services.SysSettingService{}).(*services.SysSettingService)
pb.RegisterSysSettingServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.HTTPFirewallRuleGroupService{}).(*services.HTTPFirewallRuleGroupService)
var instance = this.serviceInstance(&services.HTTPFirewallRuleGroupService{}).(*services.HTTPFirewallRuleGroupService)
pb.RegisterHTTPFirewallRuleGroupServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.HTTPFirewallRuleSetService{}).(*services.HTTPFirewallRuleSetService)
var instance = this.serviceInstance(&services.HTTPFirewallRuleSetService{}).(*services.HTTPFirewallRuleSetService)
pb.RegisterHTTPFirewallRuleSetServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.DBNodeService{}).(*services.DBNodeService)
var instance = this.serviceInstance(&services.DBNodeService{}).(*services.DBNodeService)
pb.RegisterDBNodeServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.NodeLogService{}).(*services.NodeLogService)
var instance = this.serviceInstance(&services.NodeLogService{}).(*services.NodeLogService)
pb.RegisterNodeLogServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.NodeLoginService{}).(*services.NodeLoginService)
var instance = this.serviceInstance(&services.NodeLoginService{}).(*services.NodeLoginService)
pb.RegisterNodeLoginServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.HTTPAccessLogService{}).(*services.HTTPAccessLogService)
var instance = this.serviceInstance(&services.HTTPAccessLogService{}).(*services.HTTPAccessLogService)
pb.RegisterHTTPAccessLogServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.MessageService{}).(*services.MessageService)
var instance = this.serviceInstance(&services.MessageService{}).(*services.MessageService)
pb.RegisterMessageServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.MessageRecipientService{}).(*services.MessageRecipientService)
var instance = this.serviceInstance(&services.MessageRecipientService{}).(*services.MessageRecipientService)
pb.RegisterMessageRecipientServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.MessageReceiverService{}).(*services.MessageReceiverService)
var instance = this.serviceInstance(&services.MessageReceiverService{}).(*services.MessageReceiverService)
pb.RegisterMessageReceiverServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.MessageMediaService{}).(*services.MessageMediaService)
var instance = this.serviceInstance(&services.MessageMediaService{}).(*services.MessageMediaService)
pb.RegisterMessageMediaServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.MessageRecipientGroupService{}).(*services.MessageRecipientGroupService)
var instance = this.serviceInstance(&services.MessageRecipientGroupService{}).(*services.MessageRecipientGroupService)
pb.RegisterMessageRecipientGroupServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.MessageMediaInstanceService{}).(*services.MessageMediaInstanceService)
var instance = this.serviceInstance(&services.MessageMediaInstanceService{}).(*services.MessageMediaInstanceService)
pb.RegisterMessageMediaInstanceServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.MessageTaskService{}).(*services.MessageTaskService)
var instance = this.serviceInstance(&services.MessageTaskService{}).(*services.MessageTaskService)
pb.RegisterMessageTaskServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.MessageTaskLogService{}).(*services.MessageTaskLogService)
var instance = this.serviceInstance(&services.MessageTaskLogService{}).(*services.MessageTaskLogService)
pb.RegisterMessageTaskLogServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.NodeGroupService{}).(*services.NodeGroupService)
var instance = this.serviceInstance(&services.NodeGroupService{}).(*services.NodeGroupService)
pb.RegisterNodeGroupServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.NodeRegionService{}).(*services.NodeRegionService)
var instance = this.serviceInstance(&services.NodeRegionService{}).(*services.NodeRegionService)
pb.RegisterNodeRegionServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.NodePriceItemService{}).(*services.NodePriceItemService)
var instance = this.serviceInstance(&services.NodePriceItemService{}).(*services.NodePriceItemService)
pb.RegisterNodePriceItemServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.ServerGroupService{}).(*services.ServerGroupService)
var instance = this.serviceInstance(&services.ServerGroupService{}).(*services.ServerGroupService)
pb.RegisterServerGroupServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.IPLibraryService{}).(*services.IPLibraryService)
var instance = this.serviceInstance(&services.IPLibraryService{}).(*services.IPLibraryService)
pb.RegisterIPLibraryServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.FileChunkService{}).(*services.FileChunkService)
var instance = this.serviceInstance(&services.FileChunkService{}).(*services.FileChunkService)
pb.RegisterFileChunkServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.FileService{}).(*services.FileService)
var instance = this.serviceInstance(&services.FileService{}).(*services.FileService)
pb.RegisterFileServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.RegionCountryService{}).(*services.RegionCountryService)
var instance = this.serviceInstance(&services.RegionCountryService{}).(*services.RegionCountryService)
pb.RegisterRegionCountryServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.RegionProvinceService{}).(*services.RegionProvinceService)
var instance = this.serviceInstance(&services.RegionProvinceService{}).(*services.RegionProvinceService)
pb.RegisterRegionProvinceServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.RegionCityService{}).(*services.RegionCityService)
var instance = this.serviceInstance(&services.RegionCityService{}).(*services.RegionCityService)
pb.RegisterRegionCityServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.RegionProviderService{}).(*services.RegionProviderService)
var instance = this.serviceInstance(&services.RegionProviderService{}).(*services.RegionProviderService)
pb.RegisterRegionProviderServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.IPListService{}).(*services.IPListService)
var instance = this.serviceInstance(&services.IPListService{}).(*services.IPListService)
pb.RegisterIPListServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.IPItemService{}).(*services.IPItemService)
var instance = this.serviceInstance(&services.IPItemService{}).(*services.IPItemService)
pb.RegisterIPItemServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.LogService{}).(*services.LogService)
var instance = this.serviceInstance(&services.LogService{}).(*services.LogService)
pb.RegisterLogServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.DNSProviderService{}).(*services.DNSProviderService)
var instance = this.serviceInstance(&services.DNSProviderService{}).(*services.DNSProviderService)
pb.RegisterDNSProviderServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.DNSDomainService{}).(*services.DNSDomainService)
var instance = this.serviceInstance(&services.DNSDomainService{}).(*services.DNSDomainService)
pb.RegisterDNSDomainServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.DNSService{}).(*services.DNSService)
var instance = this.serviceInstance(&services.DNSService{}).(*services.DNSService)
pb.RegisterDNSServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.ACMEUserService{}).(*services.ACMEUserService)
var instance = this.serviceInstance(&services.ACMEUserService{}).(*services.ACMEUserService)
pb.RegisterACMEUserServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.ACMETaskService{}).(*services.ACMETaskService)
var instance = this.serviceInstance(&services.ACMETaskService{}).(*services.ACMETaskService)
pb.RegisterACMETaskServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.ACMEAuthenticationService{}).(*services.ACMEAuthenticationService)
var instance = this.serviceInstance(&services.ACMEAuthenticationService{}).(*services.ACMEAuthenticationService)
pb.RegisterACMEAuthenticationServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.ACMEProviderService{}).(*services.ACMEProviderService)
var instance = this.serviceInstance(&services.ACMEProviderService{}).(*services.ACMEProviderService)
pb.RegisterACMEProviderServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.ACMEProviderAccountService{}).(*services.ACMEProviderAccountService)
var instance = this.serviceInstance(&services.ACMEProviderAccountService{}).(*services.ACMEProviderAccountService)
pb.RegisterACMEProviderAccountServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.UserService{}).(*services.UserService)
var instance = this.serviceInstance(&services.UserService{}).(*services.UserService)
pb.RegisterUserServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.ServerDailyStatService{}).(*services.ServerDailyStatService)
var instance = this.serviceInstance(&services.UserIdentityService{}).(*services.UserIdentityService)
pb.RegisterUserIdentityServiceServer(server, instance)
this.rest(instance)
}
{
var instance = this.serviceInstance(&services.ServerDailyStatService{}).(*services.ServerDailyStatService)
pb.RegisterServerDailyStatServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.UserBillService{}).(*services.UserBillService)
var instance = this.serviceInstance(&services.UserBillService{}).(*services.UserBillService)
pb.RegisterUserBillServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.ServerBillService{}).(*services.ServerBillService)
var instance = this.serviceInstance(&services.ServerBillService{}).(*services.ServerBillService)
pb.RegisterServerBillServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.UserNodeService{}).(*services.UserNodeService)
var instance = this.serviceInstance(&services.UserNodeService{}).(*services.UserNodeService)
pb.RegisterUserNodeServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.LoginService{}).(*services.LoginService)
var instance = this.serviceInstance(&services.LoginService{}).(*services.LoginService)
pb.RegisterLoginServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.UserAccessKeyService{}).(*services.UserAccessKeyService)
var instance = this.serviceInstance(&services.UserAccessKeyService{}).(*services.UserAccessKeyService)
pb.RegisterUserAccessKeyServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.SysLockerService{}).(*services.SysLockerService)
var instance = this.serviceInstance(&services.SysLockerService{}).(*services.SysLockerService)
pb.RegisterSysLockerServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.NodeTaskService{}).(*services.NodeTaskService)
var instance = this.serviceInstance(&services.NodeTaskService{}).(*services.NodeTaskService)
pb.RegisterNodeTaskServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.NodeValueService{}).(*services.NodeValueService)
var instance = this.serviceInstance(&services.NodeValueService{}).(*services.NodeValueService)
pb.RegisterNodeValueServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.DBService{}).(*services.DBService)
var instance = this.serviceInstance(&services.DBService{}).(*services.DBService)
pb.RegisterDBServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.ServerRegionCityMonthlyStatService{}).(*services.ServerRegionCityMonthlyStatService)
var instance = this.serviceInstance(&services.ServerRegionCityMonthlyStatService{}).(*services.ServerRegionCityMonthlyStatService)
pb.RegisterServerRegionCityMonthlyStatServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.ServerRegionCountryMonthlyStatService{}).(*services.ServerRegionCountryMonthlyStatService)
var instance = this.serviceInstance(&services.ServerRegionCountryMonthlyStatService{}).(*services.ServerRegionCountryMonthlyStatService)
pb.RegisterServerRegionCountryMonthlyStatServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.ServerRegionProvinceMonthlyStatService{}).(*services.ServerRegionProvinceMonthlyStatService)
var instance = this.serviceInstance(&services.ServerRegionProvinceMonthlyStatService{}).(*services.ServerRegionProvinceMonthlyStatService)
pb.RegisterServerRegionProvinceMonthlyStatServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.ServerRegionProviderMonthlyStatService{}).(*services.ServerRegionProviderMonthlyStatService)
var instance = this.serviceInstance(&services.ServerRegionProviderMonthlyStatService{}).(*services.ServerRegionProviderMonthlyStatService)
pb.RegisterServerRegionProviderMonthlyStatServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.ServerClientSystemMonthlyStatService{}).(*services.ServerClientSystemMonthlyStatService)
var instance = this.serviceInstance(&services.ServerClientSystemMonthlyStatService{}).(*services.ServerClientSystemMonthlyStatService)
pb.RegisterServerClientSystemMonthlyStatServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.ServerClientBrowserMonthlyStatService{}).(*services.ServerClientBrowserMonthlyStatService)
var instance = this.serviceInstance(&services.ServerClientBrowserMonthlyStatService{}).(*services.ServerClientBrowserMonthlyStatService)
pb.RegisterServerClientBrowserMonthlyStatServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.ServerHTTPFirewallDailyStatService{}).(*services.ServerHTTPFirewallDailyStatService)
var instance = this.serviceInstance(&services.ServerHTTPFirewallDailyStatService{}).(*services.ServerHTTPFirewallDailyStatService)
pb.RegisterServerHTTPFirewallDailyStatServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.DNSTaskService{}).(*services.DNSTaskService)
var instance = this.serviceInstance(&services.DNSTaskService{}).(*services.DNSTaskService)
pb.RegisterDNSTaskServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.NodeClusterFirewallActionService{}).(*services.NodeClusterFirewallActionService)
var instance = this.serviceInstance(&services.NodeClusterFirewallActionService{}).(*services.NodeClusterFirewallActionService)
pb.RegisterNodeClusterFirewallActionServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.MonitorNodeService{}).(*services.MonitorNodeService)
var instance = this.serviceInstance(&services.MonitorNodeService{}).(*services.MonitorNodeService)
pb.RegisterMonitorNodeServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.AuthorityNodeService{}).(*services.AuthorityNodeService)
var instance = this.serviceInstance(&services.AuthorityNodeService{}).(*services.AuthorityNodeService)
pb.RegisterAuthorityNodeServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.LatestItemService{}).(*services.LatestItemService)
var instance = this.serviceInstance(&services.LatestItemService{}).(*services.LatestItemService)
pb.RegisterLatestItemServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.NodeThresholdService{}).(*services.NodeThresholdService)
var instance = this.serviceInstance(&services.NodeThresholdService{}).(*services.NodeThresholdService)
pb.RegisterNodeThresholdServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.HTTPFastcgiService{}).(*services.HTTPFastcgiService)
var instance = this.serviceInstance(&services.HTTPFastcgiService{}).(*services.HTTPFastcgiService)
pb.RegisterHTTPFastcgiServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&nameservers.NSClusterService{}).(*nameservers.NSClusterService)
var instance = this.serviceInstance(&nameservers.NSClusterService{}).(*nameservers.NSClusterService)
pb.RegisterNSClusterServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&nameservers.NSNodeService{}).(*nameservers.NSNodeService)
var instance = this.serviceInstance(&nameservers.NSNodeService{}).(*nameservers.NSNodeService)
pb.RegisterNSNodeServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&nameservers.NSDomainService{}).(*nameservers.NSDomainService)
var instance = this.serviceInstance(&nameservers.NSDomainService{}).(*nameservers.NSDomainService)
pb.RegisterNSDomainServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&nameservers.NSRecordService{}).(*nameservers.NSRecordService)
var instance = this.serviceInstance(&nameservers.NSRecordService{}).(*nameservers.NSRecordService)
pb.RegisterNSRecordServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&nameservers.NSRouteService{}).(*nameservers.NSRouteService)
var instance = this.serviceInstance(&nameservers.NSRouteService{}).(*nameservers.NSRouteService)
pb.RegisterNSRouteServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&nameservers.NSKeyService{}).(*nameservers.NSKeyService)
var instance = this.serviceInstance(&nameservers.NSKeyService{}).(*nameservers.NSKeyService)
pb.RegisterNSKeyServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&nameservers.NSAccessLogService{}).(*nameservers.NSAccessLogService)
var instance = this.serviceInstance(&nameservers.NSAccessLogService{}).(*nameservers.NSAccessLogService)
pb.RegisterNSAccessLogServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&nameservers.NSRecordHourlyStatService{}).(*nameservers.NSRecordHourlyStatService)
var instance = this.serviceInstance(&nameservers.NSRecordHourlyStatService{}).(*nameservers.NSRecordHourlyStatService)
pb.RegisterNSRecordHourlyStatServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&nameservers.NSQuestionOptionService{}).(*nameservers.NSQuestionOptionService)
var instance = this.serviceInstance(&nameservers.NSQuestionOptionService{}).(*nameservers.NSQuestionOptionService)
pb.RegisterNSQuestionOptionServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&nameservers.NSService{}).(*nameservers.NSService)
var instance = this.serviceInstance(&nameservers.NSService{}).(*nameservers.NSService)
pb.RegisterNSServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.HTTPAuthPolicyService{}).(*services.HTTPAuthPolicyService)
var instance = this.serviceInstance(&services.HTTPAuthPolicyService{}).(*services.HTTPAuthPolicyService)
pb.RegisterHTTPAuthPolicyServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.MetricItemService{}).(*services.MetricItemService)
var instance = this.serviceInstance(&services.MetricItemService{}).(*services.MetricItemService)
pb.RegisterMetricItemServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.NodeClusterMetricItemService{}).(*services.NodeClusterMetricItemService)
var instance = this.serviceInstance(&services.NodeClusterMetricItemService{}).(*services.NodeClusterMetricItemService)
pb.RegisterNodeClusterMetricItemServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.MetricStatService{}).(*services.MetricStatService)
var instance = this.serviceInstance(&services.MetricStatService{}).(*services.MetricStatService)
pb.RegisterMetricStatServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.MetricChartService{}).(*services.MetricChartService)
var instance = this.serviceInstance(&services.MetricChartService{}).(*services.MetricChartService)
pb.RegisterMetricChartServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.ServerStatBoardService{}).(*services.ServerStatBoardService)
var instance = this.serviceInstance(&services.ServerStatBoardService{}).(*services.ServerStatBoardService)
pb.RegisterServerStatBoardServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.ServerStatBoardChartService{}).(*services.ServerStatBoardChartService)
var instance = this.serviceInstance(&services.ServerStatBoardChartService{}).(*services.ServerStatBoardChartService)
pb.RegisterServerStatBoardChartServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.PlanService{}).(*services.PlanService)
var instance = this.serviceInstance(&services.PlanService{}).(*services.PlanService)
pb.RegisterPlanServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.UserPlanService{}).(*services.UserPlanService)
var instance = this.serviceInstance(&services.UserPlanService{}).(*services.UserPlanService)
pb.RegisterUserPlanServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.ServerDomainHourlyStatService{}).(*services.ServerDomainHourlyStatService)
var instance = this.serviceInstance(&services.ServerDomainHourlyStatService{}).(*services.ServerDomainHourlyStatService)
pb.RegisterServerDomainHourlyStatServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.TrafficDailyStatService{}).(*services.TrafficDailyStatService)
var instance = this.serviceInstance(&services.TrafficDailyStatService{}).(*services.TrafficDailyStatService)
pb.RegisterTrafficDailyStatServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.HTTPCacheTaskKeyService{}).(*services.HTTPCacheTaskKeyService)
var instance = this.serviceInstance(&services.HTTPCacheTaskKeyService{}).(*services.HTTPCacheTaskKeyService)
pb.RegisterHTTPCacheTaskKeyServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.HTTPCacheTaskService{}).(*services.HTTPCacheTaskService)
var instance = this.serviceInstance(&services.HTTPCacheTaskService{}).(*services.HTTPCacheTaskService)
pb.RegisterHTTPCacheTaskServiceServer(server, instance)
this.rest(instance)
}
{
var instance = this.serviceInstance(&services.ServerBandwidthStatService{}).(*services.ServerBandwidthStatService)
pb.RegisterServerBandwidthStatServiceServer(server, instance)
this.rest(instance)
}
APINodeServicesRegister(this, server)
// TODO check service names
for serviceName := range server.GetServiceInfo() {
index := strings.LastIndex(serviceName, ".")
var index = strings.LastIndex(serviceName, ".")
if index >= 0 {
serviceName = serviceName[index+1:]
}
@@ -602,7 +613,7 @@ func (this *APINode) rest(instance interface{}) {
defer this.serviceInstanceLocker.Unlock()
var name = reflect.TypeOf(instance).String()
index := strings.LastIndex(name, ".")
var index = strings.LastIndex(name, ".")
if index >= 0 {
name = name[index+1:]
}
@@ -618,7 +629,7 @@ func (this *APINode) serviceInstance(instance interface{}) interface{} {
this.serviceInstanceLocker.Lock()
defer this.serviceInstanceLocker.Unlock()
typeName := reflect.TypeOf(instance).String()
var typeName = reflect.TypeOf(instance).String()
result, ok := this.serviceInstanceMap[typeName]
if ok {
return result

View File

@@ -462,12 +462,12 @@ func (this *NSNodeService) CheckNSNodeLatestVersion(ctx context.Context, req *pb
// DownloadNSNodeInstallationFile 下载最新DNS节点安装文件
func (this *NSNodeService) DownloadNSNodeInstallationFile(ctx context.Context, req *pb.DownloadNSNodeInstallationFileRequest) (*pb.DownloadNSNodeInstallationFileResponse, error) {
_, err := this.ValidateNSNode(ctx)
nodeId, err := this.ValidateNSNode(ctx)
if err != nil {
return nil, err
}
file := installers.SharedDeployManager.FindNSNodeFile(req.Os, req.Arch)
var file = installers.SharedDeployManager.FindNSNodeFile(req.Os, req.Arch)
if file == nil {
return &pb.DownloadNSNodeInstallationFileResponse{}, nil
}
@@ -482,6 +482,9 @@ func (this *NSNodeService) DownloadNSNodeInstallationFile(ctx context.Context, r
return nil, err
}
// 增加下载速度监控
installers.SharedUpgradeLimiter.UpdateNodeBytes(nodeconfigs.NodeRoleDNS, nodeId, int64(len(data)))
return &pb.DownloadNSNodeInstallationFileResponse{
Sum: sum,
Offset: offset,

View File

@@ -5,10 +5,81 @@ package services
import (
"context"
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
"github.com/TeaOSLab/EdgeAPI/internal/goman"
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/iwind/TeaGo/dbs"
"github.com/iwind/TeaGo/types"
"strings"
"sync"
"time"
)
// 队列相关数据
var metricStatsMap = map[string]*pb.UploadMetricStatsRequest{} // key (clusterId@nodeId@serverId@itemId) => UploadMetricStatsRequest
var metricStatKeysQueue = make(chan string, 100_000)
var metricStatsLocker = &sync.Mutex{}
func init() {
dbs.OnReadyDone(func() {
goman.New(func() {
// 将队列导入数据库
var countKeys = 0
for key := range metricStatKeysQueue {
err := func(key string) error {
var tx *dbs.Tx
metricStatsLocker.Lock()
req, ok := metricStatsMap[key]
if !ok {
metricStatsLocker.Unlock()
return nil
}
delete(metricStatsMap, key)
metricStatsLocker.Unlock()
var pieces = strings.Split(key, "@")
var clusterId = types.Int64(pieces[0])
var nodeId = types.Int64(pieces[1])
var serverId = types.Int64(pieces[2])
var itemId = types.Int64(pieces[3])
// 删除旧的数据
err := models.SharedMetricStatDAO.DeleteNodeItemStats(tx, nodeId, serverId, itemId, req.Time)
if err != nil {
return err
}
for _, stat := range req.MetricStats {
err := models.SharedMetricStatDAO.CreateStat(tx, stat.Hash, clusterId, nodeId, req.ServerId, req.ItemId, stat.Keys, float64(stat.Value), req.Time, req.Version)
if err != nil {
return err
}
}
// 保存总和
err = models.SharedMetricSumStatDAO.UpdateSum(tx, clusterId, nodeId, req.ServerId, req.Time, req.ItemId, req.Version, req.Count, req.Total)
if err != nil {
return err
}
return nil
}(key)
if err != nil {
remotelogs.Error("METRIC_STAT", "upload metric stats failed: "+err.Error())
}
// 人为限速
countKeys++
if countKeys >= 100 {
countKeys = 0
time.Sleep(1 * time.Second)
}
}
})
})
}
// MetricStatService 指标统计数据相关服务
type MetricStatService struct {
BaseService
@@ -27,24 +98,18 @@ func (this *MetricStatService) UploadMetricStats(ctx context.Context, req *pb.Up
return nil, err
}
// 删除旧的数据
err = models.SharedMetricStatDAO.DeleteNodeItemStats(tx, nodeId, req.ServerId, req.ItemId, req.Time)
if err != nil {
return nil, err
var key = types.String(clusterId) + "@" + types.String(nodeId) + "@" + types.String(req.ServerId) + "@" + types.String(req.ItemId)
metricStatsLocker.Lock()
metricStatsMap[key] = req
select {
case metricStatKeysQueue <- key:
default:
// 如果满了就删除
delete(metricStatsMap, key)
}
for _, stat := range req.MetricStats {
err := models.SharedMetricStatDAO.CreateStat(tx, stat.Hash, clusterId, nodeId, req.ServerId, req.ItemId, stat.Keys, float64(stat.Value), req.Time, req.Version)
if err != nil {
return nil, err
}
}
// 保存总和
err = models.SharedMetricSumStatDAO.UpdateSum(tx, clusterId, nodeId, req.ServerId, req.Time, req.ItemId, req.Version, req.Count, req.Total)
if err != nil {
return nil, err
}
metricStatsLocker.Unlock()
return this.Success()
}

View File

@@ -1602,12 +1602,12 @@ func (this *NodeService) UpdateNodeUp(ctx context.Context, req *pb.UpdateNodeUpR
// DownloadNodeInstallationFile 下载最新边缘节点安装文件
func (this *NodeService) DownloadNodeInstallationFile(ctx context.Context, req *pb.DownloadNodeInstallationFileRequest) (*pb.DownloadNodeInstallationFileResponse, error) {
_, err := this.ValidateNode(ctx)
nodeId, err := this.ValidateNode(ctx)
if err != nil {
return nil, err
}
file := installers.SharedDeployManager.FindNodeFile(req.Os, req.Arch)
var file = installers.SharedDeployManager.FindNodeFile(req.Os, req.Arch)
if file == nil {
return &pb.DownloadNodeInstallationFileResponse{}, nil
}
@@ -1622,6 +1622,9 @@ func (this *NodeService) DownloadNodeInstallationFile(ctx context.Context, req *
return nil, err
}
// 增加下载速度监控
installers.SharedUpgradeLimiter.UpdateNodeBytes(nodeconfigs.NodeRoleNode, nodeId, int64(len(data)))
return &pb.DownloadNodeInstallationFileResponse{
Sum: sum,
Offset: offset,

View File

@@ -429,7 +429,7 @@ func (this *NodeClusterService) FindEnabledNodeClusterDNS(ctx context.Context, r
return nil, err
}
tx := this.NullTx()
var tx = this.NullTx()
dnsInfo, err := models.SharedNodeClusterDAO.FindClusterDNSInfo(tx, req.NodeClusterId, nil)
if err != nil {
@@ -457,6 +457,7 @@ func (this *NodeClusterService) FindEnabledNodeClusterDNS(ctx context.Context, r
ServersAutoSync: dnsConfig.ServersAutoSync,
CnameRecords: dnsConfig.CNameRecords,
Ttl: dnsConfig.TTL,
CnameAsDomain: dnsConfig.CNameAsDomain,
}, nil
}
@@ -471,7 +472,7 @@ func (this *NodeClusterService) FindEnabledNodeClusterDNS(ctx context.Context, r
Provider: nil,
}, nil
}
pbDomain := &pb.DNSDomain{
var pbDomain = &pb.DNSDomain{
Id: int64(domain.Id),
Name: domain.Name,
IsOn: domain.IsOn,
@@ -515,6 +516,7 @@ func (this *NodeClusterService) FindEnabledNodeClusterDNS(ctx context.Context, r
ServersAutoSync: dnsConfig.ServersAutoSync,
CnameRecords: dnsConfig.CNameRecords,
Ttl: dnsConfig.TTL,
CnameAsDomain: dnsConfig.CNameAsDomain,
DefaultRoute: defaultRoute,
}, nil
}
@@ -527,7 +529,7 @@ func (this *NodeClusterService) CountAllEnabledNodeClustersWithDNSProviderId(ctx
return nil, err
}
tx := this.NullTx()
var tx = this.NullTx()
count, err := models.SharedNodeClusterDAO.CountAllEnabledClustersWithDNSProviderId(tx, req.DnsProviderId)
if err != nil {
@@ -544,7 +546,7 @@ func (this *NodeClusterService) CountAllEnabledNodeClustersWithDNSDomainId(ctx c
return nil, err
}
tx := this.NullTx()
var tx = this.NullTx()
count, err := models.SharedNodeClusterDAO.CountAllEnabledClustersWithDNSDomainId(tx, req.DnsDomainId)
if err != nil {
@@ -561,7 +563,7 @@ func (this *NodeClusterService) FindAllEnabledNodeClustersWithDNSDomainId(ctx co
return nil, err
}
tx := this.NullTx()
var tx = this.NullTx()
clusters, err := models.SharedNodeClusterDAO.FindAllEnabledClustersWithDNSDomainId(tx, req.DnsDomainId)
if err != nil {
@@ -589,7 +591,7 @@ func (this *NodeClusterService) CheckNodeClusterDNSName(ctx context.Context, req
return nil, err
}
tx := this.NullTx()
var tx = this.NullTx()
exists, err := models.SharedNodeClusterDAO.ExistClusterDNSName(tx, req.DnsName, req.NodeClusterId)
if err != nil {
@@ -606,9 +608,9 @@ func (this *NodeClusterService) UpdateNodeClusterDNS(ctx context.Context, req *p
return nil, err
}
tx := this.NullTx()
var tx = this.NullTx()
err = models.SharedNodeClusterDAO.UpdateClusterDNS(tx, req.NodeClusterId, req.DnsName, req.DnsDomainId, req.NodesAutoSync, req.ServersAutoSync, req.CnameRecords, req.Ttl)
err = models.SharedNodeClusterDAO.UpdateClusterDNS(tx, req.NodeClusterId, req.DnsName, req.DnsDomainId, req.NodesAutoSync, req.ServersAutoSync, req.CnameRecords, req.Ttl, req.CnameAsDomain)
if err != nil {
return nil, err
}
@@ -1040,6 +1042,18 @@ func (this *NodeClusterService) FindEnabledNodeClusterConfigInfo(ctx context.Con
result.WebpIsOn = nodeconfigs.DefaultWebPImagePolicy.IsOn
}
// UAM
if models.IsNotNull(cluster.Uam) {
var uamPolicy = &nodeconfigs.UAMPolicy{}
err = json.Unmarshal(cluster.Uam, uamPolicy)
if err != nil {
return nil, err
}
result.UamIsOn = uamPolicy.IsOn
} else {
result.UamIsOn = nodeconfigs.DefaultUAMPolicy.IsOn
}
// system service
if models.IsNotNull(cluster.SystemServices) {
var servicesMap = map[string]maps.Map{}
@@ -1104,13 +1118,18 @@ func (this *NodeClusterService) UpdateNodeClusterWebPPolicy(ctx context.Context,
return nil, err
}
var tx = this.NullTx()
var webpPolicy = &nodeconfigs.WebPImagePolicy{}
err = json.Unmarshal(req.WebpPolicyJSON, webpPolicy)
if err != nil {
return nil, err
}
err = webpPolicy.Init()
if err != nil {
return nil, errors.New("validate webp policy failed: " + err.Error())
}
var tx = this.NullTx()
err = models.SharedNodeClusterDAO.UpdateClusterWebPPolicy(tx, req.NodeClusterId, webpPolicy)
if err != nil {
return nil, err
@@ -1118,6 +1137,53 @@ func (this *NodeClusterService) UpdateNodeClusterWebPPolicy(ctx context.Context,
return this.Success()
}
// FindEnabledNodeClusterUAMPolicy 读取集群UAM策略
func (this *NodeClusterService) FindEnabledNodeClusterUAMPolicy(ctx context.Context, req *pb.FindEnabledNodeClusterUAMPolicyRequest) (*pb.FindEnabledNodeClusterUAMPolicyResponse, error) {
_, _, err := this.ValidateAdminAndUser(ctx, 0, 0)
if err != nil {
return nil, err
}
var tx = this.NullTx()
uamPolicy, err := models.SharedNodeClusterDAO.FindClusterUAMPolicy(tx, req.NodeClusterId, nil)
if err != nil {
return nil, err
}
uamPolicyJSON, err := json.Marshal(uamPolicy)
if err != nil {
return nil, err
}
return &pb.FindEnabledNodeClusterUAMPolicyResponse{
UamPolicyJSON: uamPolicyJSON,
}, nil
}
// UpdateNodeClusterUAMPolicy 设置集群的UAM策略
func (this *NodeClusterService) UpdateNodeClusterUAMPolicy(ctx context.Context, req *pb.UpdateNodeClusterUAMPolicyRequest) (*pb.RPCSuccess, error) {
_, err := this.ValidateAdmin(ctx, 0)
if err != nil {
return nil, err
}
var uamPolicy = &nodeconfigs.UAMPolicy{}
err = json.Unmarshal(req.UamPolicyJSON, uamPolicy)
if err != nil {
return nil, err
}
err = uamPolicy.Init()
if err != nil {
return nil, errors.New("validate uam policy failed: " + err.Error())
}
var tx = this.NullTx()
err = models.SharedNodeClusterDAO.UpdateClusterUAMPolicy(tx, req.NodeClusterId, uamPolicy)
if err != nil {
return nil, err
}
return this.Success()
}
// FindNodeClusterDDoSProtection 获取集群的DDOS设置
func (this *NodeClusterService) FindNodeClusterDDoSProtection(ctx context.Context, req *pb.FindNodeClusterDDoSProtectionRequest) (*pb.FindNodeClusterDDoSProtectionResponse, error) {
_, err := this.ValidateAdmin(ctx, 0)

View File

@@ -32,7 +32,7 @@ func (this *NodeTaskService) FindNodeTasks(ctx context.Context, req *pb.FindNode
return nil, err
}
pbTasks := []*pb.NodeTask{}
var pbTasks = []*pb.NodeTask{}
for _, task := range tasks {
pbTasks = append(pbTasks, &pb.NodeTask{
Id: int64(task.Id),
@@ -44,13 +44,13 @@ func (this *NodeTaskService) FindNodeTasks(ctx context.Context, req *pb.FindNode
}
// 边缘节点版本更新任务
if nodeType == rpcutils.UserTypeNode {
if nodeType == rpcutils.UserTypeNode && installers.SharedUpgradeLimiter.CanUpgrade() {
status, err := models.SharedNodeDAO.FindNodeStatus(tx, nodeId)
if err != nil {
return nil, err
}
if status != nil && len(status.OS) > 0 && len(status.Arch) > 0 && len(status.BuildVersion) > 0 {
deployFile := installers.SharedDeployManager.FindNodeFile(status.OS, status.Arch)
var deployFile = installers.SharedDeployManager.FindNodeFile(status.OS, status.Arch)
if deployFile != nil {
if stringutil.VersionCompare(deployFile.Version, status.BuildVersion) > 0 {
pbTasks = append(pbTasks, &pb.NodeTask{

View File

@@ -72,7 +72,7 @@ func (this *OriginService) CreateOrigin(ctx context.Context, req *pb.CreateOrigi
}
}
originId, err := models.SharedOriginDAO.CreateOrigin(tx, adminId, userId, req.Name, string(addrMap.AsJSON()), req.Description, req.Weight, req.IsOn, connTimeout, readTimeout, idleTimeout, req.MaxConns, req.MaxIdleConns, certRef, req.Domains, req.Host)
originId, err := models.SharedOriginDAO.CreateOrigin(tx, adminId, userId, req.Name, string(addrMap.AsJSON()), req.Description, req.Weight, req.IsOn, connTimeout, readTimeout, idleTimeout, req.MaxConns, req.MaxIdleConns, certRef, req.Domains, req.Host, req.FollowPort)
if err != nil {
return nil, err
}
@@ -87,20 +87,23 @@ func (this *OriginService) UpdateOrigin(ctx context.Context, req *pb.UpdateOrigi
return nil, err
}
var tx = this.NullTx()
if userId > 0 {
// TODO 校验权限
err = models.SharedOriginDAO.CheckUserOrigin(tx, userId, req.OriginId)
if err != nil {
return nil, err
}
}
if req.Addr == nil {
return nil, errors.New("'addr' can not be nil")
}
addrMap := maps.Map{
var addrMap = maps.Map{
"protocol": req.Addr.Protocol,
"portRange": req.Addr.PortRange,
"host": req.Addr.Host,
}
tx := this.NullTx()
// 校验参数
var connTimeout = &shared.TimeDuration{}
if len(req.ConnTimeoutJSON) > 0 {
@@ -139,7 +142,7 @@ func (this *OriginService) UpdateOrigin(ctx context.Context, req *pb.UpdateOrigi
}
}
err = models.SharedOriginDAO.UpdateOrigin(tx, req.OriginId, req.Name, string(addrMap.AsJSON()), req.Description, req.Weight, req.IsOn, connTimeout, readTimeout, idleTimeout, req.MaxConns, req.MaxIdleConns, certRef, req.Domains, req.Host)
err = models.SharedOriginDAO.UpdateOrigin(tx, req.OriginId, req.Name, string(addrMap.AsJSON()), req.Description, req.Weight, req.IsOn, connTimeout, readTimeout, idleTimeout, req.MaxConns, req.MaxIdleConns, certRef, req.Domains, req.Host, req.FollowPort)
if err != nil {
return nil, err
}
@@ -154,11 +157,14 @@ func (this *OriginService) FindEnabledOrigin(ctx context.Context, req *pb.FindEn
return nil, err
}
if userId > 0 {
// TODO 校验权限
}
var tx = this.NullTx()
tx := this.NullTx()
if userId > 0 {
err = models.SharedOriginDAO.CheckUserOrigin(tx, userId, req.OriginId)
if err != nil {
return nil, err
}
}
origin, err := models.SharedOriginDAO.FindEnabledOrigin(tx, req.OriginId)
if err != nil {
@@ -196,11 +202,14 @@ func (this *OriginService) FindEnabledOriginConfig(ctx context.Context, req *pb.
return nil, err
}
if userId > 0 {
// TODO 校验权限
}
var tx = this.NullTx()
tx := this.NullTx()
if userId > 0 {
err = models.SharedOriginDAO.CheckUserOrigin(tx, userId, req.OriginId)
if err != nil {
return nil, err
}
}
config, err := models.SharedOriginDAO.ComposeOriginConfig(tx, req.OriginId, nil)
if err != nil {

View File

@@ -84,7 +84,7 @@ func (this *ReverseProxyService) FindEnabledReverseProxyConfig(ctx context.Conte
}
}
tx := this.NullTx()
var tx = this.NullTx()
config, err := models.SharedReverseProxyDAO.ComposeReverseProxyConfig(tx, req.ReverseProxyId, nil)
if err != nil {
@@ -189,7 +189,7 @@ func (this *ReverseProxyService) UpdateReverseProxy(ctx context.Context, req *pb
}
}
tx := this.NullTx()
var tx = this.NullTx()
// 校验参数
var connTimeout = &shared.TimeDuration{}
@@ -216,7 +216,7 @@ func (this *ReverseProxyService) UpdateReverseProxy(ctx context.Context, req *pb
}
}
err = models.SharedReverseProxyDAO.UpdateReverseProxy(tx, req.ReverseProxyId, types.Int8(req.RequestHostType), req.RequestHost, req.RequestURI, req.StripPrefix, req.AutoFlush, req.AddHeaders, connTimeout, readTimeout, idleTimeout, req.MaxConns, req.MaxIdleConns, req.ProxyProtocolJSON, req.FollowRedirects)
err = models.SharedReverseProxyDAO.UpdateReverseProxy(tx, req.ReverseProxyId, types.Int8(req.RequestHostType), req.RequestHost, req.RequestHostExcludingPort, req.RequestURI, req.StripPrefix, req.AutoFlush, req.AddHeaders, connTimeout, readTimeout, idleTimeout, req.MaxConns, req.MaxIdleConns, req.ProxyProtocolJSON, req.FollowRedirects)
if err != nil {
return nil, err
}

View File

@@ -192,6 +192,56 @@ func (this *ServerService) UpdateServerBasic(ctx context.Context, req *pb.Update
return this.Success()
}
// UpdateServerGroupIds 修改服务所在分组
func (this *ServerService) UpdateServerGroupIds(ctx context.Context, req *pb.UpdateServerGroupIdsRequest) (*pb.RPCSuccess, error) {
_, userId, err := this.ValidateAdminAndUser(ctx, 0, 0)
if err != nil {
return nil, err
}
var tx = this.NullTx()
if userId > 0 {
err = models.SharedServerDAO.CheckUserServer(tx, userId, req.ServerId)
if err != nil {
return nil, err
}
}
// 检查分组IDs
for _, groupId := range req.ServerGroupIds {
if userId > 0 {
err = models.SharedServerGroupDAO.CheckUserGroup(tx, userId, groupId)
if err != nil {
return nil, err
}
} else {
b, err := models.SharedServerGroupDAO.ExistsGroup(tx, groupId)
if err != nil {
return nil, err
}
if !b {
continue
}
}
}
// 增加默认分组
if userId > 0 {
config, err := models.SharedSysSettingDAO.ReadUserServerConfig(tx)
if err == nil && config.GroupId > 0 && !lists.ContainsInt64(req.ServerGroupIds, config.GroupId) {
req.ServerGroupIds = append(req.ServerGroupIds, config.GroupId)
}
}
// 修改
err = models.SharedServerDAO.UpdateServerGroupIds(tx, req.ServerId, req.ServerGroupIds)
if err != nil {
return nil, err
}
return this.Success()
}
// UpdateServerIsOn 修改服务是否启用
func (this *ServerService) UpdateServerIsOn(ctx context.Context, req *pb.UpdateServerIsOnRequest) (*pb.RPCSuccess, error) {
_, userId, err := this.ValidateAdminAndUser(ctx, 0, 0)
@@ -199,7 +249,7 @@ func (this *ServerService) UpdateServerIsOn(ctx context.Context, req *pb.UpdateS
return nil, err
}
tx := this.NullTx()
var tx = this.NullTx()
if userId > 0 {
err = models.SharedServerDAO.CheckUserServer(tx, userId, req.ServerId)
@@ -832,8 +882,9 @@ func (this *ServerService) FindEnabledServer(ctx context.Context, req *pb.FindEn
continue
}
pbGroups = append(pbGroups, &pb.ServerGroup{
Id: int64(group.Id),
Name: group.Name,
Id: int64(group.Id),
Name: group.Name,
UserId: int64(group.UserId),
})
}
}

View File

@@ -6,6 +6,7 @@ import (
"github.com/TeaOSLab/EdgeAPI/internal/errors"
"github.com/TeaOSLab/EdgeAPI/internal/goman"
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
"github.com/TeaOSLab/EdgeAPI/internal/utils"
"github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/dbs"
"github.com/iwind/TeaGo/types"
@@ -43,6 +44,12 @@ func init() {
// 导入统计数据
goman.New(func() {
var duration = 30 * time.Minute
// 小内存的要快速处理
if utils.SystemMemoryGB() <= 2 {
duration = 15 * time.Minute
}
if Tea.IsTesting() {
// 测试条件下缩短时间,以便进行观察
duration = 10 * time.Second

View File

@@ -0,0 +1,107 @@
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
package services
import (
"context"
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
"github.com/TeaOSLab/EdgeAPI/internal/goman"
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/dbs"
"github.com/iwind/TeaGo/types"
"sync"
"time"
)
var serverBandwidthStatsMap = map[string]*pb.ServerBandwidthStat{} // key => bandwidth
var serverBandwidthStatsLocker = &sync.Mutex{}
func init() {
var ticker = time.NewTicker(5 * time.Minute)
if Tea.IsTesting() {
ticker = time.NewTicker(1 * time.Minute)
}
dbs.OnReadyDone(func() {
goman.New(func() {
for range ticker.C {
func() {
var tx *dbs.Tx
serverBandwidthStatsLocker.Lock()
var m = serverBandwidthStatsMap
serverBandwidthStatsMap = map[string]*pb.ServerBandwidthStat{}
serverBandwidthStatsLocker.Unlock()
for _, stat := range m {
err := models.SharedServerBandwidthStatDAO.UpdateServerBandwidth(tx, stat.UserId, stat.ServerId, stat.Day, stat.TimeAt, stat.Bytes)
if err != nil {
remotelogs.Error("ServerBandwidthStatService", "dump bandwidth stats failed: "+err.Error())
}
if stat.UserId > 0 {
err = models.SharedUserBandwidthStatDAO.UpdateUserBandwidth(tx, stat.UserId, stat.Day, stat.TimeAt, stat.Bytes)
if err != nil {
remotelogs.Error("SharedUserBandwidthStatDAO", "dump bandwidth stats failed: "+err.Error())
}
}
}
}()
}
})
})
}
// ServerBandwidthCacheKey 组合缓存Key
func ServerBandwidthCacheKey(serverId int64, day string, timeAt string) string {
return types.String(serverId) + "@" + day + "@" + timeAt
}
func ServerBandwidthGetCacheBytes(serverId int64, day string, timeAt string) int64 {
var key = ServerBandwidthCacheKey(serverId, day, timeAt)
var bytes int64 = 0
serverBandwidthStatsLocker.Lock()
stat, ok := serverBandwidthStatsMap[key]
if ok {
bytes = stat.Bytes
}
serverBandwidthStatsLocker.Unlock()
return bytes
}
type ServerBandwidthStatService struct {
BaseService
}
// UploadServerBandwidthStats 上传带宽统计
func (this *ServerBandwidthStatService) UploadServerBandwidthStats(ctx context.Context, req *pb.UploadServerBandwidthStatsRequest) (*pb.RPCSuccess, error) {
_, err := this.ValidateNode(ctx)
if err != nil {
return nil, err
}
for _, stat := range req.ServerBandwidthStats {
var key = ServerBandwidthCacheKey(stat.ServerId, stat.Day, stat.TimeAt)
serverBandwidthStatsLocker.Lock()
oldStat, ok := serverBandwidthStatsMap[key]
if ok {
oldStat.Bytes += stat.Bytes
} else {
serverBandwidthStatsMap[key] = &pb.ServerBandwidthStat{
Id: 0,
UserId: stat.UserId,
ServerId: stat.ServerId,
Day: stat.Day,
TimeAt: stat.TimeAt,
Bytes: stat.Bytes,
}
}
serverBandwidthStatsLocker.Unlock()
}
return this.Success()
}

View File

@@ -9,6 +9,7 @@ import (
"github.com/TeaOSLab/EdgeAPI/internal/db/models/stats"
"github.com/TeaOSLab/EdgeAPI/internal/errors"
"github.com/TeaOSLab/EdgeAPI/internal/rpc/tasks"
"github.com/TeaOSLab/EdgeAPI/internal/utils"
"github.com/TeaOSLab/EdgeCommon/pkg/configutils"
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
@@ -84,7 +85,7 @@ func (this *ServerStatBoardService) ComposeServerStatNodeClusterBoard(ctx contex
result.CountServers = countServers
// 按日流量统计
dayFrom := timeutil.Format("Ymd", time.Now().AddDate(0, 0, -14))
var dayFrom = timeutil.Format("Ymd", time.Now().AddDate(0, 0, -14))
dailyTrafficStats, err := stats.SharedNodeClusterTrafficDailyStatDAO.FindDailyStats(tx, req.NodeClusterId, dayFrom, timeutil.Format("Ymd"))
if err != nil {
return nil, err
@@ -102,8 +103,8 @@ func (this *ServerStatBoardService) ComposeServerStatNodeClusterBoard(ctx contex
}
// 小时流量统计
hourFrom := timeutil.Format("YmdH", time.Now().Add(-23*time.Hour))
hourTo := timeutil.Format("YmdH")
var hourFrom = timeutil.Format("YmdH", time.Now().Add(-23*time.Hour))
var hourTo = timeutil.Format("YmdH")
hourlyTrafficStats, err := stats.SharedNodeTrafficHourlyStatDAO.FindHourlyStatsWithClusterId(tx, req.NodeClusterId, hourFrom, hourTo)
if err != nil {
return nil, err
@@ -304,7 +305,7 @@ func (this *ServerStatBoardService) ComposeServerStatNodeBoard(ctx context.Conte
}
// 按日流量统计
dayFrom := timeutil.Format("Ymd", time.Now().AddDate(0, 0, -14))
var dayFrom = timeutil.Format("Ymd", time.Now().AddDate(0, 0, -14))
dailyTrafficStats, err := stats.SharedNodeTrafficDailyStatDAO.FindDailyStats(tx, "node", req.NodeId, dayFrom, timeutil.Format("Ymd"))
if err != nil {
return nil, err
@@ -322,8 +323,8 @@ func (this *ServerStatBoardService) ComposeServerStatNodeBoard(ctx context.Conte
}
// 小时流量统计
hourFrom := timeutil.Format("YmdH", time.Now().Add(-23*time.Hour))
hourTo := timeutil.Format("YmdH")
var hourFrom = timeutil.Format("YmdH", time.Now().Add(-23*time.Hour))
var hourTo = timeutil.Format("YmdH")
hourlyTrafficStats, err := stats.SharedNodeTrafficHourlyStatDAO.FindHourlyStatsWithNodeId(tx, "node", req.NodeId, hourFrom, hourTo)
if err != nil {
return nil, err
@@ -407,8 +408,100 @@ func (this *ServerStatBoardService) ComposeServerStatBoard(ctx context.Context,
var result = &pb.ComposeServerStatBoardResponse{}
var tx = this.NullTx()
// 带宽统计
{
var month = timeutil.Format("Ym")
var day = timeutil.Format("Ymd")
// 当前N分钟区间
{
// 查询最近的两个时段,以尽可能获取数据
var minute1 = timeutil.FormatTime("Hi", time.Now().Unix()/300*300)
var minute2 = timeutil.FormatTime("Hi", time.Now().Unix()/300*300-300)
for _, minute := range []string{minute1, minute2} {
bytes, err := models.SharedServerBandwidthStatDAO.FindMinutelyPeekBandwidthBytes(tx, req.ServerId, day, minute)
if err != nil {
return nil, err
}
if bytes == 0 {
// 尝试从缓存中读取
bytes = ServerBandwidthGetCacheBytes(req.ServerId, day, minute)
}
if bytes > 0 {
result.MinutelyPeekBandwidthBytes = bytes
break
}
}
}
// 当天
{
bytes, err := models.SharedServerBandwidthStatDAO.FindDailyPeekBandwidthBytes(tx, req.ServerId, day)
if err != nil {
return nil, err
}
result.DailyPeekBandwidthBytes = bytes
}
// 当月
{
bytes, err := models.SharedServerBandwidthStatDAO.FindMonthlyPeekBandwidthBytes(tx, req.ServerId, month)
if err != nil {
return nil, err
}
result.MonthlyPeekBandwidthBytes = bytes
}
// 上月
{
bytes, err := models.SharedServerBandwidthStatDAO.FindMonthlyPeekBandwidthBytes(tx, req.ServerId, timeutil.Format("Ym", time.Now().AddDate(0, -1, 0)))
if err != nil {
return nil, err
}
result.LastMonthlyPeekBandwidthBytes = bytes
}
}
{
var bandwidthMinutes = utils.RangeMinutes(time.Now(), 12, 5)
var bandwidthStatMap = map[string]*pb.ServerBandwidthStat{}
for _, r := range utils.GroupMinuteRanges(bandwidthMinutes) {
bandwidthStats, err := models.SharedServerBandwidthStatDAO.FindServerStats(tx, req.ServerId, r.Day, r.MinuteFrom, r.MinuteTo)
if err != nil {
return nil, err
}
for _, stat := range bandwidthStats {
bandwidthStatMap[stat.Day+"@"+stat.TimeAt] = &pb.ServerBandwidthStat{
Id: int64(stat.Id),
ServerId: int64(stat.ServerId),
Day: stat.Day,
TimeAt: stat.TimeAt,
Bytes: int64(stat.Bytes),
}
}
}
var pbBandwidthStats = []*pb.ServerBandwidthStat{}
for _, minute := range bandwidthMinutes {
stat, ok := bandwidthStatMap[minute.Day+"@"+minute.Minute]
if ok {
pbBandwidthStats = append(pbBandwidthStats, stat)
} else {
pbBandwidthStats = append(pbBandwidthStats, &pb.ServerBandwidthStat{
Id: 0,
ServerId: req.ServerId,
Day: minute.Day,
TimeAt: minute.Minute,
Bytes: ServerBandwidthGetCacheBytes(req.ServerId, minute.Day, minute.Minute), // 从当前缓存中读取
})
}
}
result.MinutelyBandwidthStats = pbBandwidthStats
}
// 按日流量统计
dayFrom := timeutil.Format("Ymd", time.Now().AddDate(0, 0, -14))
var dayFrom = timeutil.Format("Ymd", time.Now().AddDate(0, 0, -14))
dailyTrafficStats, err := models.SharedServerDailyStatDAO.FindDailyStats(tx, req.ServerId, dayFrom, timeutil.Format("Ymd"))
if err != nil {
return nil, err
@@ -426,8 +519,8 @@ func (this *ServerStatBoardService) ComposeServerStatBoard(ctx context.Context,
}
// 小时流量统计
hourFrom := timeutil.Format("YmdH", time.Now().Add(-23*time.Hour))
hourTo := timeutil.Format("YmdH")
var hourFrom = timeutil.Format("YmdH", time.Now().Add(-23*time.Hour))
var hourTo = timeutil.Format("YmdH")
hourlyTrafficStats, err := models.SharedServerDailyStatDAO.FindHourlyStats(tx, req.ServerId, hourFrom, hourTo)
if err != nil {
return nil, err

View File

@@ -387,16 +387,16 @@ func (this *UserService) UpdateUserLogin(ctx context.Context, req *pb.UpdateUser
// ComposeUserDashboard 取得用户Dashboard数据
func (this *UserService) ComposeUserDashboard(ctx context.Context, req *pb.ComposeUserDashboardRequest) (*pb.ComposeUserDashboardResponse, error) {
userId, err := this.ValidateUserNode(ctx)
_, userId, err := this.ValidateAdminAndUser(ctx, 0, 0)
if err != nil {
return nil, err
}
if userId != req.UserId {
return nil, this.PermissionError()
if userId > 0 {
req.UserId = userId
}
tx := this.NullTx()
var tx = this.NullTx()
// 网站数量
countServers, err := models.SharedServerDAO.CountAllEnabledServersMatch(tx, 0, "", req.UserId, 0, configutils.BoolStateAll, []string{})
@@ -404,61 +404,81 @@ func (this *UserService) ComposeUserDashboard(ctx context.Context, req *pb.Compo
return nil, err
}
// 时间相关
var currentMonth = timeutil.Format("Ym")
var currentDay = timeutil.Format("Ymd")
// 本月总流量
month := timeutil.Format("Ym")
monthlyTrafficBytes, err := models.SharedServerDailyStatDAO.SumUserMonthly(tx, req.UserId, month)
monthlyTrafficBytes, err := models.SharedServerDailyStatDAO.SumUserMonthly(tx, req.UserId, currentMonth)
if err != nil {
return nil, err
}
// 本月带宽峰值
monthlyPeekTrafficBytes, err := models.SharedServerDailyStatDAO.SumUserMonthlyPeek(tx, req.UserId, 0, month)
if err != nil {
return nil, err
var monthlyPeekBandwidthBytes int64 = 0
{
stat, err := models.SharedUserBandwidthStatDAO.FindUserPeekBandwidthInMonth(tx, req.UserId, currentMonth)
if err != nil {
return nil, err
}
if stat != nil {
monthlyPeekBandwidthBytes = int64(stat.Bytes)
}
}
// 本日带宽峰值
var dailyPeekBandwidthBytes int64 = 0
{
stat, err := models.SharedUserBandwidthStatDAO.FindUserPeekBandwidthInDay(tx, req.UserId, currentDay)
if err != nil {
return nil, err
}
if stat != nil {
dailyPeekBandwidthBytes = int64(stat.Bytes)
}
}
// 今日总流量
day := timeutil.Format("Ymd")
dailyTrafficBytes, err := models.SharedServerDailyStatDAO.SumUserDaily(tx, req.UserId, 0, day)
if err != nil {
return nil, err
}
// 今日带宽峰值
dailyPeekTrafficBytes, err := models.SharedServerDailyStatDAO.SumUserDailyPeek(tx, req.UserId, 0, day)
dailyTrafficBytes, err := models.SharedServerDailyStatDAO.SumUserDaily(tx, req.UserId, 0, currentDay)
if err != nil {
return nil, err
}
// 近 15 日流量带宽趋势
dailyTrafficStats := []*pb.ComposeUserDashboardResponse_DailyStat{}
dailyPeekTrafficStats := []*pb.ComposeUserDashboardResponse_DailyStat{}
var dailyTrafficStats = []*pb.ComposeUserDashboardResponse_DailyTrafficStat{}
var dailyPeekBandwidthStats = []*pb.ComposeUserDashboardResponse_DailyPeekBandwidthStat{}
for i := 14; i >= 0; i-- {
day := timeutil.Format("Ymd", time.Now().AddDate(0, 0, -i))
var day = timeutil.Format("Ymd", time.Now().AddDate(0, 0, -i))
dailyTrafficBytes, err := models.SharedServerDailyStatDAO.SumUserDaily(tx, req.UserId, 0, day)
// 流量
trafficBytes, err := models.SharedServerDailyStatDAO.SumUserDaily(tx, req.UserId, 0, day)
if err != nil {
return nil, err
}
dailyPeekTrafficBytes, err := models.SharedServerDailyStatDAO.SumUserDailyPeek(tx, req.UserId, 0, day)
// 峰值带宽
peekBandwidthBytesStat, err := models.SharedUserBandwidthStatDAO.FindUserPeekBandwidthInDay(tx, req.UserId, day)
if err != nil {
return nil, err
}
var peekBandwidthBytes int64 = 0
if peekBandwidthBytesStat != nil {
peekBandwidthBytes = int64(peekBandwidthBytesStat.Bytes)
}
dailyTrafficStats = append(dailyTrafficStats, &pb.ComposeUserDashboardResponse_DailyStat{Day: day, Count: dailyTrafficBytes})
dailyPeekTrafficStats = append(dailyPeekTrafficStats, &pb.ComposeUserDashboardResponse_DailyStat{Day: day, Count: dailyPeekTrafficBytes})
dailyTrafficStats = append(dailyTrafficStats, &pb.ComposeUserDashboardResponse_DailyTrafficStat{Day: day, Bytes: trafficBytes})
dailyPeekBandwidthStats = append(dailyPeekBandwidthStats, &pb.ComposeUserDashboardResponse_DailyPeekBandwidthStat{Day: day, Bytes: peekBandwidthBytes})
}
return &pb.ComposeUserDashboardResponse{
CountServers: countServers,
MonthlyTrafficBytes: monthlyTrafficBytes,
MonthlyPeekTrafficBytes: monthlyPeekTrafficBytes,
DailyTrafficBytes: dailyTrafficBytes,
DailyPeekTrafficBytes: dailyPeekTrafficBytes,
DailyTrafficStats: dailyTrafficStats,
DailyPeekTrafficStats: dailyPeekTrafficStats,
CountServers: countServers,
MonthlyTrafficBytes: monthlyTrafficBytes,
MonthlyPeekBandwidthBytes: monthlyPeekBandwidthBytes,
DailyTrafficBytes: dailyTrafficBytes,
DailyPeekBandwidthBytes: dailyPeekBandwidthBytes,
DailyTrafficStats: dailyTrafficStats,
DailyPeekBandwidthStats: dailyPeekBandwidthStats,
}, nil
}

View File

@@ -0,0 +1,228 @@
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
package services
import (
"context"
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
"github.com/TeaOSLab/EdgeAPI/internal/errors"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/userconfigs"
)
// UserIdentityService 用户身份认证服务
type UserIdentityService struct {
BaseService
}
// CreateUserIdentity 创建身份认证信息
func (this *UserIdentityService) CreateUserIdentity(ctx context.Context, req *pb.CreateUserIdentityRequest) (*pb.CreateUserIdentityResponse, error) {
userId, err := this.ValidateUserNode(ctx)
if err != nil {
return nil, err
}
switch req.Type {
case userconfigs.UserIdentityTypeIDCard:
if len(req.FileIds) < 2 {
return nil, errors.New("need for file(s) for id card")
}
default:
return nil, errors.New("unknown identity type '" + req.Type + "'")
}
var tx = this.NullTx()
identityId, err := models.SharedUserIdentityDAO.CreateUserIdentity(tx, userId, req.Type, req.RealName, req.Number, req.FileIds)
if err != nil {
return nil, err
}
return &pb.CreateUserIdentityResponse{UserIdentityId: identityId}, nil
}
// FindUserEnabledUserIdentityWithType 查看身份认证信息
func (this *UserIdentityService) FindUserEnabledUserIdentityWithType(ctx context.Context, req *pb.FindUserEnabledUserIdentityWithTypeRequest) (*pb.FindUserEnabledUserIdentityWithTypeResponse, error) {
_, userId, err := this.ValidateAdminAndUser(ctx, 0, 0)
if err != nil {
return nil, err
}
if userId > 0 {
req.UserId = userId
}
var tx = this.NullTx()
identity, err := models.SharedUserIdentityDAO.FindEnabledUserIdentityWithType(tx, req.UserId, req.Type)
if err != nil {
return nil, err
}
if identity == nil {
return &pb.FindUserEnabledUserIdentityWithTypeResponse{
UserIdentity: nil,
}, nil
}
return &pb.FindUserEnabledUserIdentityWithTypeResponse{
UserIdentity: &pb.UserIdentity{
Id: int64(identity.Id),
Type: identity.Type,
RealName: identity.RealName,
Number: identity.Number,
FileIds: identity.DecodeFileIds(),
Status: identity.Status,
CreatedAt: int64(identity.CreatedAt),
UpdatedAt: int64(identity.UpdatedAt),
SubmittedAt: int64(identity.SubmittedAt),
RejectedAt: int64(identity.RejectedAt),
VerifiedAt: int64(identity.VerifiedAt),
},
}, nil
}
// UpdateUserIdentity 修改身份认证信息
func (this *UserIdentityService) UpdateUserIdentity(ctx context.Context, req *pb.UpdateUserIdentityRequest) (*pb.RPCSuccess, error) {
userId, err := this.ValidateUserNode(ctx)
if err != nil {
return nil, err
}
var tx = this.NullTx()
// 检查用户
err = models.SharedUserIdentityDAO.CheckUserIdentity(tx, userId, req.UserIdentityId)
if err != nil {
return nil, err
}
// 检查状态
status, err := models.SharedUserIdentityDAO.FindUserIdentityStatus(tx, req.UserIdentityId)
if err != nil {
return nil, err
}
if len(status) > 0 && status != userconfigs.UserIdentityStatusNone {
return nil, errors.New("identity status should be '" + userconfigs.UserIdentityStatusNone + "' instead of '" + status + "'")
}
err = models.SharedUserIdentityDAO.UpdateUserIdentity(tx, req.UserIdentityId, req.Type, req.RealName, req.Number, req.FileIds)
if err != nil {
return nil, err
}
return this.Success()
}
// SubmitUserIdentity 提交审核身份认证信息
func (this *UserIdentityService) SubmitUserIdentity(ctx context.Context, req *pb.SubmitUserIdentityRequest) (*pb.RPCSuccess, error) {
userId, err := this.ValidateUserNode(ctx)
if err != nil {
return nil, err
}
var tx = this.NullTx()
// 检查用户
err = models.SharedUserIdentityDAO.CheckUserIdentity(tx, userId, req.UserIdentityId)
if err != nil {
return nil, err
}
// 检查状态
status, err := models.SharedUserIdentityDAO.FindUserIdentityStatus(tx, req.UserIdentityId)
if err != nil {
return nil, err
}
if len(status) > 0 && status != userconfigs.UserIdentityStatusNone {
return nil, errors.New("identity status should be '" + userconfigs.UserIdentityStatusNone + "' instead of '" + status + "'")
}
err = models.SharedUserIdentityDAO.SubmitUserIdentity(tx, req.UserIdentityId)
if err != nil {
return nil, err
}
return this.Success()
}
// CancelUserIdentity 取消提交身份审核认证信息
func (this *UserIdentityService) CancelUserIdentity(ctx context.Context, req *pb.CancelUserIdentityRequest) (*pb.RPCSuccess, error) {
userId, err := this.ValidateUserNode(ctx)
if err != nil {
return nil, err
}
var tx = this.NullTx()
// 检查用户
err = models.SharedUserIdentityDAO.CheckUserIdentity(tx, userId, req.UserIdentityId)
if err != nil {
return nil, err
}
// 检查状态
status, err := models.SharedUserIdentityDAO.FindUserIdentityStatus(tx, req.UserIdentityId)
if err != nil {
return nil, err
}
if status != userconfigs.UserIdentityStatusSubmitted {
return nil, errors.New("identity status should be '" + userconfigs.UserIdentityStatusSubmitted + "' instead of '" + status + "'")
}
err = models.SharedUserIdentityDAO.CancelUserIdentity(tx, req.UserIdentityId)
if err != nil {
return nil, err
}
return this.Success()
}
// RejectUserIdentity 拒绝用户身份认证信息
func (this *UserIdentityService) RejectUserIdentity(ctx context.Context, req *pb.RejectUserIdentityRequest) (*pb.RPCSuccess, error) {
_, err := this.ValidateAdmin(ctx, 0)
if err != nil {
return nil, err
}
var tx = this.NullTx()
// 检查状态
status, err := models.SharedUserIdentityDAO.FindUserIdentityStatus(tx, req.UserIdentityId)
if err != nil {
return nil, err
}
if status != userconfigs.UserIdentityStatusSubmitted {
return nil, errors.New("identity status should be '" + userconfigs.UserIdentityStatusSubmitted + "' instead of '" + status + "'")
}
err = models.SharedUserIdentityDAO.RejectUserIdentity(tx, req.UserIdentityId)
if err != nil {
return nil, err
}
return this.Success()
}
// VerifyUserIdentity 通过用户身份认证信息
func (this *UserIdentityService) VerifyUserIdentity(ctx context.Context, req *pb.VerifyUserIdentityRequest) (*pb.RPCSuccess, error) {
_, err := this.ValidateAdmin(ctx, 0)
if err != nil {
return nil, err
}
var tx = this.NullTx()
// 检查状态
status, err := models.SharedUserIdentityDAO.FindUserIdentityStatus(tx, req.UserIdentityId)
if err != nil {
return nil, err
}
if status != userconfigs.UserIdentityStatusSubmitted {
return nil, errors.New("identity status should be '" + userconfigs.UserIdentityStatusSubmitted + "' instead of '" + status + "'")
}
err = models.SharedUserIdentityDAO.VerifyUserIdentity(tx, req.UserIdentityId)
if err != nil {
return nil, err
}
return this.Success()
}

File diff suppressed because one or more lines are too long

View File

@@ -78,6 +78,9 @@ var upgradeFuncs = []*upgradeVersion{
{
"0.4.8", upgradeV0_4_8,
},
{
"0.4.9", upgradeV0_4_9,
},
}
// UpgradeSQLData 升级SQL数据
@@ -676,7 +679,7 @@ func upgradeV0_4_7(db *dbs.DB) error {
return nil
}
// v0.4.7
// v0.4.8
func upgradeV0_4_8(db *dbs.DB) error {
// 设置edgeIPLists中的serverId
{
@@ -727,3 +730,65 @@ func upgradeV0_4_8(db *dbs.DB) error {
return nil
}
// v0.4.9
func upgradeV0_4_9(db *dbs.DB) error {
// 升级用户UI配置
{
one, err := db.FindOne("SELECT value FROM edgeSysSettings WHERE code=?", systemconfigs.SettingCodeUserUIConfig)
if err != nil {
return err
}
if one != nil {
var valueJSON = one.GetBytes("value")
if len(valueJSON) > 0 {
var config = &systemconfigs.UserUIConfig{}
err = json.Unmarshal(valueJSON, config)
if err == nil {
config.ShowTrafficCharts = true
config.ShowBandwidthCharts = true
config.BandwidthUnit = systemconfigs.BandwidthUnitBit
configJSON, err := json.Marshal(config)
if err != nil {
return errors.New("encode UserUIConfig failed: " + err.Error())
} else {
_, err := db.Exec("UPDATE edgeSysSettings SET value=? WHERE code=?", configJSON, systemconfigs.SettingCodeUserUIConfig)
if err != nil {
return err
}
}
}
}
}
}
// 升级管理配置
{
one, err := db.FindOne("SELECT value FROM edgeSysSettings WHERE code=?", systemconfigs.SettingCodeAdminSecurityConfig)
if err != nil {
return err
}
if one != nil {
var valueJSON = one.GetBytes("value")
if len(valueJSON) > 0 {
var config = &systemconfigs.SecurityConfig{}
err = json.Unmarshal(valueJSON, config)
if err == nil {
config.DenySearchEngines = true
config.DenySpiders = true
configJSON, err := json.Marshal(config)
if err != nil {
return errors.New("encode SecurityConfig failed: " + err.Error())
} else {
_, err := db.Exec("UPDATE edgeSysSettings SET value=? WHERE code=?", configJSON, systemconfigs.SettingCodeAdminSecurityConfig)
if err != nil {
return err
}
}
}
}
}
}
return nil
}

View File

@@ -194,3 +194,23 @@ func TestUpgradeSQLData_v0_4_8(t *testing.T) {
}
t.Log("ok")
}
func TestUpgradeSQLData_v0_4_9(t *testing.T) {
db, err := dbs.NewInstanceFromConfig(&dbs.DBConfig{
Driver: "mysql",
Dsn: "root:123456@tcp(127.0.0.1:3306)/db_edge?charset=utf8mb4&timeout=30s",
Prefix: "edge",
})
if err != nil {
t.Fatal(err)
}
defer func() {
_ = db.Close()
}()
err = upgradeV0_4_9(db)
if err != nil {
t.Fatal(err)
}
t.Log("ok")
}

View File

@@ -0,0 +1,77 @@
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
package maputils
import (
"sync"
)
type FixedMap struct {
m map[string]any
keys []string
maxSize int
locker sync.RWMutex
}
func NewFixedMap(maxSize int) *FixedMap {
return &FixedMap{
m: map[string]any{},
maxSize: maxSize,
}
}
func (this *FixedMap) Set(key string, item any) {
if this.maxSize <= 0 {
return
}
this.locker.Lock()
defer this.locker.Unlock()
_, ok := this.m[key]
if ok {
this.m[key] = item
// TODO 将key转到keys末尾
} else {
// 是否已满
if len(this.keys) >= this.maxSize {
var firstKey = this.keys[0]
delete(this.m, firstKey)
this.keys = this.keys[1:]
}
// 新加入
this.m[key] = item
this.keys = append(this.keys, key)
}
}
func (this *FixedMap) Get(key string) (value any, ok bool) {
this.locker.RLock()
value, ok = this.m[key]
this.locker.RUnlock()
return
}
func (this *FixedMap) Has(key string) bool {
this.locker.RLock()
_, ok := this.m[key]
this.locker.RUnlock()
return ok
}
func (this *FixedMap) Size() int {
this.locker.RLock()
defer this.locker.RUnlock()
return len(this.keys)
}
func (this *FixedMap) Reset() {
this.locker.Lock()
this.m = map[string]any{}
this.keys = []string{}
this.locker.Unlock()
}

View File

@@ -0,0 +1,42 @@
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
package maputils_test
import (
maputils "github.com/TeaOSLab/EdgeAPI/internal/utils/maps"
"github.com/iwind/TeaGo/assert"
"testing"
)
func TestNewFixedMap(t *testing.T) {
var a = assert.NewAssertion(t)
{
var m = maputils.NewFixedMap(5)
m.Set("a", 1)
m.Set("b", 2)
a.IsTrue(m.Has("a"))
a.IsTrue(m.Has("b"))
a.IsFalse(m.Has("c"))
}
{
var m = maputils.NewFixedMap(5)
m.Set("a", 1)
m.Set("b", 2)
m.Set("c", 3)
m.Set("d", 4)
m.Set("e", 5)
a.IsTrue(m.Size() == 5)
m.Set("f", 6)
a.IsTrue(m.Size() == 5)
a.IsFalse(m.Has("a"))
}
{
var m = maputils.NewFixedMap(5)
m.Set("a", 1)
t.Log(m.Get("a"))
t.Log(m.Get("b"))
}
}

21
internal/utils/sha1.go Normal file
View File

@@ -0,0 +1,21 @@
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
package utils
import (
"crypto/sha1"
"fmt"
"github.com/iwind/TeaGo/rands"
"github.com/iwind/TeaGo/types"
"sync/atomic"
"time"
)
const sha1RandomPrefix = "SHA1_RANDOM"
var sha1Id int64 = 0
func Sha1RandomString() string {
var s = sha1RandomPrefix + types.String(time.Now().UnixNano()) + "@" + types.String(rands.Int64()) + "@" + types.String(atomic.AddInt64(&sha1Id, 1))
return fmt.Sprintf("%x", sha1.Sum([]byte(s)))
}

View File

@@ -0,0 +1,16 @@
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
package utils_test
import (
"github.com/TeaOSLab/EdgeAPI/internal/utils"
"github.com/iwind/TeaGo/types"
"testing"
)
func TestSha1Random(t *testing.T) {
for i := 0; i < 10; i++ {
var s = utils.Sha1RandomString()
t.Log("["+types.String(len(s))+"]", s)
}
}

27
internal/utils/system.go Normal file
View File

@@ -0,0 +1,27 @@
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
package utils
import (
"github.com/shirou/gopsutil/v3/mem"
)
var systemTotalMemory = -1
func init() {
_ = SystemMemoryGB()
}
func SystemMemoryGB() int {
if systemTotalMemory > 0 {
return systemTotalMemory
}
stat, err := mem.VirtualMemory()
if err != nil {
return 0
}
systemTotalMemory = int(stat.Total / 1024 / 1024 / 1024)
return systemTotalMemory
}

View File

@@ -0,0 +1,14 @@
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
package utils_test
import (
"github.com/TeaOSLab/EdgeAPI/internal/utils"
"testing"
)
func TestSystemMemoryGB(t *testing.T) {
t.Log(utils.SystemMemoryGB())
t.Log(utils.SystemMemoryGB())
t.Log(utils.SystemMemoryGB())
}

View File

@@ -9,6 +9,19 @@ import (
"time"
)
// 分钟时间点
type timeMinute struct {
Day string
Minute string
}
// 分钟时间范围
type timeMinuteRange struct {
Day string
MinuteFrom string
MinuteTo string
}
// RangeDays 计算日期之间的所有日期格式为YYYYMMDD
func RangeDays(dayFrom string, dayTo string) ([]string, error) {
ok, err := regexp.MatchString(`^\d{8}$`, dayFrom)
@@ -79,15 +92,15 @@ func RangeMonths(dayFrom string, dayTo string) ([]string, error) {
dayFrom, dayTo = dayTo, dayFrom
}
result := []string{dayFrom[:6]}
var result = []string{dayFrom[:6]}
year := types.Int(dayFrom[:4])
month := types.Int(dayFrom[4:6])
day := types.Int(dayFrom[6:])
t := time.Date(year, time.Month(month), day, 0, 0, 0, 0, time.Local)
var year = types.Int(dayFrom[:4])
var month = types.Int(dayFrom[4:6])
var day = types.Int(dayFrom[6:])
var t = time.Date(year, time.Month(month), day, 0, 0, 0, 0, time.Local)
for {
t = t.AddDate(0, 0, 20)
newDay := timeutil.Format("Ymd", t)
var newDay = timeutil.Format("Ymd", t)
if newDay <= dayTo {
var monthString = newDay[:6]
if !lists.ContainsString(result, monthString) {
@@ -129,17 +142,17 @@ func RangeHours(hourFrom string, hourTo string) ([]string, error) {
}
// 不能超过N天
maxHours := 100 - 1 // -1 是去掉默认加入的dayFrom
result := []string{hourFrom}
var maxHours = 100 - 1 // -1 是去掉默认加入的dayFrom
var result = []string{hourFrom}
year := types.Int(hourFrom[:4])
month := types.Int(hourFrom[4:6])
day := types.Int(hourFrom[6:8])
hour := types.Int(hourFrom[8:])
t := time.Date(year, time.Month(month), day, hour, 0, 0, 0, time.Local)
var year = types.Int(hourFrom[:4])
var month = types.Int(hourFrom[4:6])
var day = types.Int(hourFrom[6:8])
var hour = types.Int(hourFrom[8:])
var t = time.Date(year, time.Month(month), day, hour, 0, 0, 0, time.Local)
for {
t = t.Add(1 * time.Hour)
newHour := timeutil.Format("YmdH", t)
var newHour = timeutil.Format("YmdH", t)
if newHour <= hourTo {
result = append(result, newHour)
} else {
@@ -154,3 +167,56 @@ func RangeHours(hourFrom string, hourTo string) ([]string, error) {
return result, nil
}
// RangeMinutes 计算若干个时间点,返回结果为 [ [day1, minute1], [day2, minute2] ... ]
func RangeMinutes(toTime time.Time, count int, everyMinutes int64) []timeMinute {
var everySeconds = everyMinutes * 60
if everySeconds <= 0 {
everySeconds = 300
}
var result = []timeMinute{}
var fromTime = time.Unix(toTime.Unix()-everySeconds*int64(count-1), 0)
for {
var timestamp = fromTime.Unix() / everySeconds * everySeconds
result = append(result, timeMinute{
Day: timeutil.FormatTime("Ymd", timestamp),
Minute: timeutil.FormatTime("Hi", timestamp),
})
fromTime = time.Unix(fromTime.Unix()+everySeconds, 0)
count--
if count <= 0 {
break
}
}
return result
}
// GroupMinuteRanges 将时间点分组
func GroupMinuteRanges(minutes []timeMinute) []timeMinuteRange {
var result = []*timeMinuteRange{}
var lastDay = ""
var lastRange *timeMinuteRange
for _, minute := range minutes {
if minute.Day != lastDay {
lastDay = minute.Day
lastRange = &timeMinuteRange{
Day: minute.Day,
MinuteFrom: minute.Minute,
MinuteTo: minute.Minute,
}
result = append(result, lastRange)
} else {
if lastRange != nil {
lastRange.MinuteTo = minute.Minute
}
}
}
var finalResult = []timeMinuteRange{}
for _, minutePtr := range result {
finalResult = append(finalResult, *minutePtr)
}
return finalResult
}

View File

@@ -1,9 +1,13 @@
package utils
package utils_test
import "testing"
import (
"github.com/TeaOSLab/EdgeAPI/internal/utils"
"testing"
"time"
)
func TestRangeDays(t *testing.T) {
days, err := RangeDays("20210101", "20210115")
days, err := utils.RangeDays("20210101", "20210115")
if err != nil {
t.Fatal(err)
}
@@ -11,7 +15,7 @@ func TestRangeDays(t *testing.T) {
}
func TestRangeMonth(t *testing.T) {
days, err := RangeMonths("20200101", "20210115")
days, err := utils.RangeMonths("20200101", "20210115")
if err != nil {
t.Fatal(err)
}
@@ -20,7 +24,7 @@ func TestRangeMonth(t *testing.T) {
func TestRangeHours(t *testing.T) {
{
hours, err := RangeHours("2021010100", "2021010123")
hours, err := utils.RangeHours("2021010100", "2021010123")
if err != nil {
t.Fatal(err)
}
@@ -28,10 +32,49 @@ func TestRangeHours(t *testing.T) {
}
{
hours, err := RangeHours("2021010105", "2021010112")
hours, err := utils.RangeHours("2021010105", "2021010112")
if err != nil {
t.Fatal(err)
}
t.Log(hours)
}
}
func TestRangeMinutes(t *testing.T) {
{
var minutes = utils.RangeMinutes(time.Now(), 5, 5)
t.Log(minutes)
}
{
var minutes = utils.RangeMinutes(time.Now(), 5, 3)
t.Log(minutes)
}
{
var now = time.Now()
var hour = now.Hour()
var minute = now.Minute()
now = now.Add(-time.Duration(hour) * time.Hour)
now = now.Add(-time.Duration(minute-7) * time.Minute) // 后一天的 00:07 开始往前计算
var minutes = utils.RangeMinutes(now, 5, 5)
t.Log(minutes)
}
}
func TestGroupMinuteRanges(t *testing.T) {
{
var minutes = utils.GroupMinuteRanges(utils.RangeMinutes(time.Now(), 5, 5))
t.Log(minutes)
}
{
var now = time.Now()
var hour = now.Hour()
var minute = now.Minute()
now = now.Add(-time.Duration(hour) * time.Hour)
now = now.Add(-time.Duration(minute-7) * time.Minute) // 后一天的 00:07 开始往前计算
var minutes = utils.GroupMinuteRanges(utils.RangeMinutes(now, 5, 5))
t.Log(minutes)
}
}