Compare commits
58 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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.1"
|
||||
|
||||
ProductName = "Edge API"
|
||||
ProcessName = "edge-api"
|
||||
@@ -18,7 +18,7 @@ const (
|
||||
|
||||
// 其他节点版本号,用来检测是否有需要升级的节点
|
||||
|
||||
NodeVersion = "0.6.4"
|
||||
NodeVersion = "1.0.1"
|
||||
|
||||
// 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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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))
|
||||
@@ -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 {
|
||||
|
||||
@@ -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,71 @@ 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)+"')")
|
||||
}
|
||||
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())
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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(),
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
193116
internal/setup/sql.json
Normal file
193116
internal/setup/sql.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -20,7 +20,7 @@ import (
|
||||
func init() {
|
||||
dbs.OnReadyDone(func() {
|
||||
goman.New(func() {
|
||||
NewDNSTaskExecutor(10 * time.Second).Start()
|
||||
NewDNSTaskExecutor(20 * time.Second).Start()
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -39,7 +39,13 @@ func NewDNSTaskExecutor(duration time.Duration) *DNSTaskExecutor {
|
||||
}
|
||||
|
||||
func (this *DNSTaskExecutor) Start() {
|
||||
for range this.ticker.C {
|
||||
for {
|
||||
select {
|
||||
case <-this.ticker.C:
|
||||
case <-dnsmodels.DNSTasksNotifier:
|
||||
time.Sleep(3 * time.Second) // 人为延长N秒,等待可能的几个任务合并
|
||||
}
|
||||
|
||||
err := this.Loop()
|
||||
if err != nil {
|
||||
this.logErr("DNSTaskExecutor", err.Error())
|
||||
@@ -60,11 +66,13 @@ func (this *DNSTaskExecutor) loop() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, task := range tasks {
|
||||
taskId := int64(task.Id)
|
||||
var taskId = int64(task.Id)
|
||||
var taskVersion = int64(task.Version)
|
||||
switch task.Type {
|
||||
case dnsmodels.DNSTaskTypeServerChange:
|
||||
err = this.doServer(taskId, int64(task.ClusterId), int64(task.ServerId))
|
||||
err = this.doServer(taskId, int64(task.Version), int64(task.ClusterId), int64(task.ServerId))
|
||||
if err != nil {
|
||||
err = dnsmodels.SharedDNSTaskDAO.UpdateDNSTaskError(nil, taskId, err.Error())
|
||||
if err != nil {
|
||||
@@ -72,7 +80,7 @@ func (this *DNSTaskExecutor) loop() error {
|
||||
}
|
||||
}
|
||||
case dnsmodels.DNSTaskTypeNodeChange:
|
||||
err = this.doNode(taskId, int64(task.ClusterId), int64(task.NodeId))
|
||||
err = this.doNode(taskId, taskVersion, int64(task.ClusterId), int64(task.NodeId))
|
||||
if err != nil {
|
||||
err = dnsmodels.SharedDNSTaskDAO.UpdateDNSTaskError(nil, taskId, err.Error())
|
||||
if err != nil {
|
||||
@@ -80,7 +88,7 @@ func (this *DNSTaskExecutor) loop() error {
|
||||
}
|
||||
}
|
||||
case dnsmodels.DNSTaskTypeClusterChange:
|
||||
err = this.doCluster(taskId, int64(task.ClusterId))
|
||||
err = this.doCluster(taskId, taskVersion, int64(task.ClusterId))
|
||||
if err != nil {
|
||||
err = dnsmodels.SharedDNSTaskDAO.UpdateDNSTaskError(nil, taskId, err.Error())
|
||||
if err != nil {
|
||||
@@ -88,7 +96,7 @@ func (this *DNSTaskExecutor) loop() error {
|
||||
}
|
||||
}
|
||||
case dnsmodels.DNSTaskTypeClusterRemoveDomain:
|
||||
err = this.doClusterRemove(taskId, int64(task.ClusterId), int64(task.DomainId), task.RecordName)
|
||||
err = this.doClusterRemove(taskId, taskVersion, int64(task.ClusterId), int64(task.DomainId), task.RecordName)
|
||||
if err != nil {
|
||||
err = dnsmodels.SharedDNSTaskDAO.UpdateDNSTaskError(nil, taskId, err.Error())
|
||||
if err != nil {
|
||||
@@ -96,7 +104,7 @@ func (this *DNSTaskExecutor) loop() error {
|
||||
}
|
||||
}
|
||||
case dnsmodels.DNSTaskTypeDomainChange:
|
||||
err = this.doDomainWithTask(taskId, int64(task.DomainId))
|
||||
err = this.doDomainWithTask(taskId, taskVersion, int64(task.DomainId))
|
||||
if err != nil {
|
||||
err = dnsmodels.SharedDNSTaskDAO.UpdateDNSTaskError(nil, taskId, err.Error())
|
||||
if err != nil {
|
||||
@@ -110,13 +118,13 @@ func (this *DNSTaskExecutor) loop() error {
|
||||
}
|
||||
|
||||
// 修改服务相关记录
|
||||
func (this *DNSTaskExecutor) doServer(taskId int64, oldClusterId int64, serverId int64) error {
|
||||
func (this *DNSTaskExecutor) doServer(taskId int64, taskVersion int64, oldClusterId int64, serverId int64) error {
|
||||
var tx *dbs.Tx
|
||||
|
||||
isOk := false
|
||||
var isOk = false
|
||||
defer func() {
|
||||
if isOk {
|
||||
err := dnsmodels.SharedDNSTaskDAO.UpdateDNSTaskDone(tx, taskId)
|
||||
err := dnsmodels.SharedDNSTaskDAO.UpdateDNSTaskDone(tx, taskId, taskVersion)
|
||||
if err != nil {
|
||||
this.logErr("DNSTaskExecutor", err.Error())
|
||||
}
|
||||
@@ -269,11 +277,11 @@ func (this *DNSTaskExecutor) doServer(taskId int64, oldClusterId int64, serverId
|
||||
}
|
||||
|
||||
// 修改节点相关记录
|
||||
func (this *DNSTaskExecutor) doNode(taskId int64, nodeClusterId int64, nodeId int64) error {
|
||||
func (this *DNSTaskExecutor) doNode(taskId int64, taskVersion int64, nodeClusterId int64, nodeId int64) error {
|
||||
var isOk = false
|
||||
defer func() {
|
||||
if isOk {
|
||||
err := dnsmodels.SharedDNSTaskDAO.UpdateDNSTaskDone(nil, taskId)
|
||||
err := dnsmodels.SharedDNSTaskDAO.UpdateDNSTaskDone(nil, taskId, taskVersion)
|
||||
if err != nil {
|
||||
this.logErr("DNSTaskExecutor", err.Error())
|
||||
}
|
||||
@@ -315,11 +323,11 @@ func (this *DNSTaskExecutor) doNode(taskId int64, nodeClusterId int64, nodeId in
|
||||
}
|
||||
|
||||
// 修改集群相关记录
|
||||
func (this *DNSTaskExecutor) doCluster(taskId int64, clusterId int64) error {
|
||||
func (this *DNSTaskExecutor) doCluster(taskId int64, taskVersion int64, clusterId int64) error {
|
||||
isOk := false
|
||||
defer func() {
|
||||
if isOk {
|
||||
err := dnsmodels.SharedDNSTaskDAO.UpdateDNSTaskDone(nil, taskId)
|
||||
err := dnsmodels.SharedDNSTaskDAO.UpdateDNSTaskDone(nil, taskId, taskVersion)
|
||||
if err != nil {
|
||||
this.logErr("DNSTaskExecutor", err.Error())
|
||||
}
|
||||
@@ -363,7 +371,7 @@ func (this *DNSTaskExecutor) doCluster(taskId int64, clusterId int64) error {
|
||||
|
||||
// 当前的节点记录
|
||||
var newRecordKeys = []string{}
|
||||
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 err
|
||||
}
|
||||
@@ -539,11 +547,11 @@ func (this *DNSTaskExecutor) doCluster(taskId int64, clusterId int64) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this *DNSTaskExecutor) doClusterRemove(taskId int64, clusterId int64, domainId int64, dnsName string) error {
|
||||
func (this *DNSTaskExecutor) doClusterRemove(taskId int64, taskVersion int64, clusterId int64, domainId int64, dnsName string) error {
|
||||
var isOk = false
|
||||
defer func() {
|
||||
if isOk {
|
||||
err := dnsmodels.SharedDNSTaskDAO.UpdateDNSTaskDone(nil, taskId)
|
||||
err := dnsmodels.SharedDNSTaskDAO.UpdateDNSTaskDone(nil, taskId, taskVersion)
|
||||
if err != nil {
|
||||
this.logErr("DNSTaskExecutor", err.Error())
|
||||
}
|
||||
@@ -625,17 +633,17 @@ func (this *DNSTaskExecutor) doClusterRemove(taskId int64, clusterId int64, doma
|
||||
}
|
||||
|
||||
func (this *DNSTaskExecutor) doDomain(domainId int64) error {
|
||||
return this.doDomainWithTask(0, domainId)
|
||||
return this.doDomainWithTask(0, 0, domainId)
|
||||
}
|
||||
|
||||
func (this *DNSTaskExecutor) doDomainWithTask(taskId int64, domainId int64) error {
|
||||
func (this *DNSTaskExecutor) doDomainWithTask(taskId int64, taskVersion int64, domainId int64) error {
|
||||
var tx *dbs.Tx
|
||||
|
||||
isOk := false
|
||||
var isOk = false
|
||||
defer func() {
|
||||
if isOk {
|
||||
if taskId > 0 {
|
||||
err := dnsmodels.SharedDNSTaskDAO.UpdateDNSTaskDone(tx, taskId)
|
||||
err := dnsmodels.SharedDNSTaskDAO.UpdateDNSTaskDone(tx, taskId, taskVersion)
|
||||
if err != nil {
|
||||
this.logErr("DNSTaskExecutor", err.Error())
|
||||
}
|
||||
@@ -651,7 +659,7 @@ func (this *DNSTaskExecutor) doDomainWithTask(taskId int64, domainId int64) erro
|
||||
isOk = true
|
||||
return nil
|
||||
}
|
||||
providerId := int64(dnsDomain.ProviderId)
|
||||
var providerId = int64(dnsDomain.ProviderId)
|
||||
if providerId <= 0 {
|
||||
isOk = true
|
||||
return nil
|
||||
@@ -666,7 +674,7 @@ func (this *DNSTaskExecutor) doDomainWithTask(taskId int64, domainId int64) erro
|
||||
return nil
|
||||
}
|
||||
|
||||
manager := dnsclients.FindProvider(provider.Type, int64(provider.Id))
|
||||
var manager = dnsclients.FindProvider(provider.Type, int64(provider.Id))
|
||||
if manager == nil {
|
||||
this.logErr("DNSTaskExecutor", "unsupported dns provider type '"+provider.Type+"'")
|
||||
isOk = true
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
package tasks
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models/acme"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/goman"
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
timeutil "github.com/iwind/TeaGo/utils/time"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -59,7 +62,7 @@ func (this *SSLCertExpireCheckExecutor) Loop() error {
|
||||
for _, cert := range certs {
|
||||
// 发送消息
|
||||
var subject = "SSL证书\"" + cert.Name + "\"在" + strconv.Itoa(days) + "天后将到期,"
|
||||
var msg = "SSL证书\"" + cert.Name + "\"(" + string(cert.DnsNames) + ")在" + strconv.Itoa(days) + "天后将到期,"
|
||||
var msg = "SSL证书\"" + cert.Name + "\"(" + this.summaryDNSNames(cert.DnsNames) + ")在" + strconv.Itoa(days) + "天后将到期,"
|
||||
|
||||
// 是否有自动更新任务
|
||||
if cert.AcmeTaskId > 0 {
|
||||
@@ -103,7 +106,7 @@ func (this *SSLCertExpireCheckExecutor) Loop() error {
|
||||
for _, cert := range certs {
|
||||
// 发送消息
|
||||
var subject = "SSL证书\"" + cert.Name + "\"在" + strconv.Itoa(days) + "天后将到期,"
|
||||
var msg = "SSL证书\"" + cert.Name + "\"(" + string(cert.DnsNames) + ")在" + strconv.Itoa(days) + "天后将到期,"
|
||||
var msg = "SSL证书\"" + cert.Name + "\"(" + this.summaryDNSNames(cert.DnsNames) + ")在" + strconv.Itoa(days) + "天后将到期,"
|
||||
|
||||
// 是否有自动更新任务
|
||||
if cert.AcmeTaskId > 0 {
|
||||
@@ -117,7 +120,7 @@ func (this *SSLCertExpireCheckExecutor) Loop() error {
|
||||
if isOk {
|
||||
// 发送成功通知
|
||||
subject = "系统已成功为你自动更新了证书\"" + cert.Name + "\""
|
||||
msg = "系统已成功为你自动更新了证书\"" + cert.Name + "\"(" + string(cert.DnsNames) + ")。"
|
||||
msg = "系统已成功为你自动更新了证书\"" + cert.Name + "\"(" + this.summaryDNSNames(cert.DnsNames) + ")。"
|
||||
err = models.SharedMessageDAO.CreateMessage(nil, int64(cert.AdminId), int64(cert.UserId), models.MessageTypeSSLCertACMETaskSuccess, models.MessageLevelSuccess, subject, msg, maps.Map{
|
||||
"certId": cert.Id,
|
||||
"acmeTaskId": cert.AcmeTaskId,
|
||||
@@ -134,7 +137,7 @@ func (this *SSLCertExpireCheckExecutor) Loop() error {
|
||||
} else {
|
||||
// 发送失败通知
|
||||
subject = "系统在尝试自动更新证书\"" + cert.Name + "\"时发生错误"
|
||||
msg = "系统在尝试自动更新证书\"" + cert.Name + "\"(" + string(cert.DnsNames) + ")时发生错误:" + errMsg + "。请检查系统设置并修复错误。"
|
||||
msg = "系统在尝试自动更新证书\"" + cert.Name + "\"(" + this.summaryDNSNames(cert.DnsNames) + ")时发生错误:" + errMsg + "。请检查系统设置并修复错误。"
|
||||
err = models.SharedMessageDAO.CreateMessage(nil, int64(cert.AdminId), int64(cert.UserId), models.MessageTypeSSLCertACMETaskFailed, models.MessageLevelError, subject, msg, maps.Map{
|
||||
"certId": cert.Id,
|
||||
"acmeTaskId": cert.AcmeTaskId,
|
||||
@@ -187,7 +190,7 @@ func (this *SSLCertExpireCheckExecutor) Loop() error {
|
||||
// 发送消息
|
||||
var today = timeutil.Format("Y-m-d")
|
||||
var subject = "SSL证书\"" + cert.Name + "\"在今天(" + today + ")过期"
|
||||
var msg = "SSL证书\"" + cert.Name + "\"(" + string(cert.DnsNames) + ")在今天(" + today + ")过期,请及时更新证书,之后将不再重复提醒。"
|
||||
var msg = "SSL证书\"" + cert.Name + "\"(" + this.summaryDNSNames(cert.DnsNames) + ")在今天(" + today + ")过期,请及时更新证书,之后将不再重复提醒。"
|
||||
err = models.SharedMessageDAO.CreateMessage(nil, int64(cert.AdminId), int64(cert.UserId), models.MessageTypeSSLCertExpiring, models.MessageLevelWarning, subject, msg, maps.Map{
|
||||
"certId": cert.Id,
|
||||
"acmeTaskId": cert.AcmeTaskId,
|
||||
@@ -206,3 +209,29 @@ func (this *SSLCertExpireCheckExecutor) Loop() error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// 对证书中DNS域名的描述
|
||||
func (this *SSLCertExpireCheckExecutor) summaryDNSNames(dnsNamesJSON []byte) string {
|
||||
if len(dnsNamesJSON) == 0 {
|
||||
return ""
|
||||
}
|
||||
var dnsNames = []string{}
|
||||
err := json.Unmarshal(dnsNamesJSON, &dnsNames)
|
||||
if err != nil {
|
||||
// ignore error
|
||||
return ""
|
||||
}
|
||||
|
||||
var count = len(dnsNames)
|
||||
if count == 0 {
|
||||
return ""
|
||||
}
|
||||
if count == 1 {
|
||||
return "包含" + dnsNames[0] + "域名"
|
||||
}
|
||||
if count <= 10 {
|
||||
return "包含" + strings.Join(dnsNames, "、") + "等域名"
|
||||
}
|
||||
|
||||
return "包含" + strings.Join(dnsNames[:10], "、") + "等" + types.String(count) + "个域名"
|
||||
}
|
||||
|
||||
45
internal/utils/json.go
Normal file
45
internal/utils/json.go
Normal file
@@ -0,0 +1,45 @@
|
||||
// Copyright 2023 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
|
||||
package utils
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// JSONClone 使用JSON协议克隆对象
|
||||
func JSONClone[T any](ptr T) (newPtr T, err error) {
|
||||
var ptrType = reflect.TypeOf(ptr)
|
||||
var kind = ptrType.Kind()
|
||||
if kind != reflect.Ptr && kind != reflect.Slice {
|
||||
err = errors.New("JSONClone: input must be a ptr or slice")
|
||||
return
|
||||
}
|
||||
var jsonData []byte
|
||||
jsonData, err = json.Marshal(ptr)
|
||||
if err != nil {
|
||||
return ptr, errors.New("JSONClone: marshal failed: " + err.Error())
|
||||
}
|
||||
|
||||
var newValue any
|
||||
switch kind {
|
||||
case reflect.Ptr:
|
||||
newValue = reflect.New(ptrType.Elem()).Interface()
|
||||
case reflect.Slice:
|
||||
newValue = reflect.New(reflect.SliceOf(ptrType.Elem())).Interface()
|
||||
default:
|
||||
return ptr, errors.New("JSONClone: unknown data type")
|
||||
}
|
||||
err = json.Unmarshal(jsonData, newValue)
|
||||
if err != nil {
|
||||
err = errors.New("JSONClone: unmarshal failed: " + err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if kind == reflect.Slice {
|
||||
newValue = reflect.Indirect(reflect.ValueOf(newValue)).Interface()
|
||||
}
|
||||
|
||||
return newValue.(T), nil
|
||||
}
|
||||
51
internal/utils/json_test.go
Normal file
51
internal/utils/json_test.go
Normal file
@@ -0,0 +1,51 @@
|
||||
// Copyright 2023 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
|
||||
package utils_test
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
||||
"github.com/iwind/TeaGo/logs"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestJSONClone(t *testing.T) {
|
||||
type user struct {
|
||||
Name string
|
||||
Age int
|
||||
}
|
||||
|
||||
var u = &user{
|
||||
Name: "Jack",
|
||||
Age: 20,
|
||||
}
|
||||
|
||||
newU, err := utils.JSONClone[*user](u)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Logf("%#v", newU)
|
||||
}
|
||||
|
||||
func TestJSONClone_Slice(t *testing.T) {
|
||||
type user struct {
|
||||
Name string
|
||||
Age int
|
||||
}
|
||||
|
||||
var u = []*user{
|
||||
{
|
||||
Name: "Jack",
|
||||
Age: 20,
|
||||
},
|
||||
{
|
||||
Name: "Lily",
|
||||
Age: 18,
|
||||
},
|
||||
}
|
||||
|
||||
newU, err := utils.JSONClone[[]*user](u)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
logs.PrintAsJSON(newU, t)
|
||||
}
|
||||
@@ -1,27 +1,47 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"errors"
|
||||
teaconst "github.com/TeaOSLab/EdgeAPI/internal/const"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/configutils"
|
||||
"github.com/iwind/TeaGo/logs"
|
||||
"github.com/miekg/dns"
|
||||
)
|
||||
|
||||
var sharedDNSClient *dns.Client
|
||||
var sharedDNSConfig *dns.ClientConfig
|
||||
|
||||
func init() {
|
||||
if !teaconst.IsMain {
|
||||
return
|
||||
}
|
||||
|
||||
config, err := dns.ClientConfigFromFile("/etc/resolv.conf")
|
||||
if err != nil {
|
||||
logs.Println("ERROR: configure dns client failed: " + err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
sharedDNSConfig = config
|
||||
sharedDNSClient = &dns.Client{}
|
||||
|
||||
}
|
||||
|
||||
// LookupCNAME 查询CNAME记录
|
||||
// TODO 可以设置使用的DNS主机地址
|
||||
func LookupCNAME(host string) (string, error) {
|
||||
config, err := dns.ClientConfigFromFile("/etc/resolv.conf")
|
||||
if err != nil {
|
||||
return "", err
|
||||
if sharedDNSClient == nil {
|
||||
return "", errors.New("could not find dns client")
|
||||
}
|
||||
|
||||
var c = new(dns.Client)
|
||||
var m = new(dns.Msg)
|
||||
|
||||
m.SetQuestion(host+".", dns.TypeCNAME)
|
||||
m.RecursionDesired = true
|
||||
|
||||
var lastErr error
|
||||
for _, serverAddr := range config.Servers {
|
||||
r, _, err := c.Exchange(m, configutils.QuoteIP(serverAddr)+":"+config.Port)
|
||||
for _, serverAddr := range sharedDNSConfig.Servers {
|
||||
r, _, err := sharedDNSClient.Exchange(m, configutils.QuoteIP(serverAddr)+":"+sharedDNSConfig.Port)
|
||||
if err != nil {
|
||||
lastErr = err
|
||||
continue
|
||||
@@ -38,12 +58,6 @@ func LookupCNAME(host string) (string, error) {
|
||||
// LookupNS 查询NS记录
|
||||
// TODO 可以设置使用的DNS主机地址
|
||||
func LookupNS(host string) ([]string, error) {
|
||||
config, err := dns.ClientConfigFromFile("/etc/resolv.conf")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var c = new(dns.Client)
|
||||
var m = new(dns.Msg)
|
||||
|
||||
m.SetQuestion(host+".", dns.TypeNS)
|
||||
@@ -53,8 +67,8 @@ func LookupNS(host string) ([]string, error) {
|
||||
|
||||
var lastErr error
|
||||
var hasValidServer = false
|
||||
for _, serverAddr := range config.Servers {
|
||||
r, _, err := c.Exchange(m, configutils.QuoteIP(serverAddr)+":"+config.Port)
|
||||
for _, serverAddr := range sharedDNSConfig.Servers {
|
||||
r, _, err := sharedDNSClient.Exchange(m, configutils.QuoteIP(serverAddr)+":"+sharedDNSConfig.Port)
|
||||
if err != nil {
|
||||
lastErr = err
|
||||
continue
|
||||
@@ -82,22 +96,16 @@ func LookupNS(host string) ([]string, error) {
|
||||
// LookupTXT 获取CNAME
|
||||
// TODO 可以设置使用的DNS主机地址
|
||||
func LookupTXT(host string) ([]string, error) {
|
||||
config, err := dns.ClientConfigFromFile("/etc/resolv.conf")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var c = new(dns.Client)
|
||||
var m = new(dns.Msg)
|
||||
|
||||
m.SetQuestion(host + ".", dns.TypeTXT)
|
||||
m.SetQuestion(host+".", dns.TypeTXT)
|
||||
m.RecursionDesired = true
|
||||
|
||||
var lastErr error
|
||||
var result = []string{}
|
||||
var hasValidServer = false
|
||||
for _, serverAddr := range config.Servers {
|
||||
r, _, err := c.Exchange(m, configutils.QuoteIP(serverAddr)+":"+config.Port)
|
||||
for _, serverAddr := range sharedDNSConfig.Servers {
|
||||
r, _, err := sharedDNSClient.Exchange(m, configutils.QuoteIP(serverAddr)+":"+sharedDNSConfig.Port)
|
||||
if err != nil {
|
||||
lastErr = err
|
||||
continue
|
||||
|
||||
@@ -5,6 +5,7 @@ package regexputils
|
||||
import "regexp"
|
||||
|
||||
var (
|
||||
YYYYMMDD = regexp.MustCompile(`^\d{8}$`)
|
||||
YYYYMM = regexp.MustCompile(`^\d{6}$`)
|
||||
YYYYMMDDHH = regexp.MustCompile(`^\d{10}$`)
|
||||
YYYYMMDD = regexp.MustCompile(`^\d{8}$`)
|
||||
YYYYMM = regexp.MustCompile(`^\d{6}$`)
|
||||
)
|
||||
|
||||
@@ -82,3 +82,54 @@ func LimitString(s string, maxLength int) string {
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// SplitKeywordArgs 分隔关键词参数
|
||||
// 支持:hello, "hello", name:hello, name:"hello", name:\"hello\"
|
||||
func SplitKeywordArgs(s string) (args []splitArg) {
|
||||
var value []rune
|
||||
var beginQuote = false
|
||||
var runes = []rune(s)
|
||||
for index, r := range runes {
|
||||
if r == '"' && (index == 0 || runes[index-1] != '\\') {
|
||||
beginQuote = !beginQuote
|
||||
continue
|
||||
}
|
||||
if !beginQuote && (r == ' ' || r == '\t' || r == '\n' || r == '\r') {
|
||||
if len(value) > 0 {
|
||||
args = append(args, parseKeywordValue(string(value)))
|
||||
value = nil
|
||||
}
|
||||
} else {
|
||||
value = append(value, r)
|
||||
}
|
||||
}
|
||||
|
||||
if len(value) > 0 {
|
||||
args = append(args, parseKeywordValue(string(value)))
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
type splitArg struct {
|
||||
Key string
|
||||
Value string
|
||||
}
|
||||
|
||||
func (this *splitArg) String() string {
|
||||
if len(this.Key) > 0 {
|
||||
return this.Key + ":" + this.Value
|
||||
}
|
||||
return this.Value
|
||||
}
|
||||
|
||||
func parseKeywordValue(value string) (arg splitArg) {
|
||||
var colonIndex = strings.Index(value, ":")
|
||||
if colonIndex > 0 {
|
||||
arg.Key = value[:colonIndex]
|
||||
arg.Value = value[colonIndex+1:]
|
||||
} else {
|
||||
arg.Value = value
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -40,3 +40,31 @@ func TestLimitString(t *testing.T) {
|
||||
a.IsTrue(utils.LimitString("中文测试", 1) == "")
|
||||
a.IsTrue(utils.LimitString("中文测试", 3) == "中")
|
||||
}
|
||||
|
||||
|
||||
func TestSplitKeywordArgs(t *testing.T) {
|
||||
{
|
||||
var keyword = ""
|
||||
t.Logf("%+v", utils.SplitKeywordArgs(keyword))
|
||||
}
|
||||
{
|
||||
var keyword = "abc"
|
||||
t.Logf("%+v", utils.SplitKeywordArgs(keyword))
|
||||
}
|
||||
{
|
||||
var keyword = "abc def ghi123"
|
||||
t.Logf("%+v", utils.SplitKeywordArgs(keyword))
|
||||
}
|
||||
{
|
||||
var keyword = "\"hello world\""
|
||||
t.Logf("%+v", utils.SplitKeywordArgs(keyword))
|
||||
}
|
||||
{
|
||||
var keyword = "\"hello world\" hello \"world\" \"my name\" call:\"zip name\" slash:\\\"SLASH"
|
||||
t.Logf("%+v", utils.SplitKeywordArgs(keyword))
|
||||
}
|
||||
{
|
||||
var keyword = "name:abc"
|
||||
t.Logf("%+v", utils.SplitKeywordArgs(keyword))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user