Compare commits

..

75 Commits

Author SHA1 Message Date
刘祥超
476ff91bf8 版本号修改为1.0.4 2023-04-24 10:18:26 +08:00
刘祥超
ac6b10489e DNSPod支持自定义线路分组 2023-04-24 09:37:26 +08:00
刘祥超
9352e1837f 创建初始化用户 2023-04-23 20:13:55 +08:00
刘祥超
ddec102d18 远程升级API节点时自动上传边缘节点安装文件 2023-04-23 19:42:51 +08:00
刘祥超
0d50b9b0cc 创建ACME用户、ACME任务时可以指定平台用户 2023-04-23 15:00:13 +08:00
刘祥超
20b4b47eea 优化edgeIPItems索引 2023-04-23 09:44:06 +08:00
刘祥超
ee8396c760 修复在节点列表中不能同时使用关键词和排序的问题 2023-04-21 15:27:24 +08:00
刘祥超
c3fa6a753a 修复只有一个泛域名时无法查询匹配证书的问题 2023-04-21 10:41:20 +08:00
刘祥超
fbe4de2e94 节点版本号修改为1.1.0 2023-04-19 21:02:01 +08:00
刘祥超
f5c7108799 IP库查询提供更多信息 2023-04-19 20:36:48 +08:00
刘祥超
5825a7e654 修复一处访问日志可能无法正确获得对应日期的问题 2023-04-18 17:54:01 +08:00
刘祥超
a6911117af 优化可用内存检查 2023-04-11 18:52:43 +08:00
刘祥超
b428db4f5e 版本号改为1.1.0 2023-04-10 21:03:31 +08:00
刘祥超
e4145a2059 优化启动速度 2023-04-10 20:57:38 +08:00
刘祥超
af13357985 创建缓存任务接口增加参数校验 2023-04-10 17:13:20 +08:00
刘祥超
1b949bd056 版本号修改为1.0.1 2023-04-10 09:18:12 +08:00
刘祥超
c4e415a72f 修复一个单词拼写错误/如果创建服务时没有指定服务名,则自动取第一个域名作为服务名 2023-04-09 20:11:36 +08:00
刘祥超
39cb95184d 查询弱密码管理员时只查询已启用的管理员 2023-04-09 17:31:09 +08:00
刘祥超
a7abca6c09 Update sql.json 2023-04-09 17:23:37 +08:00
刘祥超
894eff89ba 去除不需要的接口 2023-04-09 17:04:32 +08:00
刘祥超
35558f1d38 版本号更改为1.0.0 2023-04-09 16:19:52 +08:00
刘祥超
5a93ec0e32 增加服务之间拷贝配置的API(开源版本只有定义,没有完全实现) 2023-04-09 16:01:23 +08:00
刘祥超
73164de93e 查询快过期证书时,只查询启用的 2023-04-08 09:15:03 +08:00
刘祥超
199349084e 提供批量更新服务配置API(阶段性提交) 2023-04-06 20:49:22 +08:00
刘祥超
648fc2cac3 审计日志列表增加级别筛选 2023-04-06 10:06:56 +08:00
刘祥超
43f34950f3 自动检查管理员弱密码并提醒 2023-04-04 17:26:08 +08:00
刘祥超
1f0182e4a5 优化错误提示 2023-04-04 15:56:44 +08:00
刘祥超
3f972571b0 5秒盾策略变化时只更新策略配置 2023-04-03 16:11:48 +08:00
刘祥超
0618ca9f8a 优化操作IP条目时检查用户ID的相关代码 2023-04-03 10:02:17 +08:00
刘祥超
efd0823b25 上传SQL 2023-04-01 21:46:54 +08:00
刘祥超
af5ca9faf5 修复删除IP名单中IP时状态设置错误的问题 2023-04-01 20:48:47 +08:00
刘祥超
87c5eeb829 可以批量上传IP名单 2023-03-31 21:42:15 +08:00
刘祥超
df775272be 提供修改网站名称的接口 2023-03-31 15:30:22 +08:00
刘祥超
dbeabe4379 节点中增加授权信息 2023-03-31 12:39:01 +08:00
刘祥超
dd33504416 IP库文件可以加密 2023-03-30 20:00:22 +08:00
刘祥超
d45dca4edb IP制品列表中增加文件尺寸 2023-03-29 20:09:00 +08:00
刘祥超
b4472271ce 优化证书到期提醒等相关消息 2023-03-28 16:52:04 +08:00
刘祥超
138eddf771 修复发送站内消息时将标题作为内容的Bug 2023-03-28 16:25:18 +08:00
刘祥超
f0667abe55 删除edgeServers表中的state索引,防止查询时产生索引冲突 2023-03-27 17:14:48 +08:00
刘祥超
873af38807 优化服务列表查询 2023-03-27 17:14:12 +08:00
刘祥超
9bf46af088 增加默认CC设置 2023-03-26 12:41:01 +08:00
刘祥超
3a3b5bca20 上传单个证书时也可以选择所属用户 2023-03-26 12:24:31 +08:00
刘祥超
4806025f89 实现自动匹配证书和批量选择证书功能 2023-03-25 20:51:08 +08:00
刘祥超
d7c757a2a1 增加批量上传证书接口、使用域名查询证书接口 2023-03-24 19:07:43 +08:00
刘祥超
3e8873d828 修复查看服务24小时流量统计会产生panic的问题 2023-03-23 15:45:03 +08:00
刘祥超
84484b6538 优化服务带宽查询速度 2023-03-23 11:23:16 +08:00
刘祥超
d36e9e80ee 上传流量数据时同时上传服务所属用户ID 2023-03-22 19:33:25 +08:00
刘祥超
1fb831ca58 修复测试用例 2023-03-22 19:10:52 +08:00
刘祥超
5e20553602 合并部分流量查询和带宽查询 2023-03-22 17:54:44 +08:00
刘祥超
0f83d8ec66 导出SQL结构时使用embed取代生成sql.go 2023-03-22 11:19:58 +08:00
刘祥超
e45a6cbcb5 优化域名查询程序 2023-03-21 11:38:20 +08:00
刘祥超
ba1fd07555 增加edge-api token --role=[admin|user|api]命令用来快速查询节点Token 2023-03-19 21:24:24 +08:00
刘祥超
a70b4bfaf3 更新相关库 2023-03-19 17:51:21 +08:00
刘祥超
9cf47ae1af DNS集群增加自动检测端口选项 2023-03-19 17:44:56 +08:00
刘祥超
7f58d65a57 修复DataMap无法在多个节点之间共享的问题 2023-03-19 10:26:05 +08:00
刘祥超
4d40dd03de 优化节点压缩程序 2023-03-18 22:44:23 +08:00
刘祥超
e3ce79c9fc 增加RPC消息最大尺寸到512MB 2023-03-18 22:44:04 +08:00
刘祥超
f543edac1a 节点组合配置时服务间可以共用证书数据 2023-03-18 22:18:13 +08:00
刘祥超
1ce11a5745 优化服务配置组合 2023-03-18 19:52:42 +08:00
刘祥超
ab56c7451a DNS解析发生变化时立即触发同步任务 2023-03-18 16:53:08 +08:00
刘祥超
9800bbb661 修复无法同时对相同对象执行多次DNS解析任务的问题 2023-03-18 16:40:00 +08:00
刘祥超
8c4d2e7301 查询节点DNS信息时可以区分节点是否已安装 2023-03-18 16:05:10 +08:00
刘祥超
2c17675b6a 增加分隔关键词函数 2023-03-18 11:10:44 +08:00
刘祥超
3b30705f33 在API节点启动时,如果无法连接到本地MySQL数据库,则尝试启动固定位置上的MySQL 2023-03-17 16:02:37 +08:00
刘祥超
4cd9c5071d 版本号更改为0.6.5 2023-03-17 15:53:52 +08:00
刘祥超
763a72d526 版本号变更为0.6.4.2 2023-03-16 08:59:59 +08:00
刘祥超
bd762ad10b 读取节点列表时可以按照连接数排序 2023-03-15 17:57:49 +08:00
刘祥超
56574ea3d9 节点看板数据中增加当月、昨日、今日流量 2023-03-15 17:02:09 +08:00
刘祥超
6a31605519 集群看板数据中增加当月流量 2023-03-15 16:24:36 +08:00
刘祥超
c7abeeaf07 优化代码 2023-03-14 09:17:05 +08:00
刘祥超
c11483ec6d 允许API之间相互调用 2023-03-13 16:15:31 +08:00
刘祥超
c3713cefc9 生成数据库结构sql.go文件的同时生成sql.json 2023-03-13 14:32:39 +08:00
刘祥超
2098bd4d32 版本号改为0.6.5 2023-03-13 14:29:34 +08:00
刘祥超
7a6a02284e 修复搜索引擎IP库可能无法升级的Bug 2023-03-13 10:36:41 +08:00
刘祥超
c749a7b088 版本号改为0.6.4.1 2023-03-13 10:36:03 +08:00
112 changed files with 196507 additions and 747 deletions

View File

@@ -17,6 +17,7 @@ import (
"github.com/iwind/gosock/pkg/gosock" "github.com/iwind/gosock/pkg/gosock"
"log" "log"
"os" "os"
"strings"
) )
func main() { func main() {
@@ -188,6 +189,38 @@ func main() {
} }
} }
}) })
app.On("token", func() {
var role = ""
if len(os.Args) <= 2 {
fmt.Println("require --role parameter")
return
}
var set = flag.NewFlagSet("", flag.ExitOnError)
set.StringVar(&role, "role", "", "edge-api token --role=[admin|user|api]")
_ = set.Parse(os.Args[2:])
var sock = gosock.NewTmpSock(teaconst.ProcessName)
reply, err := sock.Send(&gosock.Command{Code: "lookupToken", Params: map[string]any{
"role": role,
}})
if err != nil {
fmt.Println("[ERROR]" + err.Error())
} else {
var resultMap = maps.NewMap(reply.Params)
if resultMap.GetBool("isOk") {
var tokens = resultMap.GetSlice("tokens")
fmt.Printf("%-35s | %-35s\n", "nodeId", "secret")
fmt.Println(strings.Repeat("-", 70))
for _, tokenMap := range tokens {
var m = maps.NewMap(tokenMap)
fmt.Printf("%-35s | %-35s\n", m.GetString("nodeId"), m.GetString("secret"))
}
} else {
fmt.Println("[ERROR]" + resultMap.GetString("err"))
}
}
})
app.Run(func() { app.Run(func() {
nodes.NewAPINode().Start() nodes.NewAPINode().Start()

View File

@@ -4,12 +4,11 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/TeaOSLab/EdgeAPI/internal/setup" "github.com/TeaOSLab/EdgeAPI/internal/setup"
"github.com/iwind/TeaGo/Tea"
_ "github.com/iwind/TeaGo/bootstrap" _ "github.com/iwind/TeaGo/bootstrap"
"github.com/iwind/TeaGo/dbs" "github.com/iwind/TeaGo/dbs"
"go/format"
"os" "os"
"path/filepath" "path/filepath"
"strconv"
) )
func main() { func main() {
@@ -23,53 +22,20 @@ func main() {
fmt.Println("[ERROR]" + err.Error()) fmt.Println("[ERROR]" + err.Error())
return return
} }
resultsJSON, err := json.Marshal(results)
prettyResultsJSON, err := json.MarshalIndent(results, "", " ")
if err != nil { if err != nil {
fmt.Println("[ERROR]" + err.Error()) fmt.Println("[ERROR]" + err.Error())
return return
} }
dir, _ := os.Getwd()
var sqlFile string
for i := 0; i < 5; i++ {
lookupFile := dir + "/internal/setup/sql.go"
_, err = os.Stat(lookupFile)
if err != nil {
dir = filepath.Dir(dir)
continue
}
sqlFile = lookupFile
}
if len(sqlFile) == 0 { // 写入到 sql.json 中
fmt.Println("[ERROR]can not find sql.go") var dir = filepath.Dir(Tea.Root)
return err = os.WriteFile(dir+"/internal/setup/sql.json", prettyResultsJSON, 0666)
}
content := []byte(`package setup
import (
"encoding/json"
"github.com/iwind/TeaGo/logs"
)
// 最新版本的数据库SQL语句用来对比并升级已有的数据库
// 由 sql-dump/main.go 自动生成
func init() {
err := json.Unmarshal([]byte(` + strconv.Quote(string(resultsJSON)) + `), LatestSQLResult)
if err != nil { if err != nil {
logs.Println("[ERROR]load sql failed: " + err.Error()) fmt.Println("[ERROR]" + err.Error())
}
}
`)
dst, err := format.Source(content)
if err != nil {
fmt.Println("[ERROR]format code failed: " + err.Error())
return return
} }
err = os.WriteFile(sqlFile, dst, 0666)
if err != nil {
fmt.Println("[ERROR]write file failed: " + err.Error())
return
}
fmt.Println("ok") fmt.Println("ok")
} }

12
go.mod
View File

@@ -11,7 +11,7 @@ require (
github.com/cespare/xxhash v1.1.0 github.com/cespare/xxhash v1.1.0
github.com/cespare/xxhash/v2 v2.1.1 github.com/cespare/xxhash/v2 v2.1.1
github.com/go-acme/lego/v4 v4.9.0 github.com/go-acme/lego/v4 v4.9.0
github.com/go-sql-driver/mysql v1.5.0 github.com/go-sql-driver/mysql v1.7.0
github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible
github.com/iwind/TeaGo v0.0.0-20230304012706-c1f4a4e27470 github.com/iwind/TeaGo v0.0.0-20230304012706-c1f4a4e27470
github.com/iwind/gosock v0.0.0-20220505115348-f88412125a62 github.com/iwind/gosock v0.0.0-20220505115348-f88412125a62
@@ -21,8 +21,8 @@ require (
github.com/shirou/gopsutil/v3 v3.22.2 github.com/shirou/gopsutil/v3 v3.22.2
github.com/smartwalle/alipay/v3 v3.1.7 github.com/smartwalle/alipay/v3 v3.1.7
golang.org/x/crypto v0.1.0 golang.org/x/crypto v0.1.0
golang.org/x/net v0.7.0 golang.org/x/net v0.8.0
golang.org/x/sys v0.5.0 golang.org/x/sys v0.6.0
google.golang.org/grpc v1.45.0 google.golang.org/grpc v1.45.0
gopkg.in/yaml.v3 v3.0.1 gopkg.in/yaml.v3 v3.0.1
) )
@@ -44,9 +44,9 @@ require (
github.com/tklauser/go-sysconf v0.3.9 // indirect github.com/tklauser/go-sysconf v0.3.9 // indirect
github.com/tklauser/numcpus v0.3.0 // indirect github.com/tklauser/numcpus v0.3.0 // indirect
github.com/yusufpapurcu/wmi v1.2.2 // indirect github.com/yusufpapurcu/wmi v1.2.2 // indirect
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect golang.org/x/mod v0.8.0 // indirect
golang.org/x/text v0.7.0 // indirect golang.org/x/text v0.8.0 // indirect
golang.org/x/tools v0.1.12 // indirect golang.org/x/tools v0.6.0 // indirect
google.golang.org/genproto v0.0.0-20220317150908-0efb43f6373e // indirect google.golang.org/genproto v0.0.0-20220317150908-0efb43f6373e // indirect
google.golang.org/protobuf v1.28.0 // indirect google.golang.org/protobuf v1.28.0 // indirect
gopkg.in/ini.v1 v1.66.6 // indirect gopkg.in/ini.v1 v1.66.6 // indirect

31
go.sum
View File

@@ -43,8 +43,9 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-redis/redis/v8 v8.0.0-beta.7/go.mod h1:FGJAWDWFht1sQ4qxyJHZZbVyvnVcKQN0E3u5/5lRz+g= github.com/go-redis/redis/v8 v8.0.0-beta.7/go.mod h1:FGJAWDWFht1sQ4qxyJHZZbVyvnVcKQN0E3u5/5lRz+g=
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc=
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible h1:2cauKuaELYAEARXRkq2LrJ0yDDv1rW7+wrTEdVL3uaU= github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible h1:2cauKuaELYAEARXRkq2LrJ0yDDv1rW7+wrTEdVL3uaU=
github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible/go.mod h1:qf9acutJ8cwBUhm1bqgz6Bei9/C/c93FPDljKWwsOgM= github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible/go.mod h1:qf9acutJ8cwBUhm1bqgz6Bei9/C/c93FPDljKWwsOgM=
github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A= github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A=
@@ -78,10 +79,6 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/iwind/TeaGo v0.0.0-20210411134150-ddf57e240c2f/go.mod h1:KU4mS7QNiZ7QWEuDBk1zw0/Q2LrAPZv3tycEFBsuUwc= github.com/iwind/TeaGo v0.0.0-20210411134150-ddf57e240c2f/go.mod h1:KU4mS7QNiZ7QWEuDBk1zw0/Q2LrAPZv3tycEFBsuUwc=
github.com/iwind/TeaGo v0.0.0-20230109112127-225731e65eea h1:e5jlcUN13pNzUbyNW8Ag2Ev5K/2ppgY0m5grqTeFI6Q=
github.com/iwind/TeaGo v0.0.0-20230109112127-225731e65eea/go.mod h1:fi/Pq+/5m2HZoseM+39dMF57ANXRt6w4PkGu3NXPc5s=
github.com/iwind/TeaGo v0.0.0-20230303070415-9d0689db6456 h1:xv3AVaxuwjThkBDptAfsFSmuHQIrRrvt8BRaekWnsvs=
github.com/iwind/TeaGo v0.0.0-20230303070415-9d0689db6456/go.mod h1:fi/Pq+/5m2HZoseM+39dMF57ANXRt6w4PkGu3NXPc5s=
github.com/iwind/TeaGo v0.0.0-20230304012706-c1f4a4e27470 h1:TuRxvKRv9PxKVijWOkUnZm5TeanQqWGUJyPx9u6cra4= github.com/iwind/TeaGo v0.0.0-20230304012706-c1f4a4e27470 h1:TuRxvKRv9PxKVijWOkUnZm5TeanQqWGUJyPx9u6cra4=
github.com/iwind/TeaGo v0.0.0-20230304012706-c1f4a4e27470/go.mod h1:fi/Pq+/5m2HZoseM+39dMF57ANXRt6w4PkGu3NXPc5s= github.com/iwind/TeaGo v0.0.0-20230304012706-c1f4a4e27470/go.mod h1:fi/Pq+/5m2HZoseM+39dMF57ANXRt6w4PkGu3NXPc5s=
github.com/iwind/gosock v0.0.0-20220505115348-f88412125a62 h1:HJH6RDheAY156DnIfJSD/bEvqyXzsZuE2gzs8PuUjoo= github.com/iwind/gosock v0.0.0-20220505115348-f88412125a62 h1:HJH6RDheAY156DnIfJSD/bEvqyXzsZuE2gzs8PuUjoo=
@@ -179,8 +176,8 @@ golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCc
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -194,8 +191,8 @@ golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -203,7 +200,7 @@ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -225,17 +222,17 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210816074244-15123e1e1f71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210816074244-15123e1e1f71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220111092808-5a964db01320/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220111092808-5a964db01320/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY= golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
@@ -244,8 +241,8 @@ golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBn
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

View File

@@ -1,7 +1,7 @@
package teaconst package teaconst
const ( const (
Version = "0.6.4" Version = "1.0.4"
ProductName = "Edge API" ProductName = "Edge API"
ProcessName = "edge-api" ProcessName = "edge-api"
@@ -18,7 +18,7 @@ const (
// 其他节点版本号,用来检测是否有需要升级的节点 // 其他节点版本号,用来检测是否有需要升级的节点
NodeVersion = "0.6.4" NodeVersion = "1.0.4"
// SQLVersion SQL版本号 // SQLVersion SQL版本号
SQLVersion = "11" SQLVersion = "11"

View File

@@ -7,13 +7,29 @@ import (
"fmt" "fmt"
"github.com/iwind/TeaGo/rands" "github.com/iwind/TeaGo/rands"
"github.com/iwind/TeaGo/types" "github.com/iwind/TeaGo/types"
"os"
"strings"
"time" "time"
) )
var ( var (
IsPlus = false IsPlus = false
Edition = ""
MaxNodes int32 = 0 MaxNodes int32 = 0
NodeId int64 = 0 NodeId int64 = 0
Debug = false Debug = false
InstanceCode = fmt.Sprintf("%x", sha1.Sum([]byte("INSTANCE"+types.String(time.Now().UnixNano())+"@"+types.String(rands.Int64())))) InstanceCode = fmt.Sprintf("%x", sha1.Sum([]byte("INSTANCE"+types.String(time.Now().UnixNano())+"@"+types.String(rands.Int64()))))
IsMain = checkMain()
) )
// 检查是否为主程序
func checkMain() bool {
if len(os.Args) == 1 ||
(len(os.Args) >= 2 && os.Args[1] == "pprof") {
return true
}
exe, _ := os.Executable()
return strings.HasSuffix(exe, ".test") ||
strings.HasSuffix(exe, ".test.exe") ||
strings.Contains(exe, "___")
}

View File

@@ -434,7 +434,7 @@ func (this *ACMETaskDAO) runTaskWithoutLog(tx *dbs.Tx, taskId int64) (isOk bool,
CertData: certData, CertData: certData,
KeyData: keyData, KeyData: keyData,
} }
err = sslConfig.Init() err = sslConfig.Init(nil)
if err != nil { if err != nil {
errMsg = "证书生成成功,但是分析证书信息时发生错误:" + err.Error() errMsg = "证书生成成功,但是分析证书信息时发生错误:" + err.Error()
return return

View File

@@ -131,6 +131,8 @@ func (this *ACMEUserDAO) CountACMEUsersWithAdminId(tx *dbs.Tx, adminId int64, us
} }
if userId > 0 { if userId > 0 {
query.Attr("userId", userId) query.Attr("userId", userId)
} else {
query.Attr("userId", 0)
} }
if accountId > 0 { if accountId > 0 {
query.Attr("accountId", accountId) query.Attr("accountId", accountId)
@@ -149,6 +151,8 @@ func (this *ACMEUserDAO) ListACMEUsers(tx *dbs.Tx, adminId int64, userId int64,
} }
if userId > 0 { if userId > 0 {
query.Attr("userId", userId) query.Attr("userId", userId)
} else {
query.Attr("userId", 0)
} }
_, err = query. _, err = query.

View File

@@ -1,6 +1,7 @@
package models package models
import ( import (
dbutils "github.com/TeaOSLab/EdgeAPI/internal/db/utils"
"github.com/TeaOSLab/EdgeAPI/internal/errors" "github.com/TeaOSLab/EdgeAPI/internal/errors"
_ "github.com/go-sql-driver/mysql" _ "github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/Tea" "github.com/iwind/TeaGo/Tea"
@@ -266,17 +267,36 @@ func (this *AdminDAO) FindAllAdminModules(tx *dbs.Tx) (result []*Admin, err erro
} }
// CountAllEnabledAdmins 计算所有管理员数量 // CountAllEnabledAdmins 计算所有管理员数量
func (this *AdminDAO) CountAllEnabledAdmins(tx *dbs.Tx) (int64, error) { func (this *AdminDAO) CountAllEnabledAdmins(tx *dbs.Tx, keyword string, hasWeakPasswords bool) (int64, error) {
return this.Query(tx). var query = this.Query(tx)
if len(keyword) > 0 {
query.Where("(username LIKE :keyword OR fullname LIKE :keyword)")
query.Param("keyword", dbutils.QuoteLike(keyword))
}
if hasWeakPasswords {
query.Attr("password", weakPasswords)
query.Attr("isOn", true)
}
return query.
State(AdminStateEnabled). State(AdminStateEnabled).
Count() Count()
} }
// ListEnabledAdmins 列出单页的管理员 // ListEnabledAdmins 列出单页的管理员
func (this *AdminDAO) ListEnabledAdmins(tx *dbs.Tx, offset int64, size int64) (result []*Admin, err error) { func (this *AdminDAO) ListEnabledAdmins(tx *dbs.Tx, keyword string, hasWeakPasswords bool, offset int64, size int64) (result []*Admin, err error) {
_, err = this.Query(tx). var query = this.Query(tx)
if len(keyword) > 0 {
query.Where("(username LIKE :keyword OR fullname LIKE :keyword)")
query.Param("keyword", dbutils.QuoteLike(keyword))
}
if hasWeakPasswords {
query.Attr("password", weakPasswords)
query.Attr("isOn", true)
}
_, err = query.
State(AdminStateEnabled). State(AdminStateEnabled).
Result("id", "isOn", "username", "fullname", "isSuper", "createdAt", "canLogin"). Result("id", "isOn", "username", "fullname", "isSuper", "createdAt", "canLogin", "password").
Offset(offset). Offset(offset).
Limit(size). Limit(size).
DescPk(). DescPk().
@@ -292,3 +312,15 @@ func (this *AdminDAO) UpdateAdminTheme(tx *dbs.Tx, adminId int64, theme string)
Set("theme", theme). Set("theme", theme).
UpdateQuickly() UpdateQuickly()
} }
// CheckSuperAdmin 检查管理员是否为超级管理员
func (this *AdminDAO) CheckSuperAdmin(tx *dbs.Tx, adminId int64) (bool, error) {
if adminId <= 0 {
return false, nil
}
return this.Query(tx).
Pk(adminId).
State(AdminStateEnabled).
Attr("isSuper", true).
Exist()
}

View File

@@ -1 +1,42 @@
package models package models
import stringutil "github.com/iwind/TeaGo/utils/string"
// 弱密码集合
var weakPasswords = []string{}
func init() {
// 初始化弱密码集合
for _, password := range []string{
"123",
"1234",
"12345",
"123456",
"12345678",
"123456789",
"000000",
"111111",
"666666",
"888888",
"654321",
"123456789",
"password",
"qwerty",
"admin",
} {
weakPasswords = append(weakPasswords, stringutil.Md5(password))
}
}
func (this *Admin) HasWeakPassword() bool {
if len(this.Password) == 0 {
return false
}
for _, weakPassword := range weakPasswords {
if weakPassword == this.Password {
return true
}
}
return false
}

View File

@@ -37,7 +37,7 @@ func (this *APINode) DecodeHTTPS(tx *dbs.Tx, cacheMap *utils.CacheMap) (*serverc
return nil, err return nil, err
} }
err = config.Init() err = config.Init(nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -45,7 +45,7 @@ func (this *APINode) DecodeHTTPS(tx *dbs.Tx, cacheMap *utils.CacheMap) (*serverc
if config.SSLPolicyRef != nil { if config.SSLPolicyRef != nil {
var policyId = config.SSLPolicyRef.SSLPolicyId var policyId = config.SSLPolicyRef.SSLPolicyId
if policyId > 0 { if policyId > 0 {
sslPolicy, err := SharedSSLPolicyDAO.ComposePolicyConfig(tx, policyId, false, cacheMap) sslPolicy, err := SharedSSLPolicyDAO.ComposePolicyConfig(tx, policyId, false, nil, cacheMap)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -55,7 +55,7 @@ func (this *APINode) DecodeHTTPS(tx *dbs.Tx, cacheMap *utils.CacheMap) (*serverc
} }
} }
err = config.Init() err = config.Init(nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -129,13 +129,13 @@ func (this *APINode) DecodeRestHTTPS(tx *dbs.Tx, cacheMap *utils.CacheMap) (*ser
if !IsNotNull(this.RestHTTPS) { if !IsNotNull(this.RestHTTPS) {
return nil, nil return nil, nil
} }
config := &serverconfigs.HTTPSProtocolConfig{} var config = &serverconfigs.HTTPSProtocolConfig{}
err := json.Unmarshal(this.RestHTTPS, config) err := json.Unmarshal(this.RestHTTPS, config)
if err != nil { if err != nil {
return nil, err return nil, err
} }
err = config.Init() err = config.Init(nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -143,7 +143,7 @@ func (this *APINode) DecodeRestHTTPS(tx *dbs.Tx, cacheMap *utils.CacheMap) (*ser
if config.SSLPolicyRef != nil { if config.SSLPolicyRef != nil {
policyId := config.SSLPolicyRef.SSLPolicyId policyId := config.SSLPolicyRef.SSLPolicyId
if policyId > 0 { if policyId > 0 {
sslPolicy, err := SharedSSLPolicyDAO.ComposePolicyConfig(tx, policyId, false, cacheMap) sslPolicy, err := SharedSSLPolicyDAO.ComposePolicyConfig(tx, policyId, false, nil, cacheMap)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -153,7 +153,7 @@ func (this *APINode) DecodeRestHTTPS(tx *dbs.Tx, cacheMap *utils.CacheMap) (*ser
} }
} }
err = config.Init() err = config.Init(nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@@ -19,6 +19,8 @@ const (
DNSTaskTypeDomainChange DNSTaskType = "domainChange" DNSTaskTypeDomainChange DNSTaskType = "domainChange"
) )
var DNSTasksNotifier = make(chan bool, 2)
type DNSTaskDAO dbs.DAO type DNSTaskDAO dbs.DAO
func NewDNSTaskDAO() *DNSTaskDAO { func NewDNSTaskDAO() *DNSTaskDAO {
@@ -64,7 +66,17 @@ func (this *DNSTaskDAO) CreateDNSTask(tx *dbs.Tx, clusterId int64, serverId int6
"error": "", "error": "",
"version": time.Now().UnixNano(), "version": time.Now().UnixNano(),
}) })
return err if err != nil {
return err
}
// 通知更新
select {
case DNSTasksNotifier <- true:
default:
}
return nil
} }
// CreateClusterTask 生成集群变更任务 // CreateClusterTask 生成集群变更任务
@@ -156,10 +168,24 @@ func (this *DNSTaskDAO) UpdateDNSTaskError(tx *dbs.Tx, taskId int64, err string)
} }
// UpdateDNSTaskDone 设置任务完成 // UpdateDNSTaskDone 设置任务完成
func (this *DNSTaskDAO) UpdateDNSTaskDone(tx *dbs.Tx, taskId int64) error { func (this *DNSTaskDAO) UpdateDNSTaskDone(tx *dbs.Tx, taskId int64, taskVersion int64) error {
if taskId <= 0 { if taskId <= 0 {
return errors.New("invalid taskId") return errors.New("invalid taskId")
} }
currentVersion, err := this.Query(tx).
Pk(taskId).
Result("version").
FindInt64Col(0)
if err != nil {
return err
}
// 如果版本号发生变化,则说明有新的要执行的任务
if taskVersion > 0 && currentVersion > 0 && currentVersion != taskVersion {
return nil
}
var op = NewDNSTaskOperator() var op = NewDNSTaskOperator()
op.Id = taskId op.Id = taskId
op.IsDone = true op.IsDone = true

View File

@@ -105,7 +105,7 @@ func CheckClusterDNS(tx *dbs.Tx, cluster *models.NodeCluster, checkNodeIssues bo
// 检查节点 // 检查节点
if checkNodeIssues { if checkNodeIssues {
nodes, err := models.SharedNodeDAO.FindAllEnabledNodesDNSWithClusterId(tx, clusterId, true, clusterDNSConfig != nil && clusterDNSConfig.IncludingLnNodes) nodes, err := models.SharedNodeDAO.FindAllEnabledNodesDNSWithClusterId(tx, clusterId, true, clusterDNSConfig != nil && clusterDNSConfig.IncludingLnNodes, true)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@@ -237,7 +237,7 @@ func (this *HTTPAccessLogDAO) CreateHTTPAccessLog(tx *dbs.Tx, dao *HTTPAccessLog
if len(accessLog.TimeISO8601) > 10 { if len(accessLog.TimeISO8601) > 10 {
day = strings.ReplaceAll(accessLog.TimeISO8601[:10], "-", "") day = strings.ReplaceAll(accessLog.TimeISO8601[:10], "-", "")
} else { } else {
timeutil.FormatTime("Ymd", accessLog.Timestamp) day = timeutil.FormatTime("Ymd", accessLog.Timestamp)
} }
tableDef, err := SharedHTTPAccessLogManager.FindLastTable(dao.Instance, day, true) tableDef, err := SharedHTTPAccessLogManager.FindLastTable(dao.Instance, day, true)

View File

@@ -96,6 +96,27 @@ func (this *HTTPAuthPolicyDAO) UpdateHTTPAuthPolicy(tx *dbs.Tx, policyId int64,
return this.NotifyUpdate(tx, policyId) return this.NotifyUpdate(tx, policyId)
} }
// CloneAuthPolicy 复制策略
func (this *HTTPAuthPolicyDAO) CloneAuthPolicy(tx *dbs.Tx, fromPolicyId int64) (int64, error) {
policyOne, err := this.Query(tx).
Pk(fromPolicyId).
Find()
if err != nil || policyOne == nil {
return 0, err
}
var policy = policyOne.(*HTTPAuthPolicy)
var op = NewHTTPAuthPolicyOperator()
op.IsOn = policy.IsOn
op.Name = policy.Name
op.Type = policy.Type
if len(policy.Params) > 0 {
op.Params = policy.Params
}
op.State = policy.State
return this.SaveInt64(tx, op)
}
// ComposePolicyConfig 组合配置 // ComposePolicyConfig 组合配置
func (this *HTTPAuthPolicyDAO) ComposePolicyConfig(tx *dbs.Tx, policyId int64, cacheMap *utils.CacheMap) (*serverconfigs.HTTPAuthPolicy, error) { func (this *HTTPAuthPolicyDAO) ComposePolicyConfig(tx *dbs.Tx, policyId int64, cacheMap *utils.CacheMap) (*serverconfigs.HTTPAuthPolicy, error) {
if cacheMap == nil { if cacheMap == nil {

View File

@@ -150,7 +150,7 @@ func (this *HTTPLocationDAO) UpdateLocation(tx *dbs.Tx, locationId int64, name s
} }
// ComposeLocationConfig 组合配置 // ComposeLocationConfig 组合配置
func (this *HTTPLocationDAO) ComposeLocationConfig(tx *dbs.Tx, locationId int64, cacheMap *utils.CacheMap) (*serverconfigs.HTTPLocationConfig, error) { func (this *HTTPLocationDAO) ComposeLocationConfig(tx *dbs.Tx, locationId int64, forNode bool, dataMap *shared.DataMap, cacheMap *utils.CacheMap) (*serverconfigs.HTTPLocationConfig, error) {
if cacheMap == nil { if cacheMap == nil {
cacheMap = utils.NewCacheMap() cacheMap = utils.NewCacheMap()
} }
@@ -168,7 +168,7 @@ func (this *HTTPLocationDAO) ComposeLocationConfig(tx *dbs.Tx, locationId int64,
return nil, nil return nil, nil
} }
config := &serverconfigs.HTTPLocationConfig{} var config = &serverconfigs.HTTPLocationConfig{}
config.Id = int64(location.Id) config.Id = int64(location.Id)
config.IsOn = location.IsOn config.IsOn = location.IsOn
config.Description = location.Description config.Description = location.Description
@@ -179,7 +179,7 @@ func (this *HTTPLocationDAO) ComposeLocationConfig(tx *dbs.Tx, locationId int64,
// web // web
if location.WebId > 0 { if location.WebId > 0 {
webConfig, err := SharedHTTPWebDAO.ComposeWebConfig(tx, int64(location.WebId), cacheMap) webConfig, err := SharedHTTPWebDAO.ComposeWebConfig(tx, int64(location.WebId), true, forNode, dataMap, cacheMap)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -195,7 +195,7 @@ func (this *HTTPLocationDAO) ComposeLocationConfig(tx *dbs.Tx, locationId int64,
} }
config.ReverseProxyRef = ref config.ReverseProxyRef = ref
if ref.ReverseProxyId > 0 { if ref.ReverseProxyId > 0 {
reverseProxyConfig, err := SharedReverseProxyDAO.ComposeReverseProxyConfig(tx, ref.ReverseProxyId, cacheMap) reverseProxyConfig, err := SharedReverseProxyDAO.ComposeReverseProxyConfig(tx, ref.ReverseProxyId, dataMap, cacheMap)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -292,13 +292,13 @@ func (this *HTTPLocationDAO) UpdateLocationWeb(tx *dbs.Tx, locationId int64, web
} }
// ConvertLocationRefs 转换引用为配置 // ConvertLocationRefs 转换引用为配置
func (this *HTTPLocationDAO) ConvertLocationRefs(tx *dbs.Tx, refs []*serverconfigs.HTTPLocationRef, cacheMap *utils.CacheMap) (locations []*serverconfigs.HTTPLocationConfig, err error) { func (this *HTTPLocationDAO) ConvertLocationRefs(tx *dbs.Tx, refs []*serverconfigs.HTTPLocationRef, forNode bool, dataMap *shared.DataMap, cacheMap *utils.CacheMap) (locations []*serverconfigs.HTTPLocationConfig, err error) {
for _, ref := range refs { for _, ref := range refs {
config, err := this.ComposeLocationConfig(tx, ref.LocationId, cacheMap) config, err := this.ComposeLocationConfig(tx, ref.LocationId, forNode, dataMap, cacheMap)
if err != nil { if err != nil {
return nil, err return nil, err
} }
children, err := this.ConvertLocationRefs(tx, ref.Children, cacheMap) children, err := this.ConvertLocationRefs(tx, ref.Children, forNode, dataMap, cacheMap)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@@ -133,6 +133,32 @@ func (this *HTTPPageDAO) UpdatePage(tx *dbs.Tx, pageId int64, statusList []strin
return this.NotifyUpdate(tx, pageId) return this.NotifyUpdate(tx, pageId)
} }
// ClonePage 克隆页面
func (this *HTTPPageDAO) ClonePage(tx *dbs.Tx, fromPageId int64) (newPageId int64, err error) {
if fromPageId <= 0 {
return
}
pageOne, err := this.Query(tx).
Pk(fromPageId).
Find()
if err != nil || pageOne == nil {
return 0, err
}
var page = pageOne.(*HTTPPage)
var op = NewHTTPPageOperator()
op.IsOn = page.IsOn
if len(page.StatusList) > 0 {
op.StatusList = page.StatusList
}
op.Url = page.Url
op.NewStatus = page.NewStatus
op.Body = page.Body
op.BodyType = page.BodyType
op.State = page.State
return this.SaveInt64(tx, op)
}
// ComposePageConfig 组合配置 // ComposePageConfig 组合配置
func (this *HTTPPageDAO) ComposePageConfig(tx *dbs.Tx, pageId int64, cacheMap *utils.CacheMap) (*serverconfigs.HTTPPageConfig, error) { func (this *HTTPPageDAO) ComposePageConfig(tx *dbs.Tx, pageId int64, cacheMap *utils.CacheMap) (*serverconfigs.HTTPPageConfig, error) {
if cacheMap == nil { if cacheMap == nil {

View File

@@ -77,7 +77,7 @@ func (this *HTTPWebDAO) FindEnabledHTTPWeb(tx *dbs.Tx, id int64) (*HTTPWeb, erro
} }
// ComposeWebConfig 组合配置 // ComposeWebConfig 组合配置
func (this *HTTPWebDAO) ComposeWebConfig(tx *dbs.Tx, webId int64, cacheMap *utils.CacheMap) (*serverconfigs.HTTPWebConfig, error) { func (this *HTTPWebDAO) ComposeWebConfig(tx *dbs.Tx, webId int64, isLocationOrGroup bool, forNode bool, dataMap *shared.DataMap, cacheMap *utils.CacheMap) (*serverconfigs.HTTPWebConfig, error) {
if cacheMap == nil { if cacheMap == nil {
cacheMap = utils.NewCacheMap() cacheMap = utils.NewCacheMap()
} }
@@ -101,113 +101,127 @@ func (this *HTTPWebDAO) ComposeWebConfig(tx *dbs.Tx, webId int64, cacheMap *util
// root // root
if IsNotNull(web.Root) { if IsNotNull(web.Root) {
rootConfig := &serverconfigs.HTTPRootConfig{} var rootConfig = &serverconfigs.HTTPRootConfig{}
err = json.Unmarshal(web.Root, rootConfig) err = json.Unmarshal(web.Root, rootConfig)
if err != nil { if err != nil {
return nil, err return nil, err
} }
config.Root = rootConfig if this.shouldCompose(isLocationOrGroup, forNode, rootConfig.IsPrior, rootConfig.IsOn) {
config.Root = rootConfig
}
} }
// compression // compression
if IsNotNull(web.Compression) { if IsNotNull(web.Compression) {
compression := &serverconfigs.HTTPCompressionConfig{} var compressionConfig = &serverconfigs.HTTPCompressionConfig{}
err = json.Unmarshal(web.Compression, compression) err = json.Unmarshal(web.Compression, compressionConfig)
if err != nil { if err != nil {
return nil, err return nil, err
} }
config.Compression = compression
// gzip if this.shouldCompose(isLocationOrGroup, forNode, compressionConfig.IsPrior, compressionConfig.IsOn) {
if compression.GzipRef != nil && compression.GzipRef.Id > 0 { config.Compression = compressionConfig
gzipConfig, err := SharedHTTPGzipDAO.ComposeGzipConfig(tx, compression.GzipRef.Id)
if err != nil {
return nil, err
}
compression.Gzip = gzipConfig
}
// brotli // gzip
if compression.BrotliRef != nil && compression.BrotliRef.Id > 0 { if compressionConfig.GzipRef != nil && compressionConfig.GzipRef.Id > 0 {
brotliConfig, err := SharedHTTPBrotliPolicyDAO.ComposeBrotliConfig(tx, compression.BrotliRef.Id) gzipConfig, err := SharedHTTPGzipDAO.ComposeGzipConfig(tx, compressionConfig.GzipRef.Id)
if err != nil { if err != nil {
return nil, err return nil, err
}
compressionConfig.Gzip = gzipConfig
} }
compression.Brotli = brotliConfig
}
// deflate // brotli
if compression.DeflateRef != nil && compression.DeflateRef.Id > 0 { if compressionConfig.BrotliRef != nil && compressionConfig.BrotliRef.Id > 0 {
deflateConfig, err := SharedHTTPDeflatePolicyDAO.ComposeDeflateConfig(tx, compression.DeflateRef.Id) brotliConfig, err := SharedHTTPBrotliPolicyDAO.ComposeBrotliConfig(tx, compressionConfig.BrotliRef.Id)
if err != nil { if err != nil {
return nil, err return nil, err
}
compressionConfig.Brotli = brotliConfig
}
// deflate
if compressionConfig.DeflateRef != nil && compressionConfig.DeflateRef.Id > 0 {
deflateConfig, err := SharedHTTPDeflatePolicyDAO.ComposeDeflateConfig(tx, compressionConfig.DeflateRef.Id)
if err != nil {
return nil, err
}
compressionConfig.Deflate = deflateConfig
} }
compression.Deflate = deflateConfig
} }
} }
// charset // charset
if IsNotNull(web.Charset) { if IsNotNull(web.Charset) {
charsetConfig := &serverconfigs.HTTPCharsetConfig{} var charsetConfig = &serverconfigs.HTTPCharsetConfig{}
err = json.Unmarshal(web.Charset, charsetConfig) err = json.Unmarshal(web.Charset, charsetConfig)
if err != nil { if err != nil {
return nil, err return nil, err
} }
config.Charset = charsetConfig if this.shouldCompose(isLocationOrGroup, forNode, charsetConfig.IsPrior, charsetConfig.IsOn) {
config.Charset = charsetConfig
}
} }
// headers // headers
if IsNotNull(web.RequestHeader) { if IsNotNull(web.RequestHeader) {
ref := &shared.HTTPHeaderPolicyRef{} var ref = &shared.HTTPHeaderPolicyRef{}
err = json.Unmarshal(web.RequestHeader, ref) err = json.Unmarshal(web.RequestHeader, ref)
if err != nil { if err != nil {
return nil, err return nil, err
} }
config.RequestHeaderPolicyRef = ref if this.shouldCompose(isLocationOrGroup, forNode, ref.IsPrior, ref.IsOn) {
config.RequestHeaderPolicyRef = ref
if ref.HeaderPolicyId > 0 { if ref.HeaderPolicyId > 0 {
headerPolicy, err := SharedHTTPHeaderPolicyDAO.ComposeHeaderPolicyConfig(tx, ref.HeaderPolicyId) headerPolicy, err := SharedHTTPHeaderPolicyDAO.ComposeHeaderPolicyConfig(tx, ref.HeaderPolicyId)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if headerPolicy != nil { if headerPolicy != nil {
config.RequestHeaderPolicy = headerPolicy config.RequestHeaderPolicy = headerPolicy
}
} }
} }
} }
if IsNotNull(web.ResponseHeader) { if IsNotNull(web.ResponseHeader) {
ref := &shared.HTTPHeaderPolicyRef{} var ref = &shared.HTTPHeaderPolicyRef{}
err = json.Unmarshal(web.ResponseHeader, ref) err = json.Unmarshal(web.ResponseHeader, ref)
if err != nil { if err != nil {
return nil, err return nil, err
} }
config.ResponseHeaderPolicyRef = ref if this.shouldCompose(isLocationOrGroup, forNode, ref.IsPrior, ref.IsOn) {
config.ResponseHeaderPolicyRef = ref
if ref.HeaderPolicyId > 0 { if ref.HeaderPolicyId > 0 {
headerPolicy, err := SharedHTTPHeaderPolicyDAO.ComposeHeaderPolicyConfig(tx, ref.HeaderPolicyId) headerPolicy, err := SharedHTTPHeaderPolicyDAO.ComposeHeaderPolicyConfig(tx, ref.HeaderPolicyId)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if headerPolicy != nil { if headerPolicy != nil {
config.ResponseHeaderPolicy = headerPolicy config.ResponseHeaderPolicy = headerPolicy
}
} }
} }
} }
// shutdown // shutdown
if IsNotNull(web.Shutdown) { if IsNotNull(web.Shutdown) {
shutdownConfig := &serverconfigs.HTTPShutdownConfig{} var shutdownConfig = &serverconfigs.HTTPShutdownConfig{}
err = json.Unmarshal(web.Shutdown, shutdownConfig) err = json.Unmarshal(web.Shutdown, shutdownConfig)
if err != nil { if err != nil {
return nil, err return nil, err
} }
config.Shutdown = shutdownConfig if this.shouldCompose(isLocationOrGroup, forNode, shutdownConfig.IsPrior, shutdownConfig.IsOn) {
config.Shutdown = shutdownConfig
}
} }
// pages // pages
// TODO 检查forNode参数
if IsNotNull(web.Pages) { if IsNotNull(web.Pages) {
pages := []*serverconfigs.HTTPPageConfig{} var pages = []*serverconfigs.HTTPPageConfig{}
err = json.Unmarshal(web.Pages, &pages) err = json.Unmarshal(web.Pages, &pages)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -226,62 +240,72 @@ func (this *HTTPWebDAO) ComposeWebConfig(tx *dbs.Tx, webId int64, cacheMap *util
// 访问日志 // 访问日志
if IsNotNull(web.AccessLog) { if IsNotNull(web.AccessLog) {
accessLogConfig := &serverconfigs.HTTPAccessLogRef{} var accessLogConfig = &serverconfigs.HTTPAccessLogRef{}
err = json.Unmarshal(web.AccessLog, accessLogConfig) err = json.Unmarshal(web.AccessLog, accessLogConfig)
if err != nil { if err != nil {
return nil, err return nil, err
} }
config.AccessLogRef = accessLogConfig if this.shouldCompose(isLocationOrGroup, forNode, accessLogConfig.IsPrior, accessLogConfig.IsOn) {
config.AccessLogRef = accessLogConfig
}
} }
// 统计配置 // 统计配置
if IsNotNull(web.Stat) { if IsNotNull(web.Stat) {
statRef := &serverconfigs.HTTPStatRef{} var statRef = &serverconfigs.HTTPStatRef{}
err = json.Unmarshal(web.Stat, statRef) err = json.Unmarshal(web.Stat, statRef)
if err != nil { if err != nil {
return nil, err return nil, err
} }
config.StatRef = statRef if this.shouldCompose(isLocationOrGroup, forNode, statRef.IsPrior, statRef.IsOn) {
config.StatRef = statRef
}
} }
// 缓存配置 // 缓存配置
if IsNotNull(web.Cache) { if IsNotNull(web.Cache) {
cacheConfig := &serverconfigs.HTTPCacheConfig{} var cacheConfig = &serverconfigs.HTTPCacheConfig{}
err = json.Unmarshal(web.Cache, &cacheConfig) err = json.Unmarshal(web.Cache, &cacheConfig)
if err != nil { if err != nil {
return nil, err return nil, err
} }
config.Cache = cacheConfig
if this.shouldCompose(isLocationOrGroup, forNode, cacheConfig.IsPrior, cacheConfig.IsOn) {
config.Cache = cacheConfig
}
// 暂不支持自定义缓存策略设置,因为同一个集群下的服务需要集中管理 // 暂不支持自定义缓存策略设置,因为同一个集群下的服务需要集中管理
} }
// 防火墙配置 // 防火墙配置
if IsNotNull(web.Firewall) { if IsNotNull(web.Firewall) {
firewallRef := &firewallconfigs.HTTPFirewallRef{} var firewallRef = &firewallconfigs.HTTPFirewallRef{}
err = json.Unmarshal(web.Firewall, firewallRef) err = json.Unmarshal(web.Firewall, firewallRef)
if err != nil { if err != nil {
return nil, err return nil, err
} }
config.FirewallRef = firewallRef if this.shouldCompose(isLocationOrGroup, forNode, firewallRef.IsPrior, firewallRef.IsOn) {
config.FirewallRef = firewallRef
// 自定义防火墙设置 // 自定义防火墙设置
if firewallRef.FirewallPolicyId > 0 { if firewallRef.FirewallPolicyId > 0 {
firewallPolicy, err := SharedHTTPFirewallPolicyDAO.ComposeFirewallPolicy(tx, firewallRef.FirewallPolicyId, cacheMap) firewallPolicy, err := SharedHTTPFirewallPolicyDAO.ComposeFirewallPolicy(tx, firewallRef.FirewallPolicyId, cacheMap)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if firewallPolicy == nil { if firewallPolicy == nil {
config.FirewallRef = nil config.FirewallRef = nil
} else { } else {
config.FirewallPolicy = firewallPolicy config.FirewallPolicy = firewallPolicy
}
} }
} }
} }
// 路由规则 // 路由规则
// TODO 检查forNode参数
if IsNotNull(web.Locations) { if IsNotNull(web.Locations) {
refs := []*serverconfigs.HTTPLocationRef{} var refs = []*serverconfigs.HTTPLocationRef{}
err = json.Unmarshal(web.Locations, &refs) err = json.Unmarshal(web.Locations, &refs)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -289,7 +313,7 @@ func (this *HTTPWebDAO) ComposeWebConfig(tx *dbs.Tx, webId int64, cacheMap *util
if len(refs) > 0 { if len(refs) > 0 {
config.LocationRefs = refs config.LocationRefs = refs
locations, err := SharedHTTPLocationDAO.ConvertLocationRefs(tx, refs, cacheMap) locations, err := SharedHTTPLocationDAO.ConvertLocationRefs(tx, refs, forNode, dataMap, cacheMap)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -299,36 +323,41 @@ func (this *HTTPWebDAO) ComposeWebConfig(tx *dbs.Tx, webId int64, cacheMap *util
// 跳转 // 跳转
if IsNotNull(web.RedirectToHttps) { if IsNotNull(web.RedirectToHttps) {
redirectToHTTPSConfig := &serverconfigs.HTTPRedirectToHTTPSConfig{} var redirectToHTTPSConfig = &serverconfigs.HTTPRedirectToHTTPSConfig{}
err = json.Unmarshal(web.RedirectToHttps, redirectToHTTPSConfig) err = json.Unmarshal(web.RedirectToHttps, redirectToHTTPSConfig)
if err != nil { if err != nil {
return nil, err return nil, err
} }
config.RedirectToHttps = redirectToHTTPSConfig if this.shouldCompose(isLocationOrGroup, forNode, redirectToHTTPSConfig.IsPrior, redirectToHTTPSConfig.IsOn) {
config.RedirectToHttps = redirectToHTTPSConfig
}
} }
// Websocket // Websocket
if IsNotNull(web.Websocket) { if IsNotNull(web.Websocket) {
ref := &serverconfigs.HTTPWebsocketRef{} var ref = &serverconfigs.HTTPWebsocketRef{}
err = json.Unmarshal(web.Websocket, ref) err = json.Unmarshal(web.Websocket, ref)
if err != nil { if err != nil {
return nil, err return nil, err
} }
config.WebsocketRef = ref if this.shouldCompose(isLocationOrGroup, forNode, ref.IsPrior, ref.IsOn) {
if ref.WebsocketId > 0 { config.WebsocketRef = ref
websocketConfig, err := SharedHTTPWebsocketDAO.ComposeWebsocketConfig(tx, ref.WebsocketId) if ref.WebsocketId > 0 {
if err != nil { websocketConfig, err := SharedHTTPWebsocketDAO.ComposeWebsocketConfig(tx, ref.WebsocketId)
return nil, err if err != nil {
} return nil, err
if websocketConfig != nil { }
config.Websocket = websocketConfig if websocketConfig != nil {
config.Websocket = websocketConfig
}
} }
} }
} }
// 重写规则 // 重写规则
// TODO 检查forNode参数
if IsNotNull(web.RewriteRules) { if IsNotNull(web.RewriteRules) {
refs := []*serverconfigs.HTTPRewriteRef{} var refs = []*serverconfigs.HTTPRewriteRef{}
err = json.Unmarshal(web.RewriteRules, &refs) err = json.Unmarshal(web.RewriteRules, &refs)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -346,8 +375,9 @@ func (this *HTTPWebDAO) ComposeWebConfig(tx *dbs.Tx, webId int64, cacheMap *util
} }
// 主机跳转 // 主机跳转
// TODO 检查forNode参数
if IsNotNull(web.HostRedirects) { if IsNotNull(web.HostRedirects) {
redirects := []*serverconfigs.HTTPHostRedirectConfig{} var redirects = []*serverconfigs.HTTPHostRedirectConfig{}
err = json.Unmarshal(web.HostRedirects, &redirects) err = json.Unmarshal(web.HostRedirects, &redirects)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -357,25 +387,28 @@ func (this *HTTPWebDAO) ComposeWebConfig(tx *dbs.Tx, webId int64, cacheMap *util
// Fastcgi // Fastcgi
if IsNotNull(web.Fastcgi) { if IsNotNull(web.Fastcgi) {
ref := &serverconfigs.HTTPFastcgiRef{} var ref = &serverconfigs.HTTPFastcgiRef{}
err = json.Unmarshal(web.Fastcgi, ref) err = json.Unmarshal(web.Fastcgi, ref)
if err != nil { if err != nil {
return nil, err return nil, err
} }
config.FastcgiRef = ref
if len(ref.FastcgiIds) > 0 { if this.shouldCompose(isLocationOrGroup, forNode, ref.IsPrior, ref.IsOn) {
list := []*serverconfigs.HTTPFastcgiConfig{} config.FastcgiRef = ref
for _, fastcgiId := range ref.FastcgiIds {
fastcgiConfig, err := SharedHTTPFastcgiDAO.ComposeFastcgiConfig(tx, fastcgiId) if len(ref.FastcgiIds) > 0 {
if err != nil { list := []*serverconfigs.HTTPFastcgiConfig{}
return nil, err for _, fastcgiId := range ref.FastcgiIds {
} fastcgiConfig, err := SharedHTTPFastcgiDAO.ComposeFastcgiConfig(tx, fastcgiId)
if fastcgiConfig != nil { if err != nil {
list = append(list, fastcgiConfig) return nil, err
}
if fastcgiConfig != nil {
list = append(list, fastcgiConfig)
}
} }
config.FastcgiList = list
} }
config.FastcgiList = list
} }
} }
@@ -386,19 +419,21 @@ func (this *HTTPWebDAO) ComposeWebConfig(tx *dbs.Tx, webId int64, cacheMap *util
if err != nil { if err != nil {
return nil, err return nil, err
} }
var newRefs []*serverconfigs.HTTPAuthPolicyRef if this.shouldCompose(isLocationOrGroup, forNode, authConfig.IsPrior, authConfig.IsOn) {
for _, ref := range authConfig.PolicyRefs { var newRefs []*serverconfigs.HTTPAuthPolicyRef
policyConfig, err := SharedHTTPAuthPolicyDAO.ComposePolicyConfig(tx, ref.AuthPolicyId, cacheMap) for _, ref := range authConfig.PolicyRefs {
if err != nil { policyConfig, err := SharedHTTPAuthPolicyDAO.ComposePolicyConfig(tx, ref.AuthPolicyId, cacheMap)
return nil, err if err != nil {
} return nil, err
if policyConfig != nil { }
ref.AuthPolicy = policyConfig if policyConfig != nil {
newRefs = append(newRefs, ref) ref.AuthPolicy = policyConfig
authConfig.PolicyRefs = newRefs newRefs = append(newRefs, ref)
authConfig.PolicyRefs = newRefs
}
} }
config.Auth = authConfig
} }
config.Auth = authConfig
} }
// WebP // WebP
@@ -408,7 +443,9 @@ func (this *HTTPWebDAO) ComposeWebConfig(tx *dbs.Tx, webId int64, cacheMap *util
if err != nil { if err != nil {
return nil, err return nil, err
} }
config.WebP = webpConfig if this.shouldCompose(isLocationOrGroup, forNode, webpConfig.IsPrior, webpConfig.IsOn) {
config.WebP = webpConfig
}
} }
// RemoteAddr // RemoteAddr
@@ -418,7 +455,9 @@ func (this *HTTPWebDAO) ComposeWebConfig(tx *dbs.Tx, webId int64, cacheMap *util
if err != nil { if err != nil {
return nil, err return nil, err
} }
config.RemoteAddr = remoteAddrConfig if this.shouldCompose(isLocationOrGroup, forNode, remoteAddrConfig.IsPrior, remoteAddrConfig.IsOn) {
config.RemoteAddr = remoteAddrConfig
}
} }
// mergeSlashes // mergeSlashes
@@ -427,25 +466,24 @@ func (this *HTTPWebDAO) ComposeWebConfig(tx *dbs.Tx, webId int64, cacheMap *util
// 请求限制 // 请求限制
if len(web.RequestLimit) > 0 { if len(web.RequestLimit) > 0 {
var requestLimitConfig = &serverconfigs.HTTPRequestLimitConfig{} var requestLimitConfig = &serverconfigs.HTTPRequestLimitConfig{}
if len(web.RequestLimit) > 0 { err = json.Unmarshal(web.RequestLimit, requestLimitConfig)
err = json.Unmarshal(web.RequestLimit, requestLimitConfig) if err != nil {
if err != nil { return nil, err
return nil, err }
} if this.shouldCompose(isLocationOrGroup, forNode, requestLimitConfig.IsPrior, requestLimitConfig.IsOn) {
config.RequestLimit = requestLimitConfig config.RequestLimit = requestLimitConfig
} }
} }
// 请求脚本 // 请求脚本
// TODO 检查forNode设置
if len(web.RequestScripts) > 0 { if len(web.RequestScripts) > 0 {
var requestScriptsConfig = &serverconfigs.HTTPRequestScriptsConfig{} var requestScriptsConfig = &serverconfigs.HTTPRequestScriptsConfig{}
if len(web.RequestScripts) > 0 { err = json.Unmarshal(web.RequestScripts, requestScriptsConfig)
err = json.Unmarshal(web.RequestScripts, requestScriptsConfig) if err != nil {
if err != nil { return nil, err
return nil, err
}
config.RequestScripts = requestScriptsConfig
} }
config.RequestScripts = requestScriptsConfig
} }
// UAM // UAM
@@ -455,17 +493,21 @@ func (this *HTTPWebDAO) ComposeWebConfig(tx *dbs.Tx, webId int64, cacheMap *util
if err != nil { if err != nil {
return nil, err return nil, err
} }
config.UAM = uamConfig if this.shouldCompose(isLocationOrGroup, forNode, uamConfig.IsPrior, uamConfig.IsOn) {
config.UAM = uamConfig
}
} }
// CC // CC
if teaconst.IsPlus && IsNotNull(web.Cc) { if teaconst.IsPlus && IsNotNull(web.Cc) {
var ccConfig = &serverconfigs.HTTPCCConfig{} var ccConfig = serverconfigs.DefaultHTTPCCConfig()
err = json.Unmarshal(web.Cc, ccConfig) err = json.Unmarshal(web.Cc, ccConfig)
if err != nil { if err != nil {
return nil, err return nil, err
} }
config.CC = ccConfig if this.shouldCompose(isLocationOrGroup, forNode, ccConfig.IsPrior, ccConfig.IsOn) {
config.CC = ccConfig
}
} }
// Referers // Referers
@@ -475,7 +517,9 @@ func (this *HTTPWebDAO) ComposeWebConfig(tx *dbs.Tx, webId int64, cacheMap *util
if err != nil { if err != nil {
return nil, err return nil, err
} }
config.Referers = referersConfig if this.shouldCompose(isLocationOrGroup, forNode, referersConfig.IsPrior, referersConfig.IsOn) {
config.Referers = referersConfig
}
} }
// User-Agent // User-Agent
@@ -485,7 +529,9 @@ func (this *HTTPWebDAO) ComposeWebConfig(tx *dbs.Tx, webId int64, cacheMap *util
if err != nil { if err != nil {
return nil, err return nil, err
} }
config.UserAgent = userAgentConfig if this.shouldCompose(isLocationOrGroup, forNode, userAgentConfig.IsPrior, userAgentConfig.IsOn) {
config.UserAgent = userAgentConfig
}
} }
if cacheMap != nil { if cacheMap != nil {
@@ -1110,8 +1156,6 @@ func (this *HTTPWebDAO) UpdateWebHostRedirects(tx *dbs.Tx, webId int64, hostRedi
return this.NotifyUpdate(tx, webId) return this.NotifyUpdate(tx, webId)
} }
// 通用设置
// FindWebHostRedirects 查找主机跳转 // FindWebHostRedirects 查找主机跳转
func (this *HTTPWebDAO) FindWebHostRedirects(tx *dbs.Tx, webId int64) ([]byte, error) { func (this *HTTPWebDAO) FindWebHostRedirects(tx *dbs.Tx, webId int64) ([]byte, error) {
col, err := this.Query(tx). col, err := this.Query(tx).
@@ -1352,3 +1396,11 @@ func (this *HTTPWebDAO) NotifyUpdate(tx *dbs.Tx, webId int64) error {
return nil return nil
} }
// 检查是否应该组合配置
func (this *HTTPWebDAO) shouldCompose(isLocationOrGroup bool, forNode bool, isPrior bool, isOn bool) bool {
if !forNode {
return true
}
return (!isLocationOrGroup && isOn) || (isLocationOrGroup && isPrior)
}

View File

@@ -159,6 +159,31 @@ func (this *HTTPWebsocketDAO) UpdateWebsocket(tx *dbs.Tx, websocketId int64, han
return this.NotifyUpdate(tx, websocketId) return this.NotifyUpdate(tx, websocketId)
} }
// CloneWebsocket 复制配置
func (this *HTTPWebsocketDAO) CloneWebsocket(tx *dbs.Tx, fromWebsocketId int64) (newWebsocketId int64, err error) {
websocketOne, err := this.Query(tx).
Pk(fromWebsocketId).
Find()
if err != nil || websocketOne == nil {
return 0, err
}
var websocket = websocketOne.(*HTTPWebsocket)
var op = NewHTTPWebsocketOperator()
op.State = websocket.State
op.IsOn = websocket.IsOn
if len(websocket.HandshakeTimeout) > 0 {
op.HandshakeTimeout = websocket.HandshakeTimeout
}
op.AllowAllOrigins = websocket.AllowAllOrigins
if len(websocket.AllowedOrigins) > 0 {
op.AllowedOrigins = websocket.AllowedOrigins
}
op.RequestSameOrigin = websocket.RequestSameOrigin
op.RequestOrigin = websocket.RequestOrigin
return this.SaveInt64(tx, op)
}
// NotifyUpdate 通知更新 // NotifyUpdate 通知更新
func (this *HTTPWebsocketDAO) NotifyUpdate(tx *dbs.Tx, websocketId int64) error { func (this *HTTPWebsocketDAO) NotifyUpdate(tx *dbs.Tx, websocketId int64) error {
webId, err := SharedHTTPWebDAO.FindEnabledWebIdWithWebsocketId(tx, websocketId) webId, err := SharedHTTPWebDAO.FindEnabledWebIdWithWebsocketId(tx, websocketId)

View File

@@ -2,7 +2,7 @@ package models
import "github.com/iwind/TeaGo/dbs" import "github.com/iwind/TeaGo/dbs"
// Websocket设置 // HTTPWebsocket Websocket设置
type HTTPWebsocket struct { type HTTPWebsocket struct {
Id uint32 `field:"id"` // ID Id uint32 `field:"id"` // ID
AdminId uint32 `field:"adminId"` // 管理员ID AdminId uint32 `field:"adminId"` // 管理员ID
@@ -15,20 +15,22 @@ type HTTPWebsocket struct {
AllowedOrigins dbs.JSON `field:"allowedOrigins"` // 支持的源域名列表 AllowedOrigins dbs.JSON `field:"allowedOrigins"` // 支持的源域名列表
RequestSameOrigin uint8 `field:"requestSameOrigin"` // 是否请求一样的Origin RequestSameOrigin uint8 `field:"requestSameOrigin"` // 是否请求一样的Origin
RequestOrigin string `field:"requestOrigin"` // 请求Origin RequestOrigin string `field:"requestOrigin"` // 请求Origin
WebId uint64 `field:"webId"` // Web
} }
type HTTPWebsocketOperator struct { type HTTPWebsocketOperator struct {
Id interface{} // ID Id any // ID
AdminId interface{} // 管理员ID AdminId any // 管理员ID
UserId interface{} // 用户ID UserId any // 用户ID
CreatedAt interface{} // 创建时间 CreatedAt any // 创建时间
State interface{} // 状态 State any // 状态
IsOn interface{} // 是否启用 IsOn any // 是否启用
HandshakeTimeout interface{} // 握手超时时间 HandshakeTimeout any // 握手超时时间
AllowAllOrigins interface{} // 是否支持所有源 AllowAllOrigins any // 是否支持所有源
AllowedOrigins interface{} // 支持的源域名列表 AllowedOrigins any // 支持的源域名列表
RequestSameOrigin interface{} // 是否请求一样的Origin RequestSameOrigin any // 是否请求一样的Origin
RequestOrigin interface{} // 请求Origin RequestOrigin any // 请求Origin
WebId any // Web
} }
func NewHTTPWebsocketOperator() *HTTPWebsocketOperator { func NewHTTPWebsocketOperator() *HTTPWebsocketOperator {

View File

@@ -75,13 +75,18 @@ func (this *IPItemDAO) EnableIPItem(tx *dbs.Tx, id int64) error {
} }
// DisableIPItem 禁用条目 // DisableIPItem 禁用条目
func (this *IPItemDAO) DisableIPItem(tx *dbs.Tx, id int64) error { func (this *IPItemDAO) DisableIPItem(tx *dbs.Tx, id int64, sourceUserId int64) error {
version, err := SharedIPListDAO.IncreaseVersion(tx) version, err := SharedIPListDAO.IncreaseVersion(tx)
if err != nil { if err != nil {
return err return err
} }
_, err = this.Query(tx). var query = this.Query(tx)
if sourceUserId > 0 {
query.Attr("sourceUserId", sourceUserId)
}
_, err = query.
Pk(id). Pk(id).
Set("state", IPItemStateDisabled). Set("state", IPItemStateDisabled).
Set("version", version). Set("version", version).
@@ -94,7 +99,7 @@ func (this *IPItemDAO) DisableIPItem(tx *dbs.Tx, id int64) error {
} }
// DisableIPItemsWithIP 禁用某个IP相关条目 // DisableIPItemsWithIP 禁用某个IP相关条目
func (this *IPItemDAO) DisableIPItemsWithIP(tx *dbs.Tx, ipFrom string, ipTo string, userId int64, listId int64) error { func (this *IPItemDAO) DisableIPItemsWithIP(tx *dbs.Tx, ipFrom string, ipTo string, sourceUserId int64, listId int64) error {
if len(ipFrom) == 0 { if len(ipFrom) == 0 {
return errors.New("invalid 'ipFrom'") return errors.New("invalid 'ipFrom'")
} }
@@ -106,16 +111,13 @@ func (this *IPItemDAO) DisableIPItemsWithIP(tx *dbs.Tx, ipFrom string, ipTo stri
State(IPItemStateEnabled) State(IPItemStateEnabled)
if listId > 0 { if listId > 0 {
if userId > 0 {
err := SharedIPListDAO.CheckUserIPList(tx, userId, listId)
if err != nil {
return err
}
}
query.Attr("listId", listId) query.Attr("listId", listId)
} }
if sourceUserId > 0 {
query.Attr("sourceUserId", sourceUserId)
}
ones, err := query.FindAll() ones, err := query.FindAll()
if err != nil { if err != nil {
return err return err
@@ -125,14 +127,6 @@ func (this *IPItemDAO) DisableIPItemsWithIP(tx *dbs.Tx, ipFrom string, ipTo stri
for _, one := range ones { for _, one := range ones {
var item = one.(*IPItem) var item = one.(*IPItem)
var itemId = int64(item.Id) var itemId = int64(item.Id)
var itemListId = int64(item.ListId)
if itemListId != listId && userId > 0 {
err = SharedIPListDAO.CheckUserIPList(tx, userId, itemListId)
if err != nil {
// ignore error
continue
}
}
itemIds = append(itemIds, itemId) itemIds = append(itemIds, itemId)
} }
@@ -213,11 +207,12 @@ func (this *IPItemDAO) DeleteOldItem(tx *dbs.Tx, listId int64, ipFrom string, ip
Attr("listId", listId). Attr("listId", listId).
Attr("ipFrom", ipFrom). Attr("ipFrom", ipFrom).
Attr("ipTo", ipTo). Attr("ipTo", ipTo).
Set("state", IPItemStateEnabled). Attr("state", IPItemStateEnabled).
FindAll() FindAll()
if err != nil { if err != nil {
return err return err
} }
for _, one := range ones { for _, one := range ones {
var itemId = int64(one.(*IPItem).Id) var itemId = int64(one.(*IPItem).Id)
version, err := SharedIPListDAO.IncreaseVersion(tx) version, err := SharedIPListDAO.IncreaseVersion(tx)
@@ -253,7 +248,8 @@ func (this *IPItemDAO) CreateIPItem(tx *dbs.Tx,
sourceServerId int64, sourceServerId int64,
sourceHTTPFirewallPolicyId int64, sourceHTTPFirewallPolicyId int64,
sourceHTTPFirewallRuleGroupId int64, sourceHTTPFirewallRuleGroupId int64,
sourceHTTPFirewallRuleSetId int64) (int64, error) { sourceHTTPFirewallRuleSetId int64,
shouldNotify bool) (int64, error) {
version, err := SharedIPListDAO.IncreaseVersion(tx) version, err := SharedIPListDAO.IncreaseVersion(tx)
if err != nil { if err != nil {
return 0, err return 0, err
@@ -282,6 +278,15 @@ func (this *IPItemDAO) CreateIPItem(tx *dbs.Tx,
op.SourceHTTPFirewallRuleGroupId = sourceHTTPFirewallRuleGroupId op.SourceHTTPFirewallRuleGroupId = sourceHTTPFirewallRuleGroupId
op.SourceHTTPFirewallRuleSetId = sourceHTTPFirewallRuleSetId op.SourceHTTPFirewallRuleSetId = sourceHTTPFirewallRuleSetId
// 服务所属用户
if sourceServerId > 0 {
userId, err := SharedServerDAO.FindServerUserId(tx, sourceServerId)
if err != nil {
return 0, err
}
op.SourceUserId = userId
}
var autoAdded = listId == firewallconfigs.GlobalListId || sourceNodeId > 0 || sourceServerId > 0 || sourceHTTPFirewallPolicyId > 0 var autoAdded = listId == firewallconfigs.GlobalListId || sourceNodeId > 0 || sourceServerId > 0 || sourceHTTPFirewallPolicyId > 0
if autoAdded { if autoAdded {
op.IsRead = 0 op.IsRead = 0
@@ -301,9 +306,11 @@ func (this *IPItemDAO) CreateIPItem(tx *dbs.Tx,
return itemId, nil return itemId, nil
} }
err = this.NotifyUpdate(tx, itemId) if shouldNotify {
if err != nil { err = this.NotifyUpdate(tx, itemId)
return 0, err if err != nil {
return 0, err
}
} }
return itemId, nil return itemId, nil
} }
@@ -353,10 +360,13 @@ func (this *IPItemDAO) UpdateIPItem(tx *dbs.Tx, itemId int64, ipFrom string, ipT
} }
// CountIPItemsWithListId 计算IP数量 // CountIPItemsWithListId 计算IP数量
func (this *IPItemDAO) CountIPItemsWithListId(tx *dbs.Tx, listId int64, keyword string, ipFrom string, ipTo string, eventLevel string) (int64, error) { func (this *IPItemDAO) CountIPItemsWithListId(tx *dbs.Tx, listId int64, sourceUserId int64, keyword string, ipFrom string, ipTo string, eventLevel string) (int64, error) {
var query = this.Query(tx). var query = this.Query(tx).
State(IPItemStateEnabled). State(IPItemStateEnabled).
Attr("listId", listId) Attr("listId", listId)
if sourceUserId > 0 {
query.Attr("sourceUserId", sourceUserId)
}
if len(keyword) > 0 { if len(keyword) > 0 {
query.Where("(ipFrom LIKE :keyword OR ipTo LIKE :keyword)"). query.Where("(ipFrom LIKE :keyword OR ipTo LIKE :keyword)").
Param("keyword", dbutils.QuoteLike(keyword)) Param("keyword", dbutils.QuoteLike(keyword))
@@ -374,10 +384,13 @@ func (this *IPItemDAO) CountIPItemsWithListId(tx *dbs.Tx, listId int64, keyword
} }
// ListIPItemsWithListId 查找IP列表 // ListIPItemsWithListId 查找IP列表
func (this *IPItemDAO) ListIPItemsWithListId(tx *dbs.Tx, listId int64, keyword string, ipFrom string, ipTo string, eventLevel string, offset int64, size int64) (result []*IPItem, err error) { func (this *IPItemDAO) ListIPItemsWithListId(tx *dbs.Tx, listId int64, sourceUserId int64, keyword string, ipFrom string, ipTo string, eventLevel string, offset int64, size int64) (result []*IPItem, err error) {
var query = this.Query(tx). var query = this.Query(tx).
State(IPItemStateEnabled). State(IPItemStateEnabled).
Attr("listId", listId) Attr("listId", listId)
if sourceUserId > 0 {
query.Attr("sourceUserId", sourceUserId)
}
if len(keyword) > 0 { if len(keyword) > 0 {
query.Where("(ipFrom LIKE :keyword OR ipTo LIKE :keyword)"). query.Where("(ipFrom LIKE :keyword OR ipTo LIKE :keyword)").
Param("keyword", dbutils.QuoteLike(keyword)) Param("keyword", dbutils.QuoteLike(keyword))
@@ -403,10 +416,10 @@ func (this *IPItemDAO) ListIPItemsWithListId(tx *dbs.Tx, listId int64, keyword s
// ListIPItemsAfterVersion 根据版本号查找IP列表 // ListIPItemsAfterVersion 根据版本号查找IP列表
func (this *IPItemDAO) ListIPItemsAfterVersion(tx *dbs.Tx, version int64, size int64) (result []*IPItem, err error) { func (this *IPItemDAO) ListIPItemsAfterVersion(tx *dbs.Tx, version int64, size int64) (result []*IPItem, err error) {
_, err = this.Query(tx). _, err = this.Query(tx).
UseIndex("version").
// 这里不要设置状态参数,因为我们要知道哪些是删除的 // 这里不要设置状态参数,因为我们要知道哪些是删除的
Gt("version", version). Gt("version", version).
Asc("version"). Asc("version").
Asc("id").
Limit(size). Limit(size).
Slice(&result). Slice(&result).
FindAll() FindAll()
@@ -466,8 +479,12 @@ func (this *IPItemDAO) ExistsEnabledItem(tx *dbs.Tx, itemId int64) (bool, error)
} }
// CountAllEnabledIPItems 计算数量 // CountAllEnabledIPItems 计算数量
func (this *IPItemDAO) CountAllEnabledIPItems(tx *dbs.Tx, keyword string, ip string, listId int64, unread bool, eventLevel string, listType string) (int64, error) { func (this *IPItemDAO) CountAllEnabledIPItems(tx *dbs.Tx, sourceUserId int64, keyword string, ip string, listId int64, unread bool, eventLevel string, listType string) (int64, error) {
var query = this.Query(tx) var query = this.Query(tx)
if sourceUserId > 0 {
query.Attr("sourceUserId", sourceUserId)
query.UseIndex("sourceUserId")
}
if len(keyword) > 0 { if len(keyword) > 0 {
query.Like("ipFrom", dbutils.QuoteLike(keyword)) query.Like("ipFrom", dbutils.QuoteLike(keyword))
} }
@@ -499,8 +516,12 @@ func (this *IPItemDAO) CountAllEnabledIPItems(tx *dbs.Tx, keyword string, ip str
} }
// ListAllEnabledIPItems 搜索所有IP // ListAllEnabledIPItems 搜索所有IP
func (this *IPItemDAO) ListAllEnabledIPItems(tx *dbs.Tx, keyword string, ip string, listId int64, unread bool, eventLevel string, listType string, offset int64, size int64) (result []*IPItem, err error) { func (this *IPItemDAO) ListAllEnabledIPItems(tx *dbs.Tx, sourceUserId int64, keyword string, ip string, listId int64, unread bool, eventLevel string, listType string, offset int64, size int64) (result []*IPItem, err error) {
var query = this.Query(tx) var query = this.Query(tx)
if sourceUserId > 0 {
query.Attr("sourceUserId", sourceUserId)
query.UseIndex("sourceUserId")
}
if len(keyword) > 0 { if len(keyword) > 0 {
query.Like("ipFrom", dbutils.QuoteLike(keyword)) query.Like("ipFrom", dbutils.QuoteLike(keyword))
} }
@@ -536,11 +557,17 @@ func (this *IPItemDAO) ListAllEnabledIPItems(tx *dbs.Tx, keyword string, ip stri
} }
// UpdateItemsRead 设置所有未已读 // UpdateItemsRead 设置所有未已读
func (this *IPItemDAO) UpdateItemsRead(tx *dbs.Tx) error { func (this *IPItemDAO) UpdateItemsRead(tx *dbs.Tx, sourceUserId int64) error {
return this.Query(tx). var query = this.Query(tx).
Attr("isRead", 0). Attr("isRead", 0).
Set("isRead", 1). Set("isRead", 1)
UpdateQuickly()
if sourceUserId > 0 {
query.Attr("sourceUserId", sourceUserId)
query.UseIndex("sourceUserId")
}
return query.UpdateQuickly()
} }
// CleanExpiredIPItems 清除过期数据 // CleanExpiredIPItems 清除过期数据

View File

@@ -51,12 +51,12 @@ func TestIPItemDAO_CreateManyIPs(t *testing.T) {
var dao = models.NewIPItemDAO() var dao = models.NewIPItemDAO()
var n = 10 var n = 10
for i := 0; i < n; i++ { for i := 0; i < n; i++ {
itemId, err := dao.CreateIPItem(tx, firewallconfigs.GlobalListId, "192."+types.String(rands.Int(0, 255))+"."+types.String(rands.Int(0, 255))+"."+types.String(rands.Int(0, 255)), "", time.Now().Unix()+86400, "test", models.IPItemTypeIPv4, "warning", 0, 0, 0, 0, 0, 0, 0) itemId, err := dao.CreateIPItem(tx, firewallconfigs.GlobalListId, "192."+types.String(rands.Int(0, 255))+"."+types.String(rands.Int(0, 255))+"."+types.String(rands.Int(0, 255)), "", time.Now().Unix()+86400, "test", models.IPItemTypeIPv4, "warning", 0, 0, 0, 0, 0, 0, 0, false)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
_ = itemId _ = itemId
/**err = dao.Query(tx).Pk(itemId).Set("state", 0).UpdateQuickly() /**err = dao.Query(tx).Pk(itemId).Attr("state", 0).UpdateQuickly()
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
}**/ }**/

View File

@@ -23,32 +23,34 @@ type IPItem struct {
SourceHTTPFirewallPolicyId uint32 `field:"sourceHTTPFirewallPolicyId"` // 来源策略ID SourceHTTPFirewallPolicyId uint32 `field:"sourceHTTPFirewallPolicyId"` // 来源策略ID
SourceHTTPFirewallRuleGroupId uint32 `field:"sourceHTTPFirewallRuleGroupId"` // 来源规则集分组ID SourceHTTPFirewallRuleGroupId uint32 `field:"sourceHTTPFirewallRuleGroupId"` // 来源规则集分组ID
SourceHTTPFirewallRuleSetId uint32 `field:"sourceHTTPFirewallRuleSetId"` // 来源规则集ID SourceHTTPFirewallRuleSetId uint32 `field:"sourceHTTPFirewallRuleSetId"` // 来源规则集ID
SourceUserId uint64 `field:"sourceUserId"` // 用户ID
IsRead bool `field:"isRead"` // 是否已读 IsRead bool `field:"isRead"` // 是否已读
} }
type IPItemOperator struct { type IPItemOperator struct {
Id interface{} // ID Id any // ID
ListId interface{} // 所属名单ID ListId any // 所属名单ID
Type interface{} // 类型 Type any // 类型
IpFrom interface{} // 开始IP IpFrom any // 开始IP
IpTo interface{} // 结束IP IpTo any // 结束IP
IpFromLong interface{} // 开始IP整型 IpFromLong any // 开始IP整型
IpToLong interface{} // 结束IP整型 IpToLong any // 结束IP整型
Version interface{} // 版本 Version any // 版本
CreatedAt interface{} // 创建时间 CreatedAt any // 创建时间
UpdatedAt interface{} // 修改时间 UpdatedAt any // 修改时间
Reason interface{} // 加入说明 Reason any // 加入说明
EventLevel interface{} // 事件级别 EventLevel any // 事件级别
State interface{} // 状态 State any // 状态
ExpiredAt interface{} // 过期时间 ExpiredAt any // 过期时间
ServerId interface{} // 有效范围服务ID ServerId any // 有效范围服务ID
NodeId interface{} // 有效范围节点ID NodeId any // 有效范围节点ID
SourceNodeId interface{} // 来源节点ID SourceNodeId any // 来源节点ID
SourceServerId interface{} // 来源服务ID SourceServerId any // 来源服务ID
SourceHTTPFirewallPolicyId interface{} // 来源策略ID SourceHTTPFirewallPolicyId any // 来源策略ID
SourceHTTPFirewallRuleGroupId interface{} // 来源规则集分组ID SourceHTTPFirewallRuleGroupId any // 来源规则集分组ID
SourceHTTPFirewallRuleSetId interface{} // 来源规则集ID SourceHTTPFirewallRuleSetId any // 来源规则集ID
IsRead interface{} // 是否已读 SourceUserId any // 用户ID
IsRead any // 是否已读
} }
func NewIPItemOperator() *IPItemOperator { func NewIPItemOperator() *IPItemOperator {

View File

@@ -72,7 +72,7 @@ func (this *IPLibraryFileDAO) FindEnabledIPLibraryFile(tx *dbs.Tx, id int64) (*I
} }
// CreateLibraryFile 创建文件 // CreateLibraryFile 创建文件
func (this *IPLibraryFileDAO) CreateLibraryFile(tx *dbs.Tx, name string, template string, emptyValues []string, fileId int64, countries []string, provinces [][2]string, cities [][3]string, towns [][4]string, providers []string) (int64, error) { func (this *IPLibraryFileDAO) CreateLibraryFile(tx *dbs.Tx, name string, template string, emptyValues []string, password string, fileId int64, countries []string, provinces [][2]string, cities [][3]string, towns [][4]string, providers []string) (int64, error) {
var op = NewIPLibraryFileOperator() var op = NewIPLibraryFileOperator()
op.Name = name op.Name = name
op.Template = template op.Template = template
@@ -86,6 +86,8 @@ func (this *IPLibraryFileDAO) CreateLibraryFile(tx *dbs.Tx, name string, templat
} }
op.EmptyValues = emptyValuesJSON op.EmptyValues = emptyValuesJSON
op.Password = password
op.FileId = fileId op.FileId = fileId
if countries == nil { if countries == nil {
@@ -337,7 +339,7 @@ func (this *IPLibraryFileDAO) GenerateIPLibrary(tx *dbs.Tx, libraryFileId int64)
var countries = []*iplibrary.Country{} var countries = []*iplibrary.Country{}
for _, country := range dbCountries { for _, country := range dbCountries {
countries = append(countries, &iplibrary.Country{ countries = append(countries, &iplibrary.Country{
Id: country.Id, Id: types.Uint16(country.Id),
Name: country.DisplayName(), Name: country.DisplayName(),
Codes: country.AllCodes(), Codes: country.AllCodes(),
}) })
@@ -352,7 +354,7 @@ func (this *IPLibraryFileDAO) GenerateIPLibrary(tx *dbs.Tx, libraryFileId int64)
var provinces = []*iplibrary.Province{} var provinces = []*iplibrary.Province{}
for _, province := range dbProvinces { for _, province := range dbProvinces {
provinces = append(provinces, &iplibrary.Province{ provinces = append(provinces, &iplibrary.Province{
Id: province.Id, Id: types.Uint16(province.Id),
Name: province.DisplayName(), Name: province.DisplayName(),
Codes: province.AllCodes(), Codes: province.AllCodes(),
}) })
@@ -397,7 +399,7 @@ func (this *IPLibraryFileDAO) GenerateIPLibrary(tx *dbs.Tx, libraryFileId int64)
var providers = []*iplibrary.Provider{} var providers = []*iplibrary.Provider{}
for _, provider := range dbProviders { for _, provider := range dbProviders {
providers = append(providers, &iplibrary.Provider{ providers = append(providers, &iplibrary.Provider{
Id: provider.Id, Id: types.Uint16(provider.Id),
Name: provider.DisplayName(), Name: provider.DisplayName(),
Codes: provider.AllCodes(), Codes: provider.AllCodes(),
}) })
@@ -414,7 +416,7 @@ func (this *IPLibraryFileDAO) GenerateIPLibrary(tx *dbs.Tx, libraryFileId int64)
Towns: towns, Towns: towns,
Providers: providers, Providers: providers,
} }
writer, err := iplibrary.NewFileWriter(filePath, meta) writer, err := iplibrary.NewFileWriter(filePath, meta, libraryFile.Password)
if err != nil { if err != nil {
return err return err
} }

View File

@@ -18,6 +18,7 @@ type IPLibraryFile struct {
Towns dbs.JSON `field:"towns"` // 区县 Towns dbs.JSON `field:"towns"` // 区县
Providers dbs.JSON `field:"providers"` // ISP服务商 Providers dbs.JSON `field:"providers"` // ISP服务商
Code string `field:"code"` // 文件代号 Code string `field:"code"` // 文件代号
Password string `field:"password"` // 密码
CreatedAt uint64 `field:"createdAt"` // 上传时间 CreatedAt uint64 `field:"createdAt"` // 上传时间
State uint8 `field:"state"` // 状态 State uint8 `field:"state"` // 状态
} }
@@ -37,6 +38,7 @@ type IPLibraryFileOperator struct {
Towns any // 区县 Towns any // 区县
Providers any // ISP服务商 Providers any // ISP服务商
Code any // 文件代号 Code any // 文件代号
Password any // 密码
CreatedAt any // 上传时间 CreatedAt any // 上传时间
State any // 状态 State any // 状态
} }

View File

@@ -60,11 +60,11 @@ func (this *LogDAO) CreateLog(tx *dbs.Tx, adminType string, adminId int64, level
} }
// CountLogs 计算所有日志数量 // CountLogs 计算所有日志数量
func (this *LogDAO) CountLogs(tx *dbs.Tx, dayFrom string, dayTo string, keyword string, userType string) (int64, error) { func (this *LogDAO) CountLogs(tx *dbs.Tx, dayFrom string, dayTo string, keyword string, userType string, level string) (int64, error) {
dayFrom = this.formatDay(dayFrom) dayFrom = this.formatDay(dayFrom)
dayTo = this.formatDay(dayTo) dayTo = this.formatDay(dayTo)
query := this.Query(tx) var query = this.Query(tx)
if len(dayFrom) > 0 { if len(dayFrom) > 0 {
query.Gte("day", dayFrom) query.Gte("day", dayFrom)
@@ -76,6 +76,9 @@ func (this *LogDAO) CountLogs(tx *dbs.Tx, dayFrom string, dayTo string, keyword
query.Where("(description LIKE :keyword OR ip LIKE :keyword OR action LIKE :keyword)"). query.Where("(description LIKE :keyword OR ip LIKE :keyword OR action LIKE :keyword)").
Param("keyword", dbutils.QuoteLike(keyword)) Param("keyword", dbutils.QuoteLike(keyword))
} }
if len(level) > 0 {
query.Attr("level", level)
}
// 用户类型 // 用户类型
switch userType { switch userType {
@@ -89,11 +92,11 @@ func (this *LogDAO) CountLogs(tx *dbs.Tx, dayFrom string, dayTo string, keyword
} }
// ListLogs 列出单页日志 // ListLogs 列出单页日志
func (this *LogDAO) ListLogs(tx *dbs.Tx, offset int64, size int64, dayFrom string, dayTo string, keyword string, userType string) (result []*Log, err error) { func (this *LogDAO) ListLogs(tx *dbs.Tx, offset int64, size int64, dayFrom string, dayTo string, keyword string, userType string, level string) (result []*Log, err error) {
dayFrom = this.formatDay(dayFrom) dayFrom = this.formatDay(dayFrom)
dayTo = this.formatDay(dayTo) dayTo = this.formatDay(dayTo)
query := this.Query(tx) var query = this.Query(tx)
if len(dayFrom) > 0 { if len(dayFrom) > 0 {
query.Gte("day", dayFrom) query.Gte("day", dayFrom)
} }
@@ -105,6 +108,10 @@ func (this *LogDAO) ListLogs(tx *dbs.Tx, offset int64, size int64, dayFrom strin
Param("keyword", dbutils.QuoteLike(keyword)) Param("keyword", dbutils.QuoteLike(keyword))
} }
if len(level) > 0 {
query.Attr("level", level)
}
// 用户类型 // 用户类型
switch userType { switch userType {
case "admin": case "admin":

View File

@@ -155,7 +155,7 @@ func (this *MessageDAO) CreateNodeMessage(tx *dbs.Tx, role string, clusterId int
// CreateMessage 创建普通消息 // CreateMessage 创建普通消息
func (this *MessageDAO) CreateMessage(tx *dbs.Tx, adminId int64, userId int64, messageType MessageType, level string, subject string, body string, paramsJSON []byte) error { func (this *MessageDAO) CreateMessage(tx *dbs.Tx, adminId int64, userId int64, messageType MessageType, level string, subject string, body string, paramsJSON []byte) error {
body = utils.LimitString(subject, 100) subject = utils.LimitString(subject, 100)
body = utils.LimitString(body, 1024) body = utils.LimitString(body, 1024)
var op = NewMessageOperator() var op = NewMessageOperator()

View File

@@ -1077,7 +1077,7 @@ func (this *NodeClusterDAO) UpdateClusterUAMPolicy(tx *dbs.Tx, clusterId int64,
return err return err
} }
return this.NotifyUpdate(tx, clusterId) return this.NotifyUAMUpdate(tx, clusterId)
} }
uamPolicyJSON, err := json.Marshal(uamPolicy) uamPolicyJSON, err := json.Marshal(uamPolicy)
@@ -1092,7 +1092,7 @@ func (this *NodeClusterDAO) UpdateClusterUAMPolicy(tx *dbs.Tx, clusterId int64,
return err return err
} }
return this.NotifyUpdate(tx, clusterId) return this.NotifyUAMUpdate(tx, clusterId)
} }
// FindClusterUAMPolicy 查询设置 // FindClusterUAMPolicy 查询设置
@@ -1212,6 +1212,11 @@ func (this *NodeClusterDAO) NotifyUpdate(tx *dbs.Tx, clusterId int64) error {
return SharedNodeTaskDAO.CreateClusterTask(tx, nodeconfigs.NodeRoleNode, clusterId, 0, 0, NodeTaskTypeConfigChanged) return SharedNodeTaskDAO.CreateClusterTask(tx, nodeconfigs.NodeRoleNode, clusterId, 0, 0, NodeTaskTypeConfigChanged)
} }
// NotifyUAMUpdate 通知UAM更新
func (this *NodeClusterDAO) NotifyUAMUpdate(tx *dbs.Tx, clusterId int64) error {
return SharedNodeTaskDAO.CreateClusterTask(tx, nodeconfigs.NodeRoleNode, clusterId, 0, 0, NodeTaskTypeUAMPolicyChanged)
}
// NotifyDNSUpdate 通知DNS更新 // NotifyDNSUpdate 通知DNS更新
// TODO 更新新的DNS解析记录的同时需要删除老的DNS解析记录 // TODO 更新新的DNS解析记录的同时需要删除老的DNS解析记录
func (this *NodeClusterDAO) NotifyDNSUpdate(tx *dbs.Tx, clusterId int64) error { func (this *NodeClusterDAO) NotifyDNSUpdate(tx *dbs.Tx, clusterId int64) error {

View File

@@ -356,7 +356,7 @@ func (this *NodeDAO) ListEnabledNodesMatch(tx *dbs.Tx,
// 关键词 // 关键词
if len(keyword) > 0 { if len(keyword) > 0 {
query.Where("(name LIKE :keyword OR JSON_EXTRACT(status,'$.hostname') LIKE :keyword OR id IN (SELECT nodeId FROM "+SharedNodeIPAddressDAO.Table+" WHERE ip LIKE :keyword))"). query.Where("(name LIKE :keyword OR JSON_EXTRACT(status,'$.hostname') LIKE :keyword OR "+this.Table+".id IN (SELECT nodeId FROM "+SharedNodeIPAddressDAO.Table+" WHERE ip LIKE :keyword))").
Param("keyword", dbutils.QuoteLike(keyword)) Param("keyword", dbutils.QuoteLike(keyword))
} }
@@ -435,6 +435,16 @@ func (this *NodeDAO) ListEnabledNodesMatch(tx *dbs.Tx,
valueField = "load1m" valueField = "load1m"
isAsc = false isAsc = false
ifNullValue = -1 ifNullValue = -1
case "connectionsAsc":
valueItem = "connections"
valueField = "total"
isAsc = true
ifNullValue = 1000
case "connectionsDesc":
valueItem = "connections"
valueField = "total"
isAsc = false
ifNullValue = -1
default: default:
query.Desc("level") query.Desc("level")
} }
@@ -830,7 +840,24 @@ func (this *NodeDAO) UpdateNodeStatus(tx *dbs.Tx, nodeId int64, nodeStatus *node
Set("isActive", true). Set("isActive", true).
Set("status", nodeStatusJSON). Set("status", nodeStatusJSON).
Update() Update()
return err if err != nil {
return err
}
// 自动设置安装状态
isInstalled, err := this.Query(tx).
Pk(nodeId).
Result("isInstalled").
FindBoolCol()
if err != nil {
return err
}
if !isInstalled {
return this.UpdateNodeIsInstalled(tx, nodeId, true)
}
return nil
} }
// FindNodeStatus 获取节点状态 // FindNodeStatus 获取节点状态
@@ -875,7 +902,10 @@ func (this *NodeDAO) UpdateNodeIsInstalled(tx *dbs.Tx, nodeId int64, isInstalled
Set("isInstalled", isInstalled). Set("isInstalled", isInstalled).
Set("installStatus", "null"). // 重置安装状态 Set("installStatus", "null"). // 重置安装状态
Update() Update()
return err if err != nil {
return err
}
return this.NotifyDNSUpdate(tx, nodeId)
} }
// FindNodeInstallStatus 查询节点的安装状态 // FindNodeInstallStatus 查询节点的安装状态
@@ -932,11 +962,16 @@ func (this *NodeDAO) UpdateNodeInstallStatus(tx *dbs.Tx, nodeId int64, status *N
// ComposeNodeConfig 组合配置 // ComposeNodeConfig 组合配置
// TODO 提升运行速度 // TODO 提升运行速度
func (this *NodeDAO) ComposeNodeConfig(tx *dbs.Tx, nodeId int64, cacheMap *utils.CacheMap) (*nodeconfigs.NodeConfig, error) { func (this *NodeDAO) ComposeNodeConfig(tx *dbs.Tx, nodeId int64, dataMap *shared.DataMap, cacheMap *utils.CacheMap) (*nodeconfigs.NodeConfig, error) {
if cacheMap == nil { if cacheMap == nil {
cacheMap = utils.NewCacheMap() cacheMap = utils.NewCacheMap()
} }
// 放入到缓存中,以便于后面继续使用
if dataMap != nil {
cacheMap.Put("DataMap", dataMap)
}
node, err := this.FindEnabledNode(tx, nodeId) node, err := this.FindEnabledNode(tx, nodeId)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -951,6 +986,7 @@ func (this *NodeDAO) ComposeNodeConfig(tx *dbs.Tx, nodeId int64, cacheMap *utils
var config = &nodeconfigs.NodeConfig{ var config = &nodeconfigs.NodeConfig{
Id: int64(node.Id), Id: int64(node.Id),
Edition: teaconst.Edition,
NodeId: node.UniqueId, NodeId: node.UniqueId,
Secret: node.Secret, Secret: node.Secret,
IsOn: node.IsOn, IsOn: node.IsOn,
@@ -963,8 +999,17 @@ func (this *NodeDAO) ComposeNodeConfig(tx *dbs.Tx, nodeId int64, cacheMap *utils
GroupId: int64(node.GroupId), GroupId: int64(node.GroupId),
EnableIPLists: node.EnableIPLists, EnableIPLists: node.EnableIPLists,
APINodeAddrs: node.DecodeAPINodeAddrs(), APINodeAddrs: node.DecodeAPINodeAddrs(),
DataMap: dataMap,
} }
// 待更新服务ID
updatingServerListId, err := SharedUpdatingServerListDAO.FindLatestId(tx)
if err != nil {
return nil, err
}
config.UpdatingServerListId = updatingServerListId
// API节点IP // API节点IP
apiNodeIPs, err := SharedAPINodeDAO.FindAllEnabledAPIAccessIPs(tx, cacheMap) apiNodeIPs, err := SharedAPINodeDAO.FindAllEnabledAPIAccessIPs(tx, cacheMap)
if err != nil { if err != nil {
@@ -999,7 +1044,7 @@ func (this *NodeDAO) ComposeNodeConfig(tx *dbs.Tx, nodeId int64, cacheMap *utils
} }
for _, server := range servers { for _, server := range servers {
serverConfig, err := SharedServerDAO.ComposeServerConfig(tx, server, false, cacheMap, true, false) serverConfig, err := SharedServerDAO.ComposeServerConfig(tx, server, false, dataMap, cacheMap, true, false)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -1485,7 +1530,7 @@ func (this *NodeDAO) UpdateNodeRegionId(tx *dbs.Tx, nodeId int64, regionId int64
} }
// FindAllEnabledNodesDNSWithClusterId 获取一个集群的节点DNS信息 // FindAllEnabledNodesDNSWithClusterId 获取一个集群的节点DNS信息
func (this *NodeDAO) FindAllEnabledNodesDNSWithClusterId(tx *dbs.Tx, clusterId int64, includeSecondaryNodes bool, includingLnNodes bool) (result []*Node, err error) { func (this *NodeDAO) FindAllEnabledNodesDNSWithClusterId(tx *dbs.Tx, clusterId int64, includeSecondaryNodes bool, includingLnNodes bool, isInstalled bool) (result []*Node, err error) {
if clusterId <= 0 { if clusterId <= 0 {
return nil, nil return nil, nil
} }
@@ -1504,6 +1549,7 @@ func (this *NodeDAO) FindAllEnabledNodesDNSWithClusterId(tx *dbs.Tx, clusterId i
State(NodeStateEnabled). State(NodeStateEnabled).
Attr("isOn", true). Attr("isOn", true).
Attr("isUp", true). Attr("isUp", true).
Attr("isInstalled", isInstalled).
Result("id", "name", "dnsRoutes", "isOn"). Result("id", "name", "dnsRoutes", "isOn").
DescPk(). DescPk().
Slice(&result). Slice(&result).

View File

@@ -4,9 +4,11 @@
package models_test package models_test
import ( import (
"encoding/json"
teaconst "github.com/TeaOSLab/EdgeAPI/internal/const" teaconst "github.com/TeaOSLab/EdgeAPI/internal/const"
"github.com/TeaOSLab/EdgeAPI/internal/db/models" "github.com/TeaOSLab/EdgeAPI/internal/db/models"
"github.com/TeaOSLab/EdgeAPI/internal/utils" "github.com/TeaOSLab/EdgeAPI/internal/utils"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
_ "github.com/go-sql-driver/mysql" _ "github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/dbs" "github.com/iwind/TeaGo/dbs"
"github.com/iwind/TeaGo/logs" "github.com/iwind/TeaGo/logs"
@@ -47,21 +49,40 @@ func TestNodeDAO_FindEnabledNodeClusterIds(t *testing.T) {
func TestNodeDAO_ComposeNodeConfig(t *testing.T) { func TestNodeDAO_ComposeNodeConfig(t *testing.T) {
dbs.NotifyReady() dbs.NotifyReady()
before := time.Now() var before = time.Now()
defer func() {
t.Log(time.Since(before).Seconds()*1000, "ms")
}()
var tx *dbs.Tx var tx *dbs.Tx
var cacheMap = utils.NewCacheMap() var cacheMap = utils.NewCacheMap()
nodeConfig, err := models.SharedNodeDAO.ComposeNodeConfig(tx, 48, cacheMap) var dataMap = shared.NewDataMap()
//var dataMap *nodeconfigs.DataMap
nodeConfig, err := models.SharedNodeDAO.ComposeNodeConfig(tx, 48, dataMap, cacheMap)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
nodeConfig.DataMap = dataMap
t.Log(len(nodeConfig.Servers), "servers") t.Log(len(nodeConfig.Servers), "servers")
t.Log(cacheMap.Len(), "items") t.Log(cacheMap.Len(), "items")
// old: 77ms => new: 56ms t.Log(time.Since(before).Seconds()*1000, "ms")
data, err := json.Marshal(nodeConfig)
if err != nil {
t.Fatal(err)
}
t.Log(len(data), "bytes")
{
nodeConfig, err = models.SharedNodeDAO.ComposeNodeConfig(tx, 148, dataMap, cacheMap)
if err != nil {
t.Fatal(err)
}
t.Log(len(nodeConfig.DataMap.Map), "items in dataMap")
data, err = json.Marshal(nodeConfig)
if err != nil {
t.Fatal(err)
}
t.Log(len(data), "bytes")
}
} }
func TestNodeDAO_ComposeNodeConfig_ParentNodes(t *testing.T) { func TestNodeDAO_ComposeNodeConfig_ParentNodes(t *testing.T) {
@@ -71,7 +92,7 @@ func TestNodeDAO_ComposeNodeConfig_ParentNodes(t *testing.T) {
var tx *dbs.Tx var tx *dbs.Tx
var cacheMap = utils.NewCacheMap() var cacheMap = utils.NewCacheMap()
nodeConfig, err := models.SharedNodeDAO.ComposeNodeConfig(tx, 48, cacheMap) nodeConfig, err := models.SharedNodeDAO.ComposeNodeConfig(tx, 48, nil, cacheMap)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }

View File

@@ -24,6 +24,8 @@ const (
NodeTaskTypeScriptsChanged NodeTaskType = "scriptsChanged" // 脚本配置变化 NodeTaskTypeScriptsChanged NodeTaskType = "scriptsChanged" // 脚本配置变化
NodeTaskTypeNodeLevelChanged NodeTaskType = "nodeLevelChanged" // 节点级别变化 NodeTaskTypeNodeLevelChanged NodeTaskType = "nodeLevelChanged" // 节点级别变化
NodeTaskTypeUserServersStateChanged NodeTaskType = "userServersStateChanged" // 用户服务状态变化 NodeTaskTypeUserServersStateChanged NodeTaskType = "userServersStateChanged" // 用户服务状态变化
NodeTaskTypeUAMPolicyChanged NodeTaskType = "uamPolicyChanged" // UAM策略变化
NodeTaskTypeUpdatingServers NodeTaskType = "updatingServers" // 更新一组服务
// NS相关 // NS相关
@@ -236,6 +238,7 @@ func (this *NodeTaskDAO) FindDoingNodeTasks(tx *dbs.Tx, role string, nodeId int6
var query = this.Query(tx). var query = this.Query(tx).
Attr("role", role). Attr("role", role).
Attr("nodeId", nodeId). Attr("nodeId", nodeId).
UseIndex("nodeId").
Asc("version") Asc("version")
if version > 0 { if version > 0 {
query.Lt("LENGTH(version)", 19) // 兼容以往版本 query.Lt("LENGTH(version)", 19) // 兼容以往版本

View File

@@ -1,17 +1,19 @@
package models package models_test
import ( import (
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs" "github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
_ "github.com/go-sql-driver/mysql" _ "github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/dbs" "github.com/iwind/TeaGo/dbs"
"testing" "testing"
"time"
) )
func TestNodeTaskDAO_CreateNodeTask(t *testing.T) { func TestNodeTaskDAO_CreateNodeTask(t *testing.T) {
dbs.NotifyReady() dbs.NotifyReady()
var tx *dbs.Tx var tx *dbs.Tx
err := SharedNodeTaskDAO.CreateNodeTask(tx, nodeconfigs.NodeRoleNode, 1, 2, 0, 0, NodeTaskTypeConfigChanged) err := models.SharedNodeTaskDAO.CreateNodeTask(tx, nodeconfigs.NodeRoleNode, 1, 2, 0, 0, models.NodeTaskTypeConfigChanged)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@@ -22,7 +24,7 @@ func TestNodeTaskDAO_CreateClusterTask(t *testing.T) {
dbs.NotifyReady() dbs.NotifyReady()
var tx *dbs.Tx var tx *dbs.Tx
err := SharedNodeTaskDAO.CreateClusterTask(tx, nodeconfigs.NodeRoleNode, 1, 0, 0, NodeTaskTypeConfigChanged) err := models.SharedNodeTaskDAO.CreateClusterTask(tx, nodeconfigs.NodeRoleNode, 1, 0, 0, models.NodeTaskTypeConfigChanged)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@@ -33,9 +35,22 @@ func TestNodeTaskDAO_ExtractClusterTask(t *testing.T) {
dbs.NotifyReady() dbs.NotifyReady()
var tx *dbs.Tx var tx *dbs.Tx
err := SharedNodeTaskDAO.ExtractNodeClusterTask(tx, 1, 0, 0, NodeTaskTypeConfigChanged) err := models.SharedNodeTaskDAO.ExtractNodeClusterTask(tx, 1, 0, 0, models.NodeTaskTypeConfigChanged)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
t.Log("ok") t.Log("ok")
} }
func TestNodeTaskDAO_FindDoingNodeTasks(t *testing.T) {
var tx *dbs.Tx
var dao = models.NewNodeTaskDAO()
var before = time.Now()
defer func() {
t.Log(time.Since(before).Seconds()*1000, "ms")
}()
_, err := dao.FindDoingNodeTasks(tx, "node", 48, 0)
if err != nil {
t.Fatal(err)
}
}

View File

@@ -24,6 +24,7 @@ type NSCluster struct {
SoaSerial uint64 `field:"soaSerial"` // SOA序列号 SoaSerial uint64 `field:"soaSerial"` // SOA序列号
Email string `field:"email"` // 管理员邮箱 Email string `field:"email"` // 管理员邮箱
DetectAgents bool `field:"detectAgents"` // 是否监测Agents DetectAgents bool `field:"detectAgents"` // 是否监测Agents
CheckingPorts bool `field:"checkingPorts"` // 自动检测端口
} }
type NSClusterOperator struct { type NSClusterOperator struct {
@@ -47,6 +48,7 @@ type NSClusterOperator struct {
SoaSerial any // SOA序列号 SoaSerial any // SOA序列号
Email any // 管理员邮箱 Email any // 管理员邮箱
DetectAgents any // 是否监测Agents DetectAgents any // 是否监测Agents
CheckingPorts any // 自动检测端口
} }
func NewNSClusterOperator() *NSClusterOperator { func NewNSClusterOperator() *NSClusterOperator {

View File

@@ -275,8 +275,66 @@ func (this *OriginDAO) UpdateOrigin(tx *dbs.Tx,
return this.NotifyUpdate(tx, originId) return this.NotifyUpdate(tx, originId)
} }
// CloneOrigin 复制源站
func (this *OriginDAO) CloneOrigin(tx *dbs.Tx, fromOriginId int64) (newOriginId int64, err error) {
if fromOriginId <= 0 {
return
}
originOne, err := this.Find(tx, fromOriginId)
if err != nil || originOne == nil {
return
}
var origin = originOne.(*Origin)
var op = NewOriginOperator()
op.IsOn = origin.IsOn
op.Name = origin.Name
op.Version = origin.Version
if IsNotNull(origin.Addr) {
op.Addr = origin.Addr
}
op.Description = origin.Description
op.Code = origin.Code
op.Weight = origin.Weight
if IsNotNull(origin.ConnTimeout) {
op.ConnTimeout = origin.ConnTimeout
}
if IsNotNull(origin.ReadTimeout) {
op.ReadTimeout = origin.ReadTimeout
}
if IsNotNull(origin.IdleTimeout) {
op.IdleTimeout = origin.IdleTimeout
}
op.MaxFails = origin.MaxFails
op.MaxConns = origin.MaxConns
op.MaxIdleConns = origin.MaxIdleConns
op.HttpRequestURI = origin.HttpRequestURI
if IsNotNull(origin.HttpRequestHeader) {
op.HttpRequestHeader = origin.HttpRequestHeader
}
if IsNotNull(origin.HttpResponseHeader) {
op.HttpResponseHeader = origin.HttpResponseHeader
}
op.Host = origin.Host
if IsNotNull(origin.HealthCheck) {
op.HealthCheck = origin.HealthCheck
}
if IsNotNull(origin.Cert) {
// TODO 需要Clone证书
op.Cert = origin.Cert
}
if IsNotNull(origin.Ftp) {
op.Ftp = origin.Ftp
}
if IsNotNull(origin.Domains) {
op.Domains = origin.Domains
}
op.FollowPort = origin.FollowPort
op.State = origin.State
return this.SaveInt64(tx, op)
}
// ComposeOriginConfig 将源站信息转换为配置 // ComposeOriginConfig 将源站信息转换为配置
func (this *OriginDAO) ComposeOriginConfig(tx *dbs.Tx, originId int64, cacheMap *utils.CacheMap) (*serverconfigs.OriginConfig, error) { func (this *OriginDAO) ComposeOriginConfig(tx *dbs.Tx, originId int64, dataMap *shared.DataMap, cacheMap *utils.CacheMap) (*serverconfigs.OriginConfig, error) {
if cacheMap == nil { if cacheMap == nil {
cacheMap = utils.NewCacheMap() cacheMap = utils.NewCacheMap()
} }
@@ -403,7 +461,7 @@ func (this *OriginDAO) ComposeOriginConfig(tx *dbs.Tx, originId int64, cacheMap
} }
config.CertRef = ref config.CertRef = ref
if ref.CertId > 0 { if ref.CertId > 0 {
certConfig, err := SharedSSLCertDAO.ComposeCertConfig(tx, ref.CertId, false, cacheMap) certConfig, err := SharedSSLCertDAO.ComposeCertConfig(tx, ref.CertId, false, dataMap, cacheMap)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@@ -8,7 +8,7 @@ import (
func TestOriginServerDAO_ComposeOriginConfig(t *testing.T) { func TestOriginServerDAO_ComposeOriginConfig(t *testing.T) {
var tx *dbs.Tx var tx *dbs.Tx
config, err := SharedOriginDAO.ComposeOriginConfig(tx, 1, nil) config, err := SharedOriginDAO.ComposeOriginConfig(tx, 1, nil, nil)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }

View File

@@ -81,7 +81,7 @@ func (this *ReverseProxyDAO) FindEnabledReverseProxy(tx *dbs.Tx, id int64) (*Rev
} }
// ComposeReverseProxyConfig 根据ID组合配置 // ComposeReverseProxyConfig 根据ID组合配置
func (this *ReverseProxyDAO) ComposeReverseProxyConfig(tx *dbs.Tx, reverseProxyId int64, cacheMap *utils.CacheMap) (*serverconfigs.ReverseProxyConfig, error) { func (this *ReverseProxyDAO) ComposeReverseProxyConfig(tx *dbs.Tx, reverseProxyId int64, dataMap *shared.DataMap, cacheMap *utils.CacheMap) (*serverconfigs.ReverseProxyConfig, error) {
if cacheMap == nil { if cacheMap == nil {
cacheMap = utils.NewCacheMap() cacheMap = utils.NewCacheMap()
} }
@@ -125,7 +125,7 @@ func (this *ReverseProxyDAO) ComposeReverseProxyConfig(tx *dbs.Tx, reverseProxyI
return nil, err return nil, err
} }
for _, ref := range originRefs { for _, ref := range originRefs {
originConfig, err := SharedOriginDAO.ComposeOriginConfig(tx, ref.OriginId, cacheMap) originConfig, err := SharedOriginDAO.ComposeOriginConfig(tx, ref.OriginId, dataMap, cacheMap)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -142,7 +142,7 @@ func (this *ReverseProxyDAO) ComposeReverseProxyConfig(tx *dbs.Tx, reverseProxyI
return nil, err return nil, err
} }
for _, ref := range originRefs { for _, ref := range originRefs {
originConfig, err := SharedOriginDAO.ComposeOriginConfig(tx, ref.OriginId, cacheMap) originConfig, err := SharedOriginDAO.ComposeOriginConfig(tx, ref.OriginId, dataMap, cacheMap)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -243,6 +243,115 @@ func (this *ReverseProxyDAO) CreateReverseProxy(tx *dbs.Tx, adminId int64, userI
return types.Int64(op.Id), nil return types.Int64(op.Id), nil
} }
// CloneReverseProxy 复制反向代理
func (this *ReverseProxyDAO) CloneReverseProxy(tx *dbs.Tx, fromReverseProxyId int64) (newReverseProxyId int64, err error) {
if fromReverseProxyId <= 0 {
return
}
reverseProxyOne, err := this.Query(tx).
Pk(fromReverseProxyId).
State(ReverseProxyStateEnabled).
Find()
if err != nil || reverseProxyOne == nil {
return 0, err
}
var reverseProxy = reverseProxyOne.(*ReverseProxy)
var op = NewReverseProxyOperator()
op.TemplateId = reverseProxy.TemplateId
op.IsOn = reverseProxy.IsOn
if IsNotNull(reverseProxy.Scheduling) {
op.Scheduling = reverseProxy.Scheduling
}
if IsNotNull(reverseProxy.PrimaryOrigins) {
var originRefs = []*serverconfigs.OriginRef{}
err = json.Unmarshal(reverseProxy.PrimaryOrigins, &originRefs)
if err != nil {
return 0, err
}
var newRefs = []*serverconfigs.OriginRef{}
for _, originRef := range originRefs {
if originRef.OriginId > 0 {
newOriginId, err := SharedOriginDAO.CloneOrigin(tx, originRef.OriginId)
if err != nil {
return 0, err
}
if newOriginId > 0 {
newRef, err := utils.JSONClone[*serverconfigs.OriginRef](originRef)
if err != nil {
return 0, err
}
newRef.OriginId = newOriginId
newRefs = append(newRefs, newRef)
}
}
}
newRefsJSON, err := json.Marshal(newRefs)
if err != nil {
return 0, err
}
op.PrimaryOrigins = newRefsJSON
}
if IsNotNull(reverseProxy.BackupOrigins) {
var originRefs = []*serverconfigs.OriginRef{}
err = json.Unmarshal(reverseProxy.BackupOrigins, &originRefs)
if err != nil {
return 0, err
}
var newRefs = []*serverconfigs.OriginRef{}
for _, originRef := range originRefs {
if originRef.OriginId > 0 {
newOriginId, err := SharedOriginDAO.CloneOrigin(tx, originRef.OriginId)
if err != nil {
return 0, err
}
if newOriginId > 0 {
newRef, err := utils.JSONClone[*serverconfigs.OriginRef](originRef)
if err != nil {
return 0, err
}
newRef.OriginId = newOriginId
newRefs = append(newRefs, newRef)
}
}
}
newRefsJSON, err := json.Marshal(newRefs)
if err != nil {
return 0, err
}
op.BackupOrigins = newRefsJSON
}
op.StripPrefix = reverseProxy.StripPrefix
op.RequestHostType = reverseProxy.RequestHostType
op.RequestHost = reverseProxy.RequestHost
op.RequestHostExcludingPort = reverseProxy.RequestHostExcludingPort
op.RequestURI = reverseProxy.RequestURI
op.AutoFlush = reverseProxy.AutoFlush
if IsNotNull(reverseProxy.AddHeaders) {
// TODO 复制Header
op.AddHeaders = reverseProxy.AddHeaders
}
op.State = reverseProxy.State
if IsNotNull(reverseProxy.ConnTimeout) {
op.ConnTimeout = reverseProxy.ConnTimeout
}
if IsNotNull(reverseProxy.ReadTimeout) {
op.ReadTimeout = reverseProxy.ReadTimeout
}
if IsNotNull(reverseProxy.IdleTimeout) {
op.IdleTimeout = reverseProxy.IdleTimeout
}
op.MaxConns = reverseProxy.MaxConns
op.MaxIdleConns = reverseProxy.MaxIdleConns
if IsNotNull(reverseProxy.ProxyProtocol) {
op.ProxyProtocol = reverseProxy.ProxyProtocol
}
op.FollowRedirects = reverseProxy.FollowRedirects
return this.SaveInt64(tx, op)
}
// UpdateReverseProxyScheduling 修改反向代理调度算法 // UpdateReverseProxyScheduling 修改反向代理调度算法
func (this *ReverseProxyDAO) UpdateReverseProxyScheduling(tx *dbs.Tx, reverseProxyId int64, schedulingJSON []byte) error { func (this *ReverseProxyDAO) UpdateReverseProxyScheduling(tx *dbs.Tx, reverseProxyId int64, schedulingJSON []byte) error {
if reverseProxyId <= 0 { if reverseProxyId <= 0 {

View File

@@ -8,7 +8,7 @@ import (
func TestReverseProxyDAO_ComposeReverseProxyConfig(t *testing.T) { func TestReverseProxyDAO_ComposeReverseProxyConfig(t *testing.T) {
var tx *dbs.Tx var tx *dbs.Tx
config, err := SharedReverseProxyDAO.ComposeReverseProxyConfig(tx, 1, nil) config, err := SharedReverseProxyDAO.ComposeReverseProxyConfig(tx, 1, nil, nil)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }

View File

@@ -1,6 +1,7 @@
package models package models
import ( import (
"fmt"
"github.com/TeaOSLab/EdgeAPI/internal/errors" "github.com/TeaOSLab/EdgeAPI/internal/errors"
"github.com/TeaOSLab/EdgeAPI/internal/goman" "github.com/TeaOSLab/EdgeAPI/internal/goman"
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs" "github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
@@ -63,7 +64,7 @@ func init() {
// UpdateServerBandwidth 写入数据 // UpdateServerBandwidth 写入数据
// 暂时不使用region区分 // 暂时不使用region区分
func (this *ServerBandwidthStatDAO) UpdateServerBandwidth(tx *dbs.Tx, userId int64, serverId int64, day string, timeAt string, bytes int64, totalBytes int64) error { func (this *ServerBandwidthStatDAO) UpdateServerBandwidth(tx *dbs.Tx, userId int64, serverId int64, regionId int64, day string, timeAt string, bytes int64, totalBytes int64, cachedBytes int64, attackBytes int64, countRequests int64, countCachedRequests int64, countAttackRequests int64) error {
if serverId <= 0 { if serverId <= 0 {
return errors.New("invalid server id '" + types.String(serverId) + "'") return errors.New("invalid server id '" + types.String(serverId) + "'")
} }
@@ -72,18 +73,34 @@ func (this *ServerBandwidthStatDAO) UpdateServerBandwidth(tx *dbs.Tx, userId int
Table(this.partialTable(serverId)). Table(this.partialTable(serverId)).
Param("bytes", bytes). Param("bytes", bytes).
Param("totalBytes", totalBytes). Param("totalBytes", totalBytes).
Param("cachedBytes", cachedBytes).
Param("attackBytes", attackBytes).
Param("countRequests", countRequests).
Param("countCachedRequests", countCachedRequests).
Param("countAttackRequests", countAttackRequests).
InsertOrUpdateQuickly(maps.Map{ InsertOrUpdateQuickly(maps.Map{
"userId": userId, "userId": userId,
"serverId": serverId, "serverId": serverId,
"day": day, "regionId": regionId,
"timeAt": timeAt, "day": day,
"bytes": bytes, "timeAt": timeAt,
"totalBytes": totalBytes, "bytes": bytes,
"avgBytes": totalBytes / 300, "totalBytes": totalBytes,
"avgBytes": totalBytes / 300,
"cachedBytes": cachedBytes,
"attackBytes": attackBytes,
"countRequests": countRequests,
"countCachedRequests": countCachedRequests,
"countAttackRequests": countAttackRequests,
}, maps.Map{ }, maps.Map{
"bytes": dbs.SQL("bytes+:bytes"), "bytes": dbs.SQL("bytes+:bytes"),
"avgBytes": dbs.SQL("(totalBytes+:totalBytes)/300"), // 因为生成SQL语句时会自动将avgBytes排在totalBytes之前所以这里不用担心先后顺序的问题 "avgBytes": dbs.SQL("(totalBytes+:totalBytes)/300"), // 因为生成SQL语句时会自动将avgBytes排在totalBytes之前所以这里不用担心先后顺序的问题
"totalBytes": dbs.SQL("totalBytes+:totalBytes"), "totalBytes": dbs.SQL("totalBytes+:totalBytes"),
"cachedBytes": dbs.SQL("cachedBytes+:cachedBytes"),
"attackBytes": dbs.SQL("attackBytes+:attackBytes"),
"countRequests": dbs.SQL("countRequests+:countRequests"),
"countCachedRequests": dbs.SQL("countCachedRequests+:countCachedRequests"),
"countAttackRequests": dbs.SQL("countAttackRequests+:countAttackRequests"),
}) })
} }
@@ -110,6 +127,7 @@ func (this *ServerBandwidthStatDAO) FindHourlyBandwidthStats(tx *dbs.Tx, serverI
ones, _, err := this.Query(tx). ones, _, err := this.Query(tx).
Table(this.partialTable(serverId)). Table(this.partialTable(serverId)).
Between("day", timeutil.FormatTime("Ymd", timestamp), timeutil.Format("Ymd")).
Attr("serverId", serverId). Attr("serverId", serverId).
Result(this.maxBytesField(useAvg), "CONCAT(day, '.', SUBSTRING(timeAt, 1, 2)) AS fullTime"). Result(this.maxBytesField(useAvg), "CONCAT(day, '.', SUBSTRING(timeAt, 1, 2)) AS fullTime").
Gte("CONCAT(day, '.', SUBSTRING(timeAt, 1, 2))", timeutil.FormatTime("Ymd.H", timestamp)). Gte("CONCAT(day, '.', SUBSTRING(timeAt, 1, 2))", timeutil.FormatTime("Ymd.H", timestamp)).
@@ -509,6 +527,7 @@ func (this *ServerBandwidthStatDAO) FindPercentileBetweenTimes(tx *dbs.Tx, serve
// 总数量 // 总数量
total, err := this.Query(tx). total, err := this.Query(tx).
Table(this.partialTable(serverId)). Table(this.partialTable(serverId)).
Between("day", timeFrom[:8], timeTo[:8]).
Attr("serverId", serverId). Attr("serverId", serverId).
Between("CONCAT(day, timeAt)", timeFrom, timeTo). Between("CONCAT(day, timeAt)", timeFrom, timeTo).
Count() Count()
@@ -528,6 +547,7 @@ func (this *ServerBandwidthStatDAO) FindPercentileBetweenTimes(tx *dbs.Tx, serve
// 查询 nth 位置 // 查询 nth 位置
one, err := this.Query(tx). one, err := this.Query(tx).
Table(this.partialTable(serverId)). Table(this.partialTable(serverId)).
Between("day", timeFrom[:8], timeTo[:8]).
Attr("serverId", serverId). Attr("serverId", serverId).
Between("CONCAT(day, timeAt)", timeFrom, timeTo). Between("CONCAT(day, timeAt)", timeFrom, timeTo).
Desc(this.bytesOrderField(useAvg)). Desc(this.bytesOrderField(useAvg)).
@@ -540,6 +560,191 @@ func (this *ServerBandwidthStatDAO) FindPercentileBetweenTimes(tx *dbs.Tx, serve
return this.fixServerStat(one.(*ServerBandwidthStat), useAvg), nil return this.fixServerStat(one.(*ServerBandwidthStat), useAvg), nil
} }
// FindDailyStats 按天统计
func (this *ServerBandwidthStatDAO) FindDailyStats(tx *dbs.Tx, serverId int64, dayFrom string, dayTo string) (result []*ServerBandwidthStat, err error) {
// 兼容以往版本
if !regexputils.YYYYMMDD.MatchString(dayFrom) || !regexputils.YYYYMMDD.MatchString(dayTo) {
return nil, nil
}
hasFullData, err := this.HasFullData(tx, serverId, dayFrom[:6])
if err != nil {
return nil, err
}
if !hasFullData {
ones, err := SharedServerDailyStatDAO.compatFindDailyStats(tx, serverId, dayFrom, dayTo)
if err != nil {
return nil, err
}
for _, one := range ones {
result = append(result, one.AsServerBandwidthStat())
}
return result, nil
}
ones, err := this.Query(tx).
Table(this.partialTable(serverId)).
Result("SUM(totalBytes) AS totalBytes", "SUM(cachedBytes) AS cachedBytes", "SUM(countRequests) AS countRequests", "SUM(countCachedRequests) AS countCachedRequests", "SUM(countAttackRequests) AS countAttackRequests", "SUM(attackBytes) AS attackBytes", "day").
Attr("serverId", serverId).
Between("day", dayFrom, dayTo).
Group("day").
FindAll()
if err != nil {
return nil, err
}
var dayMap = map[string]*ServerBandwidthStat{} // day => Stat
for _, one := range ones {
var stat = one.(*ServerBandwidthStat)
dayMap[stat.Day] = stat
}
days, err := utils.RangeDays(dayFrom, dayTo)
if err != nil {
return nil, err
}
for _, day := range days {
stat, ok := dayMap[day]
if ok {
result = append(result, stat)
} else {
result = append(result, &ServerBandwidthStat{Day: day})
}
}
return
}
// FindHourlyStats 按小时统计
func (this *ServerBandwidthStatDAO) FindHourlyStats(tx *dbs.Tx, serverId int64, hourFrom string, hourTo string) (result []*ServerBandwidthStat, err error) {
// 兼容以往版本
if !regexputils.YYYYMMDDHH.MatchString(hourFrom) || !regexputils.YYYYMMDDHH.MatchString(hourTo) {
return nil, nil
}
hasFullData, err := this.HasFullData(tx, serverId, hourFrom[:6])
if err != nil {
return nil, err
}
if !hasFullData {
ones, err := SharedServerDailyStatDAO.compatFindHourlyStats(tx, serverId, hourFrom, hourTo)
if err != nil {
return nil, err
}
for _, one := range ones {
result = append(result, one.AsServerBandwidthStat())
}
return result, nil
}
var query = this.Query(tx).
Table(this.partialTable(serverId)).
Between("day", hourFrom[:8], hourTo[:8]).
Result("MIN(day) AS day", "MIN(timeAt) AS timeAt", "SUM(totalBytes) AS totalBytes", "SUM(cachedBytes) AS cachedBytes", "SUM(countRequests) AS countRequests", "SUM(countCachedRequests) AS countCachedRequests", "SUM(countAttackRequests) AS countAttackRequests", "SUM(attackBytes) AS attackBytes", "CONCAT(day, SUBSTR(timeAt, 1, 2)) AS hour").
Attr("serverId", serverId)
if hourFrom[:8] == hourTo[:8] { // 同一天
query.Attr("day", hourFrom[:8])
query.Between("timeAt", hourFrom[8:]+"00", hourTo[8:]+"59")
} else {
query.Between("CONCAT(day, SUBSTR(timeAt, 1, 2))", hourFrom, hourTo)
}
ones, err := query.
Group("hour").
FindAll()
if err != nil {
return nil, err
}
var hourMap = map[string]*ServerBandwidthStat{} // hour => Stat
for _, one := range ones {
var stat = one.(*ServerBandwidthStat)
var hour = stat.Day + stat.TimeAt[:2]
hourMap[hour] = stat
}
hours, err := utils.RangeHours(hourFrom, hourTo)
if err != nil {
return nil, err
}
for _, hour := range hours {
stat, ok := hourMap[hour]
if ok {
result = append(result, stat)
} else {
result = append(result, &ServerBandwidthStat{
Day: hour[:8],
TimeAt: hour[8:] + "00",
})
}
}
return
}
// SumDailyStat 获取某天内的流量
// dayFrom 格式为YYYYMMDD
// dayTo 格式为YYYYMMDD
func (this *ServerBandwidthStatDAO) SumDailyStat(tx *dbs.Tx, serverId int64, regionId int64, dayFrom string, dayTo string) (stat *pb.ServerDailyStat, err error) {
if !regexputils.YYYYMMDD.MatchString(dayFrom) {
return nil, errors.New("invalid dayFrom '" + dayFrom + "'")
}
if !regexputils.YYYYMMDD.MatchString(dayTo) {
return nil, errors.New("invalid dayTo '" + dayTo + "'")
}
// 兼容以往版本
hasFullData, err := this.HasFullData(tx, serverId, dayFrom[:6])
if err != nil {
return nil, err
}
if !hasFullData {
return SharedServerDailyStatDAO.compatSumDailyStat(tx, 0, serverId, regionId, dayFrom, dayTo)
}
stat = &pb.ServerDailyStat{}
if serverId <= 0 {
return
}
if dayFrom > dayTo {
dayFrom, dayTo = dayTo, dayFrom
}
var query = this.Query(tx).
Table(this.partialTable(serverId)).
Result("SUM(totalBytes) AS totalBytes, SUM(cachedBytes) AS cachedBytes, SUM(countRequests) AS countRequests, SUM(countCachedRequests) AS countCachedRequests, SUM(countAttackRequests) AS countAttackRequests, SUM(attackBytes) AS attackBytes")
query.Attr("serverId", serverId)
if regionId > 0 {
query.Attr("regionId", regionId)
}
if dayFrom == dayTo {
query.Attr("day", dayFrom)
} else {
query.Between("day", dayFrom, dayTo)
}
one, _, err := query.FindOne()
if err != nil {
return nil, err
}
if one == nil {
return
}
stat.Bytes = one.GetInt64("totalBytes")
stat.CachedBytes = one.GetInt64("cachedBytes")
stat.CountRequests = one.GetInt64("countRequests")
stat.CountCachedRequests = one.GetInt64("countCachedRequests")
stat.CountAttackRequests = one.GetInt64("countAttackRequests")
stat.AttackBytes = one.GetInt64("attackBytes")
return
}
// Clean 清理过期数据 // Clean 清理过期数据
func (this *ServerBandwidthStatDAO) Clean(tx *dbs.Tx) error { func (this *ServerBandwidthStatDAO) Clean(tx *dbs.Tx) error {
var day = timeutil.Format("Ymd", time.Now().AddDate(0, 0, -100)) // 保留大约3个月的数据 var day = timeutil.Format("Ymd", time.Now().AddDate(0, 0, -100)) // 保留大约3个月的数据
@@ -619,3 +824,50 @@ func (this *ServerBandwidthStatDAO) fixServerStats(stats []*ServerBandwidthStat,
} }
} }
} }
// HasFullData 检查一个月是否完整数据
// 是为了兼容以前数据,以前的表中没有缓存流量、请求数等字段
func (this *ServerBandwidthStatDAO) HasFullData(tx *dbs.Tx, serverId int64, month string) (bool, error) {
var monthKey = month + "@" + types.String(serverId)
if !regexputils.YYYYMM.MatchString(month) {
return false, errors.New("invalid month '" + month + "'")
}
fullDataLocker.Lock()
hasData, ok := fullDataMap[monthKey]
fullDataLocker.Unlock()
if ok {
return hasData, nil
}
var year = types.Int(month[:4])
var monthInt = types.Int(month[4:])
if year < 2000 || monthInt > 12 || monthInt < 1 {
return false, nil
}
var lastMonth = monthInt - 1
if lastMonth == 0 {
lastMonth = 12
year--
}
var lastMonthString = fmt.Sprintf("%d%02d", year, lastMonth)
one, err := this.Query(tx).
Table(this.partialTable(serverId)).
Between("day", lastMonthString+"01", lastMonthString+"31").
DescPk().
Find()
if err != nil {
return false, err
}
var b = one != nil && one.(*ServerBandwidthStat).CountRequests > 0
fullDataLocker.Lock()
fullDataMap[monthKey] = b
fullDataLocker.Unlock()
return b, nil
}

View File

@@ -16,7 +16,7 @@ import (
func TestServerBandwidthStatDAO_UpdateServerBandwidth(t *testing.T) { func TestServerBandwidthStatDAO_UpdateServerBandwidth(t *testing.T) {
var dao = models.NewServerBandwidthStatDAO() var dao = models.NewServerBandwidthStatDAO()
var tx *dbs.Tx var tx *dbs.Tx
err := dao.UpdateServerBandwidth(tx, 1, 1, timeutil.Format("Ymd"), timeutil.FormatTime("Hi", time.Now().Unix()/300*300), 1024, 300) err := dao.UpdateServerBandwidth(tx, 1, 1, 0, timeutil.Format("Ymd"), timeutil.FormatTime("Hi", time.Now().Unix()/300*300), 1024, 300, 0, 0, 0, 0, 0)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@@ -28,9 +28,12 @@ func TestSeverBandwidthStatDAO_InsertManyStats(t *testing.T) {
var tx *dbs.Tx var tx *dbs.Tx
var count = 1 // 测试时将此值设为一个比较大的数字 var count = 1 // 测试时将此值设为一个比较大的数字
for i := 0; i < count; i++ { for i := 0; i < count; i++ {
if i%10000 == 0 {
t.Log(i)
}
var day = timeutil.Format("Ymd", time.Now().AddDate(0, 0, -rands.Int(0, 200))) 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)) var minute = fmt.Sprintf("%02d%02d", rands.Int(0, 23), rands.Int(0, 59))
err := dao.UpdateServerBandwidth(tx, 1, 1, day, minute, 1024, 300) err := dao.UpdateServerBandwidth(tx, 1, int64(rands.Int(1, 10000)), 0, day, minute, 1024, 300, 0, 0, 0, 0, 0)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }

View File

@@ -2,27 +2,37 @@ package models
// ServerBandwidthStat 服务峰值带宽统计 // ServerBandwidthStat 服务峰值带宽统计
type ServerBandwidthStat struct { type ServerBandwidthStat struct {
Id uint64 `field:"id"` // ID Id uint64 `field:"id"` // ID
UserId uint64 `field:"userId"` // 用户ID UserId uint64 `field:"userId"` // 用户ID
ServerId uint64 `field:"serverId"` // 服务ID ServerId uint64 `field:"serverId"` // 服务ID
RegionId uint32 `field:"regionId"` // 区域ID RegionId uint32 `field:"regionId"` // 区域ID
Day string `field:"day"` // 日期YYYYMMDD Day string `field:"day"` // 日期YYYYMMDD
TimeAt string `field:"timeAt"` // 时间点HHMM TimeAt string `field:"timeAt"` // 时间点HHMM
Bytes uint64 `field:"bytes"` // 带宽字节 Bytes uint64 `field:"bytes"` // 带宽字节
AvgBytes uint64 `field:"avgBytes"` // 平均流量 AvgBytes uint64 `field:"avgBytes"` // 平均流量
TotalBytes uint64 `field:"totalBytes"` // 流量 CachedBytes uint64 `field:"cachedBytes"` // 缓存的流量
AttackBytes uint64 `field:"attackBytes"` // 攻击流量
CountRequests uint64 `field:"countRequests"` // 请求数
CountCachedRequests uint64 `field:"countCachedRequests"` // 缓存的请求数
CountAttackRequests uint64 `field:"countAttackRequests"` // 攻击请求数
TotalBytes uint64 `field:"totalBytes"` // 总流量
} }
type ServerBandwidthStatOperator struct { type ServerBandwidthStatOperator struct {
Id any // ID Id any // ID
UserId any // 用户ID UserId any // 用户ID
ServerId any // 服务ID ServerId any // 服务ID
RegionId any // 区域ID RegionId any // 区域ID
Day any // 日期YYYYMMDD Day any // 日期YYYYMMDD
TimeAt any // 时间点HHMM TimeAt any // 时间点HHMM
Bytes any // 带宽字节 Bytes any // 带宽字节
AvgBytes any // 平均流量 AvgBytes any // 平均流量
TotalBytes any // 流量 CachedBytes any // 缓存的流量
AttackBytes any // 攻击流量
CountRequests any // 请求数
CountCachedRequests any // 缓存的请求数
CountAttackRequests any // 攻击请求数
TotalBytes any // 总流量
} }
func NewServerBandwidthStatOperator() *ServerBandwidthStatOperator { func NewServerBandwidthStatOperator() *ServerBandwidthStatOperator {

View File

@@ -61,19 +61,24 @@ func (this *ServerDailyStatDAO) SaveStats(tx *dbs.Tx, stats []*pb.ServerDailySta
var serverUserMap = map[int64]int64{} // serverId => userId var serverUserMap = map[int64]int64{} // serverId => userId
var cacheMap = utils.NewCacheMap() var cacheMap = utils.NewCacheMap()
for _, stat := range stats { for _, stat := range stats {
day := timeutil.FormatTime("Ymd", stat.CreatedAt) var day = timeutil.FormatTime("Ymd", stat.CreatedAt)
hour := timeutil.FormatTime("YmdH", stat.CreatedAt) var hour = timeutil.FormatTime("YmdH", stat.CreatedAt)
timeFrom := timeutil.FormatTime("His", stat.CreatedAt) var timeFrom = timeutil.FormatTime("His", stat.CreatedAt)
timeTo := timeutil.FormatTime("His", stat.CreatedAt+5*60-1) // 5分钟 var timeTo = timeutil.FormatTime("His", stat.CreatedAt+5*60-1) // 5分钟
// 所属用户 // 用户ID
serverUserId, ok := serverUserMap[stat.ServerId] var serverUserId = stat.UserId
if !ok { if serverUserId == 0 {
userId, err := SharedServerDAO.FindServerUserId(tx, stat.ServerId) var ok bool
if err != nil { serverUserId, ok = serverUserMap[stat.ServerId]
return err if !ok {
userId, err := SharedServerDAO.FindServerUserId(tx, stat.ServerId)
if err != nil {
return err
}
serverUserMap[stat.ServerId] = userId
serverUserId = userId
} }
serverUserId = userId
} }
_, _, err := this.Query(tx). _, _, err := this.Query(tx).
@@ -195,7 +200,7 @@ func (this *ServerDailyStatDAO) SumUserMonthlyPeek(tx *dbs.Tx, userId int64, reg
// SumUserDaily 获取某天流量总和 // SumUserDaily 获取某天流量总和
// day 格式为YYYYMMDD // day 格式为YYYYMMDD
func (this *ServerDailyStatDAO) SumUserDaily(tx *dbs.Tx, userId int64, regionId int64, day string) (stat *ServerDailyStat, err error) { func (this *ServerDailyStatDAO) compatSumUserDaily(tx *dbs.Tx, userId int64, regionId int64, day string) (stat *ServerDailyStat, err error) {
var query = this.Query(tx) var query = this.Query(tx)
if regionId > 0 { if regionId > 0 {
query.Attr("regionId", regionId) query.Attr("regionId", regionId)
@@ -234,7 +239,7 @@ func (this *ServerDailyStatDAO) SumUserTrafficBytesBetweenDays(tx *dbs.Tx, userI
// SumUserMonthly 获取某月流量总和 // SumUserMonthly 获取某月流量总和
// month 格式为YYYYMM // month 格式为YYYYMM
func (this *ServerDailyStatDAO) SumUserMonthly(tx *dbs.Tx, userId int64, month string) (int64, error) { func (this *ServerDailyStatDAO) compatSumUserMonthly(tx *dbs.Tx, userId int64, month string) (int64, error) {
return this.Query(tx). return this.Query(tx).
Between("day", month+"01", month+"31"). Between("day", month+"01", month+"31").
Attr("userId", userId). Attr("userId", userId).
@@ -323,10 +328,10 @@ func (this *ServerDailyStatDAO) SumHourlyStat(tx *dbs.Tx, serverId int64, hour s
return return
} }
// SumDailyStat 获取某天内的流量 // compatSumDailyStat 获取某天内的流量
// dayFrom 格式为YYYYMMDD // dayFrom 格式为YYYYMMDD
// dayTo 格式为YYYYMMDD // dayTo 格式为YYYYMMDD
func (this *ServerDailyStatDAO) SumDailyStat(tx *dbs.Tx, userId int64, serverId int64, regionId int64, dayFrom string, dayTo string) (stat *pb.ServerDailyStat, err error) { func (this *ServerDailyStatDAO) compatSumDailyStat(tx *dbs.Tx, userId int64, serverId int64, regionId int64, dayFrom string, dayTo string) (stat *pb.ServerDailyStat, err error) {
stat = &pb.ServerDailyStat{} stat = &pb.ServerDailyStat{}
if userId <= 0 && serverId <= 0 { if userId <= 0 && serverId <= 0 {
@@ -463,7 +468,7 @@ func (this *ServerDailyStatDAO) SumMonthlyBytes(tx *dbs.Tx, serverId int64, mont
} }
// FindDailyStats 按天统计 // FindDailyStats 按天统计
func (this *ServerDailyStatDAO) FindDailyStats(tx *dbs.Tx, serverId int64, dayFrom string, dayTo string) (result []*ServerDailyStat, err error) { func (this *ServerDailyStatDAO) compatFindDailyStats(tx *dbs.Tx, serverId int64, dayFrom string, dayTo string) (result []*ServerDailyStat, err error) {
ones, err := this.Query(tx). ones, err := this.Query(tx).
Result("SUM(bytes) AS bytes", "SUM(cachedBytes) AS cachedBytes", "SUM(countRequests) AS countRequests", "SUM(countCachedRequests) AS countCachedRequests", "SUM(countAttackRequests) AS countAttackRequests", "SUM(attackBytes) AS attackBytes", "day"). Result("SUM(bytes) AS bytes", "SUM(cachedBytes) AS cachedBytes", "SUM(countRequests) AS countRequests", "SUM(countCachedRequests) AS countCachedRequests", "SUM(countAttackRequests) AS countAttackRequests", "SUM(attackBytes) AS attackBytes", "day").
Attr("serverId", serverId). Attr("serverId", serverId).
@@ -476,7 +481,7 @@ func (this *ServerDailyStatDAO) FindDailyStats(tx *dbs.Tx, serverId int64, dayFr
dayMap := map[string]*ServerDailyStat{} // day => Stat dayMap := map[string]*ServerDailyStat{} // day => Stat
for _, one := range ones { for _, one := range ones {
stat := one.(*ServerDailyStat) var stat = one.(*ServerDailyStat)
dayMap[stat.Day] = stat dayMap[stat.Day] = stat
} }
days, err := utils.RangeDays(dayFrom, dayTo) days, err := utils.RangeDays(dayFrom, dayTo)
@@ -640,7 +645,7 @@ func (this *ServerDailyStatDAO) FindMonthlyStatsWithPlan(tx *dbs.Tx, month strin
} }
// FindHourlyStats 按小时统计 // FindHourlyStats 按小时统计
func (this *ServerDailyStatDAO) FindHourlyStats(tx *dbs.Tx, serverId int64, hourFrom string, hourTo string) (result []*ServerDailyStat, err error) { func (this *ServerDailyStatDAO) compatFindHourlyStats(tx *dbs.Tx, serverId int64, hourFrom string, hourTo string) (result []*ServerDailyStat, err error) {
ones, err := this.Query(tx). ones, err := this.Query(tx).
Result("SUM(bytes) AS bytes", "SUM(cachedBytes) AS cachedBytes", "SUM(countRequests) AS countRequests", "SUM(countCachedRequests) AS countCachedRequests", "SUM(countAttackRequests) AS countAttackRequests", "SUM(attackBytes) AS attackBytes", "hour"). Result("SUM(bytes) AS bytes", "SUM(cachedBytes) AS cachedBytes", "SUM(countRequests) AS countRequests", "SUM(countCachedRequests) AS countCachedRequests", "SUM(countAttackRequests) AS countAttackRequests", "SUM(attackBytes) AS attackBytes", "hour").
Attr("serverId", serverId). Attr("serverId", serverId).
@@ -651,9 +656,11 @@ func (this *ServerDailyStatDAO) FindHourlyStats(tx *dbs.Tx, serverId int64, hour
return nil, err return nil, err
} }
hourMap := map[string]*ServerDailyStat{} // hour => Stat var hourMap = map[string]*ServerDailyStat{} // hour => Stat
for _, one := range ones { for _, one := range ones {
stat := one.(*ServerDailyStat) var stat = one.(*ServerDailyStat)
stat.Day = stat.Hour[:8]
stat.TimeFrom = stat.Hour[8:] + "00"
hourMap[stat.Hour] = stat hourMap[stat.Hour] = stat
} }
hours, err := utils.RangeHours(hourFrom, hourTo) hours, err := utils.RangeHours(hourFrom, hourTo)
@@ -665,7 +672,11 @@ func (this *ServerDailyStatDAO) FindHourlyStats(tx *dbs.Tx, serverId int64, hour
if ok { if ok {
result = append(result, stat) result = append(result, stat)
} else { } else {
result = append(result, &ServerDailyStat{Hour: hour}) result = append(result, &ServerDailyStat{
Hour: hour,
Day: hour[:8],
TimeFrom: hour[8:] + "00",
})
} }
} }

View File

@@ -1,10 +1,13 @@
package models package models_test
import ( import (
"fmt"
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
_ "github.com/go-sql-driver/mysql" _ "github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/dbs" "github.com/iwind/TeaGo/dbs"
"github.com/iwind/TeaGo/logs" "github.com/iwind/TeaGo/logs"
"github.com/iwind/TeaGo/rands"
timeutil "github.com/iwind/TeaGo/utils/time" timeutil "github.com/iwind/TeaGo/utils/time"
"testing" "testing"
"time" "time"
@@ -12,7 +15,7 @@ import (
func TestServerDailyStatDAO_SaveStats(t *testing.T) { func TestServerDailyStatDAO_SaveStats(t *testing.T) {
var tx *dbs.Tx var tx *dbs.Tx
stats := []*pb.ServerDailyStat{ var stats = []*pb.ServerDailyStat{
{ {
ServerId: 1, ServerId: 1,
NodeRegionId: 2, NodeRegionId: 2,
@@ -20,7 +23,7 @@ func TestServerDailyStatDAO_SaveStats(t *testing.T) {
CreatedAt: 1607671488, CreatedAt: 1607671488,
}, },
} }
err := NewServerDailyStatDAO().SaveStats(tx, stats) err := models.NewServerDailyStatDAO().SaveStats(tx, stats)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@@ -29,7 +32,7 @@ func TestServerDailyStatDAO_SaveStats(t *testing.T) {
func TestServerDailyStatDAO_SaveStats2(t *testing.T) { func TestServerDailyStatDAO_SaveStats2(t *testing.T) {
var tx *dbs.Tx var tx *dbs.Tx
stats := []*pb.ServerDailyStat{ var stats = []*pb.ServerDailyStat{
{ {
ServerId: 1, ServerId: 1,
NodeRegionId: 3, NodeRegionId: 3,
@@ -37,7 +40,7 @@ func TestServerDailyStatDAO_SaveStats2(t *testing.T) {
CreatedAt: 1607671488, CreatedAt: 1607671488,
}, },
} }
err := NewServerDailyStatDAO().SaveStats(tx, stats) err := models.NewServerDailyStatDAO().SaveStats(tx, stats)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@@ -47,7 +50,7 @@ func TestServerDailyStatDAO_SaveStats2(t *testing.T) {
func TestServerDailyStatDAO_SumUserMonthly(t *testing.T) { func TestServerDailyStatDAO_SumUserMonthly(t *testing.T) {
dbs.NotifyReady() dbs.NotifyReady()
var tx *dbs.Tx var tx *dbs.Tx
bytes, err := NewServerDailyStatDAO().SumUserMonthly(tx, 1, timeutil.Format("Ym")) bytes, err := models.NewUserBandwidthStatDAO().SumUserMonthly(tx, 1, timeutil.Format("Ym"))
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@@ -58,7 +61,7 @@ func TestServerDailyStatDAO_SumHourlyRequests(t *testing.T) {
dbs.NotifyReady() dbs.NotifyReady()
var tx *dbs.Tx var tx *dbs.Tx
stat, err := NewServerDailyStatDAO().SumHourlyStat(tx, 23, timeutil.Format("YmdH")) stat, err := models.NewServerDailyStatDAO().SumHourlyStat(tx, 23, timeutil.Format("YmdH"))
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@@ -69,7 +72,7 @@ func TestServerDailyStatDAO_SumMinutelyRequests(t *testing.T) {
dbs.NotifyReady() dbs.NotifyReady()
var tx *dbs.Tx var tx *dbs.Tx
stat, err := NewServerDailyStatDAO().SumMinutelyStat(tx, 23, timeutil.Format("Ymd")+"1435") stat, err := models.NewServerDailyStatDAO().SumMinutelyStat(tx, 23, timeutil.Format("Ymd")+"1435")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@@ -78,7 +81,7 @@ func TestServerDailyStatDAO_SumMinutelyRequests(t *testing.T) {
func TestServerDailyStatDAO_FindDistinctPlanServerIdsBetweenDay(t *testing.T) { func TestServerDailyStatDAO_FindDistinctPlanServerIdsBetweenDay(t *testing.T) {
var tx *dbs.Tx var tx *dbs.Tx
serverIds, err := NewServerDailyStatDAO().FindDistinctServerIds(tx, timeutil.Format("Ym01"), timeutil.Format("Ymd")) serverIds, err := models.NewServerDailyStatDAO().FindDistinctServerIds(tx, timeutil.Format("Ym01"), timeutil.Format("Ymd"))
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@@ -87,7 +90,7 @@ func TestServerDailyStatDAO_FindDistinctPlanServerIdsBetweenDay(t *testing.T) {
func TestServerDailyStatDAO_FindStatsBetweenDays(t *testing.T) { func TestServerDailyStatDAO_FindStatsBetweenDays(t *testing.T) {
var tx *dbs.Tx var tx *dbs.Tx
stats, err := NewServerDailyStatDAO().FindStatsBetweenDays(tx, 1, 0, 0, timeutil.Format("Ymd", time.Now().AddDate(0, 0, -1)), timeutil.Format("Ymd")) stats, err := models.NewServerDailyStatDAO().FindStatsBetweenDays(tx, 1, 0, 0, timeutil.Format("Ymd", time.Now().AddDate(0, 0, -1)), timeutil.Format("Ymd"))
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@@ -96,8 +99,41 @@ func TestServerDailyStatDAO_FindStatsBetweenDays(t *testing.T) {
} }
} }
func TestSeverDailyStatDAO_InsertMany(t *testing.T) {
dbs.NotifyReady()
var tx *dbs.Tx
var dao = models.NewServerDailyStatDAO()
var count = 1 // 实际测试时可以将此值调的很大
for i := 0; i < count; i++ {
if i%10000 == 0 {
t.Log(i)
}
err := dao.SaveStats(tx, []*pb.ServerDailyStat{{
ServerId: 23,
NodeRegionId: int64(rands.Int(0, 999999)),
Bytes: 1024,
CachedBytes: 1024,
CountRequests: 1024,
CountCachedRequests: 1024,
CreatedAt: time.Now().Unix(),
CountAttackRequests: 1024,
AttackBytes: 1024,
CheckTrafficLimiting: false,
PlanId: 0,
Day: "202303" + fmt.Sprintf("%02d", rands.Int(1, 31)),
Hour: "2023032101",
TimeFrom: fmt.Sprintf("%06d", rands.Int(0, 999999)),
TimeTo: "211459",
}})
if err != nil {
t.Fatal(err)
}
}
}
func TestServerDailyStatDAO_FindStatsWithDay(t *testing.T) { func TestServerDailyStatDAO_FindStatsWithDay(t *testing.T) {
var dao = NewServerDailyStatDAO() var dao = models.NewServerDailyStatDAO()
var tx *dbs.Tx var tx *dbs.Tx
stats, err := dao.FindStatsWithDay(tx, 23, timeutil.Format("Ymd"), "000000", "235900") stats, err := dao.FindStatsWithDay(tx, 23, timeutil.Format("Ymd"), "000000", "235900")
if err != nil { if err != nil {

View File

@@ -1 +1,50 @@
package models package models
func (this *ServerDailyStat) AsUserBandwidthStat() *UserBandwidthStat {
var timeAt = "0000"
if len(this.TimeFrom) >= 4 {
timeAt = this.TimeFrom[:4]
} else if len(this.Hour) > 8 {
timeAt = this.Hour[8:] + "00"
}
return &UserBandwidthStat{
Id: 0,
UserId: uint64(this.UserId),
RegionId: this.RegionId,
Day: this.Day,
TimeAt: timeAt,
Bytes: this.Bytes / 300,
TotalBytes: this.Bytes,
AvgBytes: this.Bytes / 300,
CachedBytes: this.CachedBytes,
AttackBytes: this.AttackBytes,
CountRequests: this.CountRequests,
CountCachedRequests: this.CountCachedRequests,
CountAttackRequests: this.CountAttackRequests,
}
}
func (this *ServerDailyStat) AsServerBandwidthStat() *ServerBandwidthStat {
var timeAt = "0000"
if len(this.TimeFrom) >= 4 {
timeAt = this.TimeFrom[:4]
} else if len(this.Hour) > 8 {
timeAt = this.Hour[8:] + "00"
}
return &ServerBandwidthStat{
Id: 0,
UserId: uint64(this.UserId),
ServerId: uint64(this.ServerId),
RegionId: this.RegionId,
Day: this.Day,
TimeAt: timeAt,
Bytes: this.Bytes / 300,
TotalBytes: this.Bytes,
AvgBytes: this.Bytes / 300,
CachedBytes: this.CachedBytes,
AttackBytes: this.AttackBytes,
CountRequests: this.CountRequests,
CountCachedRequests: this.CountCachedRequests,
CountAttackRequests: this.CountAttackRequests,
}
}

View File

@@ -12,6 +12,7 @@ import (
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs" "github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs" "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
_ "github.com/go-sql-driver/mysql" _ "github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/Tea" "github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/dbs" "github.com/iwind/TeaGo/dbs"
@@ -31,6 +32,10 @@ const (
ServerStateDisabled = 0 // 已禁用 ServerStateDisabled = 0 // 已禁用
) )
const (
ModelServerNameMaxLength = 60
)
type ServerDAO dbs.DAO type ServerDAO dbs.DAO
func NewServerDAO() *ServerDAO { func NewServerDAO() *ServerDAO {
@@ -121,7 +126,7 @@ func (this *ServerDAO) FindEnabledServerBasic(tx *dbs.Tx, serverId int64) (*Serv
result, err := this.Query(tx). result, err := this.Query(tx).
Pk(serverId). Pk(serverId).
State(ServerStateEnabled). State(ServerStateEnabled).
Result("id", "name", "description", "isOn", "type", "clusterId", "userId"). Result("id", "name", "description", "isOn", "type", "clusterId", "userId", "groupIds").
Find() Find()
if result == nil { if result == nil {
return nil, err return nil, err
@@ -205,6 +210,15 @@ func (this *ServerDAO) CreateServer(tx *dbs.Tx,
if IsNotNull(udpJSON) { if IsNotNull(udpJSON) {
op.Udp = udpJSON op.Udp = udpJSON
} }
// 如果没有Web配置则创建之
if webId <= 0 {
webId, err = SharedHTTPWebDAO.CreateWeb(tx, 0, userId, nil)
if err != nil {
return 0, err
}
}
op.WebId = webId op.WebId = webId
if IsNotNull(reverseProxyJSON) { if IsNotNull(reverseProxyJSON) {
op.ReverseProxy = reverseProxyJSON op.ReverseProxy = reverseProxyJSON
@@ -783,9 +797,11 @@ func (this *ServerDAO) CountAllEnabledServersMatch(tx *dbs.Tx, groupId int64, ke
} }
if userId > 0 { if userId > 0 {
query.Attr("userId", userId) query.Attr("userId", userId)
query.UseIndex("userId")
} }
if clusterId > 0 { if clusterId > 0 {
query.Attr("clusterId", clusterId) query.Attr("clusterId", clusterId)
query.UseIndex("clusterId")
} }
if auditingFlag == configutils.BoolStateYes { if auditingFlag == configutils.BoolStateYes {
query.Attr("isAuditing", true) query.Attr("isAuditing", true)
@@ -839,9 +855,11 @@ func (this *ServerDAO) ListEnabledServersMatch(tx *dbs.Tx, offset int64, size in
} }
if userId > 0 { if userId > 0 {
query.Attr("userId", userId) query.Attr("userId", userId)
query.UseIndex("userId")
} }
if clusterId > 0 { if clusterId > 0 {
query.Attr("clusterId", clusterId) query.Attr("clusterId", clusterId)
query.UseIndex("clusterId")
} }
if auditingFlag == 1 { if auditingFlag == 1 {
query.Attr("isAuditing", true) query.Attr("isAuditing", true)
@@ -1009,12 +1027,12 @@ func (this *ServerDAO) ComposeServerConfigWithServerId(tx *dbs.Tx, serverId int6
if server == nil { if server == nil {
return nil, ErrNotFound return nil, ErrNotFound
} }
return this.ComposeServerConfig(tx, server, ignoreCertData, nil, forNode, false) return this.ComposeServerConfig(tx, server, ignoreCertData, nil, nil, forNode, false)
} }
// ComposeServerConfig 构造服务的Config // ComposeServerConfig 构造服务的Config
// forNode 是否是节点请求 // forNode 是否是节点请求
func (this *ServerDAO) ComposeServerConfig(tx *dbs.Tx, server *Server, ignoreCerts bool, cacheMap *utils.CacheMap, forNode bool, forList bool) (*serverconfigs.ServerConfig, error) { func (this *ServerDAO) ComposeServerConfig(tx *dbs.Tx, server *Server, ignoreCerts bool, dataMap *shared.DataMap, cacheMap *utils.CacheMap, forNode bool, forList bool) (*serverconfigs.ServerConfig, error) {
if server == nil { if server == nil {
return nil, ErrNotFound return nil, ErrNotFound
} }
@@ -1034,12 +1052,14 @@ func (this *ServerDAO) ComposeServerConfig(tx *dbs.Tx, server *Server, ignoreCer
config.UserId = int64(server.UserId) config.UserId = int64(server.UserId)
config.Type = server.Type config.Type = server.Type
config.IsOn = server.IsOn config.IsOn = server.IsOn
config.Name = server.Name if !forNode {
config.Description = server.Description config.Name = server.Name
config.Description = server.Description
}
var groupConfig *serverconfigs.ServerGroupConfig var groupConfig *serverconfigs.ServerGroupConfig
for _, groupId := range server.DecodeGroupIds() { for _, groupId := range server.DecodeGroupIds() {
groupConfig1, err := SharedServerGroupDAO.ComposeGroupConfig(tx, groupId, forList, cacheMap) groupConfig1, err := SharedServerGroupDAO.ComposeGroupConfig(tx, groupId, forNode, forList, dataMap, cacheMap)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -1098,7 +1118,9 @@ func (this *ServerDAO) ComposeServerConfig(tx *dbs.Tx, server *Server, ignoreCer
if err != nil { if err != nil {
return nil, err return nil, err
} }
config.HTTP = httpConfig if !forNode || httpConfig.IsOn {
config.HTTP = httpConfig
}
} }
// HTTPS // HTTPS
@@ -1109,18 +1131,20 @@ func (this *ServerDAO) ComposeServerConfig(tx *dbs.Tx, server *Server, ignoreCer
return nil, err return nil, err
} }
// SSL if !forNode || httpsConfig.IsOn {
if httpsConfig.SSLPolicyRef != nil && httpsConfig.SSLPolicyRef.SSLPolicyId > 0 && !ignoreCerts { // SSL
sslPolicyConfig, err := SharedSSLPolicyDAO.ComposePolicyConfig(tx, httpsConfig.SSLPolicyRef.SSLPolicyId, false, cacheMap) if httpsConfig.SSLPolicyRef != nil && httpsConfig.SSLPolicyRef.SSLPolicyId > 0 && !ignoreCerts {
if err != nil { sslPolicyConfig, err := SharedSSLPolicyDAO.ComposePolicyConfig(tx, httpsConfig.SSLPolicyRef.SSLPolicyId, false, dataMap, cacheMap)
return nil, err if err != nil {
return nil, err
}
if sslPolicyConfig != nil {
httpsConfig.SSLPolicy = sslPolicyConfig
}
} }
if sslPolicyConfig != nil {
httpsConfig.SSLPolicy = sslPolicyConfig
}
}
config.HTTPS = httpsConfig config.HTTPS = httpsConfig
}
} }
// TCP // TCP
@@ -1130,7 +1154,9 @@ func (this *ServerDAO) ComposeServerConfig(tx *dbs.Tx, server *Server, ignoreCer
if err != nil { if err != nil {
return nil, err return nil, err
} }
config.TCP = tcpConfig if !forNode || tcpConfig.IsOn {
config.TCP = tcpConfig
}
} }
// TLS // TLS
@@ -1141,18 +1167,20 @@ func (this *ServerDAO) ComposeServerConfig(tx *dbs.Tx, server *Server, ignoreCer
return nil, err return nil, err
} }
// SSL if !forNode || tlsConfig.IsOn {
if tlsConfig.SSLPolicyRef != nil && !ignoreCerts { // SSL
sslPolicyConfig, err := SharedSSLPolicyDAO.ComposePolicyConfig(tx, tlsConfig.SSLPolicyRef.SSLPolicyId, false, cacheMap) if tlsConfig.SSLPolicyRef != nil && !ignoreCerts {
if err != nil { sslPolicyConfig, err := SharedSSLPolicyDAO.ComposePolicyConfig(tx, tlsConfig.SSLPolicyRef.SSLPolicyId, false, dataMap, cacheMap)
return nil, err if err != nil {
return nil, err
}
if sslPolicyConfig != nil {
tlsConfig.SSLPolicy = sslPolicyConfig
}
} }
if sslPolicyConfig != nil {
tlsConfig.SSLPolicy = sslPolicyConfig
}
}
config.TLS = tlsConfig config.TLS = tlsConfig
}
} }
// Unix // Unix
@@ -1162,7 +1190,9 @@ func (this *ServerDAO) ComposeServerConfig(tx *dbs.Tx, server *Server, ignoreCer
if err != nil { if err != nil {
return nil, err return nil, err
} }
config.Unix = unixConfig if !forNode || unixConfig.IsOn {
config.Unix = unixConfig
}
} }
// UDP // UDP
@@ -1172,13 +1202,15 @@ func (this *ServerDAO) ComposeServerConfig(tx *dbs.Tx, server *Server, ignoreCer
if err != nil { if err != nil {
return nil, err return nil, err
} }
config.UDP = udpConfig if !forNode || udpConfig.IsOn {
config.UDP = udpConfig
}
} }
// Web // Web
if !forList { if !forList {
if server.WebId > 0 { if server.WebId > 0 {
webConfig, err := SharedHTTPWebDAO.ComposeWebConfig(tx, int64(server.WebId), cacheMap) webConfig, err := SharedHTTPWebDAO.ComposeWebConfig(tx, int64(server.WebId), false, forNode, dataMap, cacheMap)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -1196,14 +1228,18 @@ func (this *ServerDAO) ComposeServerConfig(tx *dbs.Tx, server *Server, ignoreCer
if err != nil { if err != nil {
return nil, err return nil, err
} }
config.ReverseProxyRef = reverseProxyRef if !forNode || reverseProxyRef.IsOn {
config.ReverseProxyRef = reverseProxyRef
reverseProxyConfig, err := SharedReverseProxyDAO.ComposeReverseProxyConfig(tx, reverseProxyRef.ReverseProxyId, cacheMap) reverseProxyConfig, err := SharedReverseProxyDAO.ComposeReverseProxyConfig(tx, reverseProxyRef.ReverseProxyId, dataMap, cacheMap)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if reverseProxyConfig != nil { if reverseProxyConfig != nil {
config.ReverseProxy = reverseProxyConfig if !forNode || reverseProxyConfig.IsOn {
config.ReverseProxy = reverseProxyConfig
}
}
} }
} }
} }
@@ -1427,7 +1463,7 @@ func (this *ServerDAO) CountEnabledServersWithWebIds(tx *dbs.Tx, webIds []int64)
Count() Count()
} }
// FindAllEnabledServersWithWebIds 查找使用某个缓存策略的所有服务 // FindAllEnabledServersWithWebIds 通过WebId查找服务
func (this *ServerDAO) FindAllEnabledServersWithWebIds(tx *dbs.Tx, webIds []int64) (result []*Server, err error) { func (this *ServerDAO) FindAllEnabledServersWithWebIds(tx *dbs.Tx, webIds []int64) (result []*Server, err error) {
if len(webIds) == 0 { if len(webIds) == 0 {
return return
@@ -1435,6 +1471,7 @@ func (this *ServerDAO) FindAllEnabledServersWithWebIds(tx *dbs.Tx, webIds []int6
_, err = this.Query(tx). _, err = this.Query(tx).
State(ServerStateEnabled). State(ServerStateEnabled).
Attr("webId", webIds). Attr("webId", webIds).
UseIndex("webId").
Reuse(false). Reuse(false).
AscPk(). AscPk().
Slice(&result). Slice(&result).
@@ -2763,6 +2800,28 @@ func (this *ServerDAO) UpdateServerUserId(tx *dbs.Tx, serverId int64, userId int
return this.NotifyUpdate(tx, serverId) return this.NotifyUpdate(tx, serverId)
} }
// UpdateServerName 修改服务名
func (this *ServerDAO) UpdateServerName(tx *dbs.Tx, serverId int64, name string) error {
return this.Query(tx).
Pk(serverId).
Set("name", name).
UpdateQuickly()
}
// FindEnabledServersWithIds 根据ID查找一组服务
func (this *ServerDAO) FindEnabledServersWithIds(tx *dbs.Tx, serverIds []int64) (result []*Server, err error) {
if len(serverIds) == 0 {
return
}
_, err = this.Query(tx).
Pk(serverIds).
Reuse(false).
State(ServerStateEnabled).
Slice(&result).
FindAll()
return
}
// NotifyUpdate 同步服务所在的集群 // NotifyUpdate 同步服务所在的集群
func (this *ServerDAO) NotifyUpdate(tx *dbs.Tx, serverId int64) error { func (this *ServerDAO) NotifyUpdate(tx *dbs.Tx, serverId int64) error {
// 创建任务 // 创建任务

View File

@@ -0,0 +1,35 @@
// Copyright 2023 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
//go:build !plus
package models
import (
"errors"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
"github.com/iwind/TeaGo/dbs"
)
// CopyServerConfigToServers 拷贝服务配置到一组服务
func (this *ServerDAO) CopyServerConfigToServers(tx *dbs.Tx, fromServerId int64, toServerIds []int64, configCode serverconfigs.ConfigCode) error {
return errors.New("not implemented")
}
// CopyServerConfigToGroups 拷贝服务配置到分组
func (this *ServerDAO) CopyServerConfigToGroups(tx *dbs.Tx, fromServerId int64, groupIds []int64, configCode string) error {
return errors.New("not implemented")
}
// CopyServerConfigToCluster 拷贝服务配置到集群
func (this *ServerDAO) CopyServerConfigToCluster(tx *dbs.Tx, fromServerId int64, clusterId int64, configCode string) error {
return errors.New("not implemented")
}
// CopyServerConfigToUser 拷贝服务配置到用户
func (this *ServerDAO) CopyServerConfigToUser(tx *dbs.Tx, fromServerId int64, userId int64, configCode string) error {
return errors.New("not implemented")
}
// CopyServerUAMConfigs 复制UAM设置
func (this *ServerDAO) CopyServerUAMConfigs(tx *dbs.Tx, fromServerId int64, toServerIds []int64) error {
return errors.New("not implemented")
}

View File

@@ -190,7 +190,7 @@ func TestServerDAO_FindAllEnabledServersWithNode_Cache(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
for _, server := range servers { for _, server := range servers {
_, _ = models.SharedServerDAO.ComposeServerConfig(nil, server, false, cacheMap, true, false) _, _ = models.SharedServerDAO.ComposeServerConfig(nil, server, false, nil, cacheMap, true, false)
} }
} }
@@ -201,7 +201,7 @@ func TestServerDAO_FindAllEnabledServersWithNode_Cache(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
for _, server := range servers { for _, server := range servers {
_, _ = models.SharedServerDAO.ComposeServerConfig(nil, server, false, cacheMap, true, false) _, _ = models.SharedServerDAO.ComposeServerConfig(nil, server, false, nil, cacheMap, true, false)
} }
} }
t.Log(time.Since(before).Seconds()*1000, "ms") t.Log(time.Since(before).Seconds()*1000, "ms")
@@ -332,6 +332,16 @@ func TestServerDAO_UpdateServerBandwidth(t *testing.T) {
} }
} }
func TestServerDAO_FindEnabledServersWithIds(t *testing.T) {
var dao = models.NewServerDAO()
var tx *dbs.Tx
servers, err := dao.FindEnabledServersWithIds(tx, []int64{23, 1071})
if err != nil {
t.Fatal(err)
}
t.Log(len(servers), "servers")
}
func BenchmarkServerDAO_CountAllEnabledServers(b *testing.B) { func BenchmarkServerDAO_CountAllEnabledServers(b *testing.B) {
models.SharedServerDAO = models.NewServerDAO() models.SharedServerDAO = models.NewServerDAO()

View File

@@ -5,6 +5,7 @@ import (
"github.com/TeaOSLab/EdgeAPI/internal/errors" "github.com/TeaOSLab/EdgeAPI/internal/errors"
"github.com/TeaOSLab/EdgeAPI/internal/utils" "github.com/TeaOSLab/EdgeAPI/internal/utils"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs" "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
_ "github.com/go-sql-driver/mysql" _ "github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/Tea" "github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/dbs" "github.com/iwind/TeaGo/dbs"
@@ -279,7 +280,7 @@ func (this *ServerGroupDAO) InitGroupWeb(tx *dbs.Tx, groupId int64) (int64, erro
} }
// ComposeGroupConfig 组合配置 // ComposeGroupConfig 组合配置
func (this *ServerGroupDAO) ComposeGroupConfig(tx *dbs.Tx, groupId int64, forList bool, cacheMap *utils.CacheMap) (*serverconfigs.ServerGroupConfig, error) { func (this *ServerGroupDAO) ComposeGroupConfig(tx *dbs.Tx, groupId int64, forNode bool, forList bool, dataMap *shared.DataMap, cacheMap *utils.CacheMap) (*serverconfigs.ServerGroupConfig, error) {
if cacheMap == nil { if cacheMap == nil {
cacheMap = utils.NewCacheMap() cacheMap = utils.NewCacheMap()
} }
@@ -324,7 +325,7 @@ func (this *ServerGroupDAO) ComposeGroupConfig(tx *dbs.Tx, groupId int64, forLis
} }
config.HTTPReverseProxyRef = reverseProxyRef config.HTTPReverseProxyRef = reverseProxyRef
reverseProxyConfig, err := SharedReverseProxyDAO.ComposeReverseProxyConfig(tx, reverseProxyRef.ReverseProxyId, cacheMap) reverseProxyConfig, err := SharedReverseProxyDAO.ComposeReverseProxyConfig(tx, reverseProxyRef.ReverseProxyId, dataMap, cacheMap)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -341,7 +342,7 @@ func (this *ServerGroupDAO) ComposeGroupConfig(tx *dbs.Tx, groupId int64, forLis
} }
config.TCPReverseProxyRef = reverseProxyRef config.TCPReverseProxyRef = reverseProxyRef
reverseProxyConfig, err := SharedReverseProxyDAO.ComposeReverseProxyConfig(tx, reverseProxyRef.ReverseProxyId, cacheMap) reverseProxyConfig, err := SharedReverseProxyDAO.ComposeReverseProxyConfig(tx, reverseProxyRef.ReverseProxyId, dataMap, cacheMap)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -358,7 +359,7 @@ func (this *ServerGroupDAO) ComposeGroupConfig(tx *dbs.Tx, groupId int64, forLis
} }
config.UDPReverseProxyRef = reverseProxyRef config.UDPReverseProxyRef = reverseProxyRef
reverseProxyConfig, err := SharedReverseProxyDAO.ComposeReverseProxyConfig(tx, reverseProxyRef.ReverseProxyId, cacheMap) reverseProxyConfig, err := SharedReverseProxyDAO.ComposeReverseProxyConfig(tx, reverseProxyRef.ReverseProxyId, dataMap, cacheMap)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -369,7 +370,7 @@ func (this *ServerGroupDAO) ComposeGroupConfig(tx *dbs.Tx, groupId int64, forLis
// web // web
if group.WebId > 0 { if group.WebId > 0 {
webConfig, err := SharedHTTPWebDAO.ComposeWebConfig(tx, int64(group.WebId), cacheMap) webConfig, err := SharedHTTPWebDAO.ComposeWebConfig(tx, int64(group.WebId), true, forNode, dataMap, cacheMap)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -423,6 +424,18 @@ func (this *ServerGroupDAO) ExistsGroup(tx *dbs.Tx, groupId int64) (bool, error)
Exist() Exist()
} }
// FindGroupUserId 读取分组所属用户
func (this *ServerGroupDAO) FindGroupUserId(tx *dbs.Tx, groupId int64) (userId int64, err error) {
if groupId <= 0 {
return
}
return this.Query(tx).
Pk(groupId).
State(ServerGroupStateEnabled).
Result("userId").
FindInt64Col(0)
}
// NotifyUpdate 通知更新 // NotifyUpdate 通知更新
func (this *ServerGroupDAO) NotifyUpdate(tx *dbs.Tx, groupId int64) error { func (this *ServerGroupDAO) NotifyUpdate(tx *dbs.Tx, groupId int64) error {
serverIds, err := SharedServerDAO.FindAllEnabledServerIdsWithGroupId(tx, groupId) serverIds, err := SharedServerDAO.FindAllEnabledServerIdsWithGroupId(tx, groupId)

View File

@@ -78,7 +78,7 @@ func (this *Server) DecodeHTTPSPorts() (ports []int) {
if err != nil { if err != nil {
return nil return nil
} }
err = config.Init() err = config.Init(nil)
if err != nil { if err != nil {
return nil return nil
} }
@@ -120,7 +120,7 @@ func (this *Server) DecodeTLSPorts() (ports []int) {
if err != nil { if err != nil {
return nil return nil
} }
err = config.Init() err = config.Init(nil)
if err != nil { if err != nil {
return nil return nil
} }

View File

@@ -6,12 +6,15 @@ import (
"errors" "errors"
dbutils "github.com/TeaOSLab/EdgeAPI/internal/db/utils" dbutils "github.com/TeaOSLab/EdgeAPI/internal/db/utils"
"github.com/TeaOSLab/EdgeAPI/internal/utils" "github.com/TeaOSLab/EdgeAPI/internal/utils"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/sslconfigs" "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/sslconfigs"
_ "github.com/go-sql-driver/mysql" _ "github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/Tea" "github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/dbs" "github.com/iwind/TeaGo/dbs"
"github.com/iwind/TeaGo/types" "github.com/iwind/TeaGo/types"
timeutil "github.com/iwind/TeaGo/utils/time" timeutil "github.com/iwind/TeaGo/utils/time"
"regexp"
"strings"
"time" "time"
) )
@@ -201,7 +204,7 @@ func (this *SSLCertDAO) UpdateCert(tx *dbs.Tx,
// ComposeCertConfig 组合配置 // ComposeCertConfig 组合配置
// ignoreData 是否忽略证书数据,避免因为数据过大影响传输 // ignoreData 是否忽略证书数据,避免因为数据过大影响传输
func (this *SSLCertDAO) ComposeCertConfig(tx *dbs.Tx, certId int64, ignoreData bool, cacheMap *utils.CacheMap) (*sslconfigs.SSLCertConfig, error) { func (this *SSLCertDAO) ComposeCertConfig(tx *dbs.Tx, certId int64, ignoreData bool, dataMap *shared.DataMap, cacheMap *utils.CacheMap) (*sslconfigs.SSLCertConfig, error) {
if cacheMap == nil { if cacheMap == nil {
cacheMap = utils.NewCacheMap() cacheMap = utils.NewCacheMap()
} }
@@ -227,8 +230,17 @@ func (this *SSLCertDAO) ComposeCertConfig(tx *dbs.Tx, certId int64, ignoreData b
config.Name = cert.Name config.Name = cert.Name
config.Description = cert.Description config.Description = cert.Description
if !ignoreData { if !ignoreData {
config.CertData = cert.CertData if dataMap != nil {
config.KeyData = cert.KeyData if len(cert.CertData) > 0 {
config.CertData = dataMap.Put(cert.CertData)
}
if len(cert.KeyData) > 0 {
config.KeyData = dataMap.Put(cert.KeyData)
}
} else {
config.CertData = cert.CertData
config.KeyData = cert.KeyData
}
} }
config.ServerName = cert.ServerName config.ServerName = cert.ServerName
config.TimeBeginAt = int64(cert.TimeBeginAt) config.TimeBeginAt = int64(cert.TimeBeginAt)
@@ -236,7 +248,13 @@ func (this *SSLCertDAO) ComposeCertConfig(tx *dbs.Tx, certId int64, ignoreData b
// OCSP // OCSP
if int64(cert.OcspExpiresAt) > time.Now().Unix() { if int64(cert.OcspExpiresAt) > time.Now().Unix() {
config.OCSP = cert.Ocsp if dataMap != nil {
if len(cert.Ocsp) > 0 {
config.OCSP = dataMap.Put(cert.Ocsp)
}
} else {
config.OCSP = cert.Ocsp
}
config.OCSPExpiresAt = int64(cert.OcspExpiresAt) config.OCSPExpiresAt = int64(cert.OcspExpiresAt)
} }
config.OCSPError = cert.OcspError config.OCSPError = cert.OcspError
@@ -267,8 +285,8 @@ func (this *SSLCertDAO) ComposeCertConfig(tx *dbs.Tx, certId int64, ignoreData b
} }
// CountCerts 计算符合条件的证书数量 // CountCerts 计算符合条件的证书数量
func (this *SSLCertDAO) CountCerts(tx *dbs.Tx, isCA bool, isAvailable bool, isExpired bool, expiringDays int64, keyword string, userId int64) (int64, error) { func (this *SSLCertDAO) CountCerts(tx *dbs.Tx, isCA bool, isAvailable bool, isExpired bool, expiringDays int64, keyword string, userId int64, domains []string) (int64, error) {
query := this.Query(tx). var query = this.Query(tx).
State(SSLCertStateEnabled) State(SSLCertStateEnabled)
if isCA { if isCA {
query.Attr("isCA", true) query.Attr("isCA", true)
@@ -293,12 +311,19 @@ func (this *SSLCertDAO) CountCerts(tx *dbs.Tx, isCA bool, isAvailable bool, isEx
// 只查询管理员上传的 // 只查询管理员上传的
query.Attr("userId", 0) query.Attr("userId", 0)
} }
// 域名
err := this.buildDomainSearchingQuery(query, domains)
if err != nil {
return 0, err
}
return query.Count() return query.Count()
} }
// ListCertIds 列出符合条件的证书 // ListCertIds 列出符合条件的证书
func (this *SSLCertDAO) ListCertIds(tx *dbs.Tx, isCA bool, isAvailable bool, isExpired bool, expiringDays int64, keyword string, userId int64, offset int64, size int64) (certIds []int64, err error) { func (this *SSLCertDAO) ListCertIds(tx *dbs.Tx, isCA bool, isAvailable bool, isExpired bool, expiringDays int64, keyword string, userId int64, domains []string, offset int64, size int64) (certIds []int64, err error) {
query := this.Query(tx). var query = this.Query(tx).
State(SSLCertStateEnabled) State(SSLCertStateEnabled)
if isCA { if isCA {
query.Attr("isCA", true) query.Attr("isCA", true)
@@ -324,6 +349,12 @@ func (this *SSLCertDAO) ListCertIds(tx *dbs.Tx, isCA bool, isAvailable bool, isE
query.Attr("userId", 0) query.Attr("userId", 0)
} }
// 域名
err = this.buildDomainSearchingQuery(query, domains)
if err != nil {
return nil, err
}
ones, err := query. ones, err := query.
ResultPk(). ResultPk().
DescPk(). DescPk().
@@ -334,7 +365,7 @@ func (this *SSLCertDAO) ListCertIds(tx *dbs.Tx, isCA bool, isAvailable bool, isE
return nil, err return nil, err
} }
result := []int64{} var result = []int64{}
for _, one := range ones { for _, one := range ones {
result = append(result, int64(one.(*SSLCert).Id)) result = append(result, int64(one.(*SSLCert).Id))
} }
@@ -364,6 +395,7 @@ func (this *SSLCertDAO) FindAllExpiringCerts(tx *dbs.Tx, days int) (result []*SS
var deltaSeconds = int64(days * 86400) var deltaSeconds = int64(days * 86400)
_, err = this.Query(tx). _, err = this.Query(tx).
State(SSLCertStateEnabled). State(SSLCertStateEnabled).
Attr("isOn", true).
Where("FROM_UNIXTIME(timeEndAt, '%Y-%m-%d')=:day AND FROM_UNIXTIME(notifiedAt, '%Y-%m-%d')!=:today"). Where("FROM_UNIXTIME(timeEndAt, '%Y-%m-%d')=:day AND FROM_UNIXTIME(notifiedAt, '%Y-%m-%d')!=:today").
Param("day", timeutil.FormatTime("Y-m-d", time.Now().Unix()+deltaSeconds)). Param("day", timeutil.FormatTime("Y-m-d", time.Now().Unix()+deltaSeconds)).
Param("today", timeutil.Format("Y-m-d")). Param("today", timeutil.Format("Y-m-d")).
@@ -633,3 +665,73 @@ func (this *SSLCertDAO) NotifyUpdate(tx *dbs.Tx, certId int64) error {
return nil return nil
} }
// 构造通过域名搜索证书的查询对象
func (this *SSLCertDAO) buildDomainSearchingQuery(query *dbs.Query, domains []string) error {
if len(domains) == 0 {
return nil
}
// 不要查询太多
const maxDomains = 10_000
if len(domains) > maxDomains {
domains = domains[:maxDomains]
}
// 加入通配符
var searchingDomains = []string{}
var domainMap = map[string]bool{}
for _, domain := range domains {
domainMap[domain] = true
}
var reg = regexp.MustCompile(`^[\w*.-]+$`) // 为了下面的SQL语句安全先不支持其他字符
for domain := range domainMap {
if !reg.MatchString(domain) {
continue
}
searchingDomains = append(searchingDomains, domain)
if strings.Count(domain, ".") >= 2 && !strings.HasPrefix(domain, "*.") {
var wildcardDomain = "*" + domain[strings.Index(domain, "."):]
if !domainMap[wildcardDomain] {
domainMap[wildcardDomain] = true
searchingDomains = append(searchingDomains, wildcardDomain)
}
}
}
// 检测 JSON_OVERLAPS() 函数是否可用
var canJSONOverlaps = false
_, funcErr := this.Instance.FindCol(0, "SELECT JSON_OVERLAPS('[1]', '[1]')")
canJSONOverlaps = funcErr == nil
if canJSONOverlaps {
domainsJSON, err := json.Marshal(searchingDomains)
if err != nil {
return err
}
query.
Where("JSON_OVERLAPS(dnsNames, JSON_UNQUOTE(:domainsJSON))").
Param("domainsJSON", string(domainsJSON))
return nil
}
// 不支持JSON_OVERLAPS()的情形
query.Reuse(false)
// TODO 需要判断是否超出max_allowed_packet
var sqlPieces = []string{}
for _, domain := range searchingDomains {
domainJSON, err := json.Marshal(domain)
if err != nil {
return err
}
sqlPieces = append(sqlPieces, "JSON_CONTAINS(dnsNames, '"+string(domainJSON)+"')")
}
if len(sqlPieces) > 0 {
query.Where("(" + strings.Join(sqlPieces, " OR ") + ")")
}
return nil
}

View File

@@ -4,6 +4,7 @@ import (
"encoding/json" "encoding/json"
"errors" "errors"
"github.com/TeaOSLab/EdgeAPI/internal/utils" "github.com/TeaOSLab/EdgeAPI/internal/utils"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/sslconfigs" "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/sslconfigs"
_ "github.com/go-sql-driver/mysql" _ "github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/Tea" "github.com/iwind/TeaGo/Tea"
@@ -77,7 +78,7 @@ func (this *SSLPolicyDAO) FindEnabledSSLPolicy(tx *dbs.Tx, id int64) (*SSLPolicy
} }
// ComposePolicyConfig 组合配置 // ComposePolicyConfig 组合配置
func (this *SSLPolicyDAO) ComposePolicyConfig(tx *dbs.Tx, policyId int64, ignoreData bool, cacheMap *utils.CacheMap) (*sslconfigs.SSLPolicy, error) { func (this *SSLPolicyDAO) ComposePolicyConfig(tx *dbs.Tx, policyId int64, ignoreData bool, dataMap *shared.DataMap, cacheMap *utils.CacheMap) (*sslconfigs.SSLPolicy, error) {
if cacheMap == nil { if cacheMap == nil {
cacheMap = utils.NewCacheMap() cacheMap = utils.NewCacheMap()
} }
@@ -111,7 +112,7 @@ func (this *SSLPolicyDAO) ComposePolicyConfig(tx *dbs.Tx, policyId int64, ignore
} }
if len(refs) > 0 { if len(refs) > 0 {
for _, ref := range refs { for _, ref := range refs {
certConfig, err := SharedSSLCertDAO.ComposeCertConfig(tx, ref.CertId, ignoreData, cacheMap) certConfig, err := SharedSSLCertDAO.ComposeCertConfig(tx, ref.CertId, ignoreData, dataMap, cacheMap)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -133,7 +134,7 @@ func (this *SSLPolicyDAO) ComposePolicyConfig(tx *dbs.Tx, policyId int64, ignore
} }
if len(refs) > 0 { if len(refs) > 0 {
for _, ref := range refs { for _, ref := range refs {
certConfig, err := SharedSSLCertDAO.ComposeCertConfig(tx, ref.CertId, ignoreData, cacheMap) certConfig, err := SharedSSLCertDAO.ComposeCertConfig(tx, ref.CertId, ignoreData, dataMap, cacheMap)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@@ -114,6 +114,20 @@ func (this *NodeClusterTrafficDailyStatDAO) FindDailyStats(tx *dbs.Tx, clusterId
return result, nil return result, nil
} }
// SumDailyStat 计算当月总流量
func (this *NodeClusterTrafficDailyStatDAO) SumDailyStat(tx *dbs.Tx, clusterId int64, dayFrom string, dayTo string) (*NodeClusterTrafficDailyStat, error) {
one, err := this.Query(tx).
Result("SUM(bytes) AS bytes", "SUM(cachedBytes) AS cachedBytes", "SUM(countRequests) AS countRequests", "SUM(countCachedRequests) AS countCachedRequests", "SUM(countAttackRequests) AS countAttackRequests", "SUM(attackBytes) AS attackBytes").
Attr("clusterId", clusterId).
Between("day", dayFrom, dayTo).
Find()
if err != nil || one == nil {
return nil, err
}
return one.(*NodeClusterTrafficDailyStat), nil
}
// Clean 清理历史数据 // Clean 清理历史数据
func (this *NodeClusterTrafficDailyStatDAO) Clean(tx *dbs.Tx, days int) error { func (this *NodeClusterTrafficDailyStatDAO) Clean(tx *dbs.Tx, days int) error {
var day = timeutil.Format("Ymd", time.Now().AddDate(0, 0, -days)) var day = timeutil.Format("Ymd", time.Now().AddDate(0, 0, -days))

View File

@@ -117,6 +117,21 @@ func (this *NodeTrafficDailyStatDAO) FindDailyStats(tx *dbs.Tx, role string, nod
return result, nil return result, nil
} }
// SumDailyStat 计算日期之间的总和
func (this *NodeTrafficDailyStatDAO) SumDailyStat(tx *dbs.Tx, role string, nodeId int64, dayFrom string, dayTo string) (*NodeTrafficDailyStat, error) {
one, err := this.Query(tx).
Result("SUM(bytes) AS bytes", "SUM(cachedBytes) AS cachedBytes", "SUM(countRequests) AS countRequests", "SUM(countCachedRequests) AS countCachedRequests", "SUM(countAttackRequests) AS countAttackRequests", "SUM(attackBytes) AS attackBytes").
Attr("nodeId", nodeId).
Attr("role", role).
Between("day", dayFrom, dayTo).
Find()
if err != nil || one == nil {
return nil, err
}
return one.(*NodeTrafficDailyStat), nil
}
// Clean 清理历史数据 // Clean 清理历史数据
func (this *NodeTrafficDailyStatDAO) Clean(tx *dbs.Tx, days int) error { func (this *NodeTrafficDailyStatDAO) Clean(tx *dbs.Tx, days int) error {
var day = timeutil.Format("Ymd", time.Now().AddDate(0, 0, -days)) var day = timeutil.Format("Ymd", time.Now().AddDate(0, 0, -days))

View File

@@ -0,0 +1,108 @@
package models
import (
"encoding/json"
"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/types"
stringutil "github.com/iwind/TeaGo/utils/string"
timeutil "github.com/iwind/TeaGo/utils/time"
"sort"
"time"
)
type UpdatingServerListDAO dbs.DAO
func init() {
dbs.OnReadyDone(func() {
var ticker = time.NewTicker(24 * time.Hour)
goman.New(func() {
for range ticker.C {
err := SharedUpdatingServerListDAO.CleanExpiredLists(nil, 7)
if err != nil {
remotelogs.Error("UpdatingServerListDAO", "CleanExpiredLists(): "+err.Error())
}
}
})
})
}
func NewUpdatingServerListDAO() *UpdatingServerListDAO {
return dbs.NewDAO(&UpdatingServerListDAO{
DAOObject: dbs.DAOObject{
DB: Tea.Env,
Table: "edgeUpdatingServerLists",
Model: new(UpdatingServerList),
PkName: "id",
},
}).(*UpdatingServerListDAO)
}
var SharedUpdatingServerListDAO *UpdatingServerListDAO
func init() {
dbs.OnReady(func() {
SharedUpdatingServerListDAO = NewUpdatingServerListDAO()
})
}
// CreateList 创建待更新的服务列表
func (this *UpdatingServerListDAO) CreateList(tx *dbs.Tx, clusterId int64, serverIds []int64) error {
if clusterId <= 0 || len(serverIds) == 0 {
return nil
}
sort.Slice(serverIds, func(i, j int) bool {
return serverIds[i] < serverIds[j]
})
serverIdsJSON, err := json.Marshal(serverIds)
if err != nil {
return err
}
var uniqueId = stringutil.Md5(types.String(clusterId) + "@" + string(serverIdsJSON))
_, _, err = this.Query(tx).
Set("uniqueId", uniqueId).
Set("serverIds", serverIdsJSON).
Set("clusterId", clusterId).
Set("day", timeutil.Format("Ymd")).
Replace() // 使用Replace让ID可以自增
return err
}
// FindLists 查找待更新服务列表
func (this *UpdatingServerListDAO) FindLists(tx *dbs.Tx, clusterIds []int64, lastId int64) (result []*UpdatingServerList, err error) {
if len(clusterIds) == 0 {
return
}
_, err = this.Query(tx).
Attr("clusterId", clusterIds). // 即使clusterIds数量是变化的这里也不需要使用Reuse(false)因为clusterIds通常数量有限
Gt("id", lastId).
Asc(). // 非常重要
Slice(&result).
FindAll()
return
}
// FindLatestId 读取最新的ID
// 不需要区分集群
func (this *UpdatingServerListDAO) FindLatestId(tx *dbs.Tx) (int64, error) {
return this.Query(tx).
ResultPk().
DescPk().
FindInt64Col(0)
}
// CleanExpiredLists 清除过期列表
func (this *UpdatingServerListDAO) CleanExpiredLists(tx *dbs.Tx, days int) error {
if days <= 0 {
days = 7
}
return this.Query(tx).
Lt("day", timeutil.Format("Ymd", time.Now().AddDate(0, 0, -days))).
DeleteQuickly()
}

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,24 @@
package models
import "github.com/iwind/TeaGo/dbs"
// UpdatingServerList 待更新服务列表
type UpdatingServerList struct {
Id uint64 `field:"id"` // ID
ClusterId uint32 `field:"clusterId"` // 集群ID
UniqueId string `field:"uniqueId"` // 唯一ID
ServerIds dbs.JSON `field:"serverIds"` // 服务IDs
Day string `field:"day"` // 创建日期
}
type UpdatingServerListOperator struct {
Id any // ID
ClusterId any // 集群ID
UniqueId any // 唯一ID
ServerIds any // 服务IDs
Day any // 创建日期
}
func NewUpdatingServerListOperator() *UpdatingServerListOperator {
return &UpdatingServerListOperator{}
}

View File

@@ -0,0 +1,20 @@
package models
import (
"encoding/json"
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
)
func (this *UpdatingServerList) DecodeServerIds() []int64 {
if len(this.ServerIds) == 0 {
return nil
}
var serverIds = []int64{}
err := json.Unmarshal(this.ServerIds, &serverIds)
if err != nil {
remotelogs.Error("UpdatingServerList", "DecodeServerIds(): "+err.Error())
}
return serverIds
}

View File

@@ -1,6 +1,7 @@
package models package models
import ( import (
"fmt"
"github.com/TeaOSLab/EdgeAPI/internal/errors" "github.com/TeaOSLab/EdgeAPI/internal/errors"
"github.com/TeaOSLab/EdgeAPI/internal/goman" "github.com/TeaOSLab/EdgeAPI/internal/goman"
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs" "github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
@@ -26,6 +27,9 @@ const (
UserBandwidthStatTablePartials = 20 UserBandwidthStatTablePartials = 20
) )
var fullDataMap = map[string]bool{} // month => bool
var fullDataLocker = &sync.Mutex{}
func init() { func init() {
dbs.OnReadyDone(func() { dbs.OnReadyDone(func() {
// 清理数据任务 // 清理数据任务
@@ -61,7 +65,7 @@ func init() {
} }
// UpdateUserBandwidth 写入数据 // UpdateUserBandwidth 写入数据
func (this *UserBandwidthStatDAO) UpdateUserBandwidth(tx *dbs.Tx, userId int64, regionId int64, day string, timeAt string, bytes int64, totalBytes int64) error { func (this *UserBandwidthStatDAO) UpdateUserBandwidth(tx *dbs.Tx, userId int64, regionId int64, day string, timeAt string, bytes int64, totalBytes int64, cachedBytes int64, attackBytes int64, countRequests int64, countCachedRequests int64, countAttackRequests int64) error {
if userId <= 0 { if userId <= 0 {
// 如果用户ID不大于0则说明服务不属于任何用户此时不需要处理 // 如果用户ID不大于0则说明服务不属于任何用户此时不需要处理
return nil return nil
@@ -71,18 +75,33 @@ func (this *UserBandwidthStatDAO) UpdateUserBandwidth(tx *dbs.Tx, userId int64,
Table(this.partialTable(userId)). Table(this.partialTable(userId)).
Param("bytes", bytes). Param("bytes", bytes).
Param("totalBytes", totalBytes). Param("totalBytes", totalBytes).
Param("cachedBytes", cachedBytes).
Param("attackBytes", attackBytes).
Param("countRequests", countRequests).
Param("countCachedRequests", countCachedRequests).
Param("countAttackRequests", countAttackRequests).
InsertOrUpdateQuickly(maps.Map{ InsertOrUpdateQuickly(maps.Map{
"userId": userId, "userId": userId,
"regionId": regionId, "regionId": regionId,
"day": day, "day": day,
"timeAt": timeAt, "timeAt": timeAt,
"bytes": bytes, "bytes": bytes,
"totalBytes": totalBytes, "totalBytes": totalBytes,
"avgBytes": totalBytes / 300, "avgBytes": totalBytes / 300,
"cachedBytes": cachedBytes,
"attackBytes": attackBytes,
"countRequests": countRequests,
"countCachedRequests": countCachedRequests,
"countAttackRequests": countAttackRequests,
}, maps.Map{ }, maps.Map{
"bytes": dbs.SQL("bytes+:bytes"), "bytes": dbs.SQL("bytes+:bytes"),
"avgBytes": dbs.SQL("(totalBytes+:totalBytes)/300"), // 因为生成SQL语句时会自动将avgBytes排在totalBytes之前所以这里不用担心先后顺序的问题 "avgBytes": dbs.SQL("(totalBytes+:totalBytes)/300"), // 因为生成SQL语句时会自动将avgBytes排在totalBytes之前所以这里不用担心先后顺序的问题
"totalBytes": dbs.SQL("totalBytes+:totalBytes"), "totalBytes": dbs.SQL("totalBytes+:totalBytes"),
"cachedBytes": dbs.SQL("cachedBytes+:cachedBytes"),
"attackBytes": dbs.SQL("attackBytes+:attackBytes"),
"countRequests": dbs.SQL("countRequests+:countRequests"),
"countCachedRequests": dbs.SQL("countCachedRequests+:countCachedRequests"),
"countAttackRequests": dbs.SQL("countAttackRequests+:countAttackRequests"),
}) })
} }
@@ -320,6 +339,127 @@ func (this *UserBandwidthStatDAO) FindDistinctUserIds(tx *dbs.Tx, dayFrom string
return return
} }
// SumUserMonthly 获取某月流量总和
// month 格式为YYYYMM
func (this *UserBandwidthStatDAO) SumUserMonthly(tx *dbs.Tx, userId int64, month string) (int64, error) {
// 兼容以往版本
hasFullData, err := this.HasFullData(tx, userId, month)
if err != nil {
return 0, err
}
if !hasFullData {
return SharedServerDailyStatDAO.compatSumUserMonthly(tx, userId, month)
}
return this.Query(tx).
Table(this.partialTable(userId)).
Between("day", month+"01", month+"31").
Attr("userId", userId).
SumInt64("totalBytes", 0)
}
// SumUserDaily 获取某天流量总和
// day 格式为YYYYMMDD
func (this *UserBandwidthStatDAO) SumUserDaily(tx *dbs.Tx, userId int64, regionId int64, day string) (stat *UserBandwidthStat, err error) {
if !regexputils.YYYYMMDD.MatchString(day) {
return nil, nil
}
// 兼容以往版本
hasFullData, err := this.HasFullData(tx, userId, day[:6])
if err != nil {
return nil, err
}
if !hasFullData {
serverStat, err := SharedServerDailyStatDAO.compatSumUserDaily(tx, userId, regionId, day)
if err != nil || serverStat == nil {
return nil, err
}
return serverStat.AsUserBandwidthStat(), nil
}
var query = this.Query(tx)
if regionId > 0 {
query.Attr("regionId", regionId)
}
one, err := query.
Table(this.partialTable(userId)).
Attr("day", day).
Attr("userId", userId).
Result("SUM(totalBytes) AS totalBytes", "SUM(cachedBytes) AS cachedBytes", "SUM(attackBytes) AS attackBytes", "SUM(countRequests) AS countRequests", "SUM(countCachedRequests) AS countCachedRequests", "SUM(countAttackRequests) AS countAttackRequests").
Find()
if err != nil || one == nil {
return nil, err
}
return one.(*UserBandwidthStat), nil
}
// SumDailyStat 获取某天内的流量
// dayFrom 格式为YYYYMMDD
// dayTo 格式为YYYYMMDD
func (this *UserBandwidthStatDAO) SumDailyStat(tx *dbs.Tx, userId int64, regionId int64, dayFrom string, dayTo string) (stat *pb.ServerDailyStat, err error) {
if !regexputils.YYYYMMDD.MatchString(dayFrom) {
return nil, errors.New("invalid dayFrom '" + dayFrom + "'")
}
if !regexputils.YYYYMMDD.MatchString(dayTo) {
return nil, errors.New("invalid dayTo '" + dayTo + "'")
}
// 兼容以往版本
hasFullData, err := this.HasFullData(tx, userId, dayFrom[:6])
if err != nil {
return nil, err
}
if !hasFullData {
return SharedServerDailyStatDAO.compatSumDailyStat(tx, userId, 0, regionId, dayFrom, dayTo)
}
stat = &pb.ServerDailyStat{}
if userId <= 0 {
return
}
if dayFrom > dayTo {
dayFrom, dayTo = dayTo, dayFrom
}
var query = this.Query(tx).
Table(this.partialTable(userId)).
Result("SUM(totalBytes) AS totalBytes, SUM(cachedBytes) AS cachedBytes, SUM(countRequests) AS countRequests, SUM(countCachedRequests) AS countCachedRequests, SUM(countAttackRequests) AS countAttackRequests, SUM(attackBytes) AS attackBytes")
query.Attr("userId", userId)
if regionId > 0 {
query.Attr("regionId", regionId)
}
if dayFrom == dayTo {
query.Attr("day", dayFrom)
} else {
query.Between("day", dayFrom, dayTo)
}
one, _, err := query.FindOne()
if err != nil {
return nil, err
}
if one == nil {
return
}
stat.Bytes = one.GetInt64("totalBytes")
stat.CachedBytes = one.GetInt64("cachedBytes")
stat.CountRequests = one.GetInt64("countRequests")
stat.CountCachedRequests = one.GetInt64("countCachedRequests")
stat.CountAttackRequests = one.GetInt64("countAttackRequests")
stat.AttackBytes = one.GetInt64("attackBytes")
return
}
// Clean 清理过期数据 // Clean 清理过期数据
func (this *UserBandwidthStatDAO) Clean(tx *dbs.Tx) error { func (this *UserBandwidthStatDAO) Clean(tx *dbs.Tx) error {
var day = timeutil.Format("Ymd", time.Now().AddDate(0, 0, -100)) // 保留大约3个月的数据 var day = timeutil.Format("Ymd", time.Now().AddDate(0, 0, -100)) // 保留大约3个月的数据
@@ -375,3 +515,48 @@ func (this *UserBandwidthStatDAO) fixUserStat(stat *UserBandwidthStat, useAvg bo
} }
return stat return stat
} }
// HasFullData 检查一个月是否完整数据
// 是为了兼容以前数据,以前的表中没有缓存流量、请求数等字段
func (this *UserBandwidthStatDAO) HasFullData(tx *dbs.Tx, userId int64, month string) (bool, error) {
if !regexputils.YYYYMM.MatchString(month) {
return false, errors.New("invalid month '" + month + "'")
}
fullDataLocker.Lock()
hasData, ok := fullDataMap[month]
fullDataLocker.Unlock()
if ok {
return hasData, nil
}
var year = types.Int(month[:4])
var monthInt = types.Int(month[4:])
if year < 2000 || monthInt > 12 || monthInt < 1 {
return false, nil
}
var lastMonth = monthInt - 1
if lastMonth == 0 {
lastMonth = 12
year--
}
var lastMonthString = fmt.Sprintf("%d%02d", year, lastMonth)
one, err := this.Query(tx).
Table(this.partialTable(userId)).
Between("day", lastMonthString+"01", lastMonthString+"31").
DescPk().
Find()
if err != nil {
return false, err
}
var b = one != nil && one.(*UserBandwidthStat).CountRequests > 0
fullDataLocker.Lock()
fullDataMap[month] = b
fullDataLocker.Unlock()
return b, nil
}

View File

@@ -50,7 +50,7 @@ func TestUserBandwidthStatDAO_FindUserPeekBandwidthInDay(t *testing.T) {
func TestUserBandwidthStatDAO_UpdateServerBandwidth(t *testing.T) { func TestUserBandwidthStatDAO_UpdateServerBandwidth(t *testing.T) {
var dao = models.NewUserBandwidthStatDAO() var dao = models.NewUserBandwidthStatDAO()
var tx *dbs.Tx var tx *dbs.Tx
err := dao.UpdateUserBandwidth(tx, 1, 0, timeutil.Format("Ymd"), timeutil.FormatTime("Hi", time.Now().Unix()/300*300), 1024, 300) err := dao.UpdateUserBandwidth(tx, 1, 0, timeutil.Format("Ymd"), timeutil.FormatTime("Hi", time.Now().Unix()/300*300), 1024, 300, 0, 0, 0, 0, 0)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@@ -93,3 +93,13 @@ func TestUserBandwidthStatDAO_FindPercentileBetweenDays(t *testing.T) {
} }
logs.PrintAsJSON(stat, t) logs.PrintAsJSON(stat, t)
} }
func TestUserBandwidthStatDAO_HasFullData(t *testing.T) {
var tx *dbs.Tx
var dao = models.NewUserBandwidthStatDAO()
var month = "202304"
for i := 0; i < 3; i++ {
t.Log(dao.HasFullData(tx, 1, month))
}
}

View File

@@ -2,25 +2,35 @@ package models
// UserBandwidthStat 用户月带宽峰值 // UserBandwidthStat 用户月带宽峰值
type UserBandwidthStat struct { type UserBandwidthStat struct {
Id uint64 `field:"id"` // ID Id uint64 `field:"id"` // ID
UserId uint64 `field:"userId"` // 用户ID UserId uint64 `field:"userId"` // 用户ID
RegionId uint32 `field:"regionId"` // 区域ID RegionId uint32 `field:"regionId"` // 区域ID
Day string `field:"day"` // 日期YYYYMMDD Day string `field:"day"` // 日期YYYYMMDD
TimeAt string `field:"timeAt"` // 时间点HHII TimeAt string `field:"timeAt"` // 时间点HHII
Bytes uint64 `field:"bytes"` // 带宽 Bytes uint64 `field:"bytes"` // 带宽
TotalBytes uint64 `field:"totalBytes"` // 总流量 TotalBytes uint64 `field:"totalBytes"` // 总流量
AvgBytes uint64 `field:"avgBytes"` // 平均流量 AvgBytes uint64 `field:"avgBytes"` // 平均流量
CachedBytes uint64 `field:"cachedBytes"` // 缓存的流量
AttackBytes uint64 `field:"attackBytes"` // 攻击流量
CountRequests uint64 `field:"countRequests"` // 请求数
CountCachedRequests uint64 `field:"countCachedRequests"` // 缓存的请求数
CountAttackRequests uint64 `field:"countAttackRequests"` // 攻击请求数
} }
type UserBandwidthStatOperator struct { type UserBandwidthStatOperator struct {
Id any // ID Id any // ID
UserId any // 用户ID UserId any // 用户ID
RegionId any // 区域ID RegionId any // 区域ID
Day any // 日期YYYYMMDD Day any // 日期YYYYMMDD
TimeAt any // 时间点HHII TimeAt any // 时间点HHII
Bytes any // 带宽 Bytes any // 带宽
TotalBytes any // 总流量 TotalBytes any // 总流量
AvgBytes any // 平均流量 AvgBytes any // 平均流量
CachedBytes any // 缓存的流量
AttackBytes any // 攻击流量
CountRequests any // 请求数
CountCachedRequests any // 缓存的请求数
CountAttackRequests any // 攻击请求数
} }
func NewUserBandwidthStatOperator() *UserBandwidthStatOperator { func NewUserBandwidthStatOperator() *UserBandwidthStatOperator {

View File

@@ -36,7 +36,7 @@ func (this *UserNode) DecodeHTTPS(cacheMap *utils.CacheMap) (*serverconfigs.HTTP
return nil, err return nil, err
} }
err = config.Init() err = config.Init(nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -44,7 +44,7 @@ func (this *UserNode) DecodeHTTPS(cacheMap *utils.CacheMap) (*serverconfigs.HTTP
if config.SSLPolicyRef != nil { if config.SSLPolicyRef != nil {
policyId := config.SSLPolicyRef.SSLPolicyId policyId := config.SSLPolicyRef.SSLPolicyId
if policyId > 0 { if policyId > 0 {
sslPolicy, err := SharedSSLPolicyDAO.ComposePolicyConfig(nil, policyId, false, cacheMap) sslPolicy, err := SharedSSLPolicyDAO.ComposePolicyConfig(nil, policyId, false, nil, cacheMap)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -54,7 +54,7 @@ func (this *UserNode) DecodeHTTPS(cacheMap *utils.CacheMap) (*serverconfigs.HTTP
} }
} }
err = config.Init() err = config.Init(nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@@ -2,6 +2,7 @@ package dbutils
import ( import (
"github.com/iwind/TeaGo/dbs" "github.com/iwind/TeaGo/dbs"
"github.com/iwind/TeaGo/types"
"net" "net"
"strings" "strings"
) )
@@ -93,3 +94,36 @@ func IsLocalAddr(addr string) bool {
} }
return false return false
} }
// MySQLVersion 读取当前MySQL版本
func MySQLVersion() (version string, err error) {
db, err := dbs.Default()
if err != nil {
return "", err
}
result, err := db.FindCol(0, "SELECT VERSION()")
if err != nil {
return "", err
}
version = types.String(result)
var suffixIndex = strings.Index(version, "-")
if suffixIndex > 0 {
version = version[:suffixIndex]
}
return
}
func MySQLVersionFrom8() (bool, error) {
version, err := MySQLVersion()
if err != nil {
return false, err
}
if len(version) == 0 {
return false, nil
}
var dotIndex = strings.Index(version, ".")
if dotIndex > 0 {
return types.Int(version[:dotIndex]) >= 8, nil
}
return false, nil
}

View File

@@ -23,3 +23,15 @@ func TestIsLocalAddr(t *testing.T) {
a.IsFalse(dbutils.IsLocalAddr("192.168.2.200")) a.IsFalse(dbutils.IsLocalAddr("192.168.2.200"))
a.IsFalse(dbutils.IsLocalAddr("192.168.2.200:3306")) a.IsFalse(dbutils.IsLocalAddr("192.168.2.200:3306"))
} }
func TestMySQLVersion(t *testing.T) {
version, err := dbutils.MySQLVersion()
if err != nil {
t.Fatal(err)
}
t.Log("version:", version)
}
func TestMySQLVersionFrom8(t *testing.T) {
t.Log(dbutils.MySQLVersionFrom8())
}

View File

@@ -0,0 +1,17 @@
// Copyright 2023 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
package dnspod
type CustomLineGroupListResponse struct {
BaseResponse
Data struct {
LineGroups []struct {
Name string `json:"name"`
} `json:"line_groups"`
Info struct {
NowTotal int `json:"now_total"`
Total int `json:"total"`
} `json:"info"`
} `json:"data"`
}

View File

@@ -164,6 +164,53 @@ func (this *DNSPodProvider) GetRoutes(domain string) (routes []*dnstypes.Route,
}) })
} }
// 自定义线路分组
var groupsPerPage = 100
var customLineGroupListResponse = new(dnspod.CustomLineGroupListResponse)
err = this.doAPI("/Custom.Line.Group.List", map[string]string{
"domain": domain,
"offset": "0",
"length": types.String(groupsPerPage),
}, customLineGroupListResponse)
if err != nil {
// 忽略自定义分组错误
err = nil
} else {
if len(customLineGroupListResponse.Data.LineGroups) > 0 {
for _, lineGroup := range customLineGroupListResponse.Data.LineGroups {
routes = append(routes, &dnstypes.Route{
Name: "分组:" + lineGroup.Name,
Code: lineGroup.Name,
})
}
}
if customLineGroupListResponse.Data.Info.Total > customLineGroupListResponse.Data.Info.NowTotal {
for page := 1; page <= 100; /** 最多100页 **/ page++ {
err = this.doAPI("/Custom.Line.Group.List", map[string]string{
"domain": domain,
"offset": types.String(page * groupsPerPage),
"length": types.String(groupsPerPage),
}, customLineGroupListResponse)
if err != nil {
// 忽略错误
err = nil
} else {
if len(customLineGroupListResponse.Data.LineGroups) == 0 {
break
}
for _, lineGroup := range customLineGroupListResponse.Data.LineGroups {
routes = append(routes, &dnstypes.Route{
Name: "分组:" + lineGroup.Name,
Code: lineGroup.Name,
})
}
}
}
}
}
return routes, nil return routes, nil
} }

View File

@@ -29,8 +29,12 @@ func (this *errorObj) Error() string {
return s return s
} }
// 新错误 // New 新错误
func New(errText string) error { func New(errText string) error {
if !Tea.IsTesting() {
return errors.New(errText)
}
ptr, file, line, ok := runtime.Caller(1) ptr, file, line, ok := runtime.Caller(1)
funcName := "" funcName := ""
if ok { if ok {
@@ -45,7 +49,7 @@ func New(errText string) error {
} }
} }
// 包装已有错误 // Wrap 包装已有错误
func Wrap(err error) error { func Wrap(err error) error {
if err == nil { if err == nil {
return nil return nil

View File

@@ -5,6 +5,7 @@ import (
"github.com/iwind/TeaGo/files" "github.com/iwind/TeaGo/files"
stringutil "github.com/iwind/TeaGo/utils/string" stringutil "github.com/iwind/TeaGo/utils/string"
"regexp" "regexp"
"sync"
) )
var SharedDeployManager = NewDeployManager() var SharedDeployManager = NewDeployManager()
@@ -12,9 +13,12 @@ var SharedDeployManager = NewDeployManager()
// DeployManager 节点部署文件管理器 // DeployManager 节点部署文件管理器
// 如果节点部署文件有变化需要重启API节点以便于生效 // 如果节点部署文件有变化需要重启API节点以便于生效
type DeployManager struct { type DeployManager struct {
dir string dir string
nodeFiles []*DeployFile nodeFiles []*DeployFile
nsNodeFiles []*DeployFile nsNodeFiles []*DeployFile
locker sync.Mutex
} }
// NewDeployManager 获取新节点部署文件管理器 // NewDeployManager 获取新节点部署文件管理器
@@ -29,24 +33,27 @@ func NewDeployManager() *DeployManager {
// LoadNodeFiles 加载所有边缘节点文件 // LoadNodeFiles 加载所有边缘节点文件
func (this *DeployManager) LoadNodeFiles() []*DeployFile { func (this *DeployManager) LoadNodeFiles() []*DeployFile {
this.locker.Lock()
defer this.locker.Unlock()
if len(this.nodeFiles) > 0 { if len(this.nodeFiles) > 0 {
return this.nodeFiles return this.nodeFiles
} }
keyMap := map[string]*DeployFile{} // key => File var keyMap = map[string]*DeployFile{} // key => File
reg := regexp.MustCompile(`^edge-node-(\w+)-(\w+)-v([0-9.]+)\.zip$`) var reg = regexp.MustCompile(`^edge-node-(\w+)-(\w+)-v([0-9.]+)\.zip$`)
for _, file := range files.NewFile(this.dir).List() { for _, file := range files.NewFile(this.dir).List() {
name := file.Name() var name = file.Name()
if !reg.MatchString(name) { if !reg.MatchString(name) {
continue continue
} }
matches := reg.FindStringSubmatch(name) var matches = reg.FindStringSubmatch(name)
osName := matches[1] var osName = matches[1]
arch := matches[2] var arch = matches[2]
version := matches[3] var version = matches[3]
key := osName + "_" + arch var key = osName + "_" + arch
oldFile, ok := keyMap[key] oldFile, ok := keyMap[key]
if ok && stringutil.VersionCompare(oldFile.Version, version) > 0 { if ok && stringutil.VersionCompare(oldFile.Version, version) > 0 {
continue continue
@@ -59,7 +66,7 @@ func (this *DeployManager) LoadNodeFiles() []*DeployFile {
} }
} }
result := []*DeployFile{} var result = []*DeployFile{}
for _, v := range keyMap { for _, v := range keyMap {
result = append(result, v) result = append(result, v)
} }
@@ -81,24 +88,27 @@ func (this *DeployManager) FindNodeFile(os string, arch string) *DeployFile {
// LoadNSNodeFiles 加载所有NS节点安装文件 // LoadNSNodeFiles 加载所有NS节点安装文件
func (this *DeployManager) LoadNSNodeFiles() []*DeployFile { func (this *DeployManager) LoadNSNodeFiles() []*DeployFile {
this.locker.Lock()
defer this.locker.Unlock()
if len(this.nsNodeFiles) > 0 { if len(this.nsNodeFiles) > 0 {
return this.nsNodeFiles return this.nsNodeFiles
} }
keyMap := map[string]*DeployFile{} // key => File var keyMap = map[string]*DeployFile{} // key => File
reg := regexp.MustCompile(`^edge-dns-(\w+)-(\w+)-v([0-9.]+)\.zip$`) var reg = regexp.MustCompile(`^edge-dns-(\w+)-(\w+)-v([0-9.]+)\.zip$`)
for _, file := range files.NewFile(this.dir).List() { for _, file := range files.NewFile(this.dir).List() {
name := file.Name() var name = file.Name()
if !reg.MatchString(name) { if !reg.MatchString(name) {
continue continue
} }
matches := reg.FindStringSubmatch(name) var matches = reg.FindStringSubmatch(name)
osName := matches[1] var osName = matches[1]
arch := matches[2] var arch = matches[2]
version := matches[3] var version = matches[3]
key := osName + "_" + arch var key = osName + "_" + arch
oldFile, ok := keyMap[key] oldFile, ok := keyMap[key]
if ok && stringutil.VersionCompare(oldFile.Version, version) > 0 { if ok && stringutil.VersionCompare(oldFile.Version, version) > 0 {
continue continue
@@ -111,7 +121,7 @@ func (this *DeployManager) LoadNSNodeFiles() []*DeployFile {
} }
} }
result := []*DeployFile{} var result = []*DeployFile{}
for _, v := range keyMap { for _, v := range keyMap {
result = append(result, v) result = append(result, v)
} }
@@ -130,3 +140,12 @@ func (this *DeployManager) FindNSNodeFile(os string, arch string) *DeployFile {
} }
return nil return nil
} }
// Reload 重置缓存
func (this *DeployManager) Reload() {
this.locker.Lock()
defer this.locker.Unlock()
this.nodeFiles = nil
this.nsNodeFiles = nil
}

View File

@@ -268,8 +268,8 @@ func (this *APINode) InstallSystemService() error {
func (this *APINode) listenRPC(listener net.Listener, tlsConfig *tls.Config) error { func (this *APINode) listenRPC(listener net.Listener, tlsConfig *tls.Config) error {
var rpcServer *grpc.Server var rpcServer *grpc.Server
var options = []grpc.ServerOption{ var options = []grpc.ServerOption{
grpc.MaxRecvMsgSize(128 * 1024 * 1024), grpc.MaxRecvMsgSize(512 << 20),
grpc.MaxSendMsgSize(128 * 1024 * 1024), grpc.MaxSendMsgSize(512 << 20),
grpc.UnaryInterceptor(this.unaryInterceptor), grpc.UnaryInterceptor(this.unaryInterceptor),
} }
@@ -306,13 +306,27 @@ func (this *APINode) checkDB() error {
logs.Println("[API_NODE]" + errString) logs.Println("[API_NODE]" + errString)
this.addStartIssue("db", errString, this.dbIssueSuggestion(errString)) this.addStartIssue("db", errString, this.dbIssueSuggestion(errString))
// 决定是否尝试启动本地的MySQL
if strings.Contains(err.Error(), "connection refused") {
config, _ := db.Config()
if config != nil && (strings.Contains(config.Dsn, "tcp(127.0.0.1:") || strings.Contains(config.Dsn, "tcp(localhost:)")) && os.Getgid() == 0 /** ROOT 用户 **/ {
var mysqldSafeFile = "/usr/local/mysql/bin/mysqld_safe"
_, err = os.Stat(mysqldSafeFile)
if err == nil {
logs.Println("[API_NODE]try to start local mysql server from '" + mysqldSafeFile + "' ...")
var mysqlCmd = exec.Command(mysqldSafeFile)
_ = mysqlCmd.Start()
}
}
}
// 多次尝试 // 多次尝试
var maxTries = 600 var maxTries = 600
if Tea.IsTesting() { if Tea.IsTesting() {
maxTries = 600 maxTries = 600
} }
for i := 0; i <= maxTries; i++ { for i := 0; i <= maxTries; i++ {
_, err := db.Exec("SELECT 1") _, err = db.Exec("SELECT 1")
if err != nil { if err != nil {
if i == maxTries-1 { if i == maxTries-1 {
return err return err
@@ -741,6 +755,41 @@ func (this *APINode) listenSock() error {
"code": teaconst.InstanceCode, "code": teaconst.InstanceCode,
}, },
}) })
case "lookupToken":
var role = maps.NewMap(cmd.Params).GetString("role")
switch role {
case "admin", "user", "api":
tokens, err := models.SharedApiTokenDAO.FindAllEnabledAPITokens(nil, role)
if err != nil {
_ = cmd.Reply(&gosock.Command{
Params: map[string]any{
"isOk": false,
"err": err.Error(),
},
})
} else {
var tokenMaps = []maps.Map{}
for _, token := range tokens {
tokenMaps = append(tokenMaps, maps.Map{
"nodeId": token.NodeId,
"secret": token.Secret,
})
}
_ = cmd.Reply(&gosock.Command{
Params: map[string]any{
"isOk": true,
"tokens": tokenMaps,
},
})
}
default:
_ = cmd.Reply(&gosock.Command{
Params: map[string]any{
"isOk": false,
"err": "unsupported role '" + role + "'",
},
})
}
} }
}) })

View File

@@ -559,6 +559,12 @@ func (this *APINode) registerServices(server *grpc.Server) {
this.rest(instance) this.rest(instance)
} }
{
var instance = this.serviceInstance(&services.UpdatingServerListService{}).(*services.UpdatingServerListService)
pb.RegisterUpdatingServerListServiceServer(server, instance)
this.rest(instance)
}
APINodeServicesRegister(this, server) APINodeServicesRegister(this, server)
// TODO check service names // TODO check service names

View File

@@ -1,3 +1,4 @@
//go:build !windows
// +build !windows // +build !windows
package nodes package nodes
@@ -31,7 +32,7 @@ func (this *NodeStatusExecutor) updateMem(status *nodeconfigs.NodeStatus) {
if minFreeMemory > 1<<30 { if minFreeMemory > 1<<30 {
minFreeMemory = 1 << 30 minFreeMemory = 1 << 30
} }
if stat.Free < minFreeMemory { if stat.Available > 0 && stat.Available < minFreeMemory {
runtime.GC() runtime.GC()
debug.FreeOSMemory() debug.FreeOSMemory()
} }

View File

@@ -17,7 +17,7 @@ var sharedDAO DAOInterface
func init() { func init() {
// 定期上传日志 // 定期上传日志
ticker := time.NewTicker(60 * time.Second) var ticker = time.NewTicker(60 * time.Second)
goman.New(func() { goman.New(func() {
for range ticker.C { for range ticker.C {
err := uploadLogs() err := uploadLogs()

View File

@@ -232,6 +232,12 @@ func (this *ACMETaskService) CreateACMETask(ctx context.Context, req *pb.CreateA
req.AuthType = acme.AuthTypeDNS req.AuthType = acme.AuthTypeDNS
} }
if adminId > 0 {
if req.UserId > 0 {
userId = req.UserId
}
}
var tx = this.NullTx() var tx = this.NullTx()
taskId, err := acmemodels.SharedACMETaskDAO.CreateACMETask(tx, adminId, userId, req.AuthType, req.AcmeUserId, req.DnsProviderId, req.DnsDomain, req.Domains, req.AutoRenew, req.AuthURL) taskId, err := acmemodels.SharedACMETaskDAO.CreateACMETask(tx, adminId, userId, req.AuthType, req.AcmeUserId, req.DnsProviderId, req.DnsDomain, req.Domains, req.AutoRenew, req.AuthURL)
if err != nil { if err != nil {

View File

@@ -22,6 +22,12 @@ func (this *ACMEUserService) CreateACMEUser(ctx context.Context, req *pb.CreateA
var tx = this.NullTx() var tx = this.NullTx()
if adminId > 0 {
if req.UserId > 0 {
userId = req.UserId
}
}
acmeUserId, err := acmemodels.SharedACMEUserDAO.CreateACMEUser(tx, adminId, userId, req.AcmeProviderCode, req.AcmeProviderAccountId, req.Email, req.Description) acmeUserId, err := acmemodels.SharedACMEUserDAO.CreateACMEUser(tx, adminId, userId, req.AcmeProviderCode, req.AcmeProviderAccountId, req.Email, req.Description)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@@ -127,7 +127,7 @@ func (this *AdminService) FindAdminFullname(ctx context.Context, req *pb.FindAdm
// FindEnabledAdmin 获取管理员信息 // FindEnabledAdmin 获取管理员信息
func (this *AdminService) FindEnabledAdmin(ctx context.Context, req *pb.FindEnabledAdminRequest) (*pb.FindEnabledAdminResponse, error) { func (this *AdminService) FindEnabledAdmin(ctx context.Context, req *pb.FindEnabledAdminRequest) (*pb.FindEnabledAdminResponse, error) {
_, err := this.ValidateAdmin(ctx) adminId, err := this.ValidateAdmin(ctx)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -136,6 +136,12 @@ func (this *AdminService) FindEnabledAdmin(ctx context.Context, req *pb.FindEnab
var tx = this.NullTx() var tx = this.NullTx()
// 超级管理员才能查看是否为弱密码
isSuperAdmin, err := models.SharedAdminDAO.CheckSuperAdmin(tx, adminId)
if err != nil {
return nil, err
}
admin, err := models.SharedAdminDAO.FindEnabledAdmin(tx, req.AdminId) admin, err := models.SharedAdminDAO.FindEnabledAdmin(tx, req.AdminId)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -144,7 +150,7 @@ func (this *AdminService) FindEnabledAdmin(ctx context.Context, req *pb.FindEnab
return &pb.FindEnabledAdminResponse{Admin: nil}, nil return &pb.FindEnabledAdminResponse{Admin: nil}, nil
} }
pbModules := []*pb.AdminModule{} var pbModules = []*pb.AdminModule{}
modules := []*systemconfigs.AdminModule{} modules := []*systemconfigs.AdminModule{}
if len(admin.Modules) > 0 { if len(admin.Modules) > 0 {
err = json.Unmarshal(admin.Modules, &modules) err = json.Unmarshal(admin.Modules, &modules)
@@ -178,14 +184,15 @@ func (this *AdminService) FindEnabledAdmin(ctx context.Context, req *pb.FindEnab
} }
result := &pb.Admin{ result := &pb.Admin{
Id: int64(admin.Id), Id: int64(admin.Id),
Fullname: admin.Fullname, Fullname: admin.Fullname,
Username: admin.Username, Username: admin.Username,
IsOn: admin.IsOn, IsOn: admin.IsOn,
IsSuper: admin.IsSuper, IsSuper: admin.IsSuper,
Modules: pbModules, Modules: pbModules,
OtpLogin: pbOtpAuth, OtpLogin: pbOtpAuth,
CanLogin: admin.CanLogin, CanLogin: admin.CanLogin,
HasWeakPassword: isSuperAdmin && admin.HasWeakPassword(),
} }
return &pb.FindEnabledAdminResponse{Admin: result}, nil return &pb.FindEnabledAdminResponse{Admin: result}, nil
} }
@@ -347,7 +354,7 @@ func (this *AdminService) UpdateAdmin(ctx context.Context, req *pb.UpdateAdminRe
// CountAllEnabledAdmins 计算管理员数量 // CountAllEnabledAdmins 计算管理员数量
func (this *AdminService) CountAllEnabledAdmins(ctx context.Context, req *pb.CountAllEnabledAdminsRequest) (*pb.RPCCountResponse, error) { func (this *AdminService) CountAllEnabledAdmins(ctx context.Context, req *pb.CountAllEnabledAdminsRequest) (*pb.RPCCountResponse, error) {
_, err := this.ValidateAdmin(ctx) adminId, err := this.ValidateAdmin(ctx)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -356,7 +363,13 @@ func (this *AdminService) CountAllEnabledAdmins(ctx context.Context, req *pb.Cou
var tx = this.NullTx() var tx = this.NullTx()
count, err := models.SharedAdminDAO.CountAllEnabledAdmins(tx) // 超级管理员才能查看是否为弱密码
isSuperAdmin, err := models.SharedAdminDAO.CheckSuperAdmin(tx, adminId)
if err != nil {
return nil, err
}
count, err := models.SharedAdminDAO.CountAllEnabledAdmins(tx, req.Keyword, isSuperAdmin && req.HasWeakPassword)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -365,7 +378,7 @@ func (this *AdminService) CountAllEnabledAdmins(ctx context.Context, req *pb.Cou
// ListEnabledAdmins 列出单页的管理员 // ListEnabledAdmins 列出单页的管理员
func (this *AdminService) ListEnabledAdmins(ctx context.Context, req *pb.ListEnabledAdminsRequest) (*pb.ListEnabledAdminsResponse, error) { func (this *AdminService) ListEnabledAdmins(ctx context.Context, req *pb.ListEnabledAdminsRequest) (*pb.ListEnabledAdminsResponse, error) {
_, err := this.ValidateAdmin(ctx) adminId, err := this.ValidateAdmin(ctx)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -374,12 +387,18 @@ func (this *AdminService) ListEnabledAdmins(ctx context.Context, req *pb.ListEna
var tx = this.NullTx() var tx = this.NullTx()
admins, err := models.SharedAdminDAO.ListEnabledAdmins(tx, req.Offset, req.Size) // 超级管理员才能查看是否为弱密码
isSuperAdmin, err := models.SharedAdminDAO.CheckSuperAdmin(tx, adminId)
if err != nil { if err != nil {
return nil, err return nil, err
} }
result := []*pb.Admin{} admins, err := models.SharedAdminDAO.ListEnabledAdmins(tx, req.Keyword, isSuperAdmin && req.HasWeakPassword, req.Offset, req.Size)
if err != nil {
return nil, err
}
var result = []*pb.Admin{}
for _, admin := range admins { for _, admin := range admins {
var pbOtpAuth *pb.Login = nil var pbOtpAuth *pb.Login = nil
{ {
@@ -398,14 +417,15 @@ func (this *AdminService) ListEnabledAdmins(ctx context.Context, req *pb.ListEna
} }
result = append(result, &pb.Admin{ result = append(result, &pb.Admin{
Id: int64(admin.Id), Id: int64(admin.Id),
Fullname: admin.Fullname, Fullname: admin.Fullname,
Username: admin.Username, Username: admin.Username,
IsOn: admin.IsOn, IsOn: admin.IsOn,
IsSuper: admin.IsSuper, IsSuper: admin.IsSuper,
CreatedAt: int64(admin.CreatedAt), CreatedAt: int64(admin.CreatedAt),
OtpLogin: pbOtpAuth, OtpLogin: pbOtpAuth,
CanLogin: admin.CanLogin, CanLogin: admin.CanLogin,
HasWeakPassword: isSuperAdmin && admin.HasWeakPassword(),
}) })
} }

View File

@@ -8,6 +8,7 @@ import (
"fmt" "fmt"
teaconst "github.com/TeaOSLab/EdgeAPI/internal/const" teaconst "github.com/TeaOSLab/EdgeAPI/internal/const"
"github.com/TeaOSLab/EdgeAPI/internal/db/models" "github.com/TeaOSLab/EdgeAPI/internal/db/models"
"github.com/TeaOSLab/EdgeAPI/internal/installers"
rpcutils "github.com/TeaOSLab/EdgeAPI/internal/rpc/utils" rpcutils "github.com/TeaOSLab/EdgeAPI/internal/rpc/utils"
executils "github.com/TeaOSLab/EdgeAPI/internal/utils/exec" executils "github.com/TeaOSLab/EdgeAPI/internal/utils/exec"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
@@ -481,3 +482,106 @@ func (this *APINodeService) UploadAPINodeFile(ctx context.Context, req *pb.Uploa
return &pb.UploadAPINodeFileResponse{}, nil return &pb.UploadAPINodeFileResponse{}, nil
} }
// UploadDeployFileToAPINode 上传节点安装文件
func (this *APINodeService) UploadDeployFileToAPINode(ctx context.Context, req *pb.UploadDeployFileToAPINodeRequest) (*pb.RPCSuccess, error) {
_, err := this.ValidateAdmin(ctx)
if err != nil {
return nil, err
}
var targetDir = Tea.Root + "/deploy/"
var targetTmpFile = targetDir + "/" + req.Filename + ".tmp"
var targetFile = targetDir + "/" + req.Filename
if req.IsFirstChunk {
_ = os.Remove(targetTmpFile)
}
if len(req.ChunkData) > 0 {
err = func() error {
var flags = os.O_CREATE | os.O_WRONLY
if req.IsFirstChunk {
flags |= os.O_TRUNC
} else {
flags |= os.O_APPEND
}
fp, err := os.OpenFile(targetTmpFile, flags, 0666)
if err != nil {
return err
}
defer func() {
_ = fp.Close()
}()
_, err = fp.Write(req.ChunkData)
return err
}()
if err != nil {
return nil, errors.New("write file failed: " + err.Error())
}
}
if req.IsLastChunk {
// 检查SUM
fp, err := os.Open(targetTmpFile)
if err != nil {
return nil, err
}
var hash = md5.New()
_, err = io.Copy(hash, fp)
_ = fp.Close()
if err != nil {
return nil, err
}
var tmpSum = fmt.Sprintf("%x", hash.Sum(nil))
if tmpSum != req.Sum {
_ = os.Remove(targetTmpFile)
return nil, errors.New("check sum failed")
}
// 正式改名
err = os.Rename(targetTmpFile, targetFile)
if err != nil {
return nil, errors.New("rename failed: " + err.Error())
}
// 重载数据
installers.SharedDeployManager.Reload()
}
return this.Success()
}
// FindLatestDeployFiles 查找已有节点安装文件信息
func (this *APINodeService) FindLatestDeployFiles(ctx context.Context, req *pb.FindLatestDeployFilesRequest) (*pb.FindLatestDeployFilesResponse, error) {
_, err := this.ValidateAdmin(ctx)
if err != nil {
return nil, err
}
var pbNodeFiles = []*pb.FindLatestDeployFilesResponse_DeployFile{}
var nodeFiles = installers.SharedDeployManager.LoadNodeFiles()
for _, nodeFile := range nodeFiles {
pbNodeFiles = append(pbNodeFiles, &pb.FindLatestDeployFilesResponse_DeployFile{
Os: nodeFile.OS,
Arch: nodeFile.Arch,
Version: nodeFile.Version,
})
}
var pbNSNodeFiles = []*pb.FindLatestDeployFilesResponse_DeployFile{}
var nsNodeFiles = installers.SharedDeployManager.LoadNSNodeFiles()
for _, nodeFile := range nsNodeFiles {
pbNSNodeFiles = append(pbNSNodeFiles, &pb.FindLatestDeployFilesResponse_DeployFile{
Os: nodeFile.OS,
Arch: nodeFile.Arch,
Version: nodeFile.Version,
})
}
return &pb.FindLatestDeployFilesResponse{
NodeDeployFiles: pbNodeFiles,
NsNodeDeployFiles: pbNSNodeFiles,
}, nil
}

View File

@@ -109,7 +109,7 @@ func (this *BaseService) ValidateAuthorityNode(ctx context.Context) (nodeId int6
func (this *BaseService) ValidateNodeId(ctx context.Context, roles ...rpcutils.UserType) (role rpcutils.UserType, nodeIntId int64, err error) { func (this *BaseService) ValidateNodeId(ctx context.Context, roles ...rpcutils.UserType) (role rpcutils.UserType, nodeIntId int64, err error) {
// 默认包含大部分节点 // 默认包含大部分节点
if len(roles) == 0 { if len(roles) == 0 {
roles = []rpcutils.UserType{rpcutils.UserTypeNode, rpcutils.UserTypeCluster, rpcutils.UserTypeAdmin, rpcutils.UserTypeUser, rpcutils.UserTypeDNS, rpcutils.UserTypeReport, rpcutils.UserTypeMonitor, rpcutils.UserTypeLog} roles = []rpcutils.UserType{rpcutils.UserTypeNode, rpcutils.UserTypeCluster, rpcutils.UserTypeAdmin, rpcutils.UserTypeUser, rpcutils.UserTypeDNS, rpcutils.UserTypeReport, rpcutils.UserTypeMonitor, rpcutils.UserTypeLog, rpcutils.UserTypeAPI}
} }
if ctx == nil { if ctx == nil {

View File

@@ -454,7 +454,7 @@ func (this *DNSDomainService) findClusterDNSChanges(cluster *models.NodeCluster,
} }
// 节点域名 // 节点域名
nodes, err := models.SharedNodeDAO.FindAllEnabledNodesDNSWithClusterId(tx, clusterId, true, dnsConfig != nil && dnsConfig.IncludingLnNodes) nodes, err := models.SharedNodeDAO.FindAllEnabledNodesDNSWithClusterId(tx, clusterId, true, dnsConfig != nil && dnsConfig.IncludingLnNodes, true)
if err != nil { if err != nil {
return nil, nil, nil, 0, 0, false, false, err return nil, nil, nil, 0, 0, false, false, err
} }

View File

@@ -29,8 +29,29 @@ func (this *HTTPCacheTaskService) CreateHTTPCacheTask(ctx context.Context, req *
var tx = this.NullTx() var tx = this.NullTx()
// 检查操作类型 // 检查操作类型
if len(req.Type) == 0 {
return nil, errors.New("require 'type' parameter")
}
if req.Type != models.HTTPCacheTaskTypePurge && req.Type != models.HTTPCacheTaskTypeFetch { if req.Type != models.HTTPCacheTaskTypePurge && req.Type != models.HTTPCacheTaskTypeFetch {
return nil, errors.New("invalid type '" + req.Type + "'") return nil, errors.New("'type' must be 'purge' or 'fetch'")
}
// 检查Key类型
if len(req.KeyType) == 0 {
return nil, errors.New("require 'keyType' parameter")
}
if req.KeyType != "key" && req.KeyType != "prefix" {
return nil, errors.New("'keyType' must be 'key' or 'prefix'")
}
// 预热只能是Key
if req.Type == models.HTTPCacheTaskTypeFetch && req.KeyType != "key" {
return nil, errors.New("'keyType' should be 'key' when fetching cache")
}
// 检查key是否为空
if len(req.Keys) == 0 {
return nil, errors.New("'keys' should not be empty")
} }
// 检查Key数量 // 检查Key数量

View File

@@ -60,7 +60,7 @@ func (this *HTTPLocationService) FindEnabledHTTPLocationConfig(ctx context.Conte
var tx = this.NullTx() var tx = this.NullTx()
config, err := models.SharedHTTPLocationDAO.ComposeLocationConfig(tx, req.LocationId, nil) config, err := models.SharedHTTPLocationDAO.ComposeLocationConfig(tx, req.LocationId, false, nil, nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -121,7 +121,7 @@ func (this *HTTPLocationService) FindAndInitHTTPLocationReverseProxyConfig(ctx c
} }
} }
reverseProxyConfig, err := models.SharedReverseProxyDAO.ComposeReverseProxyConfig(tx, reverseProxyRef.ReverseProxyId, nil) reverseProxyConfig, err := models.SharedReverseProxyDAO.ComposeReverseProxyConfig(tx, reverseProxyRef.ReverseProxyId, nil, nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -167,7 +167,7 @@ func (this *HTTPLocationService) FindAndInitHTTPLocationWebConfig(ctx context.Co
} }
} }
config, err := models.SharedHTTPWebDAO.ComposeWebConfig(tx, webId, nil) config, err := models.SharedHTTPWebDAO.ComposeWebConfig(tx, webId, true, false, nil, nil)
if err != nil { if err != nil {
return nil, rpcutils.Wrap("ComposeWebConfig()", err) return nil, rpcutils.Wrap("ComposeWebConfig()", err)
} }

View File

@@ -83,7 +83,7 @@ func (this *HTTPWebService) FindEnabledHTTPWebConfig(ctx context.Context, req *p
var tx = this.NullTx() var tx = this.NullTx()
config, err := models.SharedHTTPWebDAO.ComposeWebConfig(tx, req.HttpWebId, nil) config, err := models.SharedHTTPWebDAO.ComposeWebConfig(tx, req.HttpWebId, false, false, nil, nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@@ -29,7 +29,7 @@ func (this *IPItemService) CreateIPItem(ctx context.Context, req *pb.CreateIPIte
return nil, errors.New("'ipFrom' should not be empty") return nil, errors.New("'ipFrom' should not be empty")
} }
ipFrom := net.ParseIP(req.IpFrom) var ipFrom = net.ParseIP(req.IpFrom)
if ipFrom == nil { if ipFrom == nil {
return nil, errors.New("invalid 'ipFrom'") return nil, errors.New("invalid 'ipFrom'")
} }
@@ -64,7 +64,7 @@ func (this *IPItemService) CreateIPItem(ctx context.Context, req *pb.CreateIPIte
return nil, err return nil, err
} }
itemId, err := models.SharedIPItemDAO.CreateIPItem(tx, req.IpListId, req.IpFrom, req.IpTo, req.ExpiredAt, req.Reason, req.Type, req.EventLevel, req.NodeId, req.ServerId, req.SourceNodeId, req.SourceServerId, req.SourceHTTPFirewallPolicyId, req.SourceHTTPFirewallRuleGroupId, req.SourceHTTPFirewallRuleSetId) itemId, err := models.SharedIPItemDAO.CreateIPItem(tx, req.IpListId, req.IpFrom, req.IpTo, req.ExpiredAt, req.Reason, req.Type, req.EventLevel, req.NodeId, req.ServerId, req.SourceNodeId, req.SourceServerId, req.SourceHTTPFirewallPolicyId, req.SourceHTTPFirewallRuleGroupId, req.SourceHTTPFirewallRuleSetId, true)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -72,6 +72,77 @@ func (this *IPItemService) CreateIPItem(ctx context.Context, req *pb.CreateIPIte
return &pb.CreateIPItemResponse{IpItemId: itemId}, nil return &pb.CreateIPItemResponse{IpItemId: itemId}, nil
} }
// CreateIPItems 创建一组IP
func (this *IPItemService) CreateIPItems(ctx context.Context, req *pb.CreateIPItemsRequest) (*pb.CreateIPItemsResponse, error) {
// 校验请求
userType, _, userId, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin, rpcutils.UserTypeUser, rpcutils.UserTypeNode, rpcutils.UserTypeDNS)
if err != nil {
return nil, err
}
var tx = this.NullTx()
// 校验
for _, item := range req.IpItems {
if len(item.IpFrom) == 0 {
return nil, errors.New("'ipFrom' should not be empty")
}
var ipFrom = net.ParseIP(item.IpFrom)
if ipFrom == nil {
return nil, errors.New("invalid 'ipFrom'")
}
if len(item.IpTo) > 0 {
ipTo := net.ParseIP(item.IpTo)
if ipTo == nil {
return nil, errors.New("invalid 'ipTo'")
}
}
if userType == rpcutils.UserTypeUser {
if userId <= 0 {
return nil, errors.New("invalid userId")
} else {
err = models.SharedIPListDAO.CheckUserIPList(tx, userId, item.IpListId)
if err != nil {
return nil, err
}
}
}
if len(item.Type) == 0 {
item.Type = models.IPItemTypeIPv4
}
}
// 创建
// TODO 需要区分不同的用户
var ipItemIds = []int64{}
for index, item := range req.IpItems {
var shouldNotify = index == len(req.IpItems)-1
// 删除以前的
err = models.SharedIPItemDAO.DeleteOldItem(tx, item.IpListId, item.IpFrom, item.IpTo)
if err != nil {
return nil, err
}
itemId, err := models.SharedIPItemDAO.CreateIPItem(tx, item.IpListId, item.IpFrom, item.IpTo, item.ExpiredAt, item.Reason, item.Type, item.EventLevel, item.NodeId, item.ServerId, item.SourceNodeId, item.SourceServerId, item.SourceHTTPFirewallPolicyId, item.SourceHTTPFirewallRuleGroupId, item.SourceHTTPFirewallRuleSetId, shouldNotify)
if err != nil {
return nil, err
}
if err != nil {
return nil, err
}
ipItemIds = append(ipItemIds, itemId)
}
return &pb.CreateIPItemsResponse{
IpItemIds: ipItemIds,
}, nil
}
// UpdateIPItem 修改IP // UpdateIPItem 修改IP
func (this *IPItemService) UpdateIPItem(ctx context.Context, req *pb.UpdateIPItemRequest) (*pb.RPCSuccess, error) { func (this *IPItemService) UpdateIPItem(ctx context.Context, req *pb.UpdateIPItemRequest) (*pb.RPCSuccess, error) {
// 校验请求 // 校验请求
@@ -118,19 +189,7 @@ func (this *IPItemService) DeleteIPItem(ctx context.Context, req *pb.DeleteIPIte
// 如果是使用IPItemId删除 // 如果是使用IPItemId删除
if req.IpItemId > 0 { if req.IpItemId > 0 {
if userId > 0 { err = models.SharedIPItemDAO.DisableIPItem(tx, req.IpItemId, userId)
listId, err := models.SharedIPItemDAO.FindItemListId(tx, req.IpItemId)
if err != nil {
return nil, err
}
err = models.SharedIPListDAO.CheckUserIPList(tx, userId, listId)
if err != nil {
return nil, err
}
}
err = models.SharedIPItemDAO.DisableIPItem(tx, req.IpItemId)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -139,7 +198,7 @@ func (this *IPItemService) DeleteIPItem(ctx context.Context, req *pb.DeleteIPIte
// 如果是使用ipFrom+ipTo删除 // 如果是使用ipFrom+ipTo删除
if len(req.IpFrom) > 0 { if len(req.IpFrom) > 0 {
// 检查IP列表 // 检查IP列表
if req.IpListId > 0 && userId > 0 { if req.IpListId > 0 && userId > 0 && req.IpListId != firewallconfigs.GlobalListId {
err = models.SharedIPListDAO.CheckUserIPList(tx, userId, req.IpListId) err = models.SharedIPListDAO.CheckUserIPList(tx, userId, req.IpListId)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -157,14 +216,14 @@ func (this *IPItemService) DeleteIPItem(ctx context.Context, req *pb.DeleteIPIte
// DeleteIPItems 批量删除IP // DeleteIPItems 批量删除IP
func (this *IPItemService) DeleteIPItems(ctx context.Context, req *pb.DeleteIPItemsRequest) (*pb.RPCSuccess, error) { func (this *IPItemService) DeleteIPItems(ctx context.Context, req *pb.DeleteIPItemsRequest) (*pb.RPCSuccess, error) {
_, err := this.ValidateAdmin(ctx) _, userId, err := this.ValidateAdminAndUser(ctx, true)
if err != nil { if err != nil {
return nil, err return nil, err
} }
var tx = this.NullTx() var tx = this.NullTx()
for _, itemId := range req.IpItemIds { for _, itemId := range req.IpItemIds {
err = models.SharedIPItemDAO.DisableIPItem(tx, itemId) err = models.SharedIPItemDAO.DisableIPItem(tx, itemId, userId)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -183,13 +242,16 @@ func (this *IPItemService) CountIPItemsWithListId(ctx context.Context, req *pb.C
var tx = this.NullTx() var tx = this.NullTx()
if userId > 0 { if userId > 0 {
err = models.SharedIPListDAO.CheckUserIPList(tx, userId, req.IpListId) // 检查用户所属名单
if err != nil { if req.IpListId != firewallconfigs.GlobalListId {
return nil, err err = models.SharedIPListDAO.CheckUserIPList(tx, userId, req.IpListId)
if err != nil {
return nil, err
}
} }
} }
count, err := models.SharedIPItemDAO.CountIPItemsWithListId(tx, req.IpListId, req.Keyword, req.IpFrom, req.IpTo, req.EventLevel) count, err := models.SharedIPItemDAO.CountIPItemsWithListId(tx, req.IpListId, userId, req.Keyword, req.IpFrom, req.IpTo, req.EventLevel)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -207,13 +269,16 @@ func (this *IPItemService) ListIPItemsWithListId(ctx context.Context, req *pb.Li
var tx = this.NullTx() var tx = this.NullTx()
if userId > 0 { if userId > 0 {
err = models.SharedIPListDAO.CheckUserIPList(tx, userId, req.IpListId) // 检查用户所属名单
if err != nil { if req.IpListId != firewallconfigs.GlobalListId {
return nil, err err = models.SharedIPListDAO.CheckUserIPList(tx, userId, req.IpListId)
if err != nil {
return nil, err
}
} }
} }
items, err := models.SharedIPItemDAO.ListIPItemsWithListId(tx, req.IpListId, req.Keyword, req.IpFrom, req.IpTo, req.EventLevel, req.Offset, req.Size) items, err := models.SharedIPItemDAO.ListIPItemsWithListId(tx, req.IpListId, userId, req.Keyword, req.IpFrom, req.IpTo, req.EventLevel, req.Offset, req.Size)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -493,17 +558,21 @@ func (this *IPItemService) ExistsEnabledIPItem(ctx context.Context, req *pb.Exis
// CountAllEnabledIPItems 计算所有IP数量 // CountAllEnabledIPItems 计算所有IP数量
func (this *IPItemService) CountAllEnabledIPItems(ctx context.Context, req *pb.CountAllEnabledIPItemsRequest) (*pb.RPCCountResponse, error) { func (this *IPItemService) CountAllEnabledIPItems(ctx context.Context, req *pb.CountAllEnabledIPItemsRequest) (*pb.RPCCountResponse, error) {
_, err := this.ValidateAdmin(ctx) adminId, userId, err := this.ValidateAdminAndUser(ctx, true)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if adminId > 0 {
userId = req.UserId
}
var tx = this.NullTx() var tx = this.NullTx()
var listId int64 = 0 var listId int64 = 0
if req.GlobalOnly { if req.GlobalOnly {
listId = firewallconfigs.GlobalListId listId = firewallconfigs.GlobalListId
} }
count, err := models.SharedIPItemDAO.CountAllEnabledIPItems(tx, req.Keyword, req.Ip, listId, req.Unread, req.EventLevel, req.ListType) count, err := models.SharedIPItemDAO.CountAllEnabledIPItems(tx, userId, req.Keyword, req.Ip, listId, req.Unread, req.EventLevel, req.ListType)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -512,18 +581,22 @@ func (this *IPItemService) CountAllEnabledIPItems(ctx context.Context, req *pb.C
// ListAllEnabledIPItems 搜索IP // ListAllEnabledIPItems 搜索IP
func (this *IPItemService) ListAllEnabledIPItems(ctx context.Context, req *pb.ListAllEnabledIPItemsRequest) (*pb.ListAllEnabledIPItemsResponse, error) { func (this *IPItemService) ListAllEnabledIPItems(ctx context.Context, req *pb.ListAllEnabledIPItemsRequest) (*pb.ListAllEnabledIPItemsResponse, error) {
_, err := this.ValidateAdmin(ctx) adminId, userId, err := this.ValidateAdminAndUser(ctx, true)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if adminId > 0 {
userId = req.UserId
}
var results = []*pb.ListAllEnabledIPItemsResponse_Result{} var results = []*pb.ListAllEnabledIPItemsResponse_Result{}
var tx = this.NullTx() var tx = this.NullTx()
var listId int64 = 0 var listId int64 = 0
if req.GlobalOnly { if req.GlobalOnly {
listId = firewallconfigs.GlobalListId listId = firewallconfigs.GlobalListId
} }
items, err := models.SharedIPItemDAO.ListAllEnabledIPItems(tx, req.Keyword, req.Ip, listId, req.Unread, req.EventLevel, req.ListType, req.Offset, req.Size) items, err := models.SharedIPItemDAO.ListAllEnabledIPItems(tx, userId, req.Keyword, req.Ip, listId, req.Unread, req.EventLevel, req.ListType, req.Offset, req.Size)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -632,7 +705,7 @@ func (this *IPItemService) ListAllEnabledIPItems(ctx context.Context, req *pb.Li
return nil, err return nil, err
} }
if list == nil { if list == nil {
err = models.SharedIPItemDAO.DisableIPItem(tx, int64(item.Id)) err = models.SharedIPItemDAO.DisableIPItem(tx, int64(item.Id), 0)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -657,7 +730,7 @@ func (this *IPItemService) ListAllEnabledIPItems(ctx context.Context, req *pb.Li
return nil, err return nil, err
} }
if policy == nil { if policy == nil {
err = models.SharedIPItemDAO.DisableIPItem(tx, int64(item.Id)) err = models.SharedIPItemDAO.DisableIPItem(tx, int64(item.Id), 0)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -697,13 +770,13 @@ func (this *IPItemService) ListAllEnabledIPItems(ctx context.Context, req *pb.Li
// UpdateIPItemsRead 设置所有为已读 // UpdateIPItemsRead 设置所有为已读
func (this *IPItemService) UpdateIPItemsRead(ctx context.Context, req *pb.UpdateIPItemsReadRequest) (*pb.RPCSuccess, error) { func (this *IPItemService) UpdateIPItemsRead(ctx context.Context, req *pb.UpdateIPItemsReadRequest) (*pb.RPCSuccess, error) {
_, err := this.ValidateAdmin(ctx) _, userId, err := this.ValidateAdminAndUser(ctx, true)
if err != nil { if err != nil {
return nil, err return nil, err
} }
var tx = this.NullTx() var tx = this.NullTx()
err = models.SharedIPItemDAO.UpdateItemsRead(tx) err = models.SharedIPItemDAO.UpdateItemsRead(tx, userId)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@@ -195,6 +195,9 @@ func (this *IPLibraryService) LookupIPRegion(ctx context.Context, req *pb.Lookup
Isp: result.ProviderName(), Isp: result.ProviderName(),
CountryId: result.CountryId(), CountryId: result.CountryId(),
ProvinceId: result.ProvinceId(), ProvinceId: result.ProvinceId(),
CityId: result.CityId(),
TownId: result.TownId(),
ProviderId: result.ProviderId(),
Summary: result.Summary(), Summary: result.Summary(),
}}, nil }}, nil
} }
@@ -213,12 +216,17 @@ func (this *IPLibraryService) LookupIPRegions(ctx context.Context, req *pb.Looku
var info = iplibrary.LookupIP(ip) var info = iplibrary.LookupIP(ip)
if info != nil && info.IsOk() { if info != nil && info.IsOk() {
result[ip] = &pb.IPRegion{ result[ip] = &pb.IPRegion{
Country: info.CountryName(), Country: info.CountryName(),
Region: "", Region: "",
Province: info.ProvinceName(), Province: info.ProvinceName(),
City: info.CityName(), City: info.CityName(),
Isp: info.ProviderName(), Isp: info.ProviderName(),
Summary: info.Summary(), CountryId: info.CountryId(),
ProvinceId: info.ProvinceId(),
CityId: info.CityId(),
TownId: info.TownId(),
ProviderId: info.ProviderId(),
Summary: info.Summary(),
} }
} }
} }

View File

@@ -73,6 +73,20 @@ func (this *IPLibraryArtifactService) FindAllIPLibraryArtifacts(ctx context.Cont
var pbArtifacts = []*pb.IPLibraryArtifact{} var pbArtifacts = []*pb.IPLibraryArtifact{}
for _, artifact := range artifacts { for _, artifact := range artifacts {
var pbFile *pb.File
if artifact.FileId > 0 {
fileInfo, err := models.SharedFileDAO.FindEnabledFile(tx, int64(artifact.FileId))
if err != nil {
return nil, err
}
if fileInfo != nil {
pbFile = &pb.File{
Id: int64(fileInfo.Id),
Size: int64(fileInfo.Size),
}
}
}
pbArtifacts = append(pbArtifacts, &pb.IPLibraryArtifact{ pbArtifacts = append(pbArtifacts, &pb.IPLibraryArtifact{
Id: int64(artifact.Id), Id: int64(artifact.Id),
Name: artifact.Name, Name: artifact.Name,
@@ -81,6 +95,7 @@ func (this *IPLibraryArtifactService) FindAllIPLibraryArtifacts(ctx context.Cont
MetaJSON: artifact.Meta, MetaJSON: artifact.Meta,
IsPublic: artifact.IsPublic, IsPublic: artifact.IsPublic,
Code: artifact.Code, Code: artifact.Code,
File: pbFile,
}) })
} }
return &pb.FindAllIPLibraryArtifactsResponse{ return &pb.FindAllIPLibraryArtifactsResponse{

View File

@@ -70,6 +70,7 @@ func (this *IPLibraryFileService) FindAllFinishedIPLibraryFiles(ctx context.Cont
CreatedAt: int64(libraryFile.CreatedAt), CreatedAt: int64(libraryFile.CreatedAt),
GeneratedFileId: int64(libraryFile.GeneratedFileId), GeneratedFileId: int64(libraryFile.GeneratedFileId),
GeneratedAt: int64(libraryFile.GeneratedAt), GeneratedAt: int64(libraryFile.GeneratedAt),
Password: libraryFile.Password,
CountryNames: pbCountryNames, CountryNames: pbCountryNames,
Provinces: pbProvinces, Provinces: pbProvinces,
Cities: pbCities, Cities: pbCities,
@@ -133,6 +134,7 @@ func (this *IPLibraryFileService) FindAllUnfinishedIPLibraryFiles(ctx context.Co
FileId: int64(libraryFile.FileId), FileId: int64(libraryFile.FileId),
IsFinished: libraryFile.IsFinished, IsFinished: libraryFile.IsFinished,
CreatedAt: int64(libraryFile.CreatedAt), CreatedAt: int64(libraryFile.CreatedAt),
Password: libraryFile.Password,
CountryNames: pbCountryNames, CountryNames: pbCountryNames,
Provinces: pbProvinces, Provinces: pbProvinces,
Cities: pbCities, Cities: pbCities,
@@ -204,6 +206,7 @@ func (this *IPLibraryFileService) FindIPLibraryFile(ctx context.Context, req *pb
IsFinished: libraryFile.IsFinished, IsFinished: libraryFile.IsFinished,
CreatedAt: int64(libraryFile.CreatedAt), CreatedAt: int64(libraryFile.CreatedAt),
GeneratedFileId: int64(libraryFile.GeneratedFileId), GeneratedFileId: int64(libraryFile.GeneratedFileId),
Password: libraryFile.Password,
CountryNames: pbCountryNames, CountryNames: pbCountryNames,
Provinces: pbProvinces, Provinces: pbProvinces,
Cities: pbCities, Cities: pbCities,
@@ -252,7 +255,7 @@ func (this *IPLibraryFileService) CreateIPLibraryFile(ctx context.Context, req *
} }
var tx = this.NullTx() var tx = this.NullTx()
libraryFileId, err := models.SharedIPLibraryFileDAO.CreateLibraryFile(tx, req.Name, req.Template, req.EmptyValues, req.FileId, countries, provinces, cities, towns, providers) libraryFileId, err := models.SharedIPLibraryFileDAO.CreateLibraryFile(tx, req.Name, req.Template, req.EmptyValues, req.Password, req.FileId, countries, provinces, cities, towns, providers)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@@ -5,6 +5,7 @@ import (
"github.com/TeaOSLab/EdgeAPI/internal/db/models" "github.com/TeaOSLab/EdgeAPI/internal/db/models"
"github.com/TeaOSLab/EdgeAPI/internal/utils" "github.com/TeaOSLab/EdgeAPI/internal/utils"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
"github.com/iwind/TeaGo/lists" "github.com/iwind/TeaGo/lists"
) )
@@ -68,9 +69,12 @@ func (this *IPListService) FindEnabledIPList(ctx context.Context, req *pb.FindEn
var tx = this.NullTx() var tx = this.NullTx()
if userId > 0 { if userId > 0 {
err = models.SharedIPListDAO.CheckUserIPList(tx, userId, req.IpListId) // 检查用户所属名单
if err != nil { if req.IpListId != firewallconfigs.GlobalListId {
return nil, err err = models.SharedIPListDAO.CheckUserIPList(tx, userId, req.IpListId)
if err != nil {
return nil, err
}
} }
} }

View File

@@ -39,7 +39,7 @@ func (this *LogService) CountLogs(ctx context.Context, req *pb.CountLogRequest)
var tx = this.NullTx() var tx = this.NullTx()
count, err := models.SharedLogDAO.CountLogs(tx, req.DayFrom, req.DayTo, req.Keyword, req.UserType) count, err := models.SharedLogDAO.CountLogs(tx, req.DayFrom, req.DayTo, req.Keyword, req.UserType, req.Level)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -56,7 +56,7 @@ func (this *LogService) ListLogs(ctx context.Context, req *pb.ListLogsRequest) (
var tx = this.NullTx() var tx = this.NullTx()
logs, err := models.SharedLogDAO.ListLogs(tx, req.Offset, req.Size, req.DayFrom, req.DayTo, req.Keyword, req.UserType) logs, err := models.SharedLogDAO.ListLogs(tx, req.Offset, req.Size, req.DayFrom, req.DayTo, req.Keyword, req.UserType, req.Level)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@@ -14,26 +14,6 @@ type LoginSessionService struct {
BaseService BaseService
} }
// CreateLoginSession 创建SESSION
func (this *LoginSessionService) CreateLoginSession(ctx context.Context, req *pb.CreateLoginSessionRequest) (*pb.RPCSuccess, error) {
if len(req.Sid) == 0 {
return nil, errors.New("'sid' should not be empty")
}
_, _, err := this.ValidateAdminAndUser(ctx, false)
if err != nil {
return nil, err
}
var tx = this.NullTx()
_, err = models.SharedLoginSessionDAO.CreateSession(tx, req.Sid, req.Ip, req.ExpiresAt)
if err != nil {
return nil, err
}
return this.Success()
}
// WriteLoginSessionValue 写入SESSION数据 // WriteLoginSessionValue 写入SESSION数据
func (this *LoginSessionService) WriteLoginSessionValue(ctx context.Context, req *pb.WriteLoginSessionValueRequest) (*pb.RPCSuccess, error) { func (this *LoginSessionService) WriteLoginSessionValue(ctx context.Context, req *pb.WriteLoginSessionValueRequest) (*pb.RPCSuccess, error) {
_, _, err := this.ValidateAdminAndUser(ctx, false) _, _, err := this.ValidateAdminAndUser(ctx, false)

View File

@@ -225,6 +225,10 @@ func (this *NodeService) ListEnabledNodesMatch(ctx context.Context, req *pb.List
order = "loadAsc" order = "loadAsc"
} else if req.LoadDesc { } else if req.LoadDesc {
order = "loadDesc" order = "loadDesc"
} else if req.ConnectionsAsc {
order = "connectionsAsc"
} else if req.ConnectionsDesc {
order = "connectionsDesc"
} }
nodes, err := models.SharedNodeDAO.ListEnabledNodesMatch(tx, req.NodeClusterId, configutils.ToBoolState(req.InstallState), configutils.ToBoolState(req.ActiveState), req.Keyword, req.NodeGroupId, req.NodeRegionId, req.Level, true, order, req.Offset, req.Size) nodes, err := models.SharedNodeDAO.ListEnabledNodesMatch(tx, req.NodeClusterId, configutils.ToBoolState(req.InstallState), configutils.ToBoolState(req.ActiveState), req.Keyword, req.NodeGroupId, req.NodeRegionId, req.Level, true, order, req.Offset, req.Size)
@@ -740,34 +744,66 @@ func (this *NodeService) FindCurrentNodeConfig(ctx context.Context, req *pb.Find
return nil, err return nil, err
} }
var cacheMap = this.findClusterCacheMap(clusterId, req.NodeTaskVersion) var cacheMap = this.findClusterCacheMap(clusterId, req.NodeTaskVersion)
nodeConfig, err := models.SharedNodeDAO.ComposeNodeConfig(tx, nodeId, cacheMap) var dataMap *shared.DataMap
if err != nil { if req.UseDataMap {
return nil, err // 是否有共用的
} if cacheMap != nil {
cachedDataMap, ok := cacheMap.Get("DataMap")
if ok {
dataMap = cachedDataMap.(*shared.DataMap)
}
}
data, err := json.Marshal(nodeConfig) if dataMap == nil {
dataMap = shared.NewDataMap()
}
} else {
// 如果没有使用DataMap但是获取的缓存是有DataMap的需要重新获取
_, ok := cacheMap.Get("DataMap")
if ok {
cacheMap = nil
}
}
nodeConfig, err := models.SharedNodeDAO.ComposeNodeConfig(tx, nodeId, dataMap, cacheMap)
if err != nil { if err != nil {
return nil, err return nil, err
} }
// 压缩 // 压缩
var data []byte
var isCompressed = false var isCompressed = false
var buffer = &bytes.Buffer{}
var writer io.Writer = buffer
var brotliWriter *brotli.Writer
if req.Compress { if req.Compress {
var buf = &bytes.Buffer{} brotliWriter = brotli.NewWriterLevel(writer, 5)
writer := brotli.NewWriterLevel(buf, 5) writer = brotliWriter
_, err = writer.Write(data) }
if err != nil {
_ = writer.Close() var encoder = json.NewEncoder(writer)
err = encoder.Encode(nodeConfig)
if err != nil {
return nil, err
}
if brotliWriter != nil {
err = brotliWriter.Close()
if err == nil {
data = buffer.Bytes()
isCompressed = true
} else { } else {
err = writer.Close() // 如果失败,则使用最直接方法重新编码
if err == nil { data, err = json.Marshal(nodeConfig)
isCompressed = true if err != nil {
data = buf.Bytes() return nil, err
buf.Reset()
} }
} }
} else {
data = buffer.Bytes()
} }
buffer.Reset()
return &pb.FindCurrentNodeConfigResponse{ return &pb.FindCurrentNodeConfigResponse{
IsChanged: true, IsChanged: true,
NodeJSON: data, NodeJSON: data,
@@ -808,6 +844,7 @@ func (this *NodeService) UpdateNodeStatus(ctx context.Context, req *pb.UpdateNod
if err != nil { if err != nil {
return nil, err return nil, err
} }
return this.Success() return this.Success()
} }
@@ -1317,7 +1354,7 @@ func (this *NodeService) FindAllEnabledNodesDNSWithNodeClusterId(ctx context.Con
return nil, err return nil, err
} }
nodes, err := models.SharedNodeDAO.FindAllEnabledNodesDNSWithClusterId(tx, req.NodeClusterId, true, dnsConfig != nil && dnsConfig.IncludingLnNodes) nodes, err := models.SharedNodeDAO.FindAllEnabledNodesDNSWithClusterId(tx, req.NodeClusterId, true, dnsConfig != nil && dnsConfig.IncludingLnNodes, req.IsInstalled)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -2203,3 +2240,39 @@ func (this *NodeService) UpdateNodeAPIConfig(ctx context.Context, req *pb.Update
return this.Success() return this.Success()
} }
// FindNodeUAMPolicies 查找节点的UAM策略
func (this *NodeService) FindNodeUAMPolicies(ctx context.Context, req *pb.FindNodeUAMPoliciesRequest) (*pb.FindNodeUAMPoliciesResponse, error) {
nodeId, err := this.ValidateNode(ctx)
if err != nil {
return nil, err
}
var tx = this.NullTx()
clusterIds, err := models.SharedNodeDAO.FindEnabledAndOnNodeClusterIds(tx, nodeId)
if err != nil {
return nil, err
}
var pbPolicies = []*pb.FindNodeUAMPoliciesResponse_UAMPolicy{}
for _, clusterId := range clusterIds {
policy, err := models.SharedNodeClusterDAO.FindClusterUAMPolicy(tx, clusterId, nil)
if err != nil {
return nil, err
}
if policy == nil {
continue
}
policyJSON, err := json.Marshal(policy)
if err != nil {
return nil, err
}
pbPolicies = append(pbPolicies, &pb.FindNodeUAMPoliciesResponse_UAMPolicy{
NodeClusterId: clusterId,
UamPolicyJSON: policyJSON,
})
}
return &pb.FindNodeUAMPoliciesResponse{
UamPolicies: pbPolicies,
}, nil
}

View File

@@ -642,12 +642,28 @@ func (this *NodeClusterService) FindAllEnabledNodeClustersWithDNSDomainId(ctx co
result := []*pb.NodeCluster{} result := []*pb.NodeCluster{}
for _, cluster := range clusters { for _, cluster := range clusters {
// 默认线路
domainId := int64(cluster.DnsDomainId)
domain, err := dns.SharedDNSDomainDAO.FindEnabledDNSDomain(tx, domainId, nil)
if err != nil {
return nil, err
}
if domain == nil {
continue
}
defaultRoute, err := dnsutils.FindDefaultDomainRoute(tx, domain)
if err != nil {
return nil, err
}
result = append(result, &pb.NodeCluster{ result = append(result, &pb.NodeCluster{
Id: int64(cluster.Id), Id: int64(cluster.Id),
Name: cluster.Name, Name: cluster.Name,
DnsName: cluster.DnsName, DnsName: cluster.DnsName,
DnsDomainId: int64(cluster.DnsDomainId), DnsDomainId: int64(cluster.DnsDomainId),
IsOn: cluster.IsOn, DnsDefaultRoute: defaultRoute,
IsOn: cluster.IsOn,
}) })
} }
return &pb.FindAllEnabledNodeClustersWithDNSDomainIdResponse{NodeClusters: result}, nil return &pb.FindAllEnabledNodeClustersWithDNSDomainIdResponse{NodeClusters: result}, nil

View File

@@ -211,7 +211,7 @@ func (this *OriginService) FindEnabledOriginConfig(ctx context.Context, req *pb.
} }
} }
config, err := models.SharedOriginDAO.ComposeOriginConfig(tx, req.OriginId, nil) config, err := models.SharedOriginDAO.ComposeOriginConfig(tx, req.OriginId, nil, nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@@ -86,7 +86,7 @@ func (this *ReverseProxyService) FindEnabledReverseProxyConfig(ctx context.Conte
var tx = this.NullTx() var tx = this.NullTx()
config, err := models.SharedReverseProxyDAO.ComposeReverseProxyConfig(tx, req.ReverseProxyId, nil) config, err := models.SharedReverseProxyDAO.ComposeReverseProxyConfig(tx, req.ReverseProxyId, nil, nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@@ -37,17 +37,22 @@ func (this *ServerService) CreateServer(ctx context.Context, req *pb.CreateServe
req.UserId = userId req.UserId = userId
} }
// 修复一个单词拼写错误
if len(req.ServerNamesJON) > 0 && len(req.ServerNamesJSON) == 0 {
req.ServerNamesJSON = req.ServerNamesJON
}
// 校验用户相关数据 // 校验用户相关数据
if userId > 0 { if userId > 0 {
// HTTPS // HTTPS
if len(req.HttpsJSON) > 0 { if len(req.HttpsJSON) > 0 {
httpsConfig := &serverconfigs.HTTPSProtocolConfig{} var httpsConfig = &serverconfigs.HTTPSProtocolConfig{}
err = json.Unmarshal(req.HttpsJSON, httpsConfig) err = json.Unmarshal(req.HttpsJSON, httpsConfig)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if httpsConfig.SSLPolicyRef != nil && httpsConfig.SSLPolicyRef.SSLPolicyId > 0 { if httpsConfig.SSLPolicyRef != nil && httpsConfig.SSLPolicyRef.SSLPolicyId > 0 {
err := models.SharedSSLPolicyDAO.CheckUserPolicy(tx, userId, httpsConfig.SSLPolicyRef.SSLPolicyId) err = models.SharedSSLPolicyDAO.CheckUserPolicy(tx, userId, httpsConfig.SSLPolicyRef.SSLPolicyId)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -56,13 +61,13 @@ func (this *ServerService) CreateServer(ctx context.Context, req *pb.CreateServe
// TLS // TLS
if len(req.TlsJSON) > 0 { if len(req.TlsJSON) > 0 {
tlsConfig := &serverconfigs.TLSProtocolConfig{} var tlsConfig = &serverconfigs.TLSProtocolConfig{}
err = json.Unmarshal(req.TlsJSON, tlsConfig) err = json.Unmarshal(req.TlsJSON, tlsConfig)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if tlsConfig.SSLPolicyRef != nil && tlsConfig.SSLPolicyRef.SSLPolicyId > 0 { if tlsConfig.SSLPolicyRef != nil && tlsConfig.SSLPolicyRef.SSLPolicyId > 0 {
err := models.SharedSSLPolicyDAO.CheckUserPolicy(tx, userId, tlsConfig.SSLPolicyRef.SSLPolicyId) err = models.SharedSSLPolicyDAO.CheckUserPolicy(tx, userId, tlsConfig.SSLPolicyRef.SSLPolicyId)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -103,9 +108,9 @@ func (this *ServerService) CreateServer(ctx context.Context, req *pb.CreateServe
} }
// 是否需要审核 // 是否需要审核
isAuditing := false var isAuditing = false
serverNamesJSON := req.ServerNamesJON var serverNamesJSON = req.ServerNamesJSON
auditingServerNamesJSON := []byte("[]") var auditingServerNamesJSON = []byte("[]")
if userId > 0 { if userId > 0 {
// 如果域名不为空的时候需要审核 // 如果域名不为空的时候需要审核
if len(serverNamesJSON) > 0 && string(serverNamesJSON) != "[]" { if len(serverNamesJSON) > 0 && string(serverNamesJSON) != "[]" {
@@ -116,7 +121,7 @@ func (this *ServerService) CreateServer(ctx context.Context, req *pb.CreateServe
if globalConfig != nil && globalConfig.HTTPAll.DomainAuditingIsOn { if globalConfig != nil && globalConfig.HTTPAll.DomainAuditingIsOn {
isAuditing = true isAuditing = true
serverNamesJSON = []byte("[]") serverNamesJSON = []byte("[]")
auditingServerNamesJSON = req.ServerNamesJON auditingServerNamesJSON = req.ServerNamesJSON
} }
} }
} }
@@ -159,6 +164,18 @@ func (this *ServerService) CreateServer(ctx context.Context, req *pb.CreateServe
} }
} }
// 域名
if len(req.Name) == 0 && len(req.ServerNamesJSON) > 0 {
var serverNames = []*serverconfigs.ServerNameConfig{}
err = json.Unmarshal(req.ServerNamesJSON, &serverNames)
if err != nil {
return nil, errors.New("decode server names failed: " + err.Error())
}
if len(serverNames) > 0 {
req.Name = serverNames[0].FirstName()
}
}
serverId, err := models.SharedServerDAO.CreateServer(tx, req.AdminId, req.UserId, req.Type, req.Name, req.Description, serverNamesJSON, isAuditing, auditingServerNamesJSON, req.HttpJSON, req.HttpsJSON, req.TcpJSON, req.TlsJSON, req.UnixJSON, req.UdpJSON, req.WebId, req.ReverseProxyJSON, req.NodeClusterId, req.IncludeNodesJSON, req.ExcludeNodesJSON, req.ServerGroupIds, req.UserPlanId) serverId, err := models.SharedServerDAO.CreateServer(tx, req.AdminId, req.UserId, req.Type, req.Name, req.Description, serverNamesJSON, isAuditing, auditingServerNamesJSON, req.HttpJSON, req.HttpsJSON, req.TcpJSON, req.TlsJSON, req.UnixJSON, req.UdpJSON, req.WebId, req.ReverseProxyJSON, req.NodeClusterId, req.IncludeNodesJSON, req.ExcludeNodesJSON, req.ServerGroupIds, req.UserPlanId)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -845,7 +862,7 @@ func (this *ServerService) ListEnabledServersMatch(ctx context.Context, req *pb.
} }
// 配置 // 配置
config, err := models.SharedServerDAO.ComposeServerConfig(tx, server, req.IgnoreSSLCerts, nil, false, true) config, err := models.SharedServerDAO.ComposeServerConfig(tx, server, req.IgnoreSSLCerts, nil, nil, false, true)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -899,6 +916,7 @@ func (this *ServerService) ListEnabledServersMatch(ctx context.Context, req *pb.
Name: clusterName, Name: clusterName,
}, },
ServerGroups: pbGroups, ServerGroups: pbGroups,
UserId: int64(server.UserId),
User: pbUser, User: pbUser,
BandwidthTime: server.BandwidthTime, BandwidthTime: server.BandwidthTime,
BandwidthBytes: int64(server.BandwidthBytes), BandwidthBytes: int64(server.BandwidthBytes),
@@ -1008,7 +1026,7 @@ func (this *ServerService) FindEnabledServer(ctx context.Context, req *pb.FindEn
} }
// 配置 // 配置
config, err := models.SharedServerDAO.ComposeServerConfig(tx, server, req.IgnoreSSLCerts, nil, userId > 0, false) config, err := models.SharedServerDAO.ComposeServerConfig(tx, server, req.IgnoreSSLCerts, nil, nil, userId > 0, false)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -1046,6 +1064,7 @@ func (this *ServerService) FindEnabledServer(ctx context.Context, req *pb.FindEn
Name: clusterName, Name: clusterName,
}, },
ServerGroups: pbGroups, ServerGroups: pbGroups,
UserId: int64(server.UserId),
User: pbUser, User: pbUser,
}}, nil }}, nil
} }
@@ -1144,7 +1163,7 @@ func (this *ServerService) FindAndInitServerReverseProxyConfig(ctx context.Conte
} }
} }
reverseProxyConfig, err := models.SharedReverseProxyDAO.ComposeReverseProxyConfig(tx, reverseProxyRef.ReverseProxyId, nil) reverseProxyConfig, err := models.SharedReverseProxyDAO.ComposeReverseProxyConfig(tx, reverseProxyRef.ReverseProxyId, nil, nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -1191,7 +1210,7 @@ func (this *ServerService) FindAndInitServerWebConfig(ctx context.Context, req *
} }
} }
config, err := models.SharedHTTPWebDAO.ComposeWebConfig(tx, webId, nil) config, err := models.SharedHTTPWebDAO.ComposeWebConfig(tx, webId, false, false, nil, nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -1297,6 +1316,16 @@ func (this *ServerService) CountAllEnabledServersWithServerGroupId(ctx context.C
} }
var tx = this.NullTx() var tx = this.NullTx()
if userId <= 0 {
// 指定用户ID可以加快查询速度
groupUserId, err := models.SharedServerGroupDAO.FindGroupUserId(tx, req.ServerGroupId)
if err != nil {
return nil, err
}
if groupUserId > 0 {
userId = groupUserId
}
}
count, err := models.SharedServerDAO.CountAllEnabledServersWithGroupId(tx, req.ServerGroupId, userId) count, err := models.SharedServerDAO.CountAllEnabledServersWithGroupId(tx, req.ServerGroupId, userId)
if err != nil { if err != nil {
@@ -1519,7 +1548,7 @@ func (this *ServerService) ComposeAllUserServersConfig(ctx context.Context, req
var configs = []*serverconfigs.ServerConfig{} var configs = []*serverconfigs.ServerConfig{}
var cacheMap = utils.NewCacheMap() var cacheMap = utils.NewCacheMap()
for _, server := range servers { for _, server := range servers {
config, err := models.SharedServerDAO.ComposeServerConfig(tx, server, false, cacheMap, true, false) config, err := models.SharedServerDAO.ComposeServerConfig(tx, server, false, nil, cacheMap, true, false)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -1560,21 +1589,41 @@ func (this *ServerService) FindEnabledUserServerBasic(ctx context.Context, req *
return &pb.FindEnabledUserServerBasicResponse{Server: nil}, nil return &pb.FindEnabledUserServerBasicResponse{Server: nil}, nil
} }
// 集群
clusterName, err := models.SharedNodeClusterDAO.FindNodeClusterName(tx, int64(server.ClusterId)) clusterName, err := models.SharedNodeClusterDAO.FindNodeClusterName(tx, int64(server.ClusterId))
if err != nil { if err != nil {
return nil, err return nil, err
} }
// 分组
var pbGroups = []*pb.ServerGroup{}
for _, groupId := range server.DecodeGroupIds() {
group, err := models.SharedServerGroupDAO.FindEnabledServerGroup(tx, groupId)
if err != nil {
return nil, err
}
if group == nil {
continue
}
pbGroups = append(pbGroups, &pb.ServerGroup{
Id: groupId,
Name: group.Name,
UserId: int64(group.UserId),
})
}
return &pb.FindEnabledUserServerBasicResponse{Server: &pb.Server{ return &pb.FindEnabledUserServerBasicResponse{Server: &pb.Server{
Id: int64(server.Id), Id: int64(server.Id),
Name: server.Name, Name: server.Name,
Description: server.Description, Description: server.Description,
IsOn: server.IsOn, IsOn: server.IsOn,
Type: server.Type, Type: server.Type,
UserId: int64(server.UserId),
NodeCluster: &pb.NodeCluster{ NodeCluster: &pb.NodeCluster{
Id: int64(server.ClusterId), Id: int64(server.ClusterId),
Name: clusterName, Name: clusterName,
}, },
ServerGroups: pbGroups,
}}, nil }}, nil
} }
@@ -2242,3 +2291,121 @@ func (this *ServerService) UpdateServerUser(ctx context.Context, req *pb.UpdateS
return this.Success() return this.Success()
} }
// UpdateServerName 修改服务名称
func (this *ServerService) UpdateServerName(ctx context.Context, req *pb.UpdateServerNameRequest) (*pb.RPCSuccess, error) {
_, userId, err := this.ValidateAdminAndUser(ctx, true)
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
}
}
// 检查长度
if len(req.Name) == 0 {
return nil, errors.New("'name' should not be empty")
}
if len([]rune(req.Name)) > models.ModelServerNameMaxLength {
return nil, errors.New("'name' too long, max length: " + types.String(models.ModelServerNameMaxLength))
}
err = models.SharedServerDAO.UpdateServerName(tx, req.ServerId, req.Name)
if err != nil {
return nil, err
}
return this.Success()
}
// CopyServerConfig 在服务之间复制配置
func (this *ServerService) CopyServerConfig(ctx context.Context, req *pb.CopyServerConfigRequest) (*pb.RPCSuccess, error) {
adminId, userId, err := this.ValidateAdminAndUser(ctx, true)
if err != nil {
return nil, err
}
var tx = this.NullTx()
if req.ServerId <= 0 {
return nil, errors.New("invalid 'serverId'")
}
// 检查权限
if userId > 0 {
err = models.SharedServerDAO.CheckUserServer(tx, userId, req.ServerId)
if err != nil {
return nil, err
}
}
switch req.TargetType {
case "servers":
// 检查权限
if len(req.TargetServerIds) == 0 {
return this.Success()
}
if userId > 0 {
for _, targetServerId := range req.TargetServerIds {
err = models.SharedServerDAO.CheckUserServer(tx, userId, targetServerId)
if err != nil {
return nil, err
}
}
}
err = models.SharedServerDAO.CopyServerConfigToServers(tx, req.ServerId, req.TargetServerIds, req.ConfigCode)
if err != nil {
return nil, err
}
case "groups":
// 检查权限
if len(req.TargetServerGroupIds) == 0 {
return this.Success()
}
if userId > 0 {
for _, targetGroupId := range req.TargetServerGroupIds {
err = models.SharedServerGroupDAO.CheckUserGroup(tx, userId, targetGroupId)
if err != nil {
return nil, err
}
}
}
err = models.SharedServerDAO.CopyServerConfigToGroups(tx, req.ServerId, req.TargetServerGroupIds, req.ConfigCode)
if err != nil {
return nil, err
}
case "cluster":
// 检查权限
if adminId <= 0 {
return nil, this.PermissionError()
}
if req.TargetClusterId <= 0 {
return this.Success()
}
err = models.SharedServerDAO.CopyServerConfigToCluster(tx, req.ServerId, req.TargetClusterId, req.ConfigCode)
if err != nil {
return nil, err
}
case "user":
if userId == 0 {
userId, err = models.SharedServerDAO.FindServerUserId(tx, req.ServerId)
if err != nil {
return nil, err
}
// 此时如果用户为0则同步到未分配用户的服务
}
err = models.SharedServerDAO.CopyServerConfigToUser(tx, req.ServerId, req.TargetUserId, req.ConfigCode)
if err != nil {
return nil, err
}
}
return this.Success()
}

View File

@@ -65,7 +65,7 @@ func init() {
for _, stat := range m { for _, stat := range m {
// 更新服务的带宽峰值 // 更新服务的带宽峰值
if stat.ServerId > 0 { if stat.ServerId > 0 {
err := models.SharedServerBandwidthStatDAO.UpdateServerBandwidth(tx, stat.UserId, stat.ServerId, stat.Day, stat.TimeAt, stat.Bytes, stat.TotalBytes) err := models.SharedServerBandwidthStatDAO.UpdateServerBandwidth(tx, stat.UserId, stat.ServerId, stat.NodeRegionId, stat.Day, stat.TimeAt, stat.Bytes, stat.TotalBytes, stat.CachedBytes, stat.AttackBytes, stat.CountRequests, stat.CountCachedRequests, stat.CountAttackRequests)
if err != nil { if err != nil {
remotelogs.Error("ServerBandwidthStatService", "dump bandwidth stats failed: "+err.Error()) remotelogs.Error("ServerBandwidthStatService", "dump bandwidth stats failed: "+err.Error())
} }
@@ -78,7 +78,7 @@ func init() {
// 更新用户的带宽峰值 // 更新用户的带宽峰值
if stat.UserId > 0 { if stat.UserId > 0 {
err = models.SharedUserBandwidthStatDAO.UpdateUserBandwidth(tx, stat.UserId, stat.NodeRegionId, stat.Day, stat.TimeAt, stat.Bytes, stat.TotalBytes) err = models.SharedUserBandwidthStatDAO.UpdateUserBandwidth(tx, stat.UserId, stat.NodeRegionId, stat.Day, stat.TimeAt, stat.Bytes, stat.TotalBytes, stat.CachedBytes, stat.AttackBytes, stat.CountRequests, stat.CountCachedRequests, stat.CountAttackRequests)
if err != nil { if err != nil {
remotelogs.Error("SharedUserBandwidthStatDAO", "dump bandwidth stats failed: "+err.Error()) remotelogs.Error("SharedUserBandwidthStatDAO", "dump bandwidth stats failed: "+err.Error())
} }
@@ -127,16 +127,26 @@ func (this *ServerBandwidthStatService) UploadServerBandwidthStats(ctx context.C
if ok { if ok {
oldStat.Bytes += stat.Bytes oldStat.Bytes += stat.Bytes
oldStat.TotalBytes += stat.TotalBytes oldStat.TotalBytes += stat.TotalBytes
oldStat.CachedBytes += stat.CachedBytes
oldStat.AttackBytes += stat.AttackBytes
oldStat.CountRequests += stat.CountRequests
oldStat.CountCachedRequests += stat.CountCachedRequests
oldStat.CountAttackRequests += stat.CountAttackRequests
} else { } else {
serverBandwidthStatsMap[key] = &pb.ServerBandwidthStat{ serverBandwidthStatsMap[key] = &pb.ServerBandwidthStat{
Id: 0, Id: 0,
NodeRegionId: stat.NodeRegionId, NodeRegionId: stat.NodeRegionId,
UserId: stat.UserId, UserId: stat.UserId,
ServerId: stat.ServerId, ServerId: stat.ServerId,
Day: stat.Day, Day: stat.Day,
TimeAt: stat.TimeAt, TimeAt: stat.TimeAt,
Bytes: stat.Bytes, Bytes: stat.Bytes,
TotalBytes: stat.TotalBytes, TotalBytes: stat.TotalBytes,
CachedBytes: stat.CachedBytes,
AttackBytes: stat.AttackBytes,
CountRequests: stat.CountRequests,
CountCachedRequests: stat.CountCachedRequests,
CountAttackRequests: stat.CountAttackRequests,
} }
} }
serverBandwidthStatsLocker.Unlock() serverBandwidthStatsLocker.Unlock()

View File

@@ -239,7 +239,7 @@ func (this *ServerDailyStatService) FindLatestServerDailyStats(ctx context.Conte
if req.Days > 0 { if req.Days > 0 {
for i := int32(0); i < req.Days; i++ { for i := int32(0); i < req.Days; i++ {
dayString := timeutil.Format("Ymd", time.Now().AddDate(0, 0, -int(i))) dayString := timeutil.Format("Ymd", time.Now().AddDate(0, 0, -int(i)))
stat, err := models.SharedServerDailyStatDAO.SumDailyStat(tx, 0, req.ServerId, req.NodeRegionId, dayString, dayString) stat, err := models.SharedServerBandwidthStatDAO.SumDailyStat(tx, req.ServerId, req.NodeRegionId, dayString, dayString)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -396,7 +396,12 @@ func (this *ServerDailyStatService) SumServerDailyStats(ctx context.Context, req
req.DayTo = req.DayFrom req.DayTo = req.DayFrom
} }
stat, err := models.SharedServerDailyStatDAO.SumDailyStat(tx, req.UserId, req.ServerId, req.NodeRegionId, req.DayFrom, req.DayTo) var stat *pb.ServerDailyStat
if req.ServerId > 0 {
stat, err = models.SharedServerBandwidthStatDAO.SumDailyStat(tx, req.ServerId, req.NodeRegionId, req.DayFrom, req.DayTo)
} else {
stat, err = models.SharedUserBandwidthStatDAO.SumDailyStat(tx, req.UserId, req.NodeRegionId, req.DayFrom, req.DayTo)
}
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@@ -85,21 +85,26 @@ func (this *ServerGroupService) DeleteServerGroup(ctx context.Context, req *pb.D
// FindAllEnabledServerGroups 查询所有分组 // FindAllEnabledServerGroups 查询所有分组
func (this *ServerGroupService) FindAllEnabledServerGroups(ctx context.Context, req *pb.FindAllEnabledServerGroupsRequest) (*pb.FindAllEnabledServerGroupsResponse, error) { func (this *ServerGroupService) FindAllEnabledServerGroups(ctx context.Context, req *pb.FindAllEnabledServerGroupsRequest) (*pb.FindAllEnabledServerGroupsResponse, error) {
// 校验请求 // 校验请求
_, userId, err := this.ValidateAdminAndUser(ctx, true) adminId, userId, err := this.ValidateAdminAndUser(ctx, true)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if adminId > 0 {
userId = req.UserId
}
var tx = this.NullTx() var tx = this.NullTx()
groups, err := models.SharedServerGroupDAO.FindAllEnabledGroups(tx, userId) groups, err := models.SharedServerGroupDAO.FindAllEnabledGroups(tx, userId)
if err != nil { if err != nil {
return nil, err return nil, err
} }
result := []*pb.ServerGroup{} var result = []*pb.ServerGroup{}
for _, group := range groups { for _, group := range groups {
result = append(result, &pb.ServerGroup{ result = append(result, &pb.ServerGroup{
Id: int64(group.Id), Id: int64(group.Id),
IsOn: group.IsOn,
Name: group.Name, Name: group.Name,
}) })
} }
@@ -153,6 +158,7 @@ func (this *ServerGroupService) FindEnabledServerGroup(ctx context.Context, req
return &pb.FindEnabledServerGroupResponse{ return &pb.FindEnabledServerGroupResponse{
ServerGroup: &pb.ServerGroup{ ServerGroup: &pb.ServerGroup{
Id: int64(group.Id), Id: int64(group.Id),
IsOn: group.IsOn,
Name: group.Name, Name: group.Name,
}, },
}, nil }, nil
@@ -193,7 +199,7 @@ func (this *ServerGroupService) FindAndInitServerGroupHTTPReverseProxyConfig(ctx
} }
} }
reverseProxyConfig, err := models.SharedReverseProxyDAO.ComposeReverseProxyConfig(tx, reverseProxyRef.ReverseProxyId, nil) reverseProxyConfig, err := models.SharedReverseProxyDAO.ComposeReverseProxyConfig(tx, reverseProxyRef.ReverseProxyId, nil, nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -246,7 +252,7 @@ func (this *ServerGroupService) FindAndInitServerGroupTCPReverseProxyConfig(ctx
} }
} }
reverseProxyConfig, err := models.SharedReverseProxyDAO.ComposeReverseProxyConfig(tx, reverseProxyRef.ReverseProxyId, nil) reverseProxyConfig, err := models.SharedReverseProxyDAO.ComposeReverseProxyConfig(tx, reverseProxyRef.ReverseProxyId, nil, nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -299,7 +305,7 @@ func (this *ServerGroupService) FindAndInitServerGroupUDPReverseProxyConfig(ctx
} }
} }
reverseProxyConfig, err := models.SharedReverseProxyDAO.ComposeReverseProxyConfig(tx, reverseProxyRef.ReverseProxyId, nil) reverseProxyConfig, err := models.SharedReverseProxyDAO.ComposeReverseProxyConfig(tx, reverseProxyRef.ReverseProxyId, nil, nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -463,7 +469,7 @@ func (this *ServerGroupService) FindEnabledServerGroupConfigInfo(ctx context.Con
result.HasUDPReverseProxy = ref.IsPrior result.HasUDPReverseProxy = ref.IsPrior
} }
config, err := models.SharedServerGroupDAO.ComposeGroupConfig(tx, int64(group.Id), false, nil) config, err := models.SharedServerGroupDAO.ComposeGroupConfig(tx, int64(group.Id), false, false, nil, nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -510,7 +516,7 @@ func (this *ServerGroupService) FindAndInitServerGroupWebConfig(ctx context.Cont
} }
} }
webConfig, err := models.SharedHTTPWebDAO.ComposeWebConfig(tx, webId, nil) webConfig, err := models.SharedHTTPWebDAO.ComposeWebConfig(tx, webId, true, false, nil, nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@@ -85,13 +85,30 @@ func (this *ServerStatBoardService) ComposeServerStatNodeClusterBoard(ctx contex
} }
result.CountServers = countServers result.CountServers = countServers
// 当月总流量
monthlyTrafficStat, err := stats.SharedNodeClusterTrafficDailyStatDAO.SumDailyStat(tx, req.NodeClusterId, timeutil.Format("Ym01"), timeutil.Format("Ym31"))
if err != nil {
return nil, err
}
if monthlyTrafficStat != nil {
result.MonthlyTrafficBytes = int64(monthlyTrafficStat.Bytes)
}
// 按日流量统计 // 按日流量统计
var 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")) dailyTrafficStats, err := stats.SharedNodeClusterTrafficDailyStatDAO.FindDailyStats(tx, req.NodeClusterId, dayFrom, timeutil.Format("Ymd"))
if err != nil { if err != nil {
return nil, err return nil, err
} }
var dailyTrafficBytes int64
var lastDailyTrafficBytes int64
for _, stat := range dailyTrafficStats { for _, stat := range dailyTrafficStats {
if stat.Day == timeutil.Format("Ymd") { // 今天
dailyTrafficBytes = int64(stat.Bytes)
} else if stat.Day == timeutil.Format("Ymd", time.Now().AddDate(0, 0, -1)) {
lastDailyTrafficBytes = int64(stat.Bytes)
}
result.DailyTrafficStats = append(result.DailyTrafficStats, &pb.ComposeServerStatNodeClusterBoardResponse_DailyTrafficStat{ result.DailyTrafficStats = append(result.DailyTrafficStats, &pb.ComposeServerStatNodeClusterBoardResponse_DailyTrafficStat{
Day: stat.Day, Day: stat.Day,
Bytes: int64(stat.Bytes), Bytes: int64(stat.Bytes),
@@ -102,6 +119,8 @@ func (this *ServerStatBoardService) ComposeServerStatNodeClusterBoard(ctx contex
AttackBytes: int64(stat.AttackBytes), AttackBytes: int64(stat.AttackBytes),
}) })
} }
result.DailyTrafficBytes = dailyTrafficBytes
result.LastDailyTrafficBytes = lastDailyTrafficBytes
// 小时流量统计 // 小时流量统计
var hourFrom = timeutil.Format("YmdH", time.Now().Add(-23*time.Hour)) var hourFrom = timeutil.Format("YmdH", time.Now().Add(-23*time.Hour))
@@ -305,13 +324,30 @@ func (this *ServerStatBoardService) ComposeServerStatNodeBoard(ctx context.Conte
} }
} }
// 当月总流量
monthlyTrafficStat, err := stats.SharedNodeTrafficDailyStatDAO.SumDailyStat(tx, nodeconfigs.NodeRoleNode, req.NodeId, timeutil.Format("Ym01"), timeutil.Format("Ym31"))
if err != nil {
return nil, err
}
if monthlyTrafficStat != nil {
result.MonthlyTrafficBytes = int64(monthlyTrafficStat.Bytes)
}
// 按日流量统计 // 按日流量统计
var 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")) dailyTrafficStats, err := stats.SharedNodeTrafficDailyStatDAO.FindDailyStats(tx, "node", req.NodeId, dayFrom, timeutil.Format("Ymd"))
if err != nil { if err != nil {
return nil, err return nil, err
} }
var dailyTrafficBytes int64
var lastDailyTrafficBytes int64
for _, stat := range dailyTrafficStats { for _, stat := range dailyTrafficStats {
if stat.Day == timeutil.Format("Ymd") { // 当天
dailyTrafficBytes = int64(stat.Bytes)
} else if stat.Day == timeutil.Format("Ymd", time.Now().AddDate(0, 0, -1)) { // 昨天
lastDailyTrafficBytes = int64(stat.Bytes)
}
result.DailyTrafficStats = append(result.DailyTrafficStats, &pb.ComposeServerStatNodeBoardResponse_DailyTrafficStat{ result.DailyTrafficStats = append(result.DailyTrafficStats, &pb.ComposeServerStatNodeBoardResponse_DailyTrafficStat{
Day: stat.Day, Day: stat.Day,
Bytes: int64(stat.Bytes), Bytes: int64(stat.Bytes),
@@ -322,6 +358,8 @@ func (this *ServerStatBoardService) ComposeServerStatNodeBoard(ctx context.Conte
AttackBytes: int64(stat.AttackBytes), AttackBytes: int64(stat.AttackBytes),
}) })
} }
result.DailyTrafficBytes = dailyTrafficBytes
result.LastDailyTrafficBytes = lastDailyTrafficBytes
// 小时流量统计 // 小时流量统计
var hourFrom = timeutil.Format("YmdH", time.Now().Add(-23*time.Hour)) var hourFrom = timeutil.Format("YmdH", time.Now().Add(-23*time.Hour))
@@ -549,14 +587,14 @@ func (this *ServerStatBoardService) ComposeServerStatBoard(ctx context.Context,
// 按日流量统计 // 按日流量统计
var 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")) dailyTrafficStats, err := models.SharedServerBandwidthStatDAO.FindDailyStats(tx, req.ServerId, dayFrom, timeutil.Format("Ymd"))
if err != nil { if err != nil {
return nil, err return nil, err
} }
for _, stat := range dailyTrafficStats { for _, stat := range dailyTrafficStats {
result.DailyTrafficStats = append(result.DailyTrafficStats, &pb.ComposeServerStatBoardResponse_DailyTrafficStat{ result.DailyTrafficStats = append(result.DailyTrafficStats, &pb.ComposeServerStatBoardResponse_DailyTrafficStat{
Day: stat.Day, Day: stat.Day,
Bytes: int64(stat.Bytes), Bytes: int64(stat.TotalBytes),
CachedBytes: int64(stat.CachedBytes), CachedBytes: int64(stat.CachedBytes),
CountRequests: int64(stat.CountRequests), CountRequests: int64(stat.CountRequests),
CountCachedRequests: int64(stat.CountCachedRequests), CountCachedRequests: int64(stat.CountCachedRequests),
@@ -568,14 +606,14 @@ func (this *ServerStatBoardService) ComposeServerStatBoard(ctx context.Context,
// 小时流量统计 // 小时流量统计
var hourFrom = timeutil.Format("YmdH", time.Now().Add(-23*time.Hour)) var hourFrom = timeutil.Format("YmdH", time.Now().Add(-23*time.Hour))
var hourTo = timeutil.Format("YmdH") var hourTo = timeutil.Format("YmdH")
hourlyTrafficStats, err := models.SharedServerDailyStatDAO.FindHourlyStats(tx, req.ServerId, hourFrom, hourTo) hourlyTrafficStats, err := models.SharedServerBandwidthStatDAO.FindHourlyStats(tx, req.ServerId, hourFrom, hourTo)
if err != nil { if err != nil {
return nil, err return nil, err
} }
for _, stat := range hourlyTrafficStats { for _, stat := range hourlyTrafficStats {
result.HourlyTrafficStats = append(result.HourlyTrafficStats, &pb.ComposeServerStatBoardResponse_HourlyTrafficStat{ result.HourlyTrafficStats = append(result.HourlyTrafficStats, &pb.ComposeServerStatBoardResponse_HourlyTrafficStat{
Hour: stat.Hour, Hour: stat.Day + stat.TimeAt[:2],
Bytes: int64(stat.Bytes), Bytes: int64(stat.TotalBytes),
CachedBytes: int64(stat.CachedBytes), CachedBytes: int64(stat.CachedBytes),
CountRequests: int64(stat.CountRequests), CountRequests: int64(stat.CountRequests),
CountCachedRequests: int64(stat.CountCachedRequests), CountCachedRequests: int64(stat.CountCachedRequests),

View File

@@ -8,6 +8,7 @@ import (
"github.com/TeaOSLab/EdgeAPI/internal/errors" "github.com/TeaOSLab/EdgeAPI/internal/errors"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/sslconfigs" "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/sslconfigs"
"github.com/iwind/TeaGo/dbs"
"github.com/iwind/TeaGo/types" "github.com/iwind/TeaGo/types"
) )
@@ -16,7 +17,7 @@ type SSLCertService struct {
BaseService BaseService
} }
// CreateSSLCert 创建Cert // CreateSSLCert 创建证书
func (this *SSLCertService) CreateSSLCert(ctx context.Context, req *pb.CreateSSLCertRequest) (*pb.CreateSSLCertResponse, error) { func (this *SSLCertService) CreateSSLCert(ctx context.Context, req *pb.CreateSSLCertRequest) (*pb.CreateSSLCertResponse, error) {
// 校验请求 // 校验请求
adminId, userId, err := this.ValidateAdminAndUser(ctx, true) adminId, userId, err := this.ValidateAdminAndUser(ctx, true)
@@ -24,6 +25,11 @@ func (this *SSLCertService) CreateSSLCert(ctx context.Context, req *pb.CreateSSL
return nil, err return nil, err
} }
// 用户ID
if adminId > 0 && req.UserId > 0 {
userId = req.UserId
}
var tx = this.NullTx() var tx = this.NullTx()
if req.TimeBeginAt < 0 { if req.TimeBeginAt < 0 {
@@ -41,6 +47,39 @@ func (this *SSLCertService) CreateSSLCert(ctx context.Context, req *pb.CreateSSL
return &pb.CreateSSLCertResponse{SslCertId: certId}, nil return &pb.CreateSSLCertResponse{SslCertId: certId}, nil
} }
// CreateSSLCerts 创建一组证书
func (this *SSLCertService) CreateSSLCerts(ctx context.Context, req *pb.CreateSSLCertsRequest) (*pb.CreateSSLCertsResponse, error) {
// 校验请求
adminId, userId, err := this.ValidateAdminAndUser(ctx, true)
if err != nil {
return nil, err
}
if adminId > 0 {
if req.UserId > 0 {
userId = req.UserId
} else {
userId = 0
}
}
var certIds = []int64{}
err = this.RunTx(func(tx *dbs.Tx) error {
for _, cert := range req.SSLCerts {
certId, err := models.SharedSSLCertDAO.CreateCert(tx, adminId, userId, cert.IsOn, cert.Name, cert.Description, cert.ServerName, cert.IsCA, cert.CertData, cert.KeyData, cert.TimeBeginAt, cert.TimeEndAt, cert.DnsNames, cert.CommonNames)
if err != nil {
return err
}
certIds = append(certIds, certId)
}
return nil
})
if err != nil {
return nil, err
}
return &pb.CreateSSLCertsResponse{SslCertIds: certIds}, nil
}
// UpdateSSLCert 修改Cert // UpdateSSLCert 修改Cert
func (this *SSLCertService) UpdateSSLCert(ctx context.Context, req *pb.UpdateSSLCertRequest) (*pb.RPCSuccess, error) { func (this *SSLCertService) UpdateSSLCert(ctx context.Context, req *pb.UpdateSSLCertRequest) (*pb.RPCSuccess, error) {
// 校验请求 // 校验请求
@@ -92,7 +131,7 @@ func (this *SSLCertService) FindEnabledSSLCertConfig(ctx context.Context, req *p
} }
} }
config, err := models.SharedSSLCertDAO.ComposeCertConfig(tx, req.SslCertId, false, nil) config, err := models.SharedSSLCertDAO.ComposeCertConfig(tx, req.SslCertId, false, nil, nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -139,18 +178,20 @@ func (this *SSLCertService) DeleteSSLCert(ctx context.Context, req *pb.DeleteSSL
// CountSSLCerts 计算匹配的Cert数量 // CountSSLCerts 计算匹配的Cert数量
func (this *SSLCertService) CountSSLCerts(ctx context.Context, req *pb.CountSSLCertRequest) (*pb.RPCCountResponse, error) { func (this *SSLCertService) CountSSLCerts(ctx context.Context, req *pb.CountSSLCertRequest) (*pb.RPCCountResponse, error) {
// 校验请求 // 校验请求
_, userId, err := this.ValidateAdminAndUser(ctx, true) adminId, userId, err := this.ValidateAdminAndUser(ctx, true)
if err != nil { if err != nil {
return nil, err return nil, err
} }
var tx = this.NullTx() var tx = this.NullTx()
if userId > 0 { if adminId > 0 {
userId = req.UserId userId = req.UserId
} else if userId <= 0 {
return nil, errors.New("invalid user")
} }
count, err := models.SharedSSLCertDAO.CountCerts(tx, req.IsCA, req.IsAvailable, req.IsExpired, int64(req.ExpiringDays), req.Keyword, userId) count, err := models.SharedSSLCertDAO.CountCerts(tx, req.IsCA, req.IsAvailable, req.IsExpired, int64(req.ExpiringDays), req.Keyword, userId, req.Domains)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -161,25 +202,27 @@ func (this *SSLCertService) CountSSLCerts(ctx context.Context, req *pb.CountSSLC
// ListSSLCerts 列出单页匹配的Cert // ListSSLCerts 列出单页匹配的Cert
func (this *SSLCertService) ListSSLCerts(ctx context.Context, req *pb.ListSSLCertsRequest) (*pb.ListSSLCertsResponse, error) { func (this *SSLCertService) ListSSLCerts(ctx context.Context, req *pb.ListSSLCertsRequest) (*pb.ListSSLCertsResponse, error) {
// 校验请求 // 校验请求
_, userId, err := this.ValidateAdminAndUser(ctx, true) adminId, userId, err := this.ValidateAdminAndUser(ctx, true)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if userId > 0 { if adminId > 0 {
userId = req.UserId userId = req.UserId
} else if userId <= 0 {
return nil, errors.New("invalid user")
} }
var tx = this.NullTx() var tx = this.NullTx()
certIds, err := models.SharedSSLCertDAO.ListCertIds(tx, req.IsCA, req.IsAvailable, req.IsExpired, int64(req.ExpiringDays), req.Keyword, userId, req.Offset, req.Size) certIds, err := models.SharedSSLCertDAO.ListCertIds(tx, req.IsCA, req.IsAvailable, req.IsExpired, int64(req.ExpiringDays), req.Keyword, userId, req.Domains, req.Offset, req.Size)
if err != nil { if err != nil {
return nil, err return nil, err
} }
certConfigs := []*sslconfigs.SSLCertConfig{} var certConfigs = []*sslconfigs.SSLCertConfig{}
for _, certId := range certIds { for _, certId := range certIds {
certConfig, err := models.SharedSSLCertDAO.ComposeCertConfig(tx, certId, false, nil) certConfig, err := models.SharedSSLCertDAO.ComposeCertConfig(tx, certId, false, nil, nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@@ -88,7 +88,7 @@ func (this *SSLPolicyService) FindEnabledSSLPolicyConfig(ctx context.Context, re
var tx = this.NullTx() var tx = this.NullTx()
config, err := models.SharedSSLPolicyDAO.ComposePolicyConfig(tx, req.SslPolicyId, req.IgnoreData, nil) config, err := models.SharedSSLPolicyDAO.ComposePolicyConfig(tx, req.SslPolicyId, req.IgnoreData, nil, nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@@ -0,0 +1,90 @@
// Copyright 2023 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
package services
import (
"context"
"encoding/json"
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
"github.com/TeaOSLab/EdgeAPI/internal/utils"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
)
// UpdatingServerListService 待更新服务列表服务
type UpdatingServerListService struct {
BaseService
}
// FindUpdatingServerLists 查找要更新的服务配置
func (this *UpdatingServerListService) FindUpdatingServerLists(ctx context.Context, req *pb.FindUpdatingServerListsRequest) (*pb.FindUpdatingServerListsResponse, error) {
nodeId, err := this.ValidateNode(ctx)
if err != nil {
return nil, err
}
var tx = this.NullTx()
clusterIds, err := models.SharedNodeDAO.FindEnabledAndOnNodeClusterIds(tx, nodeId)
if err != nil {
return nil, err
}
lists, err := models.SharedUpdatingServerListDAO.FindLists(tx, clusterIds, req.LastId)
if err != nil {
return nil, err
}
if len(lists) == 0 {
return &pb.FindUpdatingServerListsResponse{
MaxId: req.LastId,
}, nil
}
var serverIdMap = map[int64]bool{}
var serverIds = []int64{}
var maxId int64
for _, list := range lists {
if int64(list.Id) > maxId {
maxId = int64(list.Id)
}
for _, serverId := range list.DecodeServerIds() {
if !serverIdMap[serverId] {
serverIdMap[serverId] = true
serverIds = append(serverIds, serverId)
}
}
}
if len(serverIds) == 0 {
return &pb.FindUpdatingServerListsResponse{
MaxId: req.LastId,
}, nil
}
servers, err := models.SharedServerDAO.FindEnabledServersWithIds(tx, serverIds)
if err != nil {
return nil, err
}
var serverConfigs = []*serverconfigs.ServerConfig{}
var cacheMap = utils.NewCacheMap()
for _, server := range servers {
serverConfig, err := models.SharedServerDAO.ComposeServerConfig(tx, server, false, nil, cacheMap, true, false)
if err != nil {
return nil, err
}
if serverConfig == nil {
continue
}
serverConfigs = append(serverConfigs, serverConfig)
}
serversJSON, err := json.Marshal(serverConfigs)
if err != nil {
return nil, err
}
return &pb.FindUpdatingServerListsResponse{
ServersJSON: serversJSON,
MaxId: maxId,
}, nil
}

View File

@@ -421,7 +421,7 @@ func (this *UserService) ComposeUserDashboard(ctx context.Context, req *pb.Compo
var currentDay = timeutil.Format("Ymd") var currentDay = timeutil.Format("Ymd")
// 本月总流量 // 本月总流量
monthlyTrafficBytes, err := models.SharedServerDailyStatDAO.SumUserMonthly(tx, req.UserId, currentMonth) monthlyTrafficBytes, err := models.SharedUserBandwidthStatDAO.SumUserMonthly(tx, req.UserId, currentMonth)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -451,12 +451,12 @@ func (this *UserService) ComposeUserDashboard(ctx context.Context, req *pb.Compo
} }
// 今日总流量 // 今日总流量
dailyTrafficStat, err := models.SharedServerDailyStatDAO.SumUserDaily(tx, req.UserId, 0, currentDay) dailyTrafficStat, err := models.SharedUserBandwidthStatDAO.SumUserDaily(tx, req.UserId, 0, currentDay)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if dailyTrafficStat == nil { if dailyTrafficStat == nil {
dailyTrafficStat = &models.ServerDailyStat{} dailyTrafficStat = &models.UserBandwidthStat{}
} }
// 近 30 日流量带宽趋势 // 近 30 日流量带宽趋势
@@ -475,12 +475,12 @@ func (this *UserService) ComposeUserDashboard(ctx context.Context, req *pb.Compo
} }
// 流量 // 流量
trafficStat, err := models.SharedServerDailyStatDAO.SumUserDaily(tx, req.UserId, 0, day) trafficStat, err := models.SharedUserBandwidthStatDAO.SumUserDaily(tx, req.UserId, 0, day)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if trafficStat == nil { if trafficStat == nil {
trafficStat = &models.ServerDailyStat{} trafficStat = &models.UserBandwidthStat{}
} }
// 峰值带宽 // 峰值带宽
@@ -495,7 +495,7 @@ func (this *UserService) ComposeUserDashboard(ctx context.Context, req *pb.Compo
dailyTrafficStats = append(dailyTrafficStats, &pb.ComposeUserDashboardResponse_DailyTrafficStat{ dailyTrafficStats = append(dailyTrafficStats, &pb.ComposeUserDashboardResponse_DailyTrafficStat{
Day: day, Day: day,
Bytes: int64(trafficStat.Bytes), Bytes: int64(trafficStat.TotalBytes),
CachedBytes: int64(trafficStat.CachedBytes), CachedBytes: int64(trafficStat.CachedBytes),
AttackBytes: int64(trafficStat.AttackBytes), AttackBytes: int64(trafficStat.AttackBytes),
CountRequests: int64(trafficStat.CountRequests), CountRequests: int64(trafficStat.CountRequests),
@@ -508,7 +508,7 @@ func (this *UserService) ComposeUserDashboard(ctx context.Context, req *pb.Compo
CountServers: countServers, CountServers: countServers,
MonthlyTrafficBytes: monthlyTrafficBytes, MonthlyTrafficBytes: monthlyTrafficBytes,
MonthlyPeekBandwidthBytes: monthlyPeekBandwidthBytes, MonthlyPeekBandwidthBytes: monthlyPeekBandwidthBytes,
DailyTrafficBytes: int64(dailyTrafficStat.Bytes), DailyTrafficBytes: int64(dailyTrafficStat.TotalBytes),
DailyPeekBandwidthBytes: dailyPeekBandwidthBytes, DailyPeekBandwidthBytes: dailyPeekBandwidthBytes,
DailyTrafficStats: dailyTrafficStats, DailyTrafficStats: dailyTrafficStats,
DailyPeekBandwidthStats: dailyPeekBandwidthStats, DailyPeekBandwidthStats: dailyPeekBandwidthStats,
@@ -728,8 +728,8 @@ func (this *UserService) ComposeUserGlobalBoard(ctx context.Context, req *pb.Com
} }
// 流量排行 // 流量排行
hourFrom := timeutil.Format("YmdH", time.Now().Add(-23*time.Hour)) var hourFrom = timeutil.Format("YmdH", time.Now().Add(-23*time.Hour))
hourTo := timeutil.Format("YmdH") var hourTo = timeutil.Format("YmdH")
topUserStats, err := models.SharedServerDailyStatDAO.FindTopUserStats(tx, hourFrom, hourTo) topUserStats, err := models.SharedServerDailyStatDAO.FindTopUserStats(tx, hourFrom, hourTo)
if err != nil { if err != nil {
return nil, err return nil, err

File diff suppressed because one or more lines are too long

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