Compare commits
73 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
476ff91bf8 | ||
|
|
ac6b10489e | ||
|
|
9352e1837f | ||
|
|
ddec102d18 | ||
|
|
0d50b9b0cc | ||
|
|
20b4b47eea | ||
|
|
ee8396c760 | ||
|
|
c3fa6a753a | ||
|
|
fbe4de2e94 | ||
|
|
f5c7108799 | ||
|
|
5825a7e654 | ||
|
|
a6911117af | ||
|
|
b428db4f5e | ||
|
|
e4145a2059 | ||
|
|
af13357985 | ||
|
|
1b949bd056 | ||
|
|
c4e415a72f | ||
|
|
39cb95184d | ||
|
|
a7abca6c09 | ||
|
|
894eff89ba | ||
|
|
35558f1d38 | ||
|
|
5a93ec0e32 | ||
|
|
73164de93e | ||
|
|
199349084e | ||
|
|
648fc2cac3 | ||
|
|
43f34950f3 | ||
|
|
1f0182e4a5 | ||
|
|
3f972571b0 | ||
|
|
0618ca9f8a | ||
|
|
efd0823b25 | ||
|
|
af5ca9faf5 | ||
|
|
87c5eeb829 | ||
|
|
df775272be | ||
|
|
dbeabe4379 | ||
|
|
dd33504416 | ||
|
|
d45dca4edb | ||
|
|
b4472271ce | ||
|
|
138eddf771 | ||
|
|
f0667abe55 | ||
|
|
873af38807 | ||
|
|
9bf46af088 | ||
|
|
3a3b5bca20 | ||
|
|
4806025f89 | ||
|
|
d7c757a2a1 | ||
|
|
3e8873d828 | ||
|
|
84484b6538 | ||
|
|
d36e9e80ee | ||
|
|
1fb831ca58 | ||
|
|
5e20553602 | ||
|
|
0f83d8ec66 | ||
|
|
e45a6cbcb5 | ||
|
|
ba1fd07555 | ||
|
|
a70b4bfaf3 | ||
|
|
9cf47ae1af | ||
|
|
7f58d65a57 | ||
|
|
4d40dd03de | ||
|
|
e3ce79c9fc | ||
|
|
f543edac1a | ||
|
|
1ce11a5745 | ||
|
|
ab56c7451a | ||
|
|
9800bbb661 | ||
|
|
8c4d2e7301 | ||
|
|
2c17675b6a | ||
|
|
3b30705f33 | ||
|
|
4cd9c5071d | ||
|
|
763a72d526 | ||
|
|
bd762ad10b | ||
|
|
56574ea3d9 | ||
|
|
6a31605519 | ||
|
|
c7abeeaf07 | ||
|
|
c11483ec6d | ||
|
|
c3713cefc9 | ||
|
|
2098bd4d32 |
@@ -17,6 +17,7 @@ import (
|
||||
"github.com/iwind/gosock/pkg/gosock"
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
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() {
|
||||
nodes.NewAPINode().Start()
|
||||
|
||||
@@ -4,12 +4,11 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/setup"
|
||||
"github.com/iwind/TeaGo/Tea"
|
||||
_ "github.com/iwind/TeaGo/bootstrap"
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
"go/format"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func main() {
|
||||
@@ -23,53 +22,20 @@ func main() {
|
||||
fmt.Println("[ERROR]" + err.Error())
|
||||
return
|
||||
}
|
||||
resultsJSON, err := json.Marshal(results)
|
||||
|
||||
prettyResultsJSON, err := json.MarshalIndent(results, "", " ")
|
||||
if err != nil {
|
||||
fmt.Println("[ERROR]" + err.Error())
|
||||
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 {
|
||||
fmt.Println("[ERROR]can not find sql.go")
|
||||
return
|
||||
}
|
||||
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)
|
||||
// 写入到 sql.json 中
|
||||
var dir = filepath.Dir(Tea.Root)
|
||||
err = os.WriteFile(dir+"/internal/setup/sql.json", prettyResultsJSON, 0666)
|
||||
if err != nil {
|
||||
logs.Println("[ERROR]load sql failed: " + err.Error())
|
||||
}
|
||||
}
|
||||
`)
|
||||
dst, err := format.Source(content)
|
||||
if err != nil {
|
||||
fmt.Println("[ERROR]format code failed: " + err.Error())
|
||||
fmt.Println("[ERROR]" + err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
err = os.WriteFile(sqlFile, dst, 0666)
|
||||
if err != nil {
|
||||
fmt.Println("[ERROR]write file failed: " + err.Error())
|
||||
return
|
||||
}
|
||||
fmt.Println("ok")
|
||||
}
|
||||
|
||||
12
go.mod
12
go.mod
@@ -11,7 +11,7 @@ require (
|
||||
github.com/cespare/xxhash v1.1.0
|
||||
github.com/cespare/xxhash/v2 v2.1.1
|
||||
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/iwind/TeaGo v0.0.0-20230304012706-c1f4a4e27470
|
||||
github.com/iwind/gosock v0.0.0-20220505115348-f88412125a62
|
||||
@@ -21,8 +21,8 @@ require (
|
||||
github.com/shirou/gopsutil/v3 v3.22.2
|
||||
github.com/smartwalle/alipay/v3 v3.1.7
|
||||
golang.org/x/crypto v0.1.0
|
||||
golang.org/x/net v0.7.0
|
||||
golang.org/x/sys v0.5.0
|
||||
golang.org/x/net v0.8.0
|
||||
golang.org/x/sys v0.6.0
|
||||
google.golang.org/grpc v1.45.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
)
|
||||
@@ -44,9 +44,9 @@ require (
|
||||
github.com/tklauser/go-sysconf v0.3.9 // indirect
|
||||
github.com/tklauser/numcpus v0.3.0 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.2 // indirect
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
|
||||
golang.org/x/text v0.7.0 // indirect
|
||||
golang.org/x/tools v0.1.12 // indirect
|
||||
golang.org/x/mod v0.8.0 // indirect
|
||||
golang.org/x/text v0.8.0 // indirect
|
||||
golang.org/x/tools v0.6.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20220317150908-0efb43f6373e // indirect
|
||||
google.golang.org/protobuf v1.28.0 // indirect
|
||||
gopkg.in/ini.v1 v1.66.6 // indirect
|
||||
|
||||
31
go.sum
31
go.sum
@@ -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/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-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.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/go.mod h1:qf9acutJ8cwBUhm1bqgz6Bei9/C/c93FPDljKWwsOgM=
|
||||
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/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-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/go.mod h1:fi/Pq+/5m2HZoseM+39dMF57ANXRt6w4PkGu3NXPc5s=
|
||||
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.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
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.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8=
|
||||
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-20180826012351-8a410e7b638d/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-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
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.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
|
||||
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-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
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-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 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-20180909124046-d0be0721c37e/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-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.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
|
||||
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.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.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.5/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.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
|
||||
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-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
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-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.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM=
|
||||
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-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package teaconst
|
||||
|
||||
const (
|
||||
Version = "0.6.4.1"
|
||||
Version = "1.0.4"
|
||||
|
||||
ProductName = "Edge API"
|
||||
ProcessName = "edge-api"
|
||||
@@ -18,7 +18,7 @@ const (
|
||||
|
||||
// 其他节点版本号,用来检测是否有需要升级的节点
|
||||
|
||||
NodeVersion = "0.6.4"
|
||||
NodeVersion = "1.0.4"
|
||||
|
||||
// SQLVersion SQL版本号
|
||||
SQLVersion = "11"
|
||||
|
||||
@@ -7,13 +7,29 @@ import (
|
||||
"fmt"
|
||||
"github.com/iwind/TeaGo/rands"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
IsPlus = false
|
||||
Edition = ""
|
||||
MaxNodes int32 = 0
|
||||
NodeId int64 = 0
|
||||
Debug = false
|
||||
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, "___")
|
||||
}
|
||||
|
||||
@@ -434,7 +434,7 @@ func (this *ACMETaskDAO) runTaskWithoutLog(tx *dbs.Tx, taskId int64) (isOk bool,
|
||||
CertData: certData,
|
||||
KeyData: keyData,
|
||||
}
|
||||
err = sslConfig.Init()
|
||||
err = sslConfig.Init(nil)
|
||||
if err != nil {
|
||||
errMsg = "证书生成成功,但是分析证书信息时发生错误:" + err.Error()
|
||||
return
|
||||
|
||||
@@ -131,6 +131,8 @@ func (this *ACMEUserDAO) CountACMEUsersWithAdminId(tx *dbs.Tx, adminId int64, us
|
||||
}
|
||||
if userId > 0 {
|
||||
query.Attr("userId", userId)
|
||||
} else {
|
||||
query.Attr("userId", 0)
|
||||
}
|
||||
if accountId > 0 {
|
||||
query.Attr("accountId", accountId)
|
||||
@@ -149,6 +151,8 @@ func (this *ACMEUserDAO) ListACMEUsers(tx *dbs.Tx, adminId int64, userId int64,
|
||||
}
|
||||
if userId > 0 {
|
||||
query.Attr("userId", userId)
|
||||
} else {
|
||||
query.Attr("userId", 0)
|
||||
}
|
||||
|
||||
_, err = query.
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
dbutils "github.com/TeaOSLab/EdgeAPI/internal/db/utils"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"github.com/iwind/TeaGo/Tea"
|
||||
@@ -266,17 +267,36 @@ func (this *AdminDAO) FindAllAdminModules(tx *dbs.Tx) (result []*Admin, err erro
|
||||
}
|
||||
|
||||
// CountAllEnabledAdmins 计算所有管理员数量
|
||||
func (this *AdminDAO) CountAllEnabledAdmins(tx *dbs.Tx) (int64, error) {
|
||||
return this.Query(tx).
|
||||
func (this *AdminDAO) CountAllEnabledAdmins(tx *dbs.Tx, keyword string, hasWeakPasswords bool) (int64, error) {
|
||||
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).
|
||||
Count()
|
||||
}
|
||||
|
||||
// ListEnabledAdmins 列出单页的管理员
|
||||
func (this *AdminDAO) ListEnabledAdmins(tx *dbs.Tx, offset int64, size int64) (result []*Admin, err error) {
|
||||
_, err = this.Query(tx).
|
||||
func (this *AdminDAO) ListEnabledAdmins(tx *dbs.Tx, keyword string, hasWeakPasswords bool, offset int64, size int64) (result []*Admin, err error) {
|
||||
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).
|
||||
Result("id", "isOn", "username", "fullname", "isSuper", "createdAt", "canLogin").
|
||||
Result("id", "isOn", "username", "fullname", "isSuper", "createdAt", "canLogin", "password").
|
||||
Offset(offset).
|
||||
Limit(size).
|
||||
DescPk().
|
||||
@@ -292,3 +312,15 @@ func (this *AdminDAO) UpdateAdminTheme(tx *dbs.Tx, adminId int64, theme string)
|
||||
Set("theme", theme).
|
||||
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()
|
||||
}
|
||||
|
||||
@@ -1 +1,42 @@
|
||||
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
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ func (this *APINode) DecodeHTTPS(tx *dbs.Tx, cacheMap *utils.CacheMap) (*serverc
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = config.Init()
|
||||
err = config.Init(nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -45,7 +45,7 @@ func (this *APINode) DecodeHTTPS(tx *dbs.Tx, cacheMap *utils.CacheMap) (*serverc
|
||||
if config.SSLPolicyRef != nil {
|
||||
var policyId = config.SSLPolicyRef.SSLPolicyId
|
||||
if policyId > 0 {
|
||||
sslPolicy, err := SharedSSLPolicyDAO.ComposePolicyConfig(tx, policyId, false, cacheMap)
|
||||
sslPolicy, err := SharedSSLPolicyDAO.ComposePolicyConfig(tx, policyId, false, nil, cacheMap)
|
||||
if err != nil {
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
@@ -129,13 +129,13 @@ func (this *APINode) DecodeRestHTTPS(tx *dbs.Tx, cacheMap *utils.CacheMap) (*ser
|
||||
if !IsNotNull(this.RestHTTPS) {
|
||||
return nil, nil
|
||||
}
|
||||
config := &serverconfigs.HTTPSProtocolConfig{}
|
||||
var config = &serverconfigs.HTTPSProtocolConfig{}
|
||||
err := json.Unmarshal(this.RestHTTPS, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = config.Init()
|
||||
err = config.Init(nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -143,7 +143,7 @@ func (this *APINode) DecodeRestHTTPS(tx *dbs.Tx, cacheMap *utils.CacheMap) (*ser
|
||||
if config.SSLPolicyRef != nil {
|
||||
policyId := config.SSLPolicyRef.SSLPolicyId
|
||||
if policyId > 0 {
|
||||
sslPolicy, err := SharedSSLPolicyDAO.ComposePolicyConfig(tx, policyId, false, cacheMap)
|
||||
sslPolicy, err := SharedSSLPolicyDAO.ComposePolicyConfig(tx, policyId, false, nil, cacheMap)
|
||||
if err != nil {
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@ const (
|
||||
DNSTaskTypeDomainChange DNSTaskType = "domainChange"
|
||||
)
|
||||
|
||||
var DNSTasksNotifier = make(chan bool, 2)
|
||||
|
||||
type DNSTaskDAO dbs.DAO
|
||||
|
||||
func NewDNSTaskDAO() *DNSTaskDAO {
|
||||
@@ -64,7 +66,17 @@ func (this *DNSTaskDAO) CreateDNSTask(tx *dbs.Tx, clusterId int64, serverId int6
|
||||
"error": "",
|
||||
"version": time.Now().UnixNano(),
|
||||
})
|
||||
return err
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 通知更新
|
||||
select {
|
||||
case DNSTasksNotifier <- true:
|
||||
default:
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// CreateClusterTask 生成集群变更任务
|
||||
@@ -156,10 +168,24 @@ func (this *DNSTaskDAO) UpdateDNSTaskError(tx *dbs.Tx, taskId int64, err string)
|
||||
}
|
||||
|
||||
// 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 {
|
||||
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()
|
||||
op.Id = taskId
|
||||
op.IsDone = true
|
||||
|
||||
@@ -105,7 +105,7 @@ func CheckClusterDNS(tx *dbs.Tx, cluster *models.NodeCluster, checkNodeIssues bo
|
||||
|
||||
// 检查节点
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -237,7 +237,7 @@ func (this *HTTPAccessLogDAO) CreateHTTPAccessLog(tx *dbs.Tx, dao *HTTPAccessLog
|
||||
if len(accessLog.TimeISO8601) > 10 {
|
||||
day = strings.ReplaceAll(accessLog.TimeISO8601[:10], "-", "")
|
||||
} else {
|
||||
timeutil.FormatTime("Ymd", accessLog.Timestamp)
|
||||
day = timeutil.FormatTime("Ymd", accessLog.Timestamp)
|
||||
}
|
||||
|
||||
tableDef, err := SharedHTTPAccessLogManager.FindLastTable(dao.Instance, day, true)
|
||||
|
||||
@@ -96,6 +96,27 @@ func (this *HTTPAuthPolicyDAO) UpdateHTTPAuthPolicy(tx *dbs.Tx, policyId int64,
|
||||
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 组合配置
|
||||
func (this *HTTPAuthPolicyDAO) ComposePolicyConfig(tx *dbs.Tx, policyId int64, cacheMap *utils.CacheMap) (*serverconfigs.HTTPAuthPolicy, error) {
|
||||
if cacheMap == nil {
|
||||
|
||||
@@ -150,7 +150,7 @@ func (this *HTTPLocationDAO) UpdateLocation(tx *dbs.Tx, locationId int64, name s
|
||||
}
|
||||
|
||||
// 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 {
|
||||
cacheMap = utils.NewCacheMap()
|
||||
}
|
||||
@@ -168,7 +168,7 @@ func (this *HTTPLocationDAO) ComposeLocationConfig(tx *dbs.Tx, locationId int64,
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
config := &serverconfigs.HTTPLocationConfig{}
|
||||
var config = &serverconfigs.HTTPLocationConfig{}
|
||||
config.Id = int64(location.Id)
|
||||
config.IsOn = location.IsOn
|
||||
config.Description = location.Description
|
||||
@@ -179,7 +179,7 @@ func (this *HTTPLocationDAO) ComposeLocationConfig(tx *dbs.Tx, locationId int64,
|
||||
|
||||
// web
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
@@ -195,7 +195,7 @@ func (this *HTTPLocationDAO) ComposeLocationConfig(tx *dbs.Tx, locationId int64,
|
||||
}
|
||||
config.ReverseProxyRef = ref
|
||||
if ref.ReverseProxyId > 0 {
|
||||
reverseProxyConfig, err := SharedReverseProxyDAO.ComposeReverseProxyConfig(tx, ref.ReverseProxyId, cacheMap)
|
||||
reverseProxyConfig, err := SharedReverseProxyDAO.ComposeReverseProxyConfig(tx, ref.ReverseProxyId, dataMap, cacheMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -292,13 +292,13 @@ func (this *HTTPLocationDAO) UpdateLocationWeb(tx *dbs.Tx, locationId int64, web
|
||||
}
|
||||
|
||||
// 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 {
|
||||
config, err := this.ComposeLocationConfig(tx, ref.LocationId, cacheMap)
|
||||
config, err := this.ComposeLocationConfig(tx, ref.LocationId, forNode, dataMap, cacheMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
children, err := this.ConvertLocationRefs(tx, ref.Children, cacheMap)
|
||||
children, err := this.ConvertLocationRefs(tx, ref.Children, forNode, dataMap, cacheMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -133,6 +133,32 @@ func (this *HTTPPageDAO) UpdatePage(tx *dbs.Tx, pageId int64, statusList []strin
|
||||
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 组合配置
|
||||
func (this *HTTPPageDAO) ComposePageConfig(tx *dbs.Tx, pageId int64, cacheMap *utils.CacheMap) (*serverconfigs.HTTPPageConfig, error) {
|
||||
if cacheMap == nil {
|
||||
|
||||
@@ -77,7 +77,7 @@ func (this *HTTPWebDAO) FindEnabledHTTPWeb(tx *dbs.Tx, id int64) (*HTTPWeb, erro
|
||||
}
|
||||
|
||||
// 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 {
|
||||
cacheMap = utils.NewCacheMap()
|
||||
}
|
||||
@@ -101,113 +101,127 @@ func (this *HTTPWebDAO) ComposeWebConfig(tx *dbs.Tx, webId int64, cacheMap *util
|
||||
|
||||
// root
|
||||
if IsNotNull(web.Root) {
|
||||
rootConfig := &serverconfigs.HTTPRootConfig{}
|
||||
var rootConfig = &serverconfigs.HTTPRootConfig{}
|
||||
err = json.Unmarshal(web.Root, rootConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config.Root = rootConfig
|
||||
if this.shouldCompose(isLocationOrGroup, forNode, rootConfig.IsPrior, rootConfig.IsOn) {
|
||||
config.Root = rootConfig
|
||||
}
|
||||
}
|
||||
|
||||
// compression
|
||||
if IsNotNull(web.Compression) {
|
||||
compression := &serverconfigs.HTTPCompressionConfig{}
|
||||
err = json.Unmarshal(web.Compression, compression)
|
||||
var compressionConfig = &serverconfigs.HTTPCompressionConfig{}
|
||||
err = json.Unmarshal(web.Compression, compressionConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config.Compression = compression
|
||||
|
||||
// gzip
|
||||
if compression.GzipRef != nil && compression.GzipRef.Id > 0 {
|
||||
gzipConfig, err := SharedHTTPGzipDAO.ComposeGzipConfig(tx, compression.GzipRef.Id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
compression.Gzip = gzipConfig
|
||||
}
|
||||
if this.shouldCompose(isLocationOrGroup, forNode, compressionConfig.IsPrior, compressionConfig.IsOn) {
|
||||
config.Compression = compressionConfig
|
||||
|
||||
// brotli
|
||||
if compression.BrotliRef != nil && compression.BrotliRef.Id > 0 {
|
||||
brotliConfig, err := SharedHTTPBrotliPolicyDAO.ComposeBrotliConfig(tx, compression.BrotliRef.Id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
// gzip
|
||||
if compressionConfig.GzipRef != nil && compressionConfig.GzipRef.Id > 0 {
|
||||
gzipConfig, err := SharedHTTPGzipDAO.ComposeGzipConfig(tx, compressionConfig.GzipRef.Id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
compressionConfig.Gzip = gzipConfig
|
||||
}
|
||||
compression.Brotli = brotliConfig
|
||||
}
|
||||
|
||||
// deflate
|
||||
if compression.DeflateRef != nil && compression.DeflateRef.Id > 0 {
|
||||
deflateConfig, err := SharedHTTPDeflatePolicyDAO.ComposeDeflateConfig(tx, compression.DeflateRef.Id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
// brotli
|
||||
if compressionConfig.BrotliRef != nil && compressionConfig.BrotliRef.Id > 0 {
|
||||
brotliConfig, err := SharedHTTPBrotliPolicyDAO.ComposeBrotliConfig(tx, compressionConfig.BrotliRef.Id)
|
||||
if err != nil {
|
||||
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
|
||||
if IsNotNull(web.Charset) {
|
||||
charsetConfig := &serverconfigs.HTTPCharsetConfig{}
|
||||
var charsetConfig = &serverconfigs.HTTPCharsetConfig{}
|
||||
err = json.Unmarshal(web.Charset, charsetConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config.Charset = charsetConfig
|
||||
if this.shouldCompose(isLocationOrGroup, forNode, charsetConfig.IsPrior, charsetConfig.IsOn) {
|
||||
config.Charset = charsetConfig
|
||||
}
|
||||
}
|
||||
|
||||
// headers
|
||||
if IsNotNull(web.RequestHeader) {
|
||||
ref := &shared.HTTPHeaderPolicyRef{}
|
||||
var ref = &shared.HTTPHeaderPolicyRef{}
|
||||
err = json.Unmarshal(web.RequestHeader, ref)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config.RequestHeaderPolicyRef = ref
|
||||
if this.shouldCompose(isLocationOrGroup, forNode, ref.IsPrior, ref.IsOn) {
|
||||
config.RequestHeaderPolicyRef = ref
|
||||
|
||||
if ref.HeaderPolicyId > 0 {
|
||||
headerPolicy, err := SharedHTTPHeaderPolicyDAO.ComposeHeaderPolicyConfig(tx, ref.HeaderPolicyId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if headerPolicy != nil {
|
||||
config.RequestHeaderPolicy = headerPolicy
|
||||
if ref.HeaderPolicyId > 0 {
|
||||
headerPolicy, err := SharedHTTPHeaderPolicyDAO.ComposeHeaderPolicyConfig(tx, ref.HeaderPolicyId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if headerPolicy != nil {
|
||||
config.RequestHeaderPolicy = headerPolicy
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if IsNotNull(web.ResponseHeader) {
|
||||
ref := &shared.HTTPHeaderPolicyRef{}
|
||||
var ref = &shared.HTTPHeaderPolicyRef{}
|
||||
err = json.Unmarshal(web.ResponseHeader, ref)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config.ResponseHeaderPolicyRef = ref
|
||||
if this.shouldCompose(isLocationOrGroup, forNode, ref.IsPrior, ref.IsOn) {
|
||||
config.ResponseHeaderPolicyRef = ref
|
||||
|
||||
if ref.HeaderPolicyId > 0 {
|
||||
headerPolicy, err := SharedHTTPHeaderPolicyDAO.ComposeHeaderPolicyConfig(tx, ref.HeaderPolicyId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if headerPolicy != nil {
|
||||
config.ResponseHeaderPolicy = headerPolicy
|
||||
if ref.HeaderPolicyId > 0 {
|
||||
headerPolicy, err := SharedHTTPHeaderPolicyDAO.ComposeHeaderPolicyConfig(tx, ref.HeaderPolicyId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if headerPolicy != nil {
|
||||
config.ResponseHeaderPolicy = headerPolicy
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// shutdown
|
||||
if IsNotNull(web.Shutdown) {
|
||||
shutdownConfig := &serverconfigs.HTTPShutdownConfig{}
|
||||
var shutdownConfig = &serverconfigs.HTTPShutdownConfig{}
|
||||
err = json.Unmarshal(web.Shutdown, shutdownConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config.Shutdown = shutdownConfig
|
||||
if this.shouldCompose(isLocationOrGroup, forNode, shutdownConfig.IsPrior, shutdownConfig.IsOn) {
|
||||
config.Shutdown = shutdownConfig
|
||||
}
|
||||
}
|
||||
|
||||
// pages
|
||||
// TODO 检查forNode参数
|
||||
if IsNotNull(web.Pages) {
|
||||
pages := []*serverconfigs.HTTPPageConfig{}
|
||||
var pages = []*serverconfigs.HTTPPageConfig{}
|
||||
err = json.Unmarshal(web.Pages, &pages)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -226,62 +240,72 @@ func (this *HTTPWebDAO) ComposeWebConfig(tx *dbs.Tx, webId int64, cacheMap *util
|
||||
|
||||
// 访问日志
|
||||
if IsNotNull(web.AccessLog) {
|
||||
accessLogConfig := &serverconfigs.HTTPAccessLogRef{}
|
||||
var accessLogConfig = &serverconfigs.HTTPAccessLogRef{}
|
||||
err = json.Unmarshal(web.AccessLog, accessLogConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config.AccessLogRef = accessLogConfig
|
||||
if this.shouldCompose(isLocationOrGroup, forNode, accessLogConfig.IsPrior, accessLogConfig.IsOn) {
|
||||
config.AccessLogRef = accessLogConfig
|
||||
}
|
||||
}
|
||||
|
||||
// 统计配置
|
||||
if IsNotNull(web.Stat) {
|
||||
statRef := &serverconfigs.HTTPStatRef{}
|
||||
var statRef = &serverconfigs.HTTPStatRef{}
|
||||
err = json.Unmarshal(web.Stat, statRef)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config.StatRef = statRef
|
||||
if this.shouldCompose(isLocationOrGroup, forNode, statRef.IsPrior, statRef.IsOn) {
|
||||
config.StatRef = statRef
|
||||
}
|
||||
}
|
||||
|
||||
// 缓存配置
|
||||
if IsNotNull(web.Cache) {
|
||||
cacheConfig := &serverconfigs.HTTPCacheConfig{}
|
||||
var cacheConfig = &serverconfigs.HTTPCacheConfig{}
|
||||
err = json.Unmarshal(web.Cache, &cacheConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config.Cache = cacheConfig
|
||||
|
||||
if this.shouldCompose(isLocationOrGroup, forNode, cacheConfig.IsPrior, cacheConfig.IsOn) {
|
||||
config.Cache = cacheConfig
|
||||
}
|
||||
|
||||
// 暂不支持自定义缓存策略设置,因为同一个集群下的服务需要集中管理
|
||||
}
|
||||
|
||||
// 防火墙配置
|
||||
if IsNotNull(web.Firewall) {
|
||||
firewallRef := &firewallconfigs.HTTPFirewallRef{}
|
||||
var firewallRef = &firewallconfigs.HTTPFirewallRef{}
|
||||
err = json.Unmarshal(web.Firewall, firewallRef)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config.FirewallRef = firewallRef
|
||||
if this.shouldCompose(isLocationOrGroup, forNode, firewallRef.IsPrior, firewallRef.IsOn) {
|
||||
config.FirewallRef = firewallRef
|
||||
|
||||
// 自定义防火墙设置
|
||||
if firewallRef.FirewallPolicyId > 0 {
|
||||
firewallPolicy, err := SharedHTTPFirewallPolicyDAO.ComposeFirewallPolicy(tx, firewallRef.FirewallPolicyId, cacheMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if firewallPolicy == nil {
|
||||
config.FirewallRef = nil
|
||||
} else {
|
||||
config.FirewallPolicy = firewallPolicy
|
||||
// 自定义防火墙设置
|
||||
if firewallRef.FirewallPolicyId > 0 {
|
||||
firewallPolicy, err := SharedHTTPFirewallPolicyDAO.ComposeFirewallPolicy(tx, firewallRef.FirewallPolicyId, cacheMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if firewallPolicy == nil {
|
||||
config.FirewallRef = nil
|
||||
} else {
|
||||
config.FirewallPolicy = firewallPolicy
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 路由规则
|
||||
// TODO 检查forNode参数
|
||||
if IsNotNull(web.Locations) {
|
||||
refs := []*serverconfigs.HTTPLocationRef{}
|
||||
var refs = []*serverconfigs.HTTPLocationRef{}
|
||||
err = json.Unmarshal(web.Locations, &refs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -289,7 +313,7 @@ func (this *HTTPWebDAO) ComposeWebConfig(tx *dbs.Tx, webId int64, cacheMap *util
|
||||
if len(refs) > 0 {
|
||||
config.LocationRefs = refs
|
||||
|
||||
locations, err := SharedHTTPLocationDAO.ConvertLocationRefs(tx, refs, cacheMap)
|
||||
locations, err := SharedHTTPLocationDAO.ConvertLocationRefs(tx, refs, forNode, dataMap, cacheMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -299,36 +323,41 @@ func (this *HTTPWebDAO) ComposeWebConfig(tx *dbs.Tx, webId int64, cacheMap *util
|
||||
|
||||
// 跳转
|
||||
if IsNotNull(web.RedirectToHttps) {
|
||||
redirectToHTTPSConfig := &serverconfigs.HTTPRedirectToHTTPSConfig{}
|
||||
var redirectToHTTPSConfig = &serverconfigs.HTTPRedirectToHTTPSConfig{}
|
||||
err = json.Unmarshal(web.RedirectToHttps, redirectToHTTPSConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config.RedirectToHttps = redirectToHTTPSConfig
|
||||
if this.shouldCompose(isLocationOrGroup, forNode, redirectToHTTPSConfig.IsPrior, redirectToHTTPSConfig.IsOn) {
|
||||
config.RedirectToHttps = redirectToHTTPSConfig
|
||||
}
|
||||
}
|
||||
|
||||
// Websocket
|
||||
if IsNotNull(web.Websocket) {
|
||||
ref := &serverconfigs.HTTPWebsocketRef{}
|
||||
var ref = &serverconfigs.HTTPWebsocketRef{}
|
||||
err = json.Unmarshal(web.Websocket, ref)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config.WebsocketRef = ref
|
||||
if ref.WebsocketId > 0 {
|
||||
websocketConfig, err := SharedHTTPWebsocketDAO.ComposeWebsocketConfig(tx, ref.WebsocketId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if websocketConfig != nil {
|
||||
config.Websocket = websocketConfig
|
||||
if this.shouldCompose(isLocationOrGroup, forNode, ref.IsPrior, ref.IsOn) {
|
||||
config.WebsocketRef = ref
|
||||
if ref.WebsocketId > 0 {
|
||||
websocketConfig, err := SharedHTTPWebsocketDAO.ComposeWebsocketConfig(tx, ref.WebsocketId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if websocketConfig != nil {
|
||||
config.Websocket = websocketConfig
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 重写规则
|
||||
// TODO 检查forNode参数
|
||||
if IsNotNull(web.RewriteRules) {
|
||||
refs := []*serverconfigs.HTTPRewriteRef{}
|
||||
var refs = []*serverconfigs.HTTPRewriteRef{}
|
||||
err = json.Unmarshal(web.RewriteRules, &refs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -346,8 +375,9 @@ func (this *HTTPWebDAO) ComposeWebConfig(tx *dbs.Tx, webId int64, cacheMap *util
|
||||
}
|
||||
|
||||
// 主机跳转
|
||||
// TODO 检查forNode参数
|
||||
if IsNotNull(web.HostRedirects) {
|
||||
redirects := []*serverconfigs.HTTPHostRedirectConfig{}
|
||||
var redirects = []*serverconfigs.HTTPHostRedirectConfig{}
|
||||
err = json.Unmarshal(web.HostRedirects, &redirects)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -357,25 +387,28 @@ func (this *HTTPWebDAO) ComposeWebConfig(tx *dbs.Tx, webId int64, cacheMap *util
|
||||
|
||||
// Fastcgi
|
||||
if IsNotNull(web.Fastcgi) {
|
||||
ref := &serverconfigs.HTTPFastcgiRef{}
|
||||
var ref = &serverconfigs.HTTPFastcgiRef{}
|
||||
err = json.Unmarshal(web.Fastcgi, ref)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config.FastcgiRef = ref
|
||||
|
||||
if len(ref.FastcgiIds) > 0 {
|
||||
list := []*serverconfigs.HTTPFastcgiConfig{}
|
||||
for _, fastcgiId := range ref.FastcgiIds {
|
||||
fastcgiConfig, err := SharedHTTPFastcgiDAO.ComposeFastcgiConfig(tx, fastcgiId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if fastcgiConfig != nil {
|
||||
list = append(list, fastcgiConfig)
|
||||
if this.shouldCompose(isLocationOrGroup, forNode, ref.IsPrior, ref.IsOn) {
|
||||
config.FastcgiRef = ref
|
||||
|
||||
if len(ref.FastcgiIds) > 0 {
|
||||
list := []*serverconfigs.HTTPFastcgiConfig{}
|
||||
for _, fastcgiId := range ref.FastcgiIds {
|
||||
fastcgiConfig, err := SharedHTTPFastcgiDAO.ComposeFastcgiConfig(tx, fastcgiId)
|
||||
if err != nil {
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
var newRefs []*serverconfigs.HTTPAuthPolicyRef
|
||||
for _, ref := range authConfig.PolicyRefs {
|
||||
policyConfig, err := SharedHTTPAuthPolicyDAO.ComposePolicyConfig(tx, ref.AuthPolicyId, cacheMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if policyConfig != nil {
|
||||
ref.AuthPolicy = policyConfig
|
||||
newRefs = append(newRefs, ref)
|
||||
authConfig.PolicyRefs = newRefs
|
||||
if this.shouldCompose(isLocationOrGroup, forNode, authConfig.IsPrior, authConfig.IsOn) {
|
||||
var newRefs []*serverconfigs.HTTPAuthPolicyRef
|
||||
for _, ref := range authConfig.PolicyRefs {
|
||||
policyConfig, err := SharedHTTPAuthPolicyDAO.ComposePolicyConfig(tx, ref.AuthPolicyId, cacheMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if policyConfig != nil {
|
||||
ref.AuthPolicy = policyConfig
|
||||
newRefs = append(newRefs, ref)
|
||||
authConfig.PolicyRefs = newRefs
|
||||
}
|
||||
}
|
||||
config.Auth = authConfig
|
||||
}
|
||||
config.Auth = authConfig
|
||||
}
|
||||
|
||||
// WebP
|
||||
@@ -408,7 +443,9 @@ func (this *HTTPWebDAO) ComposeWebConfig(tx *dbs.Tx, webId int64, cacheMap *util
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config.WebP = webpConfig
|
||||
if this.shouldCompose(isLocationOrGroup, forNode, webpConfig.IsPrior, webpConfig.IsOn) {
|
||||
config.WebP = webpConfig
|
||||
}
|
||||
}
|
||||
|
||||
// RemoteAddr
|
||||
@@ -418,7 +455,9 @@ func (this *HTTPWebDAO) ComposeWebConfig(tx *dbs.Tx, webId int64, cacheMap *util
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config.RemoteAddr = remoteAddrConfig
|
||||
if this.shouldCompose(isLocationOrGroup, forNode, remoteAddrConfig.IsPrior, remoteAddrConfig.IsOn) {
|
||||
config.RemoteAddr = remoteAddrConfig
|
||||
}
|
||||
}
|
||||
|
||||
// mergeSlashes
|
||||
@@ -427,25 +466,24 @@ func (this *HTTPWebDAO) ComposeWebConfig(tx *dbs.Tx, webId int64, cacheMap *util
|
||||
// 请求限制
|
||||
if len(web.RequestLimit) > 0 {
|
||||
var requestLimitConfig = &serverconfigs.HTTPRequestLimitConfig{}
|
||||
if len(web.RequestLimit) > 0 {
|
||||
err = json.Unmarshal(web.RequestLimit, requestLimitConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = json.Unmarshal(web.RequestLimit, requestLimitConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if this.shouldCompose(isLocationOrGroup, forNode, requestLimitConfig.IsPrior, requestLimitConfig.IsOn) {
|
||||
config.RequestLimit = requestLimitConfig
|
||||
}
|
||||
}
|
||||
|
||||
// 请求脚本
|
||||
// TODO 检查forNode设置
|
||||
if len(web.RequestScripts) > 0 {
|
||||
var requestScriptsConfig = &serverconfigs.HTTPRequestScriptsConfig{}
|
||||
if len(web.RequestScripts) > 0 {
|
||||
err = json.Unmarshal(web.RequestScripts, requestScriptsConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config.RequestScripts = requestScriptsConfig
|
||||
err = json.Unmarshal(web.RequestScripts, requestScriptsConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config.RequestScripts = requestScriptsConfig
|
||||
}
|
||||
|
||||
// UAM
|
||||
@@ -455,17 +493,21 @@ func (this *HTTPWebDAO) ComposeWebConfig(tx *dbs.Tx, webId int64, cacheMap *util
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config.UAM = uamConfig
|
||||
if this.shouldCompose(isLocationOrGroup, forNode, uamConfig.IsPrior, uamConfig.IsOn) {
|
||||
config.UAM = uamConfig
|
||||
}
|
||||
}
|
||||
|
||||
// CC
|
||||
if teaconst.IsPlus && IsNotNull(web.Cc) {
|
||||
var ccConfig = &serverconfigs.HTTPCCConfig{}
|
||||
var ccConfig = serverconfigs.DefaultHTTPCCConfig()
|
||||
err = json.Unmarshal(web.Cc, ccConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config.CC = ccConfig
|
||||
if this.shouldCompose(isLocationOrGroup, forNode, ccConfig.IsPrior, ccConfig.IsOn) {
|
||||
config.CC = ccConfig
|
||||
}
|
||||
}
|
||||
|
||||
// Referers
|
||||
@@ -475,7 +517,9 @@ func (this *HTTPWebDAO) ComposeWebConfig(tx *dbs.Tx, webId int64, cacheMap *util
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config.Referers = referersConfig
|
||||
if this.shouldCompose(isLocationOrGroup, forNode, referersConfig.IsPrior, referersConfig.IsOn) {
|
||||
config.Referers = referersConfig
|
||||
}
|
||||
}
|
||||
|
||||
// User-Agent
|
||||
@@ -485,7 +529,9 @@ func (this *HTTPWebDAO) ComposeWebConfig(tx *dbs.Tx, webId int64, cacheMap *util
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config.UserAgent = userAgentConfig
|
||||
if this.shouldCompose(isLocationOrGroup, forNode, userAgentConfig.IsPrior, userAgentConfig.IsOn) {
|
||||
config.UserAgent = userAgentConfig
|
||||
}
|
||||
}
|
||||
|
||||
if cacheMap != nil {
|
||||
@@ -1110,8 +1156,6 @@ func (this *HTTPWebDAO) UpdateWebHostRedirects(tx *dbs.Tx, webId int64, hostRedi
|
||||
return this.NotifyUpdate(tx, webId)
|
||||
}
|
||||
|
||||
// 通用设置
|
||||
|
||||
// FindWebHostRedirects 查找主机跳转
|
||||
func (this *HTTPWebDAO) FindWebHostRedirects(tx *dbs.Tx, webId int64) ([]byte, error) {
|
||||
col, err := this.Query(tx).
|
||||
@@ -1352,3 +1396,11 @@ func (this *HTTPWebDAO) NotifyUpdate(tx *dbs.Tx, webId int64) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// 检查是否应该组合配置
|
||||
func (this *HTTPWebDAO) shouldCompose(isLocationOrGroup bool, forNode bool, isPrior bool, isOn bool) bool {
|
||||
if !forNode {
|
||||
return true
|
||||
}
|
||||
return (!isLocationOrGroup && isOn) || (isLocationOrGroup && isPrior)
|
||||
}
|
||||
|
||||
@@ -159,6 +159,31 @@ func (this *HTTPWebsocketDAO) UpdateWebsocket(tx *dbs.Tx, websocketId int64, han
|
||||
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 通知更新
|
||||
func (this *HTTPWebsocketDAO) NotifyUpdate(tx *dbs.Tx, websocketId int64) error {
|
||||
webId, err := SharedHTTPWebDAO.FindEnabledWebIdWithWebsocketId(tx, websocketId)
|
||||
|
||||
@@ -2,7 +2,7 @@ package models
|
||||
|
||||
import "github.com/iwind/TeaGo/dbs"
|
||||
|
||||
// Websocket设置
|
||||
// HTTPWebsocket Websocket设置
|
||||
type HTTPWebsocket struct {
|
||||
Id uint32 `field:"id"` // ID
|
||||
AdminId uint32 `field:"adminId"` // 管理员ID
|
||||
@@ -15,20 +15,22 @@ type HTTPWebsocket struct {
|
||||
AllowedOrigins dbs.JSON `field:"allowedOrigins"` // 支持的源域名列表
|
||||
RequestSameOrigin uint8 `field:"requestSameOrigin"` // 是否请求一样的Origin
|
||||
RequestOrigin string `field:"requestOrigin"` // 请求Origin
|
||||
WebId uint64 `field:"webId"` // Web
|
||||
}
|
||||
|
||||
type HTTPWebsocketOperator struct {
|
||||
Id interface{} // ID
|
||||
AdminId interface{} // 管理员ID
|
||||
UserId interface{} // 用户ID
|
||||
CreatedAt interface{} // 创建时间
|
||||
State interface{} // 状态
|
||||
IsOn interface{} // 是否启用
|
||||
HandshakeTimeout interface{} // 握手超时时间
|
||||
AllowAllOrigins interface{} // 是否支持所有源
|
||||
AllowedOrigins interface{} // 支持的源域名列表
|
||||
RequestSameOrigin interface{} // 是否请求一样的Origin
|
||||
RequestOrigin interface{} // 请求Origin
|
||||
Id any // ID
|
||||
AdminId any // 管理员ID
|
||||
UserId any // 用户ID
|
||||
CreatedAt any // 创建时间
|
||||
State any // 状态
|
||||
IsOn any // 是否启用
|
||||
HandshakeTimeout any // 握手超时时间
|
||||
AllowAllOrigins any // 是否支持所有源
|
||||
AllowedOrigins any // 支持的源域名列表
|
||||
RequestSameOrigin any // 是否请求一样的Origin
|
||||
RequestOrigin any // 请求Origin
|
||||
WebId any // Web
|
||||
}
|
||||
|
||||
func NewHTTPWebsocketOperator() *HTTPWebsocketOperator {
|
||||
|
||||
@@ -75,13 +75,18 @@ func (this *IPItemDAO) EnableIPItem(tx *dbs.Tx, id int64) error {
|
||||
}
|
||||
|
||||
// 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)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = this.Query(tx).
|
||||
var query = this.Query(tx)
|
||||
if sourceUserId > 0 {
|
||||
query.Attr("sourceUserId", sourceUserId)
|
||||
}
|
||||
|
||||
_, err = query.
|
||||
Pk(id).
|
||||
Set("state", IPItemStateDisabled).
|
||||
Set("version", version).
|
||||
@@ -94,7 +99,7 @@ func (this *IPItemDAO) DisableIPItem(tx *dbs.Tx, id int64) error {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return errors.New("invalid 'ipFrom'")
|
||||
}
|
||||
@@ -106,16 +111,13 @@ func (this *IPItemDAO) DisableIPItemsWithIP(tx *dbs.Tx, ipFrom string, ipTo stri
|
||||
State(IPItemStateEnabled)
|
||||
|
||||
if listId > 0 {
|
||||
if userId > 0 {
|
||||
err := SharedIPListDAO.CheckUserIPList(tx, userId, listId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
query.Attr("listId", listId)
|
||||
}
|
||||
|
||||
if sourceUserId > 0 {
|
||||
query.Attr("sourceUserId", sourceUserId)
|
||||
}
|
||||
|
||||
ones, err := query.FindAll()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -125,14 +127,6 @@ func (this *IPItemDAO) DisableIPItemsWithIP(tx *dbs.Tx, ipFrom string, ipTo stri
|
||||
for _, one := range ones {
|
||||
var item = one.(*IPItem)
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -213,11 +207,12 @@ func (this *IPItemDAO) DeleteOldItem(tx *dbs.Tx, listId int64, ipFrom string, ip
|
||||
Attr("listId", listId).
|
||||
Attr("ipFrom", ipFrom).
|
||||
Attr("ipTo", ipTo).
|
||||
Set("state", IPItemStateEnabled).
|
||||
Attr("state", IPItemStateEnabled).
|
||||
FindAll()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, one := range ones {
|
||||
var itemId = int64(one.(*IPItem).Id)
|
||||
version, err := SharedIPListDAO.IncreaseVersion(tx)
|
||||
@@ -253,7 +248,8 @@ func (this *IPItemDAO) CreateIPItem(tx *dbs.Tx,
|
||||
sourceServerId int64,
|
||||
sourceHTTPFirewallPolicyId int64,
|
||||
sourceHTTPFirewallRuleGroupId int64,
|
||||
sourceHTTPFirewallRuleSetId int64) (int64, error) {
|
||||
sourceHTTPFirewallRuleSetId int64,
|
||||
shouldNotify bool) (int64, error) {
|
||||
version, err := SharedIPListDAO.IncreaseVersion(tx)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
@@ -282,6 +278,15 @@ func (this *IPItemDAO) CreateIPItem(tx *dbs.Tx,
|
||||
op.SourceHTTPFirewallRuleGroupId = sourceHTTPFirewallRuleGroupId
|
||||
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
|
||||
if autoAdded {
|
||||
op.IsRead = 0
|
||||
@@ -301,9 +306,11 @@ func (this *IPItemDAO) CreateIPItem(tx *dbs.Tx,
|
||||
return itemId, nil
|
||||
}
|
||||
|
||||
err = this.NotifyUpdate(tx, itemId)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
if shouldNotify {
|
||||
err = this.NotifyUpdate(tx, itemId)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
return itemId, nil
|
||||
}
|
||||
@@ -353,10 +360,13 @@ func (this *IPItemDAO) UpdateIPItem(tx *dbs.Tx, itemId int64, ipFrom string, ipT
|
||||
}
|
||||
|
||||
// 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).
|
||||
State(IPItemStateEnabled).
|
||||
Attr("listId", listId)
|
||||
if sourceUserId > 0 {
|
||||
query.Attr("sourceUserId", sourceUserId)
|
||||
}
|
||||
if len(keyword) > 0 {
|
||||
query.Where("(ipFrom LIKE :keyword OR ipTo LIKE :keyword)").
|
||||
Param("keyword", dbutils.QuoteLike(keyword))
|
||||
@@ -374,10 +384,13 @@ func (this *IPItemDAO) CountIPItemsWithListId(tx *dbs.Tx, listId int64, keyword
|
||||
}
|
||||
|
||||
// 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).
|
||||
State(IPItemStateEnabled).
|
||||
Attr("listId", listId)
|
||||
if sourceUserId > 0 {
|
||||
query.Attr("sourceUserId", sourceUserId)
|
||||
}
|
||||
if len(keyword) > 0 {
|
||||
query.Where("(ipFrom LIKE :keyword OR ipTo LIKE :keyword)").
|
||||
Param("keyword", dbutils.QuoteLike(keyword))
|
||||
@@ -403,10 +416,10 @@ func (this *IPItemDAO) ListIPItemsWithListId(tx *dbs.Tx, listId int64, keyword s
|
||||
// ListIPItemsAfterVersion 根据版本号查找IP列表
|
||||
func (this *IPItemDAO) ListIPItemsAfterVersion(tx *dbs.Tx, version int64, size int64) (result []*IPItem, err error) {
|
||||
_, err = this.Query(tx).
|
||||
UseIndex("version").
|
||||
// 这里不要设置状态参数,因为我们要知道哪些是删除的
|
||||
Gt("version", version).
|
||||
Asc("version").
|
||||
Asc("id").
|
||||
Limit(size).
|
||||
Slice(&result).
|
||||
FindAll()
|
||||
@@ -466,8 +479,12 @@ func (this *IPItemDAO) ExistsEnabledItem(tx *dbs.Tx, itemId int64) (bool, error)
|
||||
}
|
||||
|
||||
// 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)
|
||||
if sourceUserId > 0 {
|
||||
query.Attr("sourceUserId", sourceUserId)
|
||||
query.UseIndex("sourceUserId")
|
||||
}
|
||||
if len(keyword) > 0 {
|
||||
query.Like("ipFrom", dbutils.QuoteLike(keyword))
|
||||
}
|
||||
@@ -499,8 +516,12 @@ func (this *IPItemDAO) CountAllEnabledIPItems(tx *dbs.Tx, keyword string, ip str
|
||||
}
|
||||
|
||||
// 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)
|
||||
if sourceUserId > 0 {
|
||||
query.Attr("sourceUserId", sourceUserId)
|
||||
query.UseIndex("sourceUserId")
|
||||
}
|
||||
if len(keyword) > 0 {
|
||||
query.Like("ipFrom", dbutils.QuoteLike(keyword))
|
||||
}
|
||||
@@ -536,11 +557,17 @@ func (this *IPItemDAO) ListAllEnabledIPItems(tx *dbs.Tx, keyword string, ip stri
|
||||
}
|
||||
|
||||
// UpdateItemsRead 设置所有未已读
|
||||
func (this *IPItemDAO) UpdateItemsRead(tx *dbs.Tx) error {
|
||||
return this.Query(tx).
|
||||
func (this *IPItemDAO) UpdateItemsRead(tx *dbs.Tx, sourceUserId int64) error {
|
||||
var query = this.Query(tx).
|
||||
Attr("isRead", 0).
|
||||
Set("isRead", 1).
|
||||
UpdateQuickly()
|
||||
Set("isRead", 1)
|
||||
|
||||
if sourceUserId > 0 {
|
||||
query.Attr("sourceUserId", sourceUserId)
|
||||
query.UseIndex("sourceUserId")
|
||||
}
|
||||
|
||||
return query.UpdateQuickly()
|
||||
}
|
||||
|
||||
// CleanExpiredIPItems 清除过期数据
|
||||
|
||||
@@ -51,12 +51,12 @@ func TestIPItemDAO_CreateManyIPs(t *testing.T) {
|
||||
var dao = models.NewIPItemDAO()
|
||||
var n = 10
|
||||
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 {
|
||||
t.Fatal(err)
|
||||
}
|
||||
_ = itemId
|
||||
/**err = dao.Query(tx).Pk(itemId).Set("state", 0).UpdateQuickly()
|
||||
/**err = dao.Query(tx).Pk(itemId).Attr("state", 0).UpdateQuickly()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}**/
|
||||
|
||||
@@ -23,32 +23,34 @@ type IPItem struct {
|
||||
SourceHTTPFirewallPolicyId uint32 `field:"sourceHTTPFirewallPolicyId"` // 来源策略ID
|
||||
SourceHTTPFirewallRuleGroupId uint32 `field:"sourceHTTPFirewallRuleGroupId"` // 来源规则集分组ID
|
||||
SourceHTTPFirewallRuleSetId uint32 `field:"sourceHTTPFirewallRuleSetId"` // 来源规则集ID
|
||||
SourceUserId uint64 `field:"sourceUserId"` // 用户ID
|
||||
IsRead bool `field:"isRead"` // 是否已读
|
||||
}
|
||||
|
||||
type IPItemOperator struct {
|
||||
Id interface{} // ID
|
||||
ListId interface{} // 所属名单ID
|
||||
Type interface{} // 类型
|
||||
IpFrom interface{} // 开始IP
|
||||
IpTo interface{} // 结束IP
|
||||
IpFromLong interface{} // 开始IP整型
|
||||
IpToLong interface{} // 结束IP整型
|
||||
Version interface{} // 版本
|
||||
CreatedAt interface{} // 创建时间
|
||||
UpdatedAt interface{} // 修改时间
|
||||
Reason interface{} // 加入说明
|
||||
EventLevel interface{} // 事件级别
|
||||
State interface{} // 状态
|
||||
ExpiredAt interface{} // 过期时间
|
||||
ServerId interface{} // 有效范围服务ID
|
||||
NodeId interface{} // 有效范围节点ID
|
||||
SourceNodeId interface{} // 来源节点ID
|
||||
SourceServerId interface{} // 来源服务ID
|
||||
SourceHTTPFirewallPolicyId interface{} // 来源策略ID
|
||||
SourceHTTPFirewallRuleGroupId interface{} // 来源规则集分组ID
|
||||
SourceHTTPFirewallRuleSetId interface{} // 来源规则集ID
|
||||
IsRead interface{} // 是否已读
|
||||
Id any // ID
|
||||
ListId any // 所属名单ID
|
||||
Type any // 类型
|
||||
IpFrom any // 开始IP
|
||||
IpTo any // 结束IP
|
||||
IpFromLong any // 开始IP整型
|
||||
IpToLong any // 结束IP整型
|
||||
Version any // 版本
|
||||
CreatedAt any // 创建时间
|
||||
UpdatedAt any // 修改时间
|
||||
Reason any // 加入说明
|
||||
EventLevel any // 事件级别
|
||||
State any // 状态
|
||||
ExpiredAt any // 过期时间
|
||||
ServerId any // 有效范围服务ID
|
||||
NodeId any // 有效范围节点ID
|
||||
SourceNodeId any // 来源节点ID
|
||||
SourceServerId any // 来源服务ID
|
||||
SourceHTTPFirewallPolicyId any // 来源策略ID
|
||||
SourceHTTPFirewallRuleGroupId any // 来源规则集分组ID
|
||||
SourceHTTPFirewallRuleSetId any // 来源规则集ID
|
||||
SourceUserId any // 用户ID
|
||||
IsRead any // 是否已读
|
||||
}
|
||||
|
||||
func NewIPItemOperator() *IPItemOperator {
|
||||
|
||||
@@ -72,7 +72,7 @@ func (this *IPLibraryFileDAO) FindEnabledIPLibraryFile(tx *dbs.Tx, id int64) (*I
|
||||
}
|
||||
|
||||
// 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()
|
||||
op.Name = name
|
||||
op.Template = template
|
||||
@@ -86,6 +86,8 @@ func (this *IPLibraryFileDAO) CreateLibraryFile(tx *dbs.Tx, name string, templat
|
||||
}
|
||||
op.EmptyValues = emptyValuesJSON
|
||||
|
||||
op.Password = password
|
||||
|
||||
op.FileId = fileId
|
||||
|
||||
if countries == nil {
|
||||
@@ -337,7 +339,7 @@ func (this *IPLibraryFileDAO) GenerateIPLibrary(tx *dbs.Tx, libraryFileId int64)
|
||||
var countries = []*iplibrary.Country{}
|
||||
for _, country := range dbCountries {
|
||||
countries = append(countries, &iplibrary.Country{
|
||||
Id: country.Id,
|
||||
Id: types.Uint16(country.Id),
|
||||
Name: country.DisplayName(),
|
||||
Codes: country.AllCodes(),
|
||||
})
|
||||
@@ -352,7 +354,7 @@ func (this *IPLibraryFileDAO) GenerateIPLibrary(tx *dbs.Tx, libraryFileId int64)
|
||||
var provinces = []*iplibrary.Province{}
|
||||
for _, province := range dbProvinces {
|
||||
provinces = append(provinces, &iplibrary.Province{
|
||||
Id: province.Id,
|
||||
Id: types.Uint16(province.Id),
|
||||
Name: province.DisplayName(),
|
||||
Codes: province.AllCodes(),
|
||||
})
|
||||
@@ -397,7 +399,7 @@ func (this *IPLibraryFileDAO) GenerateIPLibrary(tx *dbs.Tx, libraryFileId int64)
|
||||
var providers = []*iplibrary.Provider{}
|
||||
for _, provider := range dbProviders {
|
||||
providers = append(providers, &iplibrary.Provider{
|
||||
Id: provider.Id,
|
||||
Id: types.Uint16(provider.Id),
|
||||
Name: provider.DisplayName(),
|
||||
Codes: provider.AllCodes(),
|
||||
})
|
||||
@@ -414,7 +416,7 @@ func (this *IPLibraryFileDAO) GenerateIPLibrary(tx *dbs.Tx, libraryFileId int64)
|
||||
Towns: towns,
|
||||
Providers: providers,
|
||||
}
|
||||
writer, err := iplibrary.NewFileWriter(filePath, meta)
|
||||
writer, err := iplibrary.NewFileWriter(filePath, meta, libraryFile.Password)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ type IPLibraryFile struct {
|
||||
Towns dbs.JSON `field:"towns"` // 区县
|
||||
Providers dbs.JSON `field:"providers"` // ISP服务商
|
||||
Code string `field:"code"` // 文件代号
|
||||
Password string `field:"password"` // 密码
|
||||
CreatedAt uint64 `field:"createdAt"` // 上传时间
|
||||
State uint8 `field:"state"` // 状态
|
||||
}
|
||||
@@ -37,6 +38,7 @@ type IPLibraryFileOperator struct {
|
||||
Towns any // 区县
|
||||
Providers any // ISP服务商
|
||||
Code any // 文件代号
|
||||
Password any // 密码
|
||||
CreatedAt any // 上传时间
|
||||
State any // 状态
|
||||
}
|
||||
|
||||
@@ -60,11 +60,11 @@ func (this *LogDAO) CreateLog(tx *dbs.Tx, adminType string, adminId int64, level
|
||||
}
|
||||
|
||||
// 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)
|
||||
dayTo = this.formatDay(dayTo)
|
||||
|
||||
query := this.Query(tx)
|
||||
var query = this.Query(tx)
|
||||
|
||||
if len(dayFrom) > 0 {
|
||||
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)").
|
||||
Param("keyword", dbutils.QuoteLike(keyword))
|
||||
}
|
||||
if len(level) > 0 {
|
||||
query.Attr("level", level)
|
||||
}
|
||||
|
||||
// 用户类型
|
||||
switch userType {
|
||||
@@ -89,11 +92,11 @@ func (this *LogDAO) CountLogs(tx *dbs.Tx, dayFrom string, dayTo string, keyword
|
||||
}
|
||||
|
||||
// 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)
|
||||
dayTo = this.formatDay(dayTo)
|
||||
|
||||
query := this.Query(tx)
|
||||
var query = this.Query(tx)
|
||||
if len(dayFrom) > 0 {
|
||||
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))
|
||||
}
|
||||
|
||||
if len(level) > 0 {
|
||||
query.Attr("level", level)
|
||||
}
|
||||
|
||||
// 用户类型
|
||||
switch userType {
|
||||
case "admin":
|
||||
|
||||
@@ -155,7 +155,7 @@ func (this *MessageDAO) CreateNodeMessage(tx *dbs.Tx, role string, clusterId int
|
||||
|
||||
// CreateMessage 创建普通消息
|
||||
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)
|
||||
|
||||
var op = NewMessageOperator()
|
||||
|
||||
@@ -1077,7 +1077,7 @@ func (this *NodeClusterDAO) UpdateClusterUAMPolicy(tx *dbs.Tx, clusterId int64,
|
||||
return err
|
||||
}
|
||||
|
||||
return this.NotifyUpdate(tx, clusterId)
|
||||
return this.NotifyUAMUpdate(tx, clusterId)
|
||||
}
|
||||
|
||||
uamPolicyJSON, err := json.Marshal(uamPolicy)
|
||||
@@ -1092,7 +1092,7 @@ func (this *NodeClusterDAO) UpdateClusterUAMPolicy(tx *dbs.Tx, clusterId int64,
|
||||
return err
|
||||
}
|
||||
|
||||
return this.NotifyUpdate(tx, clusterId)
|
||||
return this.NotifyUAMUpdate(tx, clusterId)
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
// NotifyUAMUpdate 通知UAM更新
|
||||
func (this *NodeClusterDAO) NotifyUAMUpdate(tx *dbs.Tx, clusterId int64) error {
|
||||
return SharedNodeTaskDAO.CreateClusterTask(tx, nodeconfigs.NodeRoleNode, clusterId, 0, 0, NodeTaskTypeUAMPolicyChanged)
|
||||
}
|
||||
|
||||
// NotifyDNSUpdate 通知DNS更新
|
||||
// TODO 更新新的DNS解析记录的同时,需要删除老的DNS解析记录
|
||||
func (this *NodeClusterDAO) NotifyDNSUpdate(tx *dbs.Tx, clusterId int64) error {
|
||||
|
||||
@@ -356,7 +356,7 @@ func (this *NodeDAO) ListEnabledNodesMatch(tx *dbs.Tx,
|
||||
|
||||
// 关键词
|
||||
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))
|
||||
}
|
||||
|
||||
@@ -435,6 +435,16 @@ func (this *NodeDAO) ListEnabledNodesMatch(tx *dbs.Tx,
|
||||
valueField = "load1m"
|
||||
isAsc = false
|
||||
ifNullValue = -1
|
||||
case "connectionsAsc":
|
||||
valueItem = "connections"
|
||||
valueField = "total"
|
||||
isAsc = true
|
||||
ifNullValue = 1000
|
||||
case "connectionsDesc":
|
||||
valueItem = "connections"
|
||||
valueField = "total"
|
||||
isAsc = false
|
||||
ifNullValue = -1
|
||||
default:
|
||||
query.Desc("level")
|
||||
}
|
||||
@@ -830,7 +840,24 @@ func (this *NodeDAO) UpdateNodeStatus(tx *dbs.Tx, nodeId int64, nodeStatus *node
|
||||
Set("isActive", true).
|
||||
Set("status", nodeStatusJSON).
|
||||
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 获取节点状态
|
||||
@@ -875,7 +902,10 @@ func (this *NodeDAO) UpdateNodeIsInstalled(tx *dbs.Tx, nodeId int64, isInstalled
|
||||
Set("isInstalled", isInstalled).
|
||||
Set("installStatus", "null"). // 重置安装状态
|
||||
Update()
|
||||
return err
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return this.NotifyDNSUpdate(tx, nodeId)
|
||||
}
|
||||
|
||||
// FindNodeInstallStatus 查询节点的安装状态
|
||||
@@ -932,11 +962,16 @@ func (this *NodeDAO) UpdateNodeInstallStatus(tx *dbs.Tx, nodeId int64, status *N
|
||||
|
||||
// ComposeNodeConfig 组合配置
|
||||
// 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 {
|
||||
cacheMap = utils.NewCacheMap()
|
||||
}
|
||||
|
||||
// 放入到缓存中,以便于后面继续使用
|
||||
if dataMap != nil {
|
||||
cacheMap.Put("DataMap", dataMap)
|
||||
}
|
||||
|
||||
node, err := this.FindEnabledNode(tx, nodeId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -951,6 +986,7 @@ func (this *NodeDAO) ComposeNodeConfig(tx *dbs.Tx, nodeId int64, cacheMap *utils
|
||||
|
||||
var config = &nodeconfigs.NodeConfig{
|
||||
Id: int64(node.Id),
|
||||
Edition: teaconst.Edition,
|
||||
NodeId: node.UniqueId,
|
||||
Secret: node.Secret,
|
||||
IsOn: node.IsOn,
|
||||
@@ -963,8 +999,17 @@ func (this *NodeDAO) ComposeNodeConfig(tx *dbs.Tx, nodeId int64, cacheMap *utils
|
||||
GroupId: int64(node.GroupId),
|
||||
EnableIPLists: node.EnableIPLists,
|
||||
APINodeAddrs: node.DecodeAPINodeAddrs(),
|
||||
|
||||
DataMap: dataMap,
|
||||
}
|
||||
|
||||
// 待更新服务ID
|
||||
updatingServerListId, err := SharedUpdatingServerListDAO.FindLatestId(tx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config.UpdatingServerListId = updatingServerListId
|
||||
|
||||
// API节点IP
|
||||
apiNodeIPs, err := SharedAPINodeDAO.FindAllEnabledAPIAccessIPs(tx, cacheMap)
|
||||
if err != nil {
|
||||
@@ -999,7 +1044,7 @@ func (this *NodeDAO) ComposeNodeConfig(tx *dbs.Tx, nodeId int64, cacheMap *utils
|
||||
}
|
||||
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1485,7 +1530,7 @@ func (this *NodeDAO) UpdateNodeRegionId(tx *dbs.Tx, nodeId int64, regionId int64
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return nil, nil
|
||||
}
|
||||
@@ -1504,6 +1549,7 @@ func (this *NodeDAO) FindAllEnabledNodesDNSWithClusterId(tx *dbs.Tx, clusterId i
|
||||
State(NodeStateEnabled).
|
||||
Attr("isOn", true).
|
||||
Attr("isUp", true).
|
||||
Attr("isInstalled", isInstalled).
|
||||
Result("id", "name", "dnsRoutes", "isOn").
|
||||
DescPk().
|
||||
Slice(&result).
|
||||
|
||||
@@ -4,9 +4,11 @@
|
||||
package models_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
teaconst "github.com/TeaOSLab/EdgeAPI/internal/const"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
"github.com/iwind/TeaGo/logs"
|
||||
@@ -47,21 +49,40 @@ func TestNodeDAO_FindEnabledNodeClusterIds(t *testing.T) {
|
||||
func TestNodeDAO_ComposeNodeConfig(t *testing.T) {
|
||||
dbs.NotifyReady()
|
||||
|
||||
before := time.Now()
|
||||
defer func() {
|
||||
t.Log(time.Since(before).Seconds()*1000, "ms")
|
||||
}()
|
||||
var before = time.Now()
|
||||
|
||||
var tx *dbs.Tx
|
||||
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 {
|
||||
t.Fatal(err)
|
||||
}
|
||||
nodeConfig.DataMap = dataMap
|
||||
t.Log(len(nodeConfig.Servers), "servers")
|
||||
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) {
|
||||
@@ -71,7 +92,7 @@ func TestNodeDAO_ComposeNodeConfig_ParentNodes(t *testing.T) {
|
||||
|
||||
var tx *dbs.Tx
|
||||
var cacheMap = utils.NewCacheMap()
|
||||
nodeConfig, err := models.SharedNodeDAO.ComposeNodeConfig(tx, 48, cacheMap)
|
||||
nodeConfig, err := models.SharedNodeDAO.ComposeNodeConfig(tx, 48, nil, cacheMap)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -24,6 +24,8 @@ const (
|
||||
NodeTaskTypeScriptsChanged NodeTaskType = "scriptsChanged" // 脚本配置变化
|
||||
NodeTaskTypeNodeLevelChanged NodeTaskType = "nodeLevelChanged" // 节点级别变化
|
||||
NodeTaskTypeUserServersStateChanged NodeTaskType = "userServersStateChanged" // 用户服务状态变化
|
||||
NodeTaskTypeUAMPolicyChanged NodeTaskType = "uamPolicyChanged" // UAM策略变化
|
||||
NodeTaskTypeUpdatingServers NodeTaskType = "updatingServers" // 更新一组服务
|
||||
|
||||
// NS相关
|
||||
|
||||
@@ -236,6 +238,7 @@ func (this *NodeTaskDAO) FindDoingNodeTasks(tx *dbs.Tx, role string, nodeId int6
|
||||
var query = this.Query(tx).
|
||||
Attr("role", role).
|
||||
Attr("nodeId", nodeId).
|
||||
UseIndex("nodeId").
|
||||
Asc("version")
|
||||
if version > 0 {
|
||||
query.Lt("LENGTH(version)", 19) // 兼容以往版本
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
package models
|
||||
package models_test
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestNodeTaskDAO_CreateNodeTask(t *testing.T) {
|
||||
dbs.NotifyReady()
|
||||
|
||||
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 {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -22,7 +24,7 @@ func TestNodeTaskDAO_CreateClusterTask(t *testing.T) {
|
||||
dbs.NotifyReady()
|
||||
|
||||
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 {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -33,9 +35,22 @@ func TestNodeTaskDAO_ExtractClusterTask(t *testing.T) {
|
||||
dbs.NotifyReady()
|
||||
|
||||
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 {
|
||||
t.Fatal(err)
|
||||
}
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ type NSCluster struct {
|
||||
SoaSerial uint64 `field:"soaSerial"` // SOA序列号
|
||||
Email string `field:"email"` // 管理员邮箱
|
||||
DetectAgents bool `field:"detectAgents"` // 是否监测Agents
|
||||
CheckingPorts bool `field:"checkingPorts"` // 自动检测端口
|
||||
}
|
||||
|
||||
type NSClusterOperator struct {
|
||||
@@ -47,6 +48,7 @@ type NSClusterOperator struct {
|
||||
SoaSerial any // SOA序列号
|
||||
Email any // 管理员邮箱
|
||||
DetectAgents any // 是否监测Agents
|
||||
CheckingPorts any // 自动检测端口
|
||||
}
|
||||
|
||||
func NewNSClusterOperator() *NSClusterOperator {
|
||||
|
||||
@@ -275,8 +275,66 @@ func (this *OriginDAO) UpdateOrigin(tx *dbs.Tx,
|
||||
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 将源站信息转换为配置
|
||||
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 {
|
||||
cacheMap = utils.NewCacheMap()
|
||||
}
|
||||
@@ -403,7 +461,7 @@ func (this *OriginDAO) ComposeOriginConfig(tx *dbs.Tx, originId int64, cacheMap
|
||||
}
|
||||
config.CertRef = ref
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
|
||||
func TestOriginServerDAO_ComposeOriginConfig(t *testing.T) {
|
||||
var tx *dbs.Tx
|
||||
config, err := SharedOriginDAO.ComposeOriginConfig(tx, 1, nil)
|
||||
config, err := SharedOriginDAO.ComposeOriginConfig(tx, 1, nil, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ func (this *ReverseProxyDAO) FindEnabledReverseProxy(tx *dbs.Tx, id int64) (*Rev
|
||||
}
|
||||
|
||||
// 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 {
|
||||
cacheMap = utils.NewCacheMap()
|
||||
}
|
||||
@@ -125,7 +125,7 @@ func (this *ReverseProxyDAO) ComposeReverseProxyConfig(tx *dbs.Tx, reverseProxyI
|
||||
return nil, err
|
||||
}
|
||||
for _, ref := range originRefs {
|
||||
originConfig, err := SharedOriginDAO.ComposeOriginConfig(tx, ref.OriginId, cacheMap)
|
||||
originConfig, err := SharedOriginDAO.ComposeOriginConfig(tx, ref.OriginId, dataMap, cacheMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -142,7 +142,7 @@ func (this *ReverseProxyDAO) ComposeReverseProxyConfig(tx *dbs.Tx, reverseProxyI
|
||||
return nil, err
|
||||
}
|
||||
for _, ref := range originRefs {
|
||||
originConfig, err := SharedOriginDAO.ComposeOriginConfig(tx, ref.OriginId, cacheMap)
|
||||
originConfig, err := SharedOriginDAO.ComposeOriginConfig(tx, ref.OriginId, dataMap, cacheMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -243,6 +243,115 @@ func (this *ReverseProxyDAO) CreateReverseProxy(tx *dbs.Tx, adminId int64, userI
|
||||
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 修改反向代理调度算法
|
||||
func (this *ReverseProxyDAO) UpdateReverseProxyScheduling(tx *dbs.Tx, reverseProxyId int64, schedulingJSON []byte) error {
|
||||
if reverseProxyId <= 0 {
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
|
||||
func TestReverseProxyDAO_ComposeReverseProxyConfig(t *testing.T) {
|
||||
var tx *dbs.Tx
|
||||
config, err := SharedReverseProxyDAO.ComposeReverseProxyConfig(tx, 1, nil)
|
||||
config, err := SharedReverseProxyDAO.ComposeReverseProxyConfig(tx, 1, nil, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/goman"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
|
||||
@@ -63,7 +64,7 @@ func init() {
|
||||
|
||||
// UpdateServerBandwidth 写入数据
|
||||
// 暂时不使用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 {
|
||||
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)).
|
||||
Param("bytes", bytes).
|
||||
Param("totalBytes", totalBytes).
|
||||
Param("cachedBytes", cachedBytes).
|
||||
Param("attackBytes", attackBytes).
|
||||
Param("countRequests", countRequests).
|
||||
Param("countCachedRequests", countCachedRequests).
|
||||
Param("countAttackRequests", countAttackRequests).
|
||||
InsertOrUpdateQuickly(maps.Map{
|
||||
"userId": userId,
|
||||
"serverId": serverId,
|
||||
"day": day,
|
||||
"timeAt": timeAt,
|
||||
"bytes": bytes,
|
||||
"totalBytes": totalBytes,
|
||||
"avgBytes": totalBytes / 300,
|
||||
"userId": userId,
|
||||
"serverId": serverId,
|
||||
"regionId": regionId,
|
||||
"day": day,
|
||||
"timeAt": timeAt,
|
||||
"bytes": bytes,
|
||||
"totalBytes": totalBytes,
|
||||
"avgBytes": totalBytes / 300,
|
||||
"cachedBytes": cachedBytes,
|
||||
"attackBytes": attackBytes,
|
||||
"countRequests": countRequests,
|
||||
"countCachedRequests": countCachedRequests,
|
||||
"countAttackRequests": countAttackRequests,
|
||||
}, maps.Map{
|
||||
"bytes": dbs.SQL("bytes+:bytes"),
|
||||
"avgBytes": dbs.SQL("(totalBytes+:totalBytes)/300"), // 因为生成SQL语句时会自动将avgBytes排在totalBytes之前,所以这里不用担心先后顺序的问题
|
||||
"totalBytes": dbs.SQL("totalBytes+:totalBytes"),
|
||||
"bytes": dbs.SQL("bytes+:bytes"),
|
||||
"avgBytes": dbs.SQL("(totalBytes+:totalBytes)/300"), // 因为生成SQL语句时会自动将avgBytes排在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).
|
||||
Table(this.partialTable(serverId)).
|
||||
Between("day", timeutil.FormatTime("Ymd", timestamp), timeutil.Format("Ymd")).
|
||||
Attr("serverId", serverId).
|
||||
Result(this.maxBytesField(useAvg), "CONCAT(day, '.', SUBSTRING(timeAt, 1, 2)) AS fullTime").
|
||||
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).
|
||||
Table(this.partialTable(serverId)).
|
||||
Between("day", timeFrom[:8], timeTo[:8]).
|
||||
Attr("serverId", serverId).
|
||||
Between("CONCAT(day, timeAt)", timeFrom, timeTo).
|
||||
Count()
|
||||
@@ -528,6 +547,7 @@ func (this *ServerBandwidthStatDAO) FindPercentileBetweenTimes(tx *dbs.Tx, serve
|
||||
// 查询 nth 位置
|
||||
one, err := this.Query(tx).
|
||||
Table(this.partialTable(serverId)).
|
||||
Between("day", timeFrom[:8], timeTo[:8]).
|
||||
Attr("serverId", serverId).
|
||||
Between("CONCAT(day, timeAt)", timeFrom, timeTo).
|
||||
Desc(this.bytesOrderField(useAvg)).
|
||||
@@ -540,6 +560,191 @@ func (this *ServerBandwidthStatDAO) FindPercentileBetweenTimes(tx *dbs.Tx, serve
|
||||
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 清理过期数据
|
||||
func (this *ServerBandwidthStatDAO) Clean(tx *dbs.Tx) error {
|
||||
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
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ import (
|
||||
func TestServerBandwidthStatDAO_UpdateServerBandwidth(t *testing.T) {
|
||||
var dao = models.NewServerBandwidthStatDAO()
|
||||
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 {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -28,9 +28,12 @@ func TestSeverBandwidthStatDAO_InsertManyStats(t *testing.T) {
|
||||
var tx *dbs.Tx
|
||||
var count = 1 // 测试时将此值设为一个比较大的数字
|
||||
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 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 {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -2,27 +2,37 @@ package models
|
||||
|
||||
// ServerBandwidthStat 服务峰值带宽统计
|
||||
type ServerBandwidthStat struct {
|
||||
Id uint64 `field:"id"` // ID
|
||||
UserId uint64 `field:"userId"` // 用户ID
|
||||
ServerId uint64 `field:"serverId"` // 服务ID
|
||||
RegionId uint32 `field:"regionId"` // 区域ID
|
||||
Day string `field:"day"` // 日期YYYYMMDD
|
||||
TimeAt string `field:"timeAt"` // 时间点HHMM
|
||||
Bytes uint64 `field:"bytes"` // 带宽字节
|
||||
AvgBytes uint64 `field:"avgBytes"` // 平均流量
|
||||
TotalBytes uint64 `field:"totalBytes"` // 总流量
|
||||
Id uint64 `field:"id"` // ID
|
||||
UserId uint64 `field:"userId"` // 用户ID
|
||||
ServerId uint64 `field:"serverId"` // 服务ID
|
||||
RegionId uint32 `field:"regionId"` // 区域ID
|
||||
Day string `field:"day"` // 日期YYYYMMDD
|
||||
TimeAt string `field:"timeAt"` // 时间点HHMM
|
||||
Bytes uint64 `field:"bytes"` // 带宽字节
|
||||
AvgBytes uint64 `field:"avgBytes"` // 平均流量
|
||||
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 {
|
||||
Id any // ID
|
||||
UserId any // 用户ID
|
||||
ServerId any // 服务ID
|
||||
RegionId any // 区域ID
|
||||
Day any // 日期YYYYMMDD
|
||||
TimeAt any // 时间点HHMM
|
||||
Bytes any // 带宽字节
|
||||
AvgBytes any // 平均流量
|
||||
TotalBytes any // 总流量
|
||||
Id any // ID
|
||||
UserId any // 用户ID
|
||||
ServerId any // 服务ID
|
||||
RegionId any // 区域ID
|
||||
Day any // 日期YYYYMMDD
|
||||
TimeAt any // 时间点HHMM
|
||||
Bytes any // 带宽字节
|
||||
AvgBytes any // 平均流量
|
||||
CachedBytes any // 缓存的流量
|
||||
AttackBytes any // 攻击流量
|
||||
CountRequests any // 请求数
|
||||
CountCachedRequests any // 缓存的请求数
|
||||
CountAttackRequests any // 攻击请求数
|
||||
TotalBytes any // 总流量
|
||||
}
|
||||
|
||||
func NewServerBandwidthStatOperator() *ServerBandwidthStatOperator {
|
||||
|
||||
@@ -61,19 +61,24 @@ func (this *ServerDailyStatDAO) SaveStats(tx *dbs.Tx, stats []*pb.ServerDailySta
|
||||
var serverUserMap = map[int64]int64{} // serverId => userId
|
||||
var cacheMap = utils.NewCacheMap()
|
||||
for _, stat := range stats {
|
||||
day := timeutil.FormatTime("Ymd", stat.CreatedAt)
|
||||
hour := timeutil.FormatTime("YmdH", stat.CreatedAt)
|
||||
timeFrom := timeutil.FormatTime("His", stat.CreatedAt)
|
||||
timeTo := timeutil.FormatTime("His", stat.CreatedAt+5*60-1) // 5分钟
|
||||
var day = timeutil.FormatTime("Ymd", stat.CreatedAt)
|
||||
var hour = timeutil.FormatTime("YmdH", stat.CreatedAt)
|
||||
var timeFrom = timeutil.FormatTime("His", stat.CreatedAt)
|
||||
var timeTo = timeutil.FormatTime("His", stat.CreatedAt+5*60-1) // 5分钟
|
||||
|
||||
// 所属用户
|
||||
serverUserId, ok := serverUserMap[stat.ServerId]
|
||||
if !ok {
|
||||
userId, err := SharedServerDAO.FindServerUserId(tx, stat.ServerId)
|
||||
if err != nil {
|
||||
return err
|
||||
// 用户ID
|
||||
var serverUserId = stat.UserId
|
||||
if serverUserId == 0 {
|
||||
var ok bool
|
||||
serverUserId, ok = serverUserMap[stat.ServerId]
|
||||
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).
|
||||
@@ -195,7 +200,7 @@ func (this *ServerDailyStatDAO) SumUserMonthlyPeek(tx *dbs.Tx, userId int64, reg
|
||||
|
||||
// SumUserDaily 获取某天流量总和
|
||||
// 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)
|
||||
if regionId > 0 {
|
||||
query.Attr("regionId", regionId)
|
||||
@@ -234,7 +239,7 @@ func (this *ServerDailyStatDAO) SumUserTrafficBytesBetweenDays(tx *dbs.Tx, userI
|
||||
|
||||
// SumUserMonthly 获取某月流量总和
|
||||
// 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).
|
||||
Between("day", month+"01", month+"31").
|
||||
Attr("userId", userId).
|
||||
@@ -323,10 +328,10 @@ func (this *ServerDailyStatDAO) SumHourlyStat(tx *dbs.Tx, serverId int64, hour s
|
||||
return
|
||||
}
|
||||
|
||||
// SumDailyStat 获取某天内的流量
|
||||
// compatSumDailyStat 获取某天内的流量
|
||||
// dayFrom 格式为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{}
|
||||
|
||||
if userId <= 0 && serverId <= 0 {
|
||||
@@ -463,7 +468,7 @@ func (this *ServerDailyStatDAO) SumMonthlyBytes(tx *dbs.Tx, serverId int64, mont
|
||||
}
|
||||
|
||||
// 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).
|
||||
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).
|
||||
@@ -476,7 +481,7 @@ func (this *ServerDailyStatDAO) FindDailyStats(tx *dbs.Tx, serverId int64, dayFr
|
||||
|
||||
dayMap := map[string]*ServerDailyStat{} // day => Stat
|
||||
for _, one := range ones {
|
||||
stat := one.(*ServerDailyStat)
|
||||
var stat = one.(*ServerDailyStat)
|
||||
dayMap[stat.Day] = stat
|
||||
}
|
||||
days, err := utils.RangeDays(dayFrom, dayTo)
|
||||
@@ -640,7 +645,7 @@ func (this *ServerDailyStatDAO) FindMonthlyStatsWithPlan(tx *dbs.Tx, month strin
|
||||
}
|
||||
|
||||
// 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).
|
||||
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).
|
||||
@@ -651,9 +656,11 @@ func (this *ServerDailyStatDAO) FindHourlyStats(tx *dbs.Tx, serverId int64, hour
|
||||
return nil, err
|
||||
}
|
||||
|
||||
hourMap := map[string]*ServerDailyStat{} // hour => Stat
|
||||
var hourMap = map[string]*ServerDailyStat{} // hour => Stat
|
||||
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
|
||||
}
|
||||
hours, err := utils.RangeHours(hourFrom, hourTo)
|
||||
@@ -665,7 +672,11 @@ func (this *ServerDailyStatDAO) FindHourlyStats(tx *dbs.Tx, serverId int64, hour
|
||||
if ok {
|
||||
result = append(result, stat)
|
||||
} else {
|
||||
result = append(result, &ServerDailyStat{Hour: hour})
|
||||
result = append(result, &ServerDailyStat{
|
||||
Hour: hour,
|
||||
Day: hour[:8],
|
||||
TimeFrom: hour[8:] + "00",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
package models
|
||||
package models_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
"github.com/iwind/TeaGo/logs"
|
||||
"github.com/iwind/TeaGo/rands"
|
||||
timeutil "github.com/iwind/TeaGo/utils/time"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -12,7 +15,7 @@ import (
|
||||
|
||||
func TestServerDailyStatDAO_SaveStats(t *testing.T) {
|
||||
var tx *dbs.Tx
|
||||
stats := []*pb.ServerDailyStat{
|
||||
var stats = []*pb.ServerDailyStat{
|
||||
{
|
||||
ServerId: 1,
|
||||
NodeRegionId: 2,
|
||||
@@ -20,7 +23,7 @@ func TestServerDailyStatDAO_SaveStats(t *testing.T) {
|
||||
CreatedAt: 1607671488,
|
||||
},
|
||||
}
|
||||
err := NewServerDailyStatDAO().SaveStats(tx, stats)
|
||||
err := models.NewServerDailyStatDAO().SaveStats(tx, stats)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -29,7 +32,7 @@ func TestServerDailyStatDAO_SaveStats(t *testing.T) {
|
||||
|
||||
func TestServerDailyStatDAO_SaveStats2(t *testing.T) {
|
||||
var tx *dbs.Tx
|
||||
stats := []*pb.ServerDailyStat{
|
||||
var stats = []*pb.ServerDailyStat{
|
||||
{
|
||||
ServerId: 1,
|
||||
NodeRegionId: 3,
|
||||
@@ -37,7 +40,7 @@ func TestServerDailyStatDAO_SaveStats2(t *testing.T) {
|
||||
CreatedAt: 1607671488,
|
||||
},
|
||||
}
|
||||
err := NewServerDailyStatDAO().SaveStats(tx, stats)
|
||||
err := models.NewServerDailyStatDAO().SaveStats(tx, stats)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -47,7 +50,7 @@ func TestServerDailyStatDAO_SaveStats2(t *testing.T) {
|
||||
func TestServerDailyStatDAO_SumUserMonthly(t *testing.T) {
|
||||
dbs.NotifyReady()
|
||||
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 {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -58,7 +61,7 @@ func TestServerDailyStatDAO_SumHourlyRequests(t *testing.T) {
|
||||
dbs.NotifyReady()
|
||||
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 {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -69,7 +72,7 @@ func TestServerDailyStatDAO_SumMinutelyRequests(t *testing.T) {
|
||||
dbs.NotifyReady()
|
||||
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 {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -78,7 +81,7 @@ func TestServerDailyStatDAO_SumMinutelyRequests(t *testing.T) {
|
||||
|
||||
func TestServerDailyStatDAO_FindDistinctPlanServerIdsBetweenDay(t *testing.T) {
|
||||
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 {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -87,7 +90,7 @@ func TestServerDailyStatDAO_FindDistinctPlanServerIdsBetweenDay(t *testing.T) {
|
||||
|
||||
func TestServerDailyStatDAO_FindStatsBetweenDays(t *testing.T) {
|
||||
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 {
|
||||
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) {
|
||||
var dao = NewServerDailyStatDAO()
|
||||
var dao = models.NewServerDailyStatDAO()
|
||||
var tx *dbs.Tx
|
||||
stats, err := dao.FindStatsWithDay(tx, 23, timeutil.Format("Ymd"), "000000", "235900")
|
||||
if err != nil {
|
||||
|
||||
@@ -1 +1,50 @@
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"github.com/iwind/TeaGo/Tea"
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
@@ -31,6 +32,10 @@ const (
|
||||
ServerStateDisabled = 0 // 已禁用
|
||||
)
|
||||
|
||||
const (
|
||||
ModelServerNameMaxLength = 60
|
||||
)
|
||||
|
||||
type ServerDAO dbs.DAO
|
||||
|
||||
func NewServerDAO() *ServerDAO {
|
||||
@@ -121,7 +126,7 @@ func (this *ServerDAO) FindEnabledServerBasic(tx *dbs.Tx, serverId int64) (*Serv
|
||||
result, err := this.Query(tx).
|
||||
Pk(serverId).
|
||||
State(ServerStateEnabled).
|
||||
Result("id", "name", "description", "isOn", "type", "clusterId", "userId").
|
||||
Result("id", "name", "description", "isOn", "type", "clusterId", "userId", "groupIds").
|
||||
Find()
|
||||
if result == nil {
|
||||
return nil, err
|
||||
@@ -205,6 +210,15 @@ func (this *ServerDAO) CreateServer(tx *dbs.Tx,
|
||||
if IsNotNull(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
|
||||
if IsNotNull(reverseProxyJSON) {
|
||||
op.ReverseProxy = reverseProxyJSON
|
||||
@@ -783,9 +797,11 @@ func (this *ServerDAO) CountAllEnabledServersMatch(tx *dbs.Tx, groupId int64, ke
|
||||
}
|
||||
if userId > 0 {
|
||||
query.Attr("userId", userId)
|
||||
query.UseIndex("userId")
|
||||
}
|
||||
if clusterId > 0 {
|
||||
query.Attr("clusterId", clusterId)
|
||||
query.UseIndex("clusterId")
|
||||
}
|
||||
if auditingFlag == configutils.BoolStateYes {
|
||||
query.Attr("isAuditing", true)
|
||||
@@ -839,9 +855,11 @@ func (this *ServerDAO) ListEnabledServersMatch(tx *dbs.Tx, offset int64, size in
|
||||
}
|
||||
if userId > 0 {
|
||||
query.Attr("userId", userId)
|
||||
query.UseIndex("userId")
|
||||
}
|
||||
if clusterId > 0 {
|
||||
query.Attr("clusterId", clusterId)
|
||||
query.UseIndex("clusterId")
|
||||
}
|
||||
if auditingFlag == 1 {
|
||||
query.Attr("isAuditing", true)
|
||||
@@ -1009,12 +1027,12 @@ func (this *ServerDAO) ComposeServerConfigWithServerId(tx *dbs.Tx, serverId int6
|
||||
if server == nil {
|
||||
return nil, ErrNotFound
|
||||
}
|
||||
return this.ComposeServerConfig(tx, server, ignoreCertData, nil, forNode, false)
|
||||
return this.ComposeServerConfig(tx, server, ignoreCertData, nil, nil, forNode, false)
|
||||
}
|
||||
|
||||
// ComposeServerConfig 构造服务的Config
|
||||
// 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 {
|
||||
return nil, ErrNotFound
|
||||
}
|
||||
@@ -1034,12 +1052,14 @@ func (this *ServerDAO) ComposeServerConfig(tx *dbs.Tx, server *Server, ignoreCer
|
||||
config.UserId = int64(server.UserId)
|
||||
config.Type = server.Type
|
||||
config.IsOn = server.IsOn
|
||||
config.Name = server.Name
|
||||
config.Description = server.Description
|
||||
if !forNode {
|
||||
config.Name = server.Name
|
||||
config.Description = server.Description
|
||||
}
|
||||
|
||||
var groupConfig *serverconfigs.ServerGroupConfig
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1098,7 +1118,9 @@ func (this *ServerDAO) ComposeServerConfig(tx *dbs.Tx, server *Server, ignoreCer
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config.HTTP = httpConfig
|
||||
if !forNode || httpConfig.IsOn {
|
||||
config.HTTP = httpConfig
|
||||
}
|
||||
}
|
||||
|
||||
// HTTPS
|
||||
@@ -1109,18 +1131,20 @@ func (this *ServerDAO) ComposeServerConfig(tx *dbs.Tx, server *Server, ignoreCer
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// SSL
|
||||
if httpsConfig.SSLPolicyRef != nil && httpsConfig.SSLPolicyRef.SSLPolicyId > 0 && !ignoreCerts {
|
||||
sslPolicyConfig, err := SharedSSLPolicyDAO.ComposePolicyConfig(tx, httpsConfig.SSLPolicyRef.SSLPolicyId, false, cacheMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if !forNode || httpsConfig.IsOn {
|
||||
// SSL
|
||||
if httpsConfig.SSLPolicyRef != nil && httpsConfig.SSLPolicyRef.SSLPolicyId > 0 && !ignoreCerts {
|
||||
sslPolicyConfig, err := SharedSSLPolicyDAO.ComposePolicyConfig(tx, httpsConfig.SSLPolicyRef.SSLPolicyId, false, dataMap, cacheMap)
|
||||
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
|
||||
@@ -1130,7 +1154,9 @@ func (this *ServerDAO) ComposeServerConfig(tx *dbs.Tx, server *Server, ignoreCer
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config.TCP = tcpConfig
|
||||
if !forNode || tcpConfig.IsOn {
|
||||
config.TCP = tcpConfig
|
||||
}
|
||||
}
|
||||
|
||||
// TLS
|
||||
@@ -1141,18 +1167,20 @@ func (this *ServerDAO) ComposeServerConfig(tx *dbs.Tx, server *Server, ignoreCer
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// SSL
|
||||
if tlsConfig.SSLPolicyRef != nil && !ignoreCerts {
|
||||
sslPolicyConfig, err := SharedSSLPolicyDAO.ComposePolicyConfig(tx, tlsConfig.SSLPolicyRef.SSLPolicyId, false, cacheMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if !forNode || tlsConfig.IsOn {
|
||||
// SSL
|
||||
if tlsConfig.SSLPolicyRef != nil && !ignoreCerts {
|
||||
sslPolicyConfig, err := SharedSSLPolicyDAO.ComposePolicyConfig(tx, tlsConfig.SSLPolicyRef.SSLPolicyId, false, dataMap, cacheMap)
|
||||
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
|
||||
@@ -1162,7 +1190,9 @@ func (this *ServerDAO) ComposeServerConfig(tx *dbs.Tx, server *Server, ignoreCer
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config.Unix = unixConfig
|
||||
if !forNode || unixConfig.IsOn {
|
||||
config.Unix = unixConfig
|
||||
}
|
||||
}
|
||||
|
||||
// UDP
|
||||
@@ -1172,13 +1202,15 @@ func (this *ServerDAO) ComposeServerConfig(tx *dbs.Tx, server *Server, ignoreCer
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config.UDP = udpConfig
|
||||
if !forNode || udpConfig.IsOn {
|
||||
config.UDP = udpConfig
|
||||
}
|
||||
}
|
||||
|
||||
// Web
|
||||
if !forList {
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1196,14 +1228,18 @@ func (this *ServerDAO) ComposeServerConfig(tx *dbs.Tx, server *Server, ignoreCer
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config.ReverseProxyRef = reverseProxyRef
|
||||
if !forNode || reverseProxyRef.IsOn {
|
||||
config.ReverseProxyRef = reverseProxyRef
|
||||
|
||||
reverseProxyConfig, err := SharedReverseProxyDAO.ComposeReverseProxyConfig(tx, reverseProxyRef.ReverseProxyId, cacheMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if reverseProxyConfig != nil {
|
||||
config.ReverseProxy = reverseProxyConfig
|
||||
reverseProxyConfig, err := SharedReverseProxyDAO.ComposeReverseProxyConfig(tx, reverseProxyRef.ReverseProxyId, dataMap, cacheMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if reverseProxyConfig != nil {
|
||||
if !forNode || reverseProxyConfig.IsOn {
|
||||
config.ReverseProxy = reverseProxyConfig
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1427,7 +1463,7 @@ func (this *ServerDAO) CountEnabledServersWithWebIds(tx *dbs.Tx, webIds []int64)
|
||||
Count()
|
||||
}
|
||||
|
||||
// FindAllEnabledServersWithWebIds 查找使用某个缓存策略的所有服务
|
||||
// FindAllEnabledServersWithWebIds 通过WebId查找服务
|
||||
func (this *ServerDAO) FindAllEnabledServersWithWebIds(tx *dbs.Tx, webIds []int64) (result []*Server, err error) {
|
||||
if len(webIds) == 0 {
|
||||
return
|
||||
@@ -1435,6 +1471,7 @@ func (this *ServerDAO) FindAllEnabledServersWithWebIds(tx *dbs.Tx, webIds []int6
|
||||
_, err = this.Query(tx).
|
||||
State(ServerStateEnabled).
|
||||
Attr("webId", webIds).
|
||||
UseIndex("webId").
|
||||
Reuse(false).
|
||||
AscPk().
|
||||
Slice(&result).
|
||||
@@ -2763,6 +2800,28 @@ func (this *ServerDAO) UpdateServerUserId(tx *dbs.Tx, serverId int64, userId int
|
||||
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 同步服务所在的集群
|
||||
func (this *ServerDAO) NotifyUpdate(tx *dbs.Tx, serverId int64) error {
|
||||
// 创建任务
|
||||
|
||||
35
internal/db/models/server_dao_copy_ext.go
Normal file
35
internal/db/models/server_dao_copy_ext.go
Normal 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")
|
||||
}
|
||||
@@ -190,7 +190,7 @@ func TestServerDAO_FindAllEnabledServersWithNode_Cache(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
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)
|
||||
}
|
||||
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")
|
||||
@@ -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) {
|
||||
models.SharedServerDAO = models.NewServerDAO()
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"github.com/iwind/TeaGo/Tea"
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
@@ -279,7 +280,7 @@ func (this *ServerGroupDAO) InitGroupWeb(tx *dbs.Tx, groupId int64) (int64, erro
|
||||
}
|
||||
|
||||
// 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 {
|
||||
cacheMap = utils.NewCacheMap()
|
||||
}
|
||||
@@ -324,7 +325,7 @@ func (this *ServerGroupDAO) ComposeGroupConfig(tx *dbs.Tx, groupId int64, forLis
|
||||
}
|
||||
config.HTTPReverseProxyRef = reverseProxyRef
|
||||
|
||||
reverseProxyConfig, err := SharedReverseProxyDAO.ComposeReverseProxyConfig(tx, reverseProxyRef.ReverseProxyId, cacheMap)
|
||||
reverseProxyConfig, err := SharedReverseProxyDAO.ComposeReverseProxyConfig(tx, reverseProxyRef.ReverseProxyId, dataMap, cacheMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -341,7 +342,7 @@ func (this *ServerGroupDAO) ComposeGroupConfig(tx *dbs.Tx, groupId int64, forLis
|
||||
}
|
||||
config.TCPReverseProxyRef = reverseProxyRef
|
||||
|
||||
reverseProxyConfig, err := SharedReverseProxyDAO.ComposeReverseProxyConfig(tx, reverseProxyRef.ReverseProxyId, cacheMap)
|
||||
reverseProxyConfig, err := SharedReverseProxyDAO.ComposeReverseProxyConfig(tx, reverseProxyRef.ReverseProxyId, dataMap, cacheMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -358,7 +359,7 @@ func (this *ServerGroupDAO) ComposeGroupConfig(tx *dbs.Tx, groupId int64, forLis
|
||||
}
|
||||
config.UDPReverseProxyRef = reverseProxyRef
|
||||
|
||||
reverseProxyConfig, err := SharedReverseProxyDAO.ComposeReverseProxyConfig(tx, reverseProxyRef.ReverseProxyId, cacheMap)
|
||||
reverseProxyConfig, err := SharedReverseProxyDAO.ComposeReverseProxyConfig(tx, reverseProxyRef.ReverseProxyId, dataMap, cacheMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -369,7 +370,7 @@ func (this *ServerGroupDAO) ComposeGroupConfig(tx *dbs.Tx, groupId int64, forLis
|
||||
|
||||
// web
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
@@ -423,6 +424,18 @@ func (this *ServerGroupDAO) ExistsGroup(tx *dbs.Tx, groupId int64) (bool, error)
|
||||
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 通知更新
|
||||
func (this *ServerGroupDAO) NotifyUpdate(tx *dbs.Tx, groupId int64) error {
|
||||
serverIds, err := SharedServerDAO.FindAllEnabledServerIdsWithGroupId(tx, groupId)
|
||||
|
||||
@@ -78,7 +78,7 @@ func (this *Server) DecodeHTTPSPorts() (ports []int) {
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
err = config.Init()
|
||||
err = config.Init(nil)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
@@ -120,7 +120,7 @@ func (this *Server) DecodeTLSPorts() (ports []int) {
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
err = config.Init()
|
||||
err = config.Init(nil)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -6,12 +6,15 @@ import (
|
||||
"errors"
|
||||
dbutils "github.com/TeaOSLab/EdgeAPI/internal/db/utils"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/sslconfigs"
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"github.com/iwind/TeaGo/Tea"
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
timeutil "github.com/iwind/TeaGo/utils/time"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -201,7 +204,7 @@ func (this *SSLCertDAO) UpdateCert(tx *dbs.Tx,
|
||||
|
||||
// ComposeCertConfig 组合配置
|
||||
// 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 {
|
||||
cacheMap = utils.NewCacheMap()
|
||||
}
|
||||
@@ -227,8 +230,17 @@ func (this *SSLCertDAO) ComposeCertConfig(tx *dbs.Tx, certId int64, ignoreData b
|
||||
config.Name = cert.Name
|
||||
config.Description = cert.Description
|
||||
if !ignoreData {
|
||||
config.CertData = cert.CertData
|
||||
config.KeyData = cert.KeyData
|
||||
if dataMap != nil {
|
||||
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.TimeBeginAt = int64(cert.TimeBeginAt)
|
||||
@@ -236,7 +248,13 @@ func (this *SSLCertDAO) ComposeCertConfig(tx *dbs.Tx, certId int64, ignoreData b
|
||||
|
||||
// OCSP
|
||||
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.OCSPError = cert.OcspError
|
||||
@@ -267,8 +285,8 @@ func (this *SSLCertDAO) ComposeCertConfig(tx *dbs.Tx, certId int64, ignoreData b
|
||||
}
|
||||
|
||||
// CountCerts 计算符合条件的证书数量
|
||||
func (this *SSLCertDAO) CountCerts(tx *dbs.Tx, isCA bool, isAvailable bool, isExpired bool, expiringDays int64, keyword string, userId int64) (int64, error) {
|
||||
query := this.Query(tx).
|
||||
func (this *SSLCertDAO) CountCerts(tx *dbs.Tx, isCA bool, isAvailable bool, isExpired bool, expiringDays int64, keyword string, userId int64, domains []string) (int64, error) {
|
||||
var query = this.Query(tx).
|
||||
State(SSLCertStateEnabled)
|
||||
if isCA {
|
||||
query.Attr("isCA", true)
|
||||
@@ -293,12 +311,19 @@ func (this *SSLCertDAO) CountCerts(tx *dbs.Tx, isCA bool, isAvailable bool, isEx
|
||||
// 只查询管理员上传的
|
||||
query.Attr("userId", 0)
|
||||
}
|
||||
|
||||
// 域名
|
||||
err := this.buildDomainSearchingQuery(query, domains)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return query.Count()
|
||||
}
|
||||
|
||||
// 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) {
|
||||
query := this.Query(tx).
|
||||
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) {
|
||||
var query = this.Query(tx).
|
||||
State(SSLCertStateEnabled)
|
||||
if isCA {
|
||||
query.Attr("isCA", true)
|
||||
@@ -324,6 +349,12 @@ func (this *SSLCertDAO) ListCertIds(tx *dbs.Tx, isCA bool, isAvailable bool, isE
|
||||
query.Attr("userId", 0)
|
||||
}
|
||||
|
||||
// 域名
|
||||
err = this.buildDomainSearchingQuery(query, domains)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ones, err := query.
|
||||
ResultPk().
|
||||
DescPk().
|
||||
@@ -334,7 +365,7 @@ func (this *SSLCertDAO) ListCertIds(tx *dbs.Tx, isCA bool, isAvailable bool, isE
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := []int64{}
|
||||
var result = []int64{}
|
||||
for _, one := range ones {
|
||||
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)
|
||||
_, err = this.Query(tx).
|
||||
State(SSLCertStateEnabled).
|
||||
Attr("isOn", true).
|
||||
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("today", timeutil.Format("Y-m-d")).
|
||||
@@ -633,3 +665,73 @@ func (this *SSLCertDAO) NotifyUpdate(tx *dbs.Tx, certId int64) error {
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/sslconfigs"
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"github.com/iwind/TeaGo/Tea"
|
||||
@@ -77,7 +78,7 @@ func (this *SSLPolicyDAO) FindEnabledSSLPolicy(tx *dbs.Tx, id int64) (*SSLPolicy
|
||||
}
|
||||
|
||||
// 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 {
|
||||
cacheMap = utils.NewCacheMap()
|
||||
}
|
||||
@@ -111,7 +112,7 @@ func (this *SSLPolicyDAO) ComposePolicyConfig(tx *dbs.Tx, policyId int64, ignore
|
||||
}
|
||||
if len(refs) > 0 {
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
@@ -133,7 +134,7 @@ func (this *SSLPolicyDAO) ComposePolicyConfig(tx *dbs.Tx, policyId int64, ignore
|
||||
}
|
||||
if len(refs) > 0 {
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -114,6 +114,20 @@ func (this *NodeClusterTrafficDailyStatDAO) FindDailyStats(tx *dbs.Tx, clusterId
|
||||
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 清理历史数据
|
||||
func (this *NodeClusterTrafficDailyStatDAO) Clean(tx *dbs.Tx, days int) error {
|
||||
var day = timeutil.Format("Ymd", time.Now().AddDate(0, 0, -days))
|
||||
|
||||
@@ -117,6 +117,21 @@ func (this *NodeTrafficDailyStatDAO) FindDailyStats(tx *dbs.Tx, role string, nod
|
||||
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 清理历史数据
|
||||
func (this *NodeTrafficDailyStatDAO) Clean(tx *dbs.Tx, days int) error {
|
||||
var day = timeutil.Format("Ymd", time.Now().AddDate(0, 0, -days))
|
||||
|
||||
108
internal/db/models/updating_server_list_dao.go
Normal file
108
internal/db/models/updating_server_list_dao.go
Normal 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()
|
||||
}
|
||||
6
internal/db/models/updating_server_list_dao_test.go
Normal file
6
internal/db/models/updating_server_list_dao_test.go
Normal file
@@ -0,0 +1,6 @@
|
||||
package models_test
|
||||
|
||||
import (
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
_ "github.com/iwind/TeaGo/bootstrap"
|
||||
)
|
||||
24
internal/db/models/updating_server_list_model.go
Normal file
24
internal/db/models/updating_server_list_model.go
Normal 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{}
|
||||
}
|
||||
20
internal/db/models/updating_server_list_model_ext.go
Normal file
20
internal/db/models/updating_server_list_model_ext.go
Normal 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
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/goman"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
|
||||
@@ -26,6 +27,9 @@ const (
|
||||
UserBandwidthStatTablePartials = 20
|
||||
)
|
||||
|
||||
var fullDataMap = map[string]bool{} // month => bool
|
||||
var fullDataLocker = &sync.Mutex{}
|
||||
|
||||
func init() {
|
||||
dbs.OnReadyDone(func() {
|
||||
// 清理数据任务
|
||||
@@ -61,7 +65,7 @@ func init() {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
// 如果用户ID不大于0,则说明服务不属于任何用户,此时不需要处理
|
||||
return nil
|
||||
@@ -71,18 +75,33 @@ func (this *UserBandwidthStatDAO) UpdateUserBandwidth(tx *dbs.Tx, userId int64,
|
||||
Table(this.partialTable(userId)).
|
||||
Param("bytes", bytes).
|
||||
Param("totalBytes", totalBytes).
|
||||
Param("cachedBytes", cachedBytes).
|
||||
Param("attackBytes", attackBytes).
|
||||
Param("countRequests", countRequests).
|
||||
Param("countCachedRequests", countCachedRequests).
|
||||
Param("countAttackRequests", countAttackRequests).
|
||||
InsertOrUpdateQuickly(maps.Map{
|
||||
"userId": userId,
|
||||
"regionId": regionId,
|
||||
"day": day,
|
||||
"timeAt": timeAt,
|
||||
"bytes": bytes,
|
||||
"totalBytes": totalBytes,
|
||||
"avgBytes": totalBytes / 300,
|
||||
"userId": userId,
|
||||
"regionId": regionId,
|
||||
"day": day,
|
||||
"timeAt": timeAt,
|
||||
"bytes": bytes,
|
||||
"totalBytes": totalBytes,
|
||||
"avgBytes": totalBytes / 300,
|
||||
"cachedBytes": cachedBytes,
|
||||
"attackBytes": attackBytes,
|
||||
"countRequests": countRequests,
|
||||
"countCachedRequests": countCachedRequests,
|
||||
"countAttackRequests": countAttackRequests,
|
||||
}, maps.Map{
|
||||
"bytes": dbs.SQL("bytes+:bytes"),
|
||||
"avgBytes": dbs.SQL("(totalBytes+:totalBytes)/300"), // 因为生成SQL语句时会自动将avgBytes排在totalBytes之前,所以这里不用担心先后顺序的问题
|
||||
"totalBytes": dbs.SQL("totalBytes+:totalBytes"),
|
||||
"bytes": dbs.SQL("bytes+:bytes"),
|
||||
"avgBytes": dbs.SQL("(totalBytes+:totalBytes)/300"), // 因为生成SQL语句时会自动将avgBytes排在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
|
||||
}
|
||||
|
||||
// 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 清理过期数据
|
||||
func (this *UserBandwidthStatDAO) Clean(tx *dbs.Tx) error {
|
||||
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
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ func TestUserBandwidthStatDAO_FindUserPeekBandwidthInDay(t *testing.T) {
|
||||
func TestUserBandwidthStatDAO_UpdateServerBandwidth(t *testing.T) {
|
||||
var dao = models.NewUserBandwidthStatDAO()
|
||||
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 {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -93,3 +93,13 @@ func TestUserBandwidthStatDAO_FindPercentileBetweenDays(t *testing.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))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,25 +2,35 @@ package models
|
||||
|
||||
// UserBandwidthStat 用户月带宽峰值
|
||||
type UserBandwidthStat struct {
|
||||
Id uint64 `field:"id"` // ID
|
||||
UserId uint64 `field:"userId"` // 用户ID
|
||||
RegionId uint32 `field:"regionId"` // 区域ID
|
||||
Day string `field:"day"` // 日期YYYYMMDD
|
||||
TimeAt string `field:"timeAt"` // 时间点HHII
|
||||
Bytes uint64 `field:"bytes"` // 带宽
|
||||
TotalBytes uint64 `field:"totalBytes"` // 总流量
|
||||
AvgBytes uint64 `field:"avgBytes"` // 平均流量
|
||||
Id uint64 `field:"id"` // ID
|
||||
UserId uint64 `field:"userId"` // 用户ID
|
||||
RegionId uint32 `field:"regionId"` // 区域ID
|
||||
Day string `field:"day"` // 日期YYYYMMDD
|
||||
TimeAt string `field:"timeAt"` // 时间点HHII
|
||||
Bytes uint64 `field:"bytes"` // 带宽
|
||||
TotalBytes uint64 `field:"totalBytes"` // 总流量
|
||||
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 {
|
||||
Id any // ID
|
||||
UserId any // 用户ID
|
||||
RegionId any // 区域ID
|
||||
Day any // 日期YYYYMMDD
|
||||
TimeAt any // 时间点HHII
|
||||
Bytes any // 带宽
|
||||
TotalBytes any // 总流量
|
||||
AvgBytes any // 平均流量
|
||||
Id any // ID
|
||||
UserId any // 用户ID
|
||||
RegionId any // 区域ID
|
||||
Day any // 日期YYYYMMDD
|
||||
TimeAt any // 时间点HHII
|
||||
Bytes any // 带宽
|
||||
TotalBytes any // 总流量
|
||||
AvgBytes any // 平均流量
|
||||
CachedBytes any // 缓存的流量
|
||||
AttackBytes any // 攻击流量
|
||||
CountRequests any // 请求数
|
||||
CountCachedRequests any // 缓存的请求数
|
||||
CountAttackRequests any // 攻击请求数
|
||||
}
|
||||
|
||||
func NewUserBandwidthStatOperator() *UserBandwidthStatOperator {
|
||||
|
||||
@@ -36,7 +36,7 @@ func (this *UserNode) DecodeHTTPS(cacheMap *utils.CacheMap) (*serverconfigs.HTTP
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = config.Init()
|
||||
err = config.Init(nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -44,7 +44,7 @@ func (this *UserNode) DecodeHTTPS(cacheMap *utils.CacheMap) (*serverconfigs.HTTP
|
||||
if config.SSLPolicyRef != nil {
|
||||
policyId := config.SSLPolicyRef.SSLPolicyId
|
||||
if policyId > 0 {
|
||||
sslPolicy, err := SharedSSLPolicyDAO.ComposePolicyConfig(nil, policyId, false, cacheMap)
|
||||
sslPolicy, err := SharedSSLPolicyDAO.ComposePolicyConfig(nil, policyId, false, nil, cacheMap)
|
||||
if err != nil {
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package dbutils
|
||||
|
||||
import (
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
"net"
|
||||
"strings"
|
||||
)
|
||||
@@ -93,3 +94,36 @@ func IsLocalAddr(addr string) bool {
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
@@ -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: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())
|
||||
}
|
||||
|
||||
@@ -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"`
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -29,8 +29,12 @@ func (this *errorObj) Error() string {
|
||||
return s
|
||||
}
|
||||
|
||||
// 新错误
|
||||
// New 新错误
|
||||
func New(errText string) error {
|
||||
if !Tea.IsTesting() {
|
||||
return errors.New(errText)
|
||||
}
|
||||
|
||||
ptr, file, line, ok := runtime.Caller(1)
|
||||
funcName := ""
|
||||
if ok {
|
||||
@@ -45,7 +49,7 @@ func New(errText string) error {
|
||||
}
|
||||
}
|
||||
|
||||
// 包装已有错误
|
||||
// Wrap 包装已有错误
|
||||
func Wrap(err error) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"github.com/iwind/TeaGo/files"
|
||||
stringutil "github.com/iwind/TeaGo/utils/string"
|
||||
"regexp"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var SharedDeployManager = NewDeployManager()
|
||||
@@ -12,9 +13,12 @@ var SharedDeployManager = NewDeployManager()
|
||||
// DeployManager 节点部署文件管理器
|
||||
// 如果节点部署文件有变化,需要重启API节点以便于生效
|
||||
type DeployManager struct {
|
||||
dir string
|
||||
dir string
|
||||
|
||||
nodeFiles []*DeployFile
|
||||
nsNodeFiles []*DeployFile
|
||||
|
||||
locker sync.Mutex
|
||||
}
|
||||
|
||||
// NewDeployManager 获取新节点部署文件管理器
|
||||
@@ -29,24 +33,27 @@ func NewDeployManager() *DeployManager {
|
||||
|
||||
// LoadNodeFiles 加载所有边缘节点文件
|
||||
func (this *DeployManager) LoadNodeFiles() []*DeployFile {
|
||||
this.locker.Lock()
|
||||
defer this.locker.Unlock()
|
||||
|
||||
if len(this.nodeFiles) > 0 {
|
||||
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() {
|
||||
name := file.Name()
|
||||
var name = file.Name()
|
||||
if !reg.MatchString(name) {
|
||||
continue
|
||||
}
|
||||
matches := reg.FindStringSubmatch(name)
|
||||
osName := matches[1]
|
||||
arch := matches[2]
|
||||
version := matches[3]
|
||||
var matches = reg.FindStringSubmatch(name)
|
||||
var osName = matches[1]
|
||||
var arch = matches[2]
|
||||
var version = matches[3]
|
||||
|
||||
key := osName + "_" + arch
|
||||
var key = osName + "_" + arch
|
||||
oldFile, ok := keyMap[key]
|
||||
if ok && stringutil.VersionCompare(oldFile.Version, version) > 0 {
|
||||
continue
|
||||
@@ -59,7 +66,7 @@ func (this *DeployManager) LoadNodeFiles() []*DeployFile {
|
||||
}
|
||||
}
|
||||
|
||||
result := []*DeployFile{}
|
||||
var result = []*DeployFile{}
|
||||
for _, v := range keyMap {
|
||||
result = append(result, v)
|
||||
}
|
||||
@@ -81,24 +88,27 @@ func (this *DeployManager) FindNodeFile(os string, arch string) *DeployFile {
|
||||
|
||||
// LoadNSNodeFiles 加载所有NS节点安装文件
|
||||
func (this *DeployManager) LoadNSNodeFiles() []*DeployFile {
|
||||
this.locker.Lock()
|
||||
defer this.locker.Unlock()
|
||||
|
||||
if len(this.nsNodeFiles) > 0 {
|
||||
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() {
|
||||
name := file.Name()
|
||||
var name = file.Name()
|
||||
if !reg.MatchString(name) {
|
||||
continue
|
||||
}
|
||||
matches := reg.FindStringSubmatch(name)
|
||||
osName := matches[1]
|
||||
arch := matches[2]
|
||||
version := matches[3]
|
||||
var matches = reg.FindStringSubmatch(name)
|
||||
var osName = matches[1]
|
||||
var arch = matches[2]
|
||||
var version = matches[3]
|
||||
|
||||
key := osName + "_" + arch
|
||||
var key = osName + "_" + arch
|
||||
oldFile, ok := keyMap[key]
|
||||
if ok && stringutil.VersionCompare(oldFile.Version, version) > 0 {
|
||||
continue
|
||||
@@ -111,7 +121,7 @@ func (this *DeployManager) LoadNSNodeFiles() []*DeployFile {
|
||||
}
|
||||
}
|
||||
|
||||
result := []*DeployFile{}
|
||||
var result = []*DeployFile{}
|
||||
for _, v := range keyMap {
|
||||
result = append(result, v)
|
||||
}
|
||||
@@ -130,3 +140,12 @@ func (this *DeployManager) FindNSNodeFile(os string, arch string) *DeployFile {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Reload 重置缓存
|
||||
func (this *DeployManager) Reload() {
|
||||
this.locker.Lock()
|
||||
defer this.locker.Unlock()
|
||||
|
||||
this.nodeFiles = nil
|
||||
this.nsNodeFiles = nil
|
||||
}
|
||||
|
||||
@@ -268,8 +268,8 @@ func (this *APINode) InstallSystemService() error {
|
||||
func (this *APINode) listenRPC(listener net.Listener, tlsConfig *tls.Config) error {
|
||||
var rpcServer *grpc.Server
|
||||
var options = []grpc.ServerOption{
|
||||
grpc.MaxRecvMsgSize(128 * 1024 * 1024),
|
||||
grpc.MaxSendMsgSize(128 * 1024 * 1024),
|
||||
grpc.MaxRecvMsgSize(512 << 20),
|
||||
grpc.MaxSendMsgSize(512 << 20),
|
||||
grpc.UnaryInterceptor(this.unaryInterceptor),
|
||||
}
|
||||
|
||||
@@ -306,13 +306,27 @@ func (this *APINode) checkDB() error {
|
||||
logs.Println("[API_NODE]" + 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
|
||||
if Tea.IsTesting() {
|
||||
maxTries = 600
|
||||
}
|
||||
for i := 0; i <= maxTries; i++ {
|
||||
_, err := db.Exec("SELECT 1")
|
||||
_, err = db.Exec("SELECT 1")
|
||||
if err != nil {
|
||||
if i == maxTries-1 {
|
||||
return err
|
||||
@@ -741,6 +755,41 @@ func (this *APINode) listenSock() error {
|
||||
"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 + "'",
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -559,6 +559,12 @@ func (this *APINode) registerServices(server *grpc.Server) {
|
||||
this.rest(instance)
|
||||
}
|
||||
|
||||
{
|
||||
var instance = this.serviceInstance(&services.UpdatingServerListService{}).(*services.UpdatingServerListService)
|
||||
pb.RegisterUpdatingServerListServiceServer(server, instance)
|
||||
this.rest(instance)
|
||||
}
|
||||
|
||||
APINodeServicesRegister(this, server)
|
||||
|
||||
// TODO check service names
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
package nodes
|
||||
@@ -31,7 +32,7 @@ func (this *NodeStatusExecutor) updateMem(status *nodeconfigs.NodeStatus) {
|
||||
if minFreeMemory > 1<<30 {
|
||||
minFreeMemory = 1 << 30
|
||||
}
|
||||
if stat.Free < minFreeMemory {
|
||||
if stat.Available > 0 && stat.Available < minFreeMemory {
|
||||
runtime.GC()
|
||||
debug.FreeOSMemory()
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ var sharedDAO DAOInterface
|
||||
|
||||
func init() {
|
||||
// 定期上传日志
|
||||
ticker := time.NewTicker(60 * time.Second)
|
||||
var ticker = time.NewTicker(60 * time.Second)
|
||||
goman.New(func() {
|
||||
for range ticker.C {
|
||||
err := uploadLogs()
|
||||
|
||||
@@ -232,6 +232,12 @@ func (this *ACMETaskService) CreateACMETask(ctx context.Context, req *pb.CreateA
|
||||
req.AuthType = acme.AuthTypeDNS
|
||||
}
|
||||
|
||||
if adminId > 0 {
|
||||
if req.UserId > 0 {
|
||||
userId = req.UserId
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
if err != nil {
|
||||
|
||||
@@ -22,6 +22,12 @@ func (this *ACMEUserService) CreateACMEUser(ctx context.Context, req *pb.CreateA
|
||||
|
||||
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)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -127,7 +127,7 @@ func (this *AdminService) FindAdminFullname(ctx context.Context, req *pb.FindAdm
|
||||
|
||||
// FindEnabledAdmin 获取管理员信息
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
@@ -136,6 +136,12 @@ func (this *AdminService) FindEnabledAdmin(ctx context.Context, req *pb.FindEnab
|
||||
|
||||
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)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -144,7 +150,7 @@ func (this *AdminService) FindEnabledAdmin(ctx context.Context, req *pb.FindEnab
|
||||
return &pb.FindEnabledAdminResponse{Admin: nil}, nil
|
||||
}
|
||||
|
||||
pbModules := []*pb.AdminModule{}
|
||||
var pbModules = []*pb.AdminModule{}
|
||||
modules := []*systemconfigs.AdminModule{}
|
||||
if len(admin.Modules) > 0 {
|
||||
err = json.Unmarshal(admin.Modules, &modules)
|
||||
@@ -178,14 +184,15 @@ func (this *AdminService) FindEnabledAdmin(ctx context.Context, req *pb.FindEnab
|
||||
}
|
||||
|
||||
result := &pb.Admin{
|
||||
Id: int64(admin.Id),
|
||||
Fullname: admin.Fullname,
|
||||
Username: admin.Username,
|
||||
IsOn: admin.IsOn,
|
||||
IsSuper: admin.IsSuper,
|
||||
Modules: pbModules,
|
||||
OtpLogin: pbOtpAuth,
|
||||
CanLogin: admin.CanLogin,
|
||||
Id: int64(admin.Id),
|
||||
Fullname: admin.Fullname,
|
||||
Username: admin.Username,
|
||||
IsOn: admin.IsOn,
|
||||
IsSuper: admin.IsSuper,
|
||||
Modules: pbModules,
|
||||
OtpLogin: pbOtpAuth,
|
||||
CanLogin: admin.CanLogin,
|
||||
HasWeakPassword: isSuperAdmin && admin.HasWeakPassword(),
|
||||
}
|
||||
return &pb.FindEnabledAdminResponse{Admin: result}, nil
|
||||
}
|
||||
@@ -347,7 +354,7 @@ func (this *AdminService) UpdateAdmin(ctx context.Context, req *pb.UpdateAdminRe
|
||||
|
||||
// CountAllEnabledAdmins 计算管理员数量
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
@@ -356,7 +363,13 @@ func (this *AdminService) CountAllEnabledAdmins(ctx context.Context, req *pb.Cou
|
||||
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
@@ -365,7 +378,7 @@ func (this *AdminService) CountAllEnabledAdmins(ctx context.Context, req *pb.Cou
|
||||
|
||||
// ListEnabledAdmins 列出单页的管理员
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
@@ -374,12 +387,18 @@ func (this *AdminService) ListEnabledAdmins(ctx context.Context, req *pb.ListEna
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
admins, err := models.SharedAdminDAO.ListEnabledAdmins(tx, req.Offset, req.Size)
|
||||
// 超级管理员才能查看是否为弱密码
|
||||
isSuperAdmin, err := models.SharedAdminDAO.CheckSuperAdmin(tx, adminId)
|
||||
if err != nil {
|
||||
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 {
|
||||
var pbOtpAuth *pb.Login = nil
|
||||
{
|
||||
@@ -398,14 +417,15 @@ func (this *AdminService) ListEnabledAdmins(ctx context.Context, req *pb.ListEna
|
||||
}
|
||||
|
||||
result = append(result, &pb.Admin{
|
||||
Id: int64(admin.Id),
|
||||
Fullname: admin.Fullname,
|
||||
Username: admin.Username,
|
||||
IsOn: admin.IsOn,
|
||||
IsSuper: admin.IsSuper,
|
||||
CreatedAt: int64(admin.CreatedAt),
|
||||
OtpLogin: pbOtpAuth,
|
||||
CanLogin: admin.CanLogin,
|
||||
Id: int64(admin.Id),
|
||||
Fullname: admin.Fullname,
|
||||
Username: admin.Username,
|
||||
IsOn: admin.IsOn,
|
||||
IsSuper: admin.IsSuper,
|
||||
CreatedAt: int64(admin.CreatedAt),
|
||||
OtpLogin: pbOtpAuth,
|
||||
CanLogin: admin.CanLogin,
|
||||
HasWeakPassword: isSuperAdmin && admin.HasWeakPassword(),
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"fmt"
|
||||
teaconst "github.com/TeaOSLab/EdgeAPI/internal/const"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/installers"
|
||||
rpcutils "github.com/TeaOSLab/EdgeAPI/internal/rpc/utils"
|
||||
executils "github.com/TeaOSLab/EdgeAPI/internal/utils/exec"
|
||||
"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
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
// 默认包含大部分节点
|
||||
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 {
|
||||
|
||||
@@ -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 {
|
||||
return nil, nil, nil, 0, 0, false, false, err
|
||||
}
|
||||
|
||||
@@ -29,8 +29,29 @@ func (this *HTTPCacheTaskService) CreateHTTPCacheTask(ctx context.Context, req *
|
||||
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 {
|
||||
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数量
|
||||
|
||||
@@ -60,7 +60,7 @@ func (this *HTTPLocationService) FindEnabledHTTPLocationConfig(ctx context.Conte
|
||||
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
return nil, rpcutils.Wrap("ComposeWebConfig()", err)
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ func (this *HTTPWebService) FindEnabledHTTPWebConfig(ctx context.Context, req *p
|
||||
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ func (this *IPItemService) CreateIPItem(ctx context.Context, req *pb.CreateIPIte
|
||||
return nil, errors.New("'ipFrom' should not be empty")
|
||||
}
|
||||
|
||||
ipFrom := net.ParseIP(req.IpFrom)
|
||||
var ipFrom = net.ParseIP(req.IpFrom)
|
||||
if ipFrom == nil {
|
||||
return nil, errors.New("invalid 'ipFrom'")
|
||||
}
|
||||
@@ -64,7 +64,7 @@ func (this *IPItemService) CreateIPItem(ctx context.Context, req *pb.CreateIPIte
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
@@ -72,6 +72,77 @@ func (this *IPItemService) CreateIPItem(ctx context.Context, req *pb.CreateIPIte
|
||||
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
|
||||
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删除
|
||||
if req.IpItemId > 0 {
|
||||
if userId > 0 {
|
||||
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)
|
||||
err = models.SharedIPItemDAO.DisableIPItem(tx, req.IpItemId, userId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -139,7 +198,7 @@ func (this *IPItemService) DeleteIPItem(ctx context.Context, req *pb.DeleteIPIte
|
||||
// 如果是使用ipFrom+ipTo删除
|
||||
if len(req.IpFrom) > 0 {
|
||||
// 检查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)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -157,14 +216,14 @@ func (this *IPItemService) DeleteIPItem(ctx context.Context, req *pb.DeleteIPIte
|
||||
|
||||
// DeleteIPItems 批量删除IP
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
for _, itemId := range req.IpItemIds {
|
||||
err = models.SharedIPItemDAO.DisableIPItem(tx, itemId)
|
||||
err = models.SharedIPItemDAO.DisableIPItem(tx, itemId, userId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -183,13 +242,16 @@ func (this *IPItemService) CountIPItemsWithListId(ctx context.Context, req *pb.C
|
||||
var tx = this.NullTx()
|
||||
|
||||
if userId > 0 {
|
||||
err = models.SharedIPListDAO.CheckUserIPList(tx, userId, req.IpListId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
// 检查用户所属名单
|
||||
if req.IpListId != firewallconfigs.GlobalListId {
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
@@ -207,13 +269,16 @@ func (this *IPItemService) ListIPItemsWithListId(ctx context.Context, req *pb.Li
|
||||
var tx = this.NullTx()
|
||||
|
||||
if userId > 0 {
|
||||
err = models.SharedIPListDAO.CheckUserIPList(tx, userId, req.IpListId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
// 检查用户所属名单
|
||||
if req.IpListId != firewallconfigs.GlobalListId {
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
@@ -493,17 +558,21 @@ func (this *IPItemService) ExistsEnabledIPItem(ctx context.Context, req *pb.Exis
|
||||
|
||||
// CountAllEnabledIPItems 计算所有IP数量
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if adminId > 0 {
|
||||
userId = req.UserId
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
var listId int64 = 0
|
||||
if req.GlobalOnly {
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
@@ -512,18 +581,22 @@ func (this *IPItemService) CountAllEnabledIPItems(ctx context.Context, req *pb.C
|
||||
|
||||
// ListAllEnabledIPItems 搜索IP
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if adminId > 0 {
|
||||
userId = req.UserId
|
||||
}
|
||||
|
||||
var results = []*pb.ListAllEnabledIPItemsResponse_Result{}
|
||||
var tx = this.NullTx()
|
||||
var listId int64 = 0
|
||||
if req.GlobalOnly {
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
@@ -632,7 +705,7 @@ func (this *IPItemService) ListAllEnabledIPItems(ctx context.Context, req *pb.Li
|
||||
return nil, err
|
||||
}
|
||||
if list == nil {
|
||||
err = models.SharedIPItemDAO.DisableIPItem(tx, int64(item.Id))
|
||||
err = models.SharedIPItemDAO.DisableIPItem(tx, int64(item.Id), 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -657,7 +730,7 @@ func (this *IPItemService) ListAllEnabledIPItems(ctx context.Context, req *pb.Li
|
||||
return nil, err
|
||||
}
|
||||
if policy == nil {
|
||||
err = models.SharedIPItemDAO.DisableIPItem(tx, int64(item.Id))
|
||||
err = models.SharedIPItemDAO.DisableIPItem(tx, int64(item.Id), 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -697,13 +770,13 @@ func (this *IPItemService) ListAllEnabledIPItems(ctx context.Context, req *pb.Li
|
||||
|
||||
// UpdateIPItemsRead 设置所有为已读
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
err = models.SharedIPItemDAO.UpdateItemsRead(tx)
|
||||
err = models.SharedIPItemDAO.UpdateItemsRead(tx, userId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -195,6 +195,9 @@ func (this *IPLibraryService) LookupIPRegion(ctx context.Context, req *pb.Lookup
|
||||
Isp: result.ProviderName(),
|
||||
CountryId: result.CountryId(),
|
||||
ProvinceId: result.ProvinceId(),
|
||||
CityId: result.CityId(),
|
||||
TownId: result.TownId(),
|
||||
ProviderId: result.ProviderId(),
|
||||
Summary: result.Summary(),
|
||||
}}, nil
|
||||
}
|
||||
@@ -213,12 +216,17 @@ func (this *IPLibraryService) LookupIPRegions(ctx context.Context, req *pb.Looku
|
||||
var info = iplibrary.LookupIP(ip)
|
||||
if info != nil && info.IsOk() {
|
||||
result[ip] = &pb.IPRegion{
|
||||
Country: info.CountryName(),
|
||||
Region: "",
|
||||
Province: info.ProvinceName(),
|
||||
City: info.CityName(),
|
||||
Isp: info.ProviderName(),
|
||||
Summary: info.Summary(),
|
||||
Country: info.CountryName(),
|
||||
Region: "",
|
||||
Province: info.ProvinceName(),
|
||||
City: info.CityName(),
|
||||
Isp: info.ProviderName(),
|
||||
CountryId: info.CountryId(),
|
||||
ProvinceId: info.ProvinceId(),
|
||||
CityId: info.CityId(),
|
||||
TownId: info.TownId(),
|
||||
ProviderId: info.ProviderId(),
|
||||
Summary: info.Summary(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,6 +73,20 @@ func (this *IPLibraryArtifactService) FindAllIPLibraryArtifacts(ctx context.Cont
|
||||
|
||||
var pbArtifacts = []*pb.IPLibraryArtifact{}
|
||||
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{
|
||||
Id: int64(artifact.Id),
|
||||
Name: artifact.Name,
|
||||
@@ -81,6 +95,7 @@ func (this *IPLibraryArtifactService) FindAllIPLibraryArtifacts(ctx context.Cont
|
||||
MetaJSON: artifact.Meta,
|
||||
IsPublic: artifact.IsPublic,
|
||||
Code: artifact.Code,
|
||||
File: pbFile,
|
||||
})
|
||||
}
|
||||
return &pb.FindAllIPLibraryArtifactsResponse{
|
||||
|
||||
@@ -70,6 +70,7 @@ func (this *IPLibraryFileService) FindAllFinishedIPLibraryFiles(ctx context.Cont
|
||||
CreatedAt: int64(libraryFile.CreatedAt),
|
||||
GeneratedFileId: int64(libraryFile.GeneratedFileId),
|
||||
GeneratedAt: int64(libraryFile.GeneratedAt),
|
||||
Password: libraryFile.Password,
|
||||
CountryNames: pbCountryNames,
|
||||
Provinces: pbProvinces,
|
||||
Cities: pbCities,
|
||||
@@ -133,6 +134,7 @@ func (this *IPLibraryFileService) FindAllUnfinishedIPLibraryFiles(ctx context.Co
|
||||
FileId: int64(libraryFile.FileId),
|
||||
IsFinished: libraryFile.IsFinished,
|
||||
CreatedAt: int64(libraryFile.CreatedAt),
|
||||
Password: libraryFile.Password,
|
||||
CountryNames: pbCountryNames,
|
||||
Provinces: pbProvinces,
|
||||
Cities: pbCities,
|
||||
@@ -204,6 +206,7 @@ func (this *IPLibraryFileService) FindIPLibraryFile(ctx context.Context, req *pb
|
||||
IsFinished: libraryFile.IsFinished,
|
||||
CreatedAt: int64(libraryFile.CreatedAt),
|
||||
GeneratedFileId: int64(libraryFile.GeneratedFileId),
|
||||
Password: libraryFile.Password,
|
||||
CountryNames: pbCountryNames,
|
||||
Provinces: pbProvinces,
|
||||
Cities: pbCities,
|
||||
@@ -252,7 +255,7 @@ func (this *IPLibraryFileService) CreateIPLibraryFile(ctx context.Context, req *
|
||||
}
|
||||
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"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/firewallconfigs"
|
||||
"github.com/iwind/TeaGo/lists"
|
||||
)
|
||||
|
||||
@@ -68,9 +69,12 @@ func (this *IPListService) FindEnabledIPList(ctx context.Context, req *pb.FindEn
|
||||
|
||||
var tx = this.NullTx()
|
||||
if userId > 0 {
|
||||
err = models.SharedIPListDAO.CheckUserIPList(tx, userId, req.IpListId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
// 检查用户所属名单
|
||||
if req.IpListId != firewallconfigs.GlobalListId {
|
||||
err = models.SharedIPListDAO.CheckUserIPList(tx, userId, req.IpListId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ func (this *LogService) CountLogs(ctx context.Context, req *pb.CountLogRequest)
|
||||
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
@@ -56,7 +56,7 @@ func (this *LogService) ListLogs(ctx context.Context, req *pb.ListLogsRequest) (
|
||||
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -14,26 +14,6 @@ type LoginSessionService struct {
|
||||
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数据
|
||||
func (this *LoginSessionService) WriteLoginSessionValue(ctx context.Context, req *pb.WriteLoginSessionValueRequest) (*pb.RPCSuccess, error) {
|
||||
_, _, err := this.ValidateAdminAndUser(ctx, false)
|
||||
|
||||
@@ -225,6 +225,10 @@ func (this *NodeService) ListEnabledNodesMatch(ctx context.Context, req *pb.List
|
||||
order = "loadAsc"
|
||||
} else if req.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)
|
||||
@@ -740,34 +744,66 @@ func (this *NodeService) FindCurrentNodeConfig(ctx context.Context, req *pb.Find
|
||||
return nil, err
|
||||
}
|
||||
var cacheMap = this.findClusterCacheMap(clusterId, req.NodeTaskVersion)
|
||||
nodeConfig, err := models.SharedNodeDAO.ComposeNodeConfig(tx, nodeId, cacheMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var dataMap *shared.DataMap
|
||||
if req.UseDataMap {
|
||||
// 是否有共用的
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 压缩
|
||||
var data []byte
|
||||
var isCompressed = false
|
||||
var buffer = &bytes.Buffer{}
|
||||
var writer io.Writer = buffer
|
||||
var brotliWriter *brotli.Writer
|
||||
if req.Compress {
|
||||
var buf = &bytes.Buffer{}
|
||||
writer := brotli.NewWriterLevel(buf, 5)
|
||||
_, err = writer.Write(data)
|
||||
if err != nil {
|
||||
_ = writer.Close()
|
||||
brotliWriter = brotli.NewWriterLevel(writer, 5)
|
||||
writer = brotliWriter
|
||||
}
|
||||
|
||||
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 {
|
||||
err = writer.Close()
|
||||
if err == nil {
|
||||
isCompressed = true
|
||||
data = buf.Bytes()
|
||||
buf.Reset()
|
||||
// 如果失败,则使用最直接方法重新编码
|
||||
data, err = json.Marshal(nodeConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
data = buffer.Bytes()
|
||||
}
|
||||
|
||||
buffer.Reset()
|
||||
|
||||
return &pb.FindCurrentNodeConfigResponse{
|
||||
IsChanged: true,
|
||||
NodeJSON: data,
|
||||
@@ -808,6 +844,7 @@ func (this *NodeService) UpdateNodeStatus(ctx context.Context, req *pb.UpdateNod
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
@@ -1317,7 +1354,7 @@ func (this *NodeService) FindAllEnabledNodesDNSWithNodeClusterId(ctx context.Con
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
@@ -2203,3 +2240,39 @@ func (this *NodeService) UpdateNodeAPIConfig(ctx context.Context, req *pb.Update
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
@@ -642,12 +642,28 @@ func (this *NodeClusterService) FindAllEnabledNodeClustersWithDNSDomainId(ctx co
|
||||
|
||||
result := []*pb.NodeCluster{}
|
||||
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{
|
||||
Id: int64(cluster.Id),
|
||||
Name: cluster.Name,
|
||||
DnsName: cluster.DnsName,
|
||||
DnsDomainId: int64(cluster.DnsDomainId),
|
||||
IsOn: cluster.IsOn,
|
||||
Id: int64(cluster.Id),
|
||||
Name: cluster.Name,
|
||||
DnsName: cluster.DnsName,
|
||||
DnsDomainId: int64(cluster.DnsDomainId),
|
||||
DnsDefaultRoute: defaultRoute,
|
||||
IsOn: cluster.IsOn,
|
||||
})
|
||||
}
|
||||
return &pb.FindAllEnabledNodeClustersWithDNSDomainIdResponse{NodeClusters: result}, nil
|
||||
|
||||
@@ -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 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ func (this *ReverseProxyService) FindEnabledReverseProxyConfig(ctx context.Conte
|
||||
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -37,17 +37,22 @@ func (this *ServerService) CreateServer(ctx context.Context, req *pb.CreateServe
|
||||
req.UserId = userId
|
||||
}
|
||||
|
||||
// 修复一个单词拼写错误
|
||||
if len(req.ServerNamesJON) > 0 && len(req.ServerNamesJSON) == 0 {
|
||||
req.ServerNamesJSON = req.ServerNamesJON
|
||||
}
|
||||
|
||||
// 校验用户相关数据
|
||||
if userId > 0 {
|
||||
// HTTPS
|
||||
if len(req.HttpsJSON) > 0 {
|
||||
httpsConfig := &serverconfigs.HTTPSProtocolConfig{}
|
||||
var httpsConfig = &serverconfigs.HTTPSProtocolConfig{}
|
||||
err = json.Unmarshal(req.HttpsJSON, httpsConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
@@ -56,13 +61,13 @@ func (this *ServerService) CreateServer(ctx context.Context, req *pb.CreateServe
|
||||
|
||||
// TLS
|
||||
if len(req.TlsJSON) > 0 {
|
||||
tlsConfig := &serverconfigs.TLSProtocolConfig{}
|
||||
var tlsConfig = &serverconfigs.TLSProtocolConfig{}
|
||||
err = json.Unmarshal(req.TlsJSON, tlsConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
@@ -103,9 +108,9 @@ func (this *ServerService) CreateServer(ctx context.Context, req *pb.CreateServe
|
||||
}
|
||||
|
||||
// 是否需要审核
|
||||
isAuditing := false
|
||||
serverNamesJSON := req.ServerNamesJON
|
||||
auditingServerNamesJSON := []byte("[]")
|
||||
var isAuditing = false
|
||||
var serverNamesJSON = req.ServerNamesJSON
|
||||
var auditingServerNamesJSON = []byte("[]")
|
||||
if userId > 0 {
|
||||
// 如果域名不为空的时候需要审核
|
||||
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 {
|
||||
isAuditing = true
|
||||
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)
|
||||
if err != nil {
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
@@ -899,6 +916,7 @@ func (this *ServerService) ListEnabledServersMatch(ctx context.Context, req *pb.
|
||||
Name: clusterName,
|
||||
},
|
||||
ServerGroups: pbGroups,
|
||||
UserId: int64(server.UserId),
|
||||
User: pbUser,
|
||||
BandwidthTime: server.BandwidthTime,
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1046,6 +1064,7 @@ func (this *ServerService) FindEnabledServer(ctx context.Context, req *pb.FindEn
|
||||
Name: clusterName,
|
||||
},
|
||||
ServerGroups: pbGroups,
|
||||
UserId: int64(server.UserId),
|
||||
User: pbUser,
|
||||
}}, 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 {
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1297,6 +1316,16 @@ func (this *ServerService) CountAllEnabledServersWithServerGroupId(ctx context.C
|
||||
}
|
||||
|
||||
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)
|
||||
if err != nil {
|
||||
@@ -1519,7 +1548,7 @@ func (this *ServerService) ComposeAllUserServersConfig(ctx context.Context, req
|
||||
var configs = []*serverconfigs.ServerConfig{}
|
||||
var cacheMap = utils.NewCacheMap()
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1560,21 +1589,41 @@ func (this *ServerService) FindEnabledUserServerBasic(ctx context.Context, req *
|
||||
return &pb.FindEnabledUserServerBasicResponse{Server: nil}, nil
|
||||
}
|
||||
|
||||
// 集群
|
||||
clusterName, err := models.SharedNodeClusterDAO.FindNodeClusterName(tx, int64(server.ClusterId))
|
||||
if err != nil {
|
||||
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{
|
||||
Id: int64(server.Id),
|
||||
Name: server.Name,
|
||||
Description: server.Description,
|
||||
IsOn: server.IsOn,
|
||||
Type: server.Type,
|
||||
UserId: int64(server.UserId),
|
||||
NodeCluster: &pb.NodeCluster{
|
||||
Id: int64(server.ClusterId),
|
||||
Name: clusterName,
|
||||
},
|
||||
ServerGroups: pbGroups,
|
||||
}}, nil
|
||||
}
|
||||
|
||||
@@ -2242,3 +2291,121 @@ func (this *ServerService) UpdateServerUser(ctx context.Context, req *pb.UpdateS
|
||||
|
||||
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()
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ func init() {
|
||||
for _, stat := range m {
|
||||
// 更新服务的带宽峰值
|
||||
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 {
|
||||
remotelogs.Error("ServerBandwidthStatService", "dump bandwidth stats failed: "+err.Error())
|
||||
}
|
||||
@@ -78,7 +78,7 @@ func init() {
|
||||
|
||||
// 更新用户的带宽峰值
|
||||
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 {
|
||||
remotelogs.Error("SharedUserBandwidthStatDAO", "dump bandwidth stats failed: "+err.Error())
|
||||
}
|
||||
@@ -127,16 +127,26 @@ func (this *ServerBandwidthStatService) UploadServerBandwidthStats(ctx context.C
|
||||
if ok {
|
||||
oldStat.Bytes += stat.Bytes
|
||||
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 {
|
||||
serverBandwidthStatsMap[key] = &pb.ServerBandwidthStat{
|
||||
Id: 0,
|
||||
NodeRegionId: stat.NodeRegionId,
|
||||
UserId: stat.UserId,
|
||||
ServerId: stat.ServerId,
|
||||
Day: stat.Day,
|
||||
TimeAt: stat.TimeAt,
|
||||
Bytes: stat.Bytes,
|
||||
TotalBytes: stat.TotalBytes,
|
||||
Id: 0,
|
||||
NodeRegionId: stat.NodeRegionId,
|
||||
UserId: stat.UserId,
|
||||
ServerId: stat.ServerId,
|
||||
Day: stat.Day,
|
||||
TimeAt: stat.TimeAt,
|
||||
Bytes: stat.Bytes,
|
||||
TotalBytes: stat.TotalBytes,
|
||||
CachedBytes: stat.CachedBytes,
|
||||
AttackBytes: stat.AttackBytes,
|
||||
CountRequests: stat.CountRequests,
|
||||
CountCachedRequests: stat.CountCachedRequests,
|
||||
CountAttackRequests: stat.CountAttackRequests,
|
||||
}
|
||||
}
|
||||
serverBandwidthStatsLocker.Unlock()
|
||||
|
||||
@@ -239,7 +239,7 @@ func (this *ServerDailyStatService) FindLatestServerDailyStats(ctx context.Conte
|
||||
if req.Days > 0 {
|
||||
for i := int32(0); i < req.Days; 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 {
|
||||
return nil, err
|
||||
}
|
||||
@@ -396,7 +396,12 @@ func (this *ServerDailyStatService) SumServerDailyStats(ctx context.Context, req
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -85,21 +85,26 @@ func (this *ServerGroupService) DeleteServerGroup(ctx context.Context, req *pb.D
|
||||
// FindAllEnabledServerGroups 查询所有分组
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if adminId > 0 {
|
||||
userId = req.UserId
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
groups, err := models.SharedServerGroupDAO.FindAllEnabledGroups(tx, userId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := []*pb.ServerGroup{}
|
||||
var result = []*pb.ServerGroup{}
|
||||
for _, group := range groups {
|
||||
result = append(result, &pb.ServerGroup{
|
||||
Id: int64(group.Id),
|
||||
IsOn: group.IsOn,
|
||||
Name: group.Name,
|
||||
})
|
||||
}
|
||||
@@ -153,6 +158,7 @@ func (this *ServerGroupService) FindEnabledServerGroup(ctx context.Context, req
|
||||
return &pb.FindEnabledServerGroupResponse{
|
||||
ServerGroup: &pb.ServerGroup{
|
||||
Id: int64(group.Id),
|
||||
IsOn: group.IsOn,
|
||||
Name: group.Name,
|
||||
},
|
||||
}, 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 {
|
||||
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 {
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
@@ -463,7 +469,7 @@ func (this *ServerGroupService) FindEnabledServerGroupConfigInfo(ctx context.Con
|
||||
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 {
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -85,13 +85,30 @@ func (this *ServerStatBoardService) ComposeServerStatNodeClusterBoard(ctx contex
|
||||
}
|
||||
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))
|
||||
dailyTrafficStats, err := stats.SharedNodeClusterTrafficDailyStatDAO.FindDailyStats(tx, req.NodeClusterId, dayFrom, timeutil.Format("Ymd"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var dailyTrafficBytes int64
|
||||
var lastDailyTrafficBytes int64
|
||||
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{
|
||||
Day: stat.Day,
|
||||
Bytes: int64(stat.Bytes),
|
||||
@@ -102,6 +119,8 @@ func (this *ServerStatBoardService) ComposeServerStatNodeClusterBoard(ctx contex
|
||||
AttackBytes: int64(stat.AttackBytes),
|
||||
})
|
||||
}
|
||||
result.DailyTrafficBytes = dailyTrafficBytes
|
||||
result.LastDailyTrafficBytes = lastDailyTrafficBytes
|
||||
|
||||
// 小时流量统计
|
||||
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))
|
||||
dailyTrafficStats, err := stats.SharedNodeTrafficDailyStatDAO.FindDailyStats(tx, "node", req.NodeId, dayFrom, timeutil.Format("Ymd"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var dailyTrafficBytes int64
|
||||
var lastDailyTrafficBytes int64
|
||||
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{
|
||||
Day: stat.Day,
|
||||
Bytes: int64(stat.Bytes),
|
||||
@@ -322,6 +358,8 @@ func (this *ServerStatBoardService) ComposeServerStatNodeBoard(ctx context.Conte
|
||||
AttackBytes: int64(stat.AttackBytes),
|
||||
})
|
||||
}
|
||||
result.DailyTrafficBytes = dailyTrafficBytes
|
||||
result.LastDailyTrafficBytes = lastDailyTrafficBytes
|
||||
|
||||
// 小时流量统计
|
||||
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))
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
for _, stat := range dailyTrafficStats {
|
||||
result.DailyTrafficStats = append(result.DailyTrafficStats, &pb.ComposeServerStatBoardResponse_DailyTrafficStat{
|
||||
Day: stat.Day,
|
||||
Bytes: int64(stat.Bytes),
|
||||
Bytes: int64(stat.TotalBytes),
|
||||
CachedBytes: int64(stat.CachedBytes),
|
||||
CountRequests: int64(stat.CountRequests),
|
||||
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 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 {
|
||||
return nil, err
|
||||
}
|
||||
for _, stat := range hourlyTrafficStats {
|
||||
result.HourlyTrafficStats = append(result.HourlyTrafficStats, &pb.ComposeServerStatBoardResponse_HourlyTrafficStat{
|
||||
Hour: stat.Hour,
|
||||
Bytes: int64(stat.Bytes),
|
||||
Hour: stat.Day + stat.TimeAt[:2],
|
||||
Bytes: int64(stat.TotalBytes),
|
||||
CachedBytes: int64(stat.CachedBytes),
|
||||
CountRequests: int64(stat.CountRequests),
|
||||
CountCachedRequests: int64(stat.CountCachedRequests),
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/sslconfigs"
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
)
|
||||
|
||||
@@ -16,7 +17,7 @@ type SSLCertService struct {
|
||||
BaseService
|
||||
}
|
||||
|
||||
// CreateSSLCert 创建Cert
|
||||
// CreateSSLCert 创建证书
|
||||
func (this *SSLCertService) CreateSSLCert(ctx context.Context, req *pb.CreateSSLCertRequest) (*pb.CreateSSLCertResponse, error) {
|
||||
// 校验请求
|
||||
adminId, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
@@ -24,6 +25,11 @@ func (this *SSLCertService) CreateSSLCert(ctx context.Context, req *pb.CreateSSL
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 用户ID
|
||||
if adminId > 0 && req.UserId > 0 {
|
||||
userId = req.UserId
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
if req.TimeBeginAt < 0 {
|
||||
@@ -41,6 +47,39 @@ func (this *SSLCertService) CreateSSLCert(ctx context.Context, req *pb.CreateSSL
|
||||
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
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
@@ -139,18 +178,20 @@ func (this *SSLCertService) DeleteSSLCert(ctx context.Context, req *pb.DeleteSSL
|
||||
// CountSSLCerts 计算匹配的Cert数量
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
if userId > 0 {
|
||||
if adminId > 0 {
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
@@ -161,25 +202,27 @@ func (this *SSLCertService) CountSSLCerts(ctx context.Context, req *pb.CountSSLC
|
||||
// ListSSLCerts 列出单页匹配的Cert
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if userId > 0 {
|
||||
if adminId > 0 {
|
||||
userId = req.UserId
|
||||
} else if userId <= 0 {
|
||||
return nil, errors.New("invalid user")
|
||||
}
|
||||
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
certConfigs := []*sslconfigs.SSLCertConfig{}
|
||||
var certConfigs = []*sslconfigs.SSLCertConfig{}
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ func (this *SSLPolicyService) FindEnabledSSLPolicyConfig(ctx context.Context, re
|
||||
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
90
internal/rpc/services/service_updating_server_list.go
Normal file
90
internal/rpc/services/service_updating_server_list.go
Normal 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
|
||||
}
|
||||
@@ -421,7 +421,7 @@ func (this *UserService) ComposeUserDashboard(ctx context.Context, req *pb.Compo
|
||||
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 {
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
if dailyTrafficStat == nil {
|
||||
dailyTrafficStat = &models.ServerDailyStat{}
|
||||
dailyTrafficStat = &models.UserBandwidthStat{}
|
||||
}
|
||||
|
||||
// 近 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 {
|
||||
return nil, err
|
||||
}
|
||||
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{
|
||||
Day: day,
|
||||
Bytes: int64(trafficStat.Bytes),
|
||||
Bytes: int64(trafficStat.TotalBytes),
|
||||
CachedBytes: int64(trafficStat.CachedBytes),
|
||||
AttackBytes: int64(trafficStat.AttackBytes),
|
||||
CountRequests: int64(trafficStat.CountRequests),
|
||||
@@ -508,7 +508,7 @@ func (this *UserService) ComposeUserDashboard(ctx context.Context, req *pb.Compo
|
||||
CountServers: countServers,
|
||||
MonthlyTrafficBytes: monthlyTrafficBytes,
|
||||
MonthlyPeekBandwidthBytes: monthlyPeekBandwidthBytes,
|
||||
DailyTrafficBytes: int64(dailyTrafficStat.Bytes),
|
||||
DailyTrafficBytes: int64(dailyTrafficStat.TotalBytes),
|
||||
DailyPeekBandwidthBytes: dailyPeekBandwidthBytes,
|
||||
DailyTrafficStats: dailyTrafficStats,
|
||||
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))
|
||||
hourTo := timeutil.Format("YmdH")
|
||||
var hourFrom = timeutil.Format("YmdH", time.Now().Add(-23*time.Hour))
|
||||
var hourTo = timeutil.Format("YmdH")
|
||||
topUserStats, err := models.SharedServerDailyStatDAO.FindTopUserStats(tx, hourFrom, hourTo)
|
||||
if err != nil {
|
||||
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
Reference in New Issue
Block a user