Compare commits
92 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a987837904 | ||
|
|
4bcad223ca | ||
|
|
b9e5005d05 | ||
|
|
fd9bdee6be | ||
|
|
4460956de6 | ||
|
|
1923c2706a | ||
|
|
1470ec2b65 | ||
|
|
62fc9bcc68 | ||
|
|
8a08df8593 | ||
|
|
bc7a1f37b6 | ||
|
|
f8a01e4639 | ||
|
|
8e4c00ef31 | ||
|
|
dc894828e0 | ||
|
|
7f6d8ba7b4 | ||
|
|
b8b56db83c | ||
|
|
17f0821945 | ||
|
|
b5436a6e57 | ||
|
|
46fe2d8369 | ||
|
|
ff429c270d | ||
|
|
92de19e359 | ||
|
|
4121c81a0a | ||
|
|
f639ab8342 | ||
|
|
f17a8ab1d0 | ||
|
|
12f677eb12 | ||
|
|
7595bdeb6b | ||
|
|
fc223af3f0 | ||
|
|
ebe3632f07 | ||
|
|
930babc010 | ||
|
|
255e3a61e6 | ||
|
|
52155a23ab | ||
|
|
200f244c0c | ||
|
|
ab5d7539ce | ||
|
|
3e79840fe6 | ||
|
|
d03455e3b0 | ||
|
|
af1cb14110 | ||
|
|
0feffa755e | ||
|
|
7cfbe2e473 | ||
|
|
7f63dc4565 | ||
|
|
e90424f80a | ||
|
|
6271125296 | ||
|
|
44ac4b83c5 | ||
|
|
c75e2c55c6 | ||
|
|
51a3029c09 | ||
|
|
580341d397 | ||
|
|
fb4bad0731 | ||
|
|
70efff2e6b | ||
|
|
97c76ef22f | ||
|
|
e763095756 | ||
|
|
b7dc2738e2 | ||
|
|
3db826b578 | ||
|
|
dc8975e374 | ||
|
|
c0cbd7c607 | ||
|
|
4d9f404bb0 | ||
|
|
06bb61804b | ||
|
|
32c1442878 | ||
|
|
b99652801d | ||
|
|
be565a98b9 | ||
|
|
5195a380db | ||
|
|
8dbbabb0e8 | ||
|
|
bec4500746 | ||
|
|
66a31f599d | ||
|
|
534cfb2180 | ||
|
|
a9dc20ffbd | ||
|
|
7f20ad32b6 | ||
|
|
a3c0b43bc4 | ||
|
|
1f2c9a6b3a | ||
|
|
194b0ec184 | ||
|
|
c94895a7c4 | ||
|
|
22d15bcb27 | ||
|
|
361fb9b868 | ||
|
|
2d675f4281 | ||
|
|
e19bbdf891 | ||
|
|
d48c0a2328 | ||
|
|
a70b20cf13 | ||
|
|
eb83017ed4 | ||
|
|
98ba31174b | ||
|
|
aa28e84507 | ||
|
|
da8fe918fe | ||
|
|
2b26bed97c | ||
|
|
5e50518bd9 | ||
|
|
e49db916f8 | ||
|
|
16083fd0d7 | ||
|
|
e0e2729fef | ||
|
|
9b95042936 | ||
|
|
44d45c53a1 | ||
|
|
c5fb340eb7 | ||
|
|
cbb61d2f0e | ||
|
|
a143714370 | ||
|
|
0e1a98c5d8 | ||
|
|
707a9f8caf | ||
|
|
da391f565b | ||
|
|
78f396129f |
@@ -115,7 +115,11 @@ function build() {
|
||||
fi
|
||||
|
||||
# building api node
|
||||
env GOOS="$OS" GOARCH="$ARCH" go build -trimpath -tags $TAG --ldflags="-s -w" -o "$DIST"/bin/edge-api "$ROOT"/../cmd/edge-api/main.go
|
||||
env GOOS="$OS" GOARCH="$ARCH" go build -trimpath -tags $TAG --ldflags="-s -w" -o "$DIST/bin/$NAME" "$ROOT"/../cmd/edge-api/main.go
|
||||
if [ ! -f "${DIST}/bin/${NAME}" ]; then
|
||||
echo "build failed!"
|
||||
exit
|
||||
fi
|
||||
|
||||
# delete hidden files
|
||||
find "$DIST" -name ".DS_Store" -delete
|
||||
|
||||
@@ -12,5 +12,5 @@ dbs:
|
||||
|
||||
|
||||
fields:
|
||||
bool: [ "uamIsOn", "followPort", "requestHostExcludingPort", "autoRemoteStart", "autoInstallNftables", "enableIPLists", "detectAgents", "checkingPorts", "enableRecordHealthCheck", "offlineIsNotified", "http2Enabled", "http3Enabled", "enableHTTP2", "retry50X", "retry40X", "autoSystemTuning", "disableDefaultDB" ]
|
||||
bool: [ "uamIsOn", "followPort", "requestHostExcludingPort", "autoRemoteStart", "autoInstallNftables", "enableIPLists", "detectAgents", "checkingPorts", "enableRecordHealthCheck", "offlineIsNotified", "http2Enabled", "http3Enabled", "enableHTTP2", "retry50X", "retry40X", "autoSystemTuning", "disableDefaultDB", "autoTrimDisks" ]
|
||||
|
||||
|
||||
2
cmd/edge-instance-installer/.gitignore
vendored
Normal file
2
cmd/edge-instance-installer/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
edge-instance-installer*
|
||||
prepare.sh
|
||||
45
cmd/edge-instance-installer/build.sh
Executable file
45
cmd/edge-instance-installer/build.sh
Executable file
@@ -0,0 +1,45 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
function build() {
|
||||
ROOT=$(dirname "$0")
|
||||
|
||||
OS="${1}"
|
||||
ARCH="${2}"
|
||||
TAG="${3}"
|
||||
|
||||
if [ -z "$OS" ]; then
|
||||
echo "usage: build.sh OS ARCH"
|
||||
exit
|
||||
fi
|
||||
|
||||
if [ -z "$ARCH" ]; then
|
||||
echo "usage: build.sh OS ARCH"
|
||||
exit
|
||||
fi
|
||||
|
||||
VERSION=$(lookup_version "${ROOT}/../../internal/const/const.go")
|
||||
TARGET_NAME="edge-instance-installer-${OS}-${ARCH}-v${VERSION}"
|
||||
|
||||
env GOOS=linux GOARCH="${ARCH}" go build -tags="${TAG}" -trimpath -ldflags="-s -w" -o "${TARGET_NAME}" main.go
|
||||
|
||||
if [ -f "${TARGET_NAME}" ]; then
|
||||
cp "${TARGET_NAME}" "${ROOT}/../../../EdgeAdmin/docker/instance/edge-instance/assets"
|
||||
fi
|
||||
|
||||
echo "[done]"
|
||||
}
|
||||
|
||||
function lookup_version() {
|
||||
FILE=$1
|
||||
VERSION_DATA=$(cat "$FILE")
|
||||
re="Version[ ]+=[ ]+\"([0-9.]+)\""
|
||||
if [[ $VERSION_DATA =~ $re ]]; then
|
||||
VERSION=${BASH_REMATCH[1]}
|
||||
echo "$VERSION"
|
||||
else
|
||||
echo "could not match version"
|
||||
exit
|
||||
fi
|
||||
}
|
||||
|
||||
build "$1" "$2" "$3"
|
||||
97
cmd/edge-instance-installer/main.go
Normal file
97
cmd/edge-instance-installer/main.go
Normal file
@@ -0,0 +1,97 @@
|
||||
// Copyright 2024 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/instances"
|
||||
_ "github.com/iwind/TeaGo/bootstrap"
|
||||
"github.com/iwind/TeaGo/lists"
|
||||
"log"
|
||||
"os"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var verbose = lists.ContainsString(os.Args, "-v")
|
||||
|
||||
var dbHost = "127.0.0.1"
|
||||
var dbPassword = "123456"
|
||||
var dbName = "edges"
|
||||
|
||||
envDBHost, _ := os.LookupEnv("EDGE_DB_HOST")
|
||||
if len(envDBHost) > 0 {
|
||||
dbHost = envDBHost
|
||||
if verbose {
|
||||
log.Println("env EDGE_DB_HOST=" + envDBHost)
|
||||
}
|
||||
}
|
||||
|
||||
envDBPassword, _ := os.LookupEnv("EDGE_DB_PASSWORD")
|
||||
if len(envDBPassword) > 0 {
|
||||
dbPassword = envDBPassword
|
||||
if verbose {
|
||||
log.Println("env EDGE_DB_PASSWORD=" + envDBPassword)
|
||||
}
|
||||
}
|
||||
|
||||
envDBName, _ := os.LookupEnv("EDGE_DB_NAME")
|
||||
if len(envDBName) > 0 {
|
||||
dbName = envDBName
|
||||
if verbose {
|
||||
log.Println("env EDGE_DB_NAME=" + envDBName)
|
||||
}
|
||||
}
|
||||
|
||||
var isTesting = lists.ContainsString(os.Args, "-test") || lists.ContainsString(os.Args, "--test")
|
||||
if isTesting {
|
||||
fmt.Println("testing mode ...")
|
||||
}
|
||||
|
||||
var instance = instances.NewInstance(instances.Options{
|
||||
IsTesting: isTesting,
|
||||
Verbose: verbose,
|
||||
Cacheable: false,
|
||||
WorkDir: "",
|
||||
SrcDir: "/usr/local/goedge/src",
|
||||
DB: struct {
|
||||
Host string
|
||||
Port int
|
||||
Username string
|
||||
Password string
|
||||
Name string
|
||||
}{
|
||||
Host: dbHost,
|
||||
Port: 3306,
|
||||
Username: "root",
|
||||
Password: dbPassword,
|
||||
Name: dbName,
|
||||
},
|
||||
AdminNode: struct {
|
||||
Port int
|
||||
}{
|
||||
Port: 7788,
|
||||
},
|
||||
APINode: struct {
|
||||
HTTPPort int
|
||||
RestHTTPPort int
|
||||
}{
|
||||
HTTPPort: 8001,
|
||||
RestHTTPPort: 8002,
|
||||
},
|
||||
Node: struct{ HTTPPort int }{
|
||||
HTTPPort: 80,
|
||||
},
|
||||
UserNode: struct {
|
||||
HTTPPort int
|
||||
}{
|
||||
HTTPPort: 7799,
|
||||
},
|
||||
})
|
||||
err := instance.SetupAll()
|
||||
if err != nil {
|
||||
fmt.Println("[ERROR]setup failed: " + err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println("ok")
|
||||
}
|
||||
37
go.mod
37
go.mod
@@ -1,10 +1,11 @@
|
||||
module github.com/TeaOSLab/EdgeAPI
|
||||
|
||||
go 1.18
|
||||
go 1.21
|
||||
|
||||
replace github.com/TeaOSLab/EdgeCommon => ../EdgeCommon
|
||||
|
||||
require (
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.8.0
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/dns/armdns v1.1.0
|
||||
github.com/TeaOSLab/EdgeCommon v0.0.0-00010101000000-000000000000
|
||||
@@ -12,35 +13,35 @@ require (
|
||||
github.com/andybalholm/brotli v1.0.4
|
||||
github.com/aws/aws-sdk-go v1.40.45
|
||||
github.com/cespare/xxhash v1.1.0
|
||||
github.com/cespare/xxhash/v2 v2.1.2
|
||||
github.com/fsnotify/fsnotify v1.6.0
|
||||
github.com/go-acme/lego/v4 v4.10.2
|
||||
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-20230704135818-4a5646ab1f5b
|
||||
github.com/iwind/TeaGo v0.0.0-20240312020455-6f20b5121caf
|
||||
github.com/iwind/gosock v0.0.0-20220505115348-f88412125a62
|
||||
github.com/miekg/dns v1.1.50
|
||||
github.com/mozillazg/go-pinyin v0.18.0
|
||||
github.com/pkg/sftp v1.12.0
|
||||
github.com/shirou/gopsutil/v3 v3.22.2
|
||||
github.com/smartwalle/alipay/v3 v3.1.7
|
||||
github.com/smartwalle/alipay/v3 v3.2.20
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.801
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.801
|
||||
github.com/volcengine/volc-sdk-golang v1.0.124
|
||||
golang.org/x/crypto v0.14.0
|
||||
golang.org/x/net v0.15.0
|
||||
golang.org/x/sys v0.13.0
|
||||
google.golang.org/grpc v1.45.0
|
||||
golang.org/x/crypto v0.22.0
|
||||
golang.org/x/net v0.24.0
|
||||
golang.org/x/sys v0.19.0
|
||||
google.golang.org/grpc v1.62.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.8.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 // indirect
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.1.1 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.2.0 // indirect
|
||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||
github.com/golang-jwt/jwt/v5 v5.0.0 // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/google/uuid v1.3.1 // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/kr/fs v0.1.0 // indirect
|
||||
@@ -52,20 +53,18 @@ require (
|
||||
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
|
||||
github.com/smartwalle/crypto4go v1.0.2 // indirect
|
||||
github.com/tdewolff/minify/v2 v2.12.7 // indirect
|
||||
github.com/tdewolff/parse/v2 v2.6.6 // indirect
|
||||
github.com/smartwalle/ncrypto v1.0.4 // indirect
|
||||
github.com/smartwalle/ngx v1.0.9 // indirect
|
||||
github.com/smartwalle/nsign v1.0.9 // indirect
|
||||
github.com/technoweenie/multipartstreamer v1.0.1 // indirect
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.801 // indirect
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.801 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.9 // indirect
|
||||
github.com/tklauser/numcpus v0.3.0 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.2 // indirect
|
||||
golang.org/x/mod v0.8.0 // indirect
|
||||
golang.org/x/text v0.13.0 // indirect
|
||||
golang.org/x/text v0.14.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
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240228224816-df926f6c8641 // indirect
|
||||
google.golang.org/protobuf v1.33.0 // indirect
|
||||
gopkg.in/ini.v1 v1.66.6 // indirect
|
||||
gopkg.in/square/go-jose.v2 v2.6.0 // indirect
|
||||
)
|
||||
|
||||
98
go.sum
98
go.sum
@@ -45,7 +45,6 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
|
||||
github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
|
||||
github.com/DataDog/sketches-go v0.0.0-20190923095040-43f19ad77ff7/go.mod h1:Q5DbzQ+3AkgGwymQO7aZFNP7ns2lZKGtvRBzRXfdi60=
|
||||
github.com/HdrHistogram/hdrhistogram-go v1.1.0/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo=
|
||||
github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo=
|
||||
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
|
||||
@@ -83,7 +82,6 @@ github.com/aws/aws-sdk-go v1.40.45/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm
|
||||
github.com/aws/aws-sdk-go-v2 v1.9.1/go.mod h1:cK/D0BBs0b/oWPIcX/Z/obahJK1TT7IPVjy53i/mX/4=
|
||||
github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.8.1/go.mod h1:CM+19rL1+4dFWnOQKwDc7H1KwXTz+h61oUSHyhV0b3o=
|
||||
github.com/aws/smithy-go v1.8.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E=
|
||||
github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM=
|
||||
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
@@ -98,9 +96,7 @@ github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA
|
||||
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
|
||||
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cheekybits/is v0.0.0-20150225183255-68e9c0620927/go.mod h1:h/aW8ynjgkuj+NQRlZcDbAbM1ORAbXjXX77sX7T289U=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
@@ -112,11 +108,7 @@ github.com/cloudwego/hertz/cmd/hz v0.7.0/go.mod h1:6SroAwvZkyL54CiPANDkTR3YoX2MY
|
||||
github.com/cloudwego/thriftgo v0.1.7/go.mod h1:LzeafuLSiHA9JTiWC8TIMIq64iadeObgRUhmVG1OC/w=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
|
||||
github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
@@ -126,11 +118,9 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/demdxx/gocast v1.2.0/go.mod h1:RTyqNS6BdIq/19jJX96PlVhfqG31tldKMnpVJnPa3pw=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200624174652-8d2f3be8b2d9/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||
github.com/djherbis/atime v1.1.0/go.mod h1:28OF6Y8s3NQWwacXc5eZTsEsiMzp7LF8MbXE+XJPdBE=
|
||||
github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI=
|
||||
github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
||||
github.com/eapache/go-resiliency v1.2.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
||||
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
|
||||
@@ -142,7 +132,6 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
|
||||
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
|
||||
@@ -171,8 +160,6 @@ github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG
|
||||
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
|
||||
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/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-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
@@ -215,8 +202,9 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
@@ -234,8 +222,9 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=
|
||||
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
@@ -251,8 +240,8 @@ github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm4
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
|
||||
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
@@ -297,9 +286,8 @@ github.com/hudl/fargo v1.4.0/go.mod h1:9Ai6uvFy5fQNq6VPKtg+Ceq1+eTY4nKUlR2JElEOc
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||
github.com/influxdata/influxdb1-client v0.0.0-20200827194710-b269163b24ab/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
|
||||
github.com/iwind/TeaGo v0.0.0-20210411134150-ddf57e240c2f/go.mod h1:KU4mS7QNiZ7QWEuDBk1zw0/Q2LrAPZv3tycEFBsuUwc=
|
||||
github.com/iwind/TeaGo v0.0.0-20230704135818-4a5646ab1f5b h1:yYUaxnc04uzfr7C9HBN52ZZvcQomND+C5aZTpjOUYFI=
|
||||
github.com/iwind/TeaGo v0.0.0-20230704135818-4a5646ab1f5b/go.mod h1:fi/Pq+/5m2HZoseM+39dMF57ANXRt6w4PkGu3NXPc5s=
|
||||
github.com/iwind/TeaGo v0.0.0-20240312020455-6f20b5121caf h1:WA9qgiynESu/DDTnLH6npRI5AK6UL9qwJ2YZ5qhJX5E=
|
||||
github.com/iwind/TeaGo v0.0.0-20240312020455-6f20b5121caf/go.mod h1:SfqVbWyIPdVflyA6lMgicZzsoGS8pyeLiTRe8/CIpGI=
|
||||
github.com/iwind/gosock v0.0.0-20220505115348-f88412125a62 h1:HJH6RDheAY156DnIfJSD/bEvqyXzsZuE2gzs8PuUjoo=
|
||||
github.com/iwind/gosock v0.0.0-20220505115348-f88412125a62/go.mod h1:H5Q7SXwbx3a97ecJkaS2sD77gspzE7HFUafBO0peEyA=
|
||||
github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs=
|
||||
@@ -354,7 +342,6 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4=
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
|
||||
github.com/matryer/try v0.0.0-20161228173917-9ac251b645a2/go.mod h1:0KeJpeMD6o+O4hW7qJOT7vyQPKrWmj26uf5wMc/IiIs=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
@@ -404,17 +391,13 @@ github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI
|
||||
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||
github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
|
||||
github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/onsi/gomega v1.13.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY=
|
||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
|
||||
github.com/opentracing/opentracing-go v1.1.1-0.20190913142402-a7454ce5950e/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
|
||||
github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b h1:FfH+VrHHk6Lxt9HdVS0PXzSXFyS2NbZKXv33FYPol0A=
|
||||
github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b/go.mod h1:AC62GU6hc0BrNm+9RK9VSiwa/EUe1bkIeFORAMcHvJU=
|
||||
@@ -475,17 +458,20 @@ github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/smartwalle/alipay/v3 v3.1.7 h1:J4U5slABafKVD/b9gPCZe/3HAPB8Pa2NOYOPcugEJBo=
|
||||
github.com/smartwalle/alipay/v3 v3.1.7/go.mod h1:cZUMCCnsux9YAxA0/f3PWUR+7wckWtE1BqxbVRtGij0=
|
||||
github.com/smartwalle/crypto4go v1.0.2 h1:9DUEOOsPhmp00438L4oBdcL8EZG1zumecft5bWj5phI=
|
||||
github.com/smartwalle/crypto4go v1.0.2/go.mod h1:LQ7vCZIb7BE5+MuMtJBuO8ORkkQ01m4DXDBWPzLbkMY=
|
||||
github.com/smartwalle/alipay/v3 v3.2.20 h1:IjpG3YYgUgzCfS0z/EHlUbbr0OlrmOBHUst/3FzToYE=
|
||||
github.com/smartwalle/alipay/v3 v3.2.20/go.mod h1:KWg91KsY+eIOf26ZfZeH7bed1bWulGpGrL1ErHF3jWo=
|
||||
github.com/smartwalle/ncrypto v1.0.4 h1:P2rqQxDepJwgeO5ShoC+wGcK2wNJDmcdBOWAksuIgx8=
|
||||
github.com/smartwalle/ncrypto v1.0.4/go.mod h1:Dwlp6sfeNaPMnOxMNayMTacvC5JGEVln3CVdiVDgbBk=
|
||||
github.com/smartwalle/ngx v1.0.9 h1:pUXDvWRZJIHVrCKA1uZ15YwNti+5P4GuJGbpJ4WvpMw=
|
||||
github.com/smartwalle/ngx v1.0.9/go.mod h1:mx/nz2Pk5j+RBs7t6u6k22MPiBG/8CtOMpCnALIG8Y0=
|
||||
github.com/smartwalle/nsign v1.0.9 h1:8poAgG7zBd8HkZy9RQDwasC6XZvJpDGQWSjzL2FZL6E=
|
||||
github.com/smartwalle/nsign v1.0.9/go.mod h1:eY6I4CJlyNdVMP+t6z1H6Jpd4m5/V+8xi44ufSTxXgc=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
|
||||
github.com/streadway/amqp v1.0.0/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
|
||||
github.com/streadway/handy v0.0.0-20200128134331-0f66f006fb2e/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI=
|
||||
@@ -498,13 +484,7 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
||||
github.com/tdewolff/minify/v2 v2.12.7 h1:pBzz2tAfz5VghOXiQIsSta6srhmTeinQPjRDHWoumCA=
|
||||
github.com/tdewolff/minify/v2 v2.12.7/go.mod h1:ZRKTheiOGyLSK8hOZWWv+YoJAECzDivNgAlVYDHp/Ws=
|
||||
github.com/tdewolff/parse/v2 v2.6.6 h1:Yld+0CrKUJaCV78DL1G2nk3C9lKrxyRTux5aaK/AkDo=
|
||||
github.com/tdewolff/parse/v2 v2.6.6/go.mod h1:woz0cgbLwFdtbjJu8PIKxhW05KplTFQkOdX78o+Jgrs=
|
||||
github.com/tdewolff/test v1.0.7/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE=
|
||||
github.com/tdewolff/test v1.0.9 h1:SswqJCmeN4B+9gEAi/5uqT0qpi1y2/2O47V/1hhGZT0=
|
||||
github.com/tdewolff/test v1.0.9/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/technoweenie/multipartstreamer v1.0.1 h1:XRztA5MXiR1TIRHxH2uNxXxaIkKQDeX7m2XsSOlQEnM=
|
||||
github.com/technoweenie/multipartstreamer v1.0.1/go.mod h1:jNVxdtShOxzAsukZwTSw6MDx5eUJoiEBsSvzDU9uzog=
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.801 h1:zLWU179K63I2oLFIl9gXJ/NVfh7qDOVUARksccRDknE=
|
||||
@@ -546,7 +526,6 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
|
||||
go.opentelemetry.io/otel v0.7.0/go.mod h1:aZMyHG5TqDOXEgH2tyLiXSUKly1jT3yqE9PmrzIeCdo=
|
||||
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
|
||||
@@ -559,7 +538,6 @@ go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190506204251-e1dfcc566284/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
|
||||
@@ -575,8 +553,8 @@ golang.org/x/crypto v0.0.0-20210920023735-84f357641f63/go.mod h1:GvvjBRRGRdwPK5y
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
||||
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
|
||||
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
|
||||
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
|
||||
golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
|
||||
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
|
||||
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
@@ -590,7 +568,6 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
|
||||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||
golang.org/x/exp v0.0.0-20200513190911-00229845015e/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw=
|
||||
golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
@@ -665,8 +642,8 @@ golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
|
||||
golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8=
|
||||
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
|
||||
golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
|
||||
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
@@ -685,8 +662,9 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
|
||||
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@@ -711,7 +689,6 @@ golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -730,7 +707,6 @@ golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -758,11 +734,10 @@ golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
|
||||
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
|
||||
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
|
||||
@@ -770,7 +745,8 @@ golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o=
|
||||
golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek=
|
||||
golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q=
|
||||
golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@@ -784,8 +760,8 @@ golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
|
||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
@@ -848,7 +824,6 @@ 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=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
|
||||
gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0=
|
||||
@@ -884,7 +859,6 @@ google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRn
|
||||
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
||||
google.golang.org/genproto v0.0.0-20191009194640-548a555dbc03/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
@@ -909,8 +883,8 @@ google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6D
|
||||
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
|
||||
google.golang.org/genproto v0.0.0-20210917145530-b395a37504d4/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
|
||||
google.golang.org/genproto v0.0.0-20220317150908-0efb43f6373e h1:fNKDNuUyC4WH+inqDMpfXDdfvwfYILbsX+oskGZ8hxg=
|
||||
google.golang.org/genproto v0.0.0-20220317150908-0efb43f6373e/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240228224816-df926f6c8641 h1:DKU1r6Tj5s1vlU/moGhuGz7E3xRfwjdAfDzbsaQJtEY=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240228224816-df926f6c8641/go.mod h1:UCOku4NytXMJuLQE5VuqA5lX3PcHCBo8pxNyvkf4xBs=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
@@ -928,8 +902,8 @@ google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv
|
||||
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
||||
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
|
||||
google.golang.org/grpc v1.45.0 h1:NEpgUqV3Z+ZjkqMsxMg11IaDrXY4RY6CQukSGK0uI1M=
|
||||
google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=
|
||||
google.golang.org/grpc v1.62.0 h1:HQKZ/fa1bXkX1oFOvSjmZEUL8wLSaZTjCcLAlmZRtdk=
|
||||
google.golang.org/grpc v1.62.0/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
@@ -943,8 +917,9 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
|
||||
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
|
||||
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
@@ -968,7 +943,6 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package teaconst
|
||||
|
||||
const (
|
||||
Version = "1.3.1"
|
||||
Version = "1.3.7"
|
||||
|
||||
ProductName = "Edge API"
|
||||
ProcessName = "edge-api"
|
||||
@@ -20,8 +20,5 @@ const (
|
||||
|
||||
// 其他节点版本号,用来检测是否有需要升级的节点
|
||||
|
||||
NodeVersion = "1.3.1"
|
||||
|
||||
// SQLVersion SQL版本号
|
||||
SQLVersion = "11"
|
||||
NodeVersion = "1.3.7"
|
||||
)
|
||||
|
||||
9
internal/const/const_community.go
Normal file
9
internal/const/const_community.go
Normal file
@@ -0,0 +1,9 @@
|
||||
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
//go:build !plus
|
||||
|
||||
package teaconst
|
||||
|
||||
const (
|
||||
// DefaultMaxNodes 节点数限制
|
||||
DefaultMaxNodes int32 = 50
|
||||
)
|
||||
@@ -1,6 +1,7 @@
|
||||
package acme
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"github.com/iwind/TeaGo/Tea"
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
@@ -31,7 +32,7 @@ func init() {
|
||||
func (this *ACMETaskLogDAO) CreateACMETaskLog(tx *dbs.Tx, taskId int64, isOk bool, errMsg string) error {
|
||||
var op = NewACMETaskLogOperator()
|
||||
op.TaskId = taskId
|
||||
op.Error = errMsg
|
||||
op.Error = utils.LimitString(errMsg, 1024)
|
||||
op.IsOk = isOk
|
||||
err := this.Save(tx, op)
|
||||
return err
|
||||
|
||||
@@ -130,6 +130,19 @@ func (this *AdminDAO) FindAdminIdWithUsername(tx *dbs.Tx, username string) (int6
|
||||
return int64(one.(*Admin).Id), nil
|
||||
}
|
||||
|
||||
// FindAdminWithUsername 根据用户名查询管理员信息
|
||||
func (this *AdminDAO) FindAdminWithUsername(tx *dbs.Tx, username string) (*Admin, error) {
|
||||
one, err := this.Query(tx).
|
||||
Attr("username", username).
|
||||
State(AdminStateEnabled).
|
||||
ResultPk().
|
||||
Find()
|
||||
if err != nil || one == nil {
|
||||
return nil, err
|
||||
}
|
||||
return one.(*Admin), nil
|
||||
}
|
||||
|
||||
// UpdateAdminPassword 更改管理员密码
|
||||
func (this *AdminDAO) UpdateAdminPassword(tx *dbs.Tx, adminId int64, password string) error {
|
||||
if adminId <= 0 {
|
||||
@@ -212,7 +225,7 @@ func (this *AdminDAO) UpdateAdmin(tx *dbs.Tx, adminId int64, username string, ca
|
||||
return nil
|
||||
}
|
||||
|
||||
// CheckAdminUsername 检查用户名是否存在
|
||||
// CheckAdminUsername 检查管理员用户名是否存在
|
||||
func (this *AdminDAO) CheckAdminUsername(tx *dbs.Tx, adminId int64, username string) (bool, error) {
|
||||
query := this.Query(tx).
|
||||
State(AdminStateEnabled).
|
||||
@@ -260,7 +273,7 @@ func (this *AdminDAO) FindAllAdminModules(tx *dbs.Tx) (result []*Admin, err erro
|
||||
_, err = this.Query(tx).
|
||||
State(AdminStateEnabled).
|
||||
Attr("isOn", true).
|
||||
Result("id", "modules", "isSuper", "fullname", "theme").
|
||||
Result("id", "modules", "isSuper", "fullname", "theme", "lang").
|
||||
Slice(&result).
|
||||
FindAll()
|
||||
return
|
||||
@@ -313,6 +326,14 @@ func (this *AdminDAO) UpdateAdminTheme(tx *dbs.Tx, adminId int64, theme string)
|
||||
UpdateQuickly()
|
||||
}
|
||||
|
||||
// UpdateAdminLang 设置管理员语言
|
||||
func (this *AdminDAO) UpdateAdminLang(tx *dbs.Tx, adminId int64, langCode string) error {
|
||||
return this.Query(tx).
|
||||
Pk(adminId).
|
||||
Set("lang", langCode).
|
||||
UpdateQuickly()
|
||||
}
|
||||
|
||||
// CheckSuperAdmin 检查管理员是否为超级管理员
|
||||
func (this *AdminDAO) CheckSuperAdmin(tx *dbs.Tx, adminId int64) (bool, error) {
|
||||
if adminId <= 0 {
|
||||
|
||||
@@ -7,8 +7,8 @@ import (
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/goman"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/zero"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/iputils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
|
||||
@@ -520,14 +520,14 @@ func (this *HTTPAccessLogDAO) listAccessLogs(tx *dbs.Tx,
|
||||
|
||||
// keyword
|
||||
if len(ip) > 0 {
|
||||
// TODO 支持IP范围
|
||||
// TODO 支持IPv6范围
|
||||
if tableQuery.hasRemoteAddrField {
|
||||
// IP格式
|
||||
if strings.Contains(ip, ",") || strings.Contains(ip, "-") {
|
||||
rangeConfig, err := shared.ParseIPRange(ip)
|
||||
if err == nil {
|
||||
if len(rangeConfig.IPFrom) > 0 && len(rangeConfig.IPTo) > 0 {
|
||||
query.Between("INET_ATON(remoteAddr)", utils.IP2Long(rangeConfig.IPFrom), utils.IP2Long(rangeConfig.IPTo))
|
||||
query.Between("INET_ATON(remoteAddr)", iputils.ToLong(rangeConfig.IPFrom), iputils.ToLong(rangeConfig.IPTo))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -580,7 +580,7 @@ func (this *HTTPAccessLogDAO) listAccessLogs(tx *dbs.Tx,
|
||||
if len(pieces) == 1 || len(pieces[1]) == 0 || pieces[0] == pieces[1] {
|
||||
query.Attr("remoteAddr", pieces[0])
|
||||
} else {
|
||||
query.Between("INET_ATON(remoteAddr)", utils.IP2Long(pieces[0]), utils.IP2Long(pieces[1]))
|
||||
query.Between("INET_ATON(remoteAddr)", iputils.ToLong(pieces[0]), iputils.ToLong(pieces[1]))
|
||||
}
|
||||
} else if statusRangeReg.MatchString(keyword) { // status:200-400
|
||||
isSpecialKeyword = true
|
||||
|
||||
@@ -174,7 +174,8 @@ func (this *HTTPCachePolicyDAO) CreateDefaultCachePolicy(tx *dbs.Tx, name string
|
||||
}
|
||||
|
||||
var storageOptions = &serverconfigs.HTTPFileCacheStorage{
|
||||
Dir: "/opt/cache",
|
||||
Dir: "/opt/cache",
|
||||
EnableMMAP: true,
|
||||
MemoryPolicy: &serverconfigs.HTTPCachePolicy{
|
||||
Capacity: &shared.SizeCapacity{
|
||||
Count: 1,
|
||||
|
||||
@@ -134,7 +134,7 @@ func (this *HTTPFirewallPolicyDAO) CreateFirewallPolicy(tx *dbs.Tx, userId int64
|
||||
|
||||
if userId <= 0 && serverGroupId <= 0 && serverId <= 0 {
|
||||
// synFlood
|
||||
var synFloodConfig = firewallconfigs.DefaultSYNFloodConfig()
|
||||
var synFloodConfig = firewallconfigs.NewSYNFloodConfig()
|
||||
synFloodJSON, err := json.Marshal(synFloodConfig)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
@@ -142,20 +142,36 @@ func (this *HTTPFirewallPolicyDAO) CreateFirewallPolicy(tx *dbs.Tx, userId int64
|
||||
op.SynFlood = synFloodJSON
|
||||
|
||||
// block options
|
||||
var blockOptions = firewallconfigs.DefaultHTTPFirewallBlockAction()
|
||||
var blockOptions = firewallconfigs.NewHTTPFirewallBlockAction()
|
||||
blockOptionsJSON, err := json.Marshal(blockOptions)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
op.BlockOptions = blockOptionsJSON
|
||||
|
||||
// page options
|
||||
var pageOptions = firewallconfigs.NewHTTPFirewallPageAction()
|
||||
pageOptionsJSON, err := json.Marshal(pageOptions)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
op.PageOptions = pageOptionsJSON
|
||||
|
||||
// captcha options
|
||||
var captchaOptions = firewallconfigs.DefaultHTTPFirewallCaptchaAction()
|
||||
var captchaOptions = firewallconfigs.NewHTTPFirewallCaptchaAction()
|
||||
captchaOptionsJSON, err := json.Marshal(captchaOptions)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
op.CaptchaOptions = captchaOptionsJSON
|
||||
|
||||
// jscookie options
|
||||
var jsCookieOptions = firewallconfigs.NewHTTPFirewallJavascriptCookieAction()
|
||||
jsCookieOptionsJSON, err := json.Marshal(jsCookieOptions)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
op.JsCookieOptions = jsCookieOptionsJSON
|
||||
}
|
||||
|
||||
err := this.Save(tx, op)
|
||||
@@ -313,7 +329,9 @@ func (this *HTTPFirewallPolicyDAO) UpdateFirewallPolicy(tx *dbs.Tx,
|
||||
inboundJSON []byte,
|
||||
outboundJSON []byte,
|
||||
blockOptionsJSON []byte,
|
||||
pageOptionsJSON []byte,
|
||||
captchaOptionsJSON []byte,
|
||||
jsCookieOptionsJSON []byte,
|
||||
mode firewallconfigs.FirewallMode,
|
||||
useLocalFirewall bool,
|
||||
synFloodConfig *firewallconfigs.SYNFloodConfig,
|
||||
@@ -343,9 +361,15 @@ func (this *HTTPFirewallPolicyDAO) UpdateFirewallPolicy(tx *dbs.Tx,
|
||||
if IsNotNull(blockOptionsJSON) {
|
||||
op.BlockOptions = blockOptionsJSON
|
||||
}
|
||||
if IsNotNull(pageOptionsJSON) {
|
||||
op.PageOptions = pageOptionsJSON
|
||||
}
|
||||
if IsNotNull(captchaOptionsJSON) {
|
||||
op.CaptchaOptions = captchaOptionsJSON
|
||||
}
|
||||
if IsNotNull(jsCookieOptionsJSON) {
|
||||
op.JsCookieOptions = jsCookieOptionsJSON
|
||||
}
|
||||
|
||||
if synFloodConfig != nil {
|
||||
synFloodConfigJSON, err := json.Marshal(synFloodConfig)
|
||||
@@ -444,6 +468,7 @@ func (this *HTTPFirewallPolicyDAO) ComposeFirewallPolicy(tx *dbs.Tx, policyId in
|
||||
|
||||
var config = &firewallconfigs.HTTPFirewallPolicy{}
|
||||
config.Id = int64(policy.Id)
|
||||
config.ServerId = int64(policy.ServerId)
|
||||
config.IsOn = policy.IsOn
|
||||
config.Name = policy.Name
|
||||
config.Description = policy.Description
|
||||
@@ -515,7 +540,7 @@ func (this *HTTPFirewallPolicyDAO) ComposeFirewallPolicy(tx *dbs.Tx, policyId in
|
||||
|
||||
// Block动作配置
|
||||
if IsNotNull(policy.BlockOptions) {
|
||||
var blockAction = &firewallconfigs.HTTPFirewallBlockAction{}
|
||||
var blockAction = firewallconfigs.NewHTTPFirewallBlockAction()
|
||||
err = json.Unmarshal(policy.BlockOptions, blockAction)
|
||||
if err != nil {
|
||||
return config, err
|
||||
@@ -523,9 +548,19 @@ func (this *HTTPFirewallPolicyDAO) ComposeFirewallPolicy(tx *dbs.Tx, policyId in
|
||||
config.BlockOptions = blockAction
|
||||
}
|
||||
|
||||
// Page动作配置
|
||||
if IsNotNull(policy.PageOptions) {
|
||||
var pageAction = firewallconfigs.NewHTTPFirewallPageAction()
|
||||
err = json.Unmarshal(policy.PageOptions, pageAction)
|
||||
if err != nil {
|
||||
return config, err
|
||||
}
|
||||
config.PageOptions = pageAction
|
||||
}
|
||||
|
||||
// Captcha动作配置
|
||||
if IsNotNull(policy.CaptchaOptions) {
|
||||
var captchaAction = &firewallconfigs.HTTPFirewallCaptchaAction{}
|
||||
var captchaAction = firewallconfigs.NewHTTPFirewallCaptchaAction()
|
||||
err = json.Unmarshal(policy.CaptchaOptions, captchaAction)
|
||||
if err != nil {
|
||||
return config, err
|
||||
@@ -533,6 +568,16 @@ func (this *HTTPFirewallPolicyDAO) ComposeFirewallPolicy(tx *dbs.Tx, policyId in
|
||||
config.CaptchaOptions = captchaAction
|
||||
}
|
||||
|
||||
// JSCookie动作配置
|
||||
if IsNotNull(policy.JsCookieOptions) {
|
||||
var jsCookieAction = firewallconfigs.NewHTTPFirewallJavascriptCookieAction()
|
||||
err = json.Unmarshal(policy.JsCookieOptions, jsCookieAction)
|
||||
if err != nil {
|
||||
return config, err
|
||||
}
|
||||
config.JSCookieOptions = jsCookieAction
|
||||
}
|
||||
|
||||
// syn flood
|
||||
if IsNotNull(policy.SynFlood) {
|
||||
var synFloodConfig = &firewallconfigs.SYNFloodConfig{}
|
||||
@@ -667,6 +712,19 @@ func (this *HTTPFirewallPolicyDAO) FindFirewallPolicyIdsWithServerId(tx *dbs.Tx,
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// FindServerIdWithFirewallPolicyId 根据策略查找网站ID
|
||||
func (this *HTTPFirewallPolicyDAO) FindServerIdWithFirewallPolicyId(tx *dbs.Tx, policyId int64) (serverId int64, err error) {
|
||||
if policyId <= 0 {
|
||||
return
|
||||
}
|
||||
|
||||
serverId, err = this.Query(tx).
|
||||
Pk(policyId).
|
||||
Result("serverId").
|
||||
FindInt64Col(0)
|
||||
return
|
||||
}
|
||||
|
||||
// NotifyUpdate 通知更新
|
||||
func (this *HTTPFirewallPolicyDAO) NotifyUpdate(tx *dbs.Tx, policyId int64) error {
|
||||
webIds, err := SharedHTTPWebDAO.FindAllWebIdsWithHTTPFirewallPolicyId(tx, policyId)
|
||||
|
||||
@@ -16,8 +16,10 @@ const (
|
||||
HTTPFirewallPolicyField_Description dbs.FieldName = "description" // 描述
|
||||
HTTPFirewallPolicyField_Inbound dbs.FieldName = "inbound" // 入站规则
|
||||
HTTPFirewallPolicyField_Outbound dbs.FieldName = "outbound" // 出站规则
|
||||
HTTPFirewallPolicyField_BlockOptions dbs.FieldName = "blockOptions" // BLOCK选项
|
||||
HTTPFirewallPolicyField_CaptchaOptions dbs.FieldName = "captchaOptions" // 验证码选项
|
||||
HTTPFirewallPolicyField_BlockOptions dbs.FieldName = "blockOptions" // BLOCK动作选项
|
||||
HTTPFirewallPolicyField_PageOptions dbs.FieldName = "pageOptions" // PAGE动作选项
|
||||
HTTPFirewallPolicyField_CaptchaOptions dbs.FieldName = "captchaOptions" // 验证码动作选项
|
||||
HTTPFirewallPolicyField_JsCookieOptions dbs.FieldName = "jsCookieOptions" // JSCookie动作选项
|
||||
HTTPFirewallPolicyField_Mode dbs.FieldName = "mode" // 模式
|
||||
HTTPFirewallPolicyField_UseLocalFirewall dbs.FieldName = "useLocalFirewall" // 是否自动使用本地防火墙
|
||||
HTTPFirewallPolicyField_SynFlood dbs.FieldName = "synFlood" // SynFlood防御设置
|
||||
@@ -42,8 +44,10 @@ type HTTPFirewallPolicy struct {
|
||||
Description string `field:"description"` // 描述
|
||||
Inbound dbs.JSON `field:"inbound"` // 入站规则
|
||||
Outbound dbs.JSON `field:"outbound"` // 出站规则
|
||||
BlockOptions dbs.JSON `field:"blockOptions"` // BLOCK选项
|
||||
CaptchaOptions dbs.JSON `field:"captchaOptions"` // 验证码选项
|
||||
BlockOptions dbs.JSON `field:"blockOptions"` // BLOCK动作选项
|
||||
PageOptions dbs.JSON `field:"pageOptions"` // PAGE动作选项
|
||||
CaptchaOptions dbs.JSON `field:"captchaOptions"` // 验证码动作选项
|
||||
JsCookieOptions dbs.JSON `field:"jsCookieOptions"` // JSCookie动作选项
|
||||
Mode string `field:"mode"` // 模式
|
||||
UseLocalFirewall uint8 `field:"useLocalFirewall"` // 是否自动使用本地防火墙
|
||||
SynFlood dbs.JSON `field:"synFlood"` // SynFlood防御设置
|
||||
@@ -67,8 +71,10 @@ type HTTPFirewallPolicyOperator struct {
|
||||
Description any // 描述
|
||||
Inbound any // 入站规则
|
||||
Outbound any // 出站规则
|
||||
BlockOptions any // BLOCK选项
|
||||
CaptchaOptions any // 验证码选项
|
||||
BlockOptions any // BLOCK动作选项
|
||||
PageOptions any // PAGE动作选项
|
||||
CaptchaOptions any // 验证码动作选项
|
||||
JsCookieOptions any // JSCookie动作选项
|
||||
Mode any // 模式
|
||||
UseLocalFirewall any // 是否自动使用本地防火墙
|
||||
SynFlood any // SynFlood防御设置
|
||||
|
||||
@@ -554,6 +554,18 @@ func (this *HTTPWebDAO) ComposeWebConfig(tx *dbs.Tx, webId int64, isLocationOrGr
|
||||
}
|
||||
}
|
||||
|
||||
// hls
|
||||
if IsNotNull(web.Hls) {
|
||||
var hlsConfig = &serverconfigs.HLSConfig{}
|
||||
err = json.Unmarshal(web.Hls, hlsConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if this.shouldCompose(isLocationOrGroup, forNode, hlsConfig.IsPrior, true) {
|
||||
config.HLS = hlsConfig
|
||||
}
|
||||
}
|
||||
|
||||
if cacheMap != nil {
|
||||
cacheMap.Put(cacheKey, config)
|
||||
}
|
||||
@@ -1299,6 +1311,61 @@ func (this *HTTPWebDAO) UpdateWebRequestScripts(tx *dbs.Tx, webId int64, config
|
||||
return this.NotifyUpdate(tx, webId)
|
||||
}
|
||||
|
||||
// UpdateWebRequestScriptsAsPassed 设置请求脚本为审核通过
|
||||
func (this *HTTPWebDAO) UpdateWebRequestScriptsAsPassed(tx *dbs.Tx, webId int64, codeMD5 string) error {
|
||||
if webId <= 0 || len(codeMD5) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
configString, err := this.Query(tx).
|
||||
Pk(webId).
|
||||
Result("requestScripts").
|
||||
FindStringCol("")
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
var config = &serverconfigs.HTTPRequestScriptsConfig{}
|
||||
if len(configString) == 0 {
|
||||
return nil
|
||||
}
|
||||
err = json.Unmarshal([]byte(configString), config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var found bool
|
||||
|
||||
for _, group := range config.AllGroups() {
|
||||
for _, script := range group.Scripts {
|
||||
if script.AuditingCodeMD5 == codeMD5 {
|
||||
script.Code = script.AuditingCode
|
||||
script.AuditingCode = ""
|
||||
script.AuditingCodeMD5 = ""
|
||||
|
||||
found = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if found {
|
||||
configJSON, err := json.Marshal(config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = this.Query(tx).
|
||||
Pk(webId).
|
||||
Set("requestScripts", configJSON).
|
||||
UpdateQuickly()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return this.NotifyUpdate(tx, webId)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// FindWebRequestScripts 查找服务的脚本设置
|
||||
func (this *HTTPWebDAO) FindWebRequestScripts(tx *dbs.Tx, webId int64) (*serverconfigs.HTTPRequestScriptsConfig, error) {
|
||||
configString, err := this.Query(tx).
|
||||
@@ -1399,7 +1466,7 @@ func (this *HTTPWebDAO) UpdateWebReferers(tx *dbs.Tx, webId int64, referersConfi
|
||||
return this.NotifyUpdate(tx, webId)
|
||||
}
|
||||
|
||||
// FindWebReferers 查找服务的防盗链配置
|
||||
// FindWebReferers 查找网站的防盗链配置
|
||||
func (this *HTTPWebDAO) FindWebReferers(tx *dbs.Tx, webId int64) ([]byte, error) {
|
||||
return this.Query(tx).
|
||||
Pk(webId).
|
||||
@@ -1409,6 +1476,10 @@ func (this *HTTPWebDAO) FindWebReferers(tx *dbs.Tx, webId int64) ([]byte, error)
|
||||
|
||||
// UpdateWebUserAgent 修改User-Agent设置
|
||||
func (this *HTTPWebDAO) UpdateWebUserAgent(tx *dbs.Tx, webId int64, userAgentConfig *serverconfigs.UserAgentConfig) error {
|
||||
if webId <= 0 {
|
||||
return errors.New("require 'webId'")
|
||||
}
|
||||
|
||||
if userAgentConfig == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@ const (
|
||||
HTTPWebField_Referers dbs.FieldName = "referers" // 防盗链设置
|
||||
HTTPWebField_UserAgent dbs.FieldName = "userAgent" // UserAgent设置
|
||||
HTTPWebField_Optimization dbs.FieldName = "optimization" // 页面优化配置
|
||||
HTTPWebField_Hls dbs.FieldName = "hls" // HLS设置
|
||||
)
|
||||
|
||||
// HTTPWeb HTTP Web
|
||||
@@ -83,6 +84,7 @@ type HTTPWeb struct {
|
||||
Referers dbs.JSON `field:"referers"` // 防盗链设置
|
||||
UserAgent dbs.JSON `field:"userAgent"` // UserAgent设置
|
||||
Optimization dbs.JSON `field:"optimization"` // 页面优化配置
|
||||
Hls dbs.JSON `field:"hls"` // HLS设置
|
||||
}
|
||||
|
||||
type HTTPWebOperator struct {
|
||||
@@ -124,6 +126,7 @@ type HTTPWebOperator struct {
|
||||
Referers any // 防盗链设置
|
||||
UserAgent any // UserAgent设置
|
||||
Optimization any // 页面优化配置
|
||||
Hls any // HLS设置
|
||||
}
|
||||
|
||||
func NewHTTPWebOperator() *HTTPWebOperator {
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/goman"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/iputils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
@@ -13,8 +13,8 @@ import (
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
"github.com/iwind/TeaGo/lists"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
"math"
|
||||
"net"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -156,6 +156,59 @@ func (this *IPItemDAO) DisableIPItemsWithIP(tx *dbs.Tx, ipFrom string, ipTo stri
|
||||
return nil
|
||||
}
|
||||
|
||||
// DisableIPItemsWithIPValue 禁用某个IP相关条目
|
||||
func (this *IPItemDAO) DisableIPItemsWithIPValue(tx *dbs.Tx, value string, sourceUserId int64, listId int64) error {
|
||||
if len(value) == 0 {
|
||||
return errors.New("invalid 'value'")
|
||||
}
|
||||
|
||||
var query = this.Query(tx).
|
||||
Result("id", "listId").
|
||||
Attr("value", value).
|
||||
State(IPItemStateEnabled)
|
||||
|
||||
if listId > 0 {
|
||||
query.Attr("listId", listId)
|
||||
}
|
||||
|
||||
if sourceUserId > 0 {
|
||||
query.Attr("sourceUserId", sourceUserId)
|
||||
}
|
||||
|
||||
ones, err := query.FindAll()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var itemIds = []int64{}
|
||||
for _, one := range ones {
|
||||
var item = one.(*IPItem)
|
||||
var itemId = int64(item.Id)
|
||||
itemIds = append(itemIds, itemId)
|
||||
}
|
||||
|
||||
for _, itemId := range itemIds {
|
||||
version, err := SharedIPListDAO.IncreaseVersion(tx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = this.Query(tx).
|
||||
Pk(itemId).
|
||||
Set("state", IPItemStateDisabled).
|
||||
Set("version", version).
|
||||
Update()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if len(itemIds) > 0 {
|
||||
return this.NotifyUpdate(tx, itemIds[len(itemIds)-1])
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DisableIPItemsWithListId 禁用某个IP名单内的所有IP
|
||||
func (this *IPItemDAO) DisableIPItemsWithListId(tx *dbs.Tx, listId int64) error {
|
||||
for {
|
||||
@@ -237,9 +290,46 @@ func (this *IPItemDAO) DeleteOldItem(tx *dbs.Tx, listId int64, ipFrom string, ip
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteOldItemWithValue 根据IP删除以前的旧记录
|
||||
func (this *IPItemDAO) DeleteOldItemWithValue(tx *dbs.Tx, listId int64, value string) error {
|
||||
if len(value) == 0 {
|
||||
return nil
|
||||
}
|
||||
ones, err := this.Query(tx).
|
||||
ResultPk().
|
||||
UseIndex("ipFrom").
|
||||
Attr("listId", listId).
|
||||
Attr("value", value).
|
||||
Attr("state", IPItemStateEnabled).
|
||||
FindAll()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, one := range ones {
|
||||
var itemId = int64(one.(*IPItem).Id)
|
||||
version, err := SharedIPListDAO.IncreaseVersion(tx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = this.Query(tx).
|
||||
Pk(itemId).
|
||||
Set("version", version).
|
||||
Set("state", IPItemStateDisabled).
|
||||
UpdateQuickly()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// CreateIPItem 创建IP
|
||||
func (this *IPItemDAO) CreateIPItem(tx *dbs.Tx,
|
||||
listId int64,
|
||||
value string,
|
||||
ipFrom string,
|
||||
ipTo string,
|
||||
expiredAt int64,
|
||||
@@ -254,6 +344,15 @@ func (this *IPItemDAO) CreateIPItem(tx *dbs.Tx,
|
||||
sourceHTTPFirewallRuleGroupId int64,
|
||||
sourceHTTPFirewallRuleSetId int64,
|
||||
shouldNotify bool) (int64, error) {
|
||||
// generate 'itemType'
|
||||
if itemType != IPItemTypeAll && len(ipFrom) > 0 {
|
||||
if iputils.IsIPv4(ipFrom) {
|
||||
itemType = IPItemTypeIPv4
|
||||
} else if iputils.IsIPv6(ipFrom) {
|
||||
itemType = IPItemTypeIPv6
|
||||
}
|
||||
}
|
||||
|
||||
version, err := SharedIPListDAO.IncreaseVersion(tx)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
@@ -261,10 +360,10 @@ func (this *IPItemDAO) CreateIPItem(tx *dbs.Tx,
|
||||
|
||||
var op = NewIPItemOperator()
|
||||
op.ListId = listId
|
||||
op.Value = value
|
||||
op.IpFrom = ipFrom
|
||||
op.IpTo = ipTo
|
||||
op.IpFromLong = utils.IP2Long(ipFrom)
|
||||
op.IpToLong = utils.IP2Long(ipTo)
|
||||
|
||||
op.Reason = reason
|
||||
op.Type = itemType
|
||||
op.EventLevel = eventLevel
|
||||
@@ -320,11 +419,20 @@ func (this *IPItemDAO) CreateIPItem(tx *dbs.Tx,
|
||||
}
|
||||
|
||||
// UpdateIPItem 修改IP
|
||||
func (this *IPItemDAO) UpdateIPItem(tx *dbs.Tx, itemId int64, ipFrom string, ipTo string, expiredAt int64, reason string, itemType IPItemType, eventLevel string) error {
|
||||
func (this *IPItemDAO) UpdateIPItem(tx *dbs.Tx, itemId int64, value string, ipFrom string, ipTo string, expiredAt int64, reason string, itemType IPItemType, eventLevel string) error {
|
||||
if itemId <= 0 {
|
||||
return errors.New("invalid itemId")
|
||||
}
|
||||
|
||||
// generate 'itemType'
|
||||
if itemType != IPItemTypeAll && len(ipFrom) > 0 {
|
||||
if iputils.IsIPv4(ipFrom) {
|
||||
itemType = IPItemTypeIPv4
|
||||
} else if iputils.IsIPv6(ipFrom) {
|
||||
itemType = IPItemTypeIPv6
|
||||
}
|
||||
}
|
||||
|
||||
listId, err := this.Query(tx).
|
||||
Pk(itemId).
|
||||
Result("listId").
|
||||
@@ -343,10 +451,10 @@ func (this *IPItemDAO) UpdateIPItem(tx *dbs.Tx, itemId int64, ipFrom string, ipT
|
||||
|
||||
var op = NewIPItemOperator()
|
||||
op.Id = itemId
|
||||
op.Value = value
|
||||
op.IpFrom = ipFrom
|
||||
op.IpTo = ipTo
|
||||
op.IpFromLong = utils.IP2Long(ipFrom)
|
||||
op.IpToLong = utils.IP2Long(ipTo)
|
||||
|
||||
op.Reason = reason
|
||||
op.Type = itemType
|
||||
op.EventLevel = eventLevel
|
||||
@@ -443,16 +551,21 @@ func (this *IPItemDAO) FindItemListId(tx *dbs.Tx, itemId int64) (int64, error) {
|
||||
}
|
||||
|
||||
// FindEnabledItemContainsIP 查找包含某个IP的Item
|
||||
func (this *IPItemDAO) FindEnabledItemContainsIP(tx *dbs.Tx, listId int64, ip uint64) (*IPItem, error) {
|
||||
query := this.Query(tx).
|
||||
func (this *IPItemDAO) FindEnabledItemContainsIP(tx *dbs.Tx, listId int64, ip string) (*IPItem, error) {
|
||||
var query = this.Query(tx).
|
||||
Attr("listId", listId).
|
||||
State(IPItemStateEnabled)
|
||||
if ip > math.MaxUint32 {
|
||||
query.Where("(type='all' OR ipFromLong=:ip)")
|
||||
} else {
|
||||
query.Where("(type='all' OR ipFromLong=:ip OR (ipToLong>0 AND ipFromLong<=:ip AND ipToLong>=:ip))").
|
||||
|
||||
if iputils.IsIPv4(ip) {
|
||||
query.Where("(type='all' OR ipFrom =:ip OR INET_ATON(:ip) BETWEEN INET_ATON(ipFrom) AND INET_ATON(ipTo))").
|
||||
Param("ip", ip)
|
||||
} else if iputils.IsIPv6(ip) {
|
||||
query.Where("(type='all' OR ipFrom =:ip OR HEX(INET6_ATON(:ip)) BETWEEN HEX(INET6_ATON(ipFrom)) AND HEX(INET6_ATON(ipTo)))").
|
||||
Param("ip", ip)
|
||||
} else {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
one, err := query.Find()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -500,7 +613,13 @@ func (this *IPItemDAO) CountAllEnabledIPItems(tx *dbs.Tx, sourceUserId int64, ke
|
||||
}
|
||||
if len(keyword) > 0 {
|
||||
if net.ParseIP(keyword) != nil { // 是一个IP地址
|
||||
query.Attr("ipFrom", keyword)
|
||||
if iputils.IsIPv4(keyword) {
|
||||
query.Where("(type='all' OR ipFrom =:ipKeyword OR INET_ATON(:ipKeyword) BETWEEN INET_ATON(ipFrom) AND INET_ATON(ipTo))").
|
||||
Param("ipKeyword", keyword)
|
||||
} else if iputils.IsIPv6(keyword) {
|
||||
query.Where("(type='all' OR ipFrom =:ipKeyword OR HEX(INET6_ATON(:ipKeyword)) BETWEEN HEX(INET6_ATON(ipFrom)) AND HEX(INET6_ATON(ipTo)))").
|
||||
Param("ipKeyword", keyword)
|
||||
}
|
||||
} else {
|
||||
query.Like("ipFrom", dbutils.QuoteLike(keyword))
|
||||
}
|
||||
@@ -546,7 +665,13 @@ func (this *IPItemDAO) ListAllEnabledIPItems(tx *dbs.Tx, sourceUserId int64, key
|
||||
}
|
||||
if len(keyword) > 0 {
|
||||
if net.ParseIP(keyword) != nil { // 是一个IP地址
|
||||
query.Attr("ipFrom", keyword)
|
||||
if iputils.IsIPv4(keyword) {
|
||||
query.Where("(type='all' OR ipFrom =:ipKeyword OR INET_ATON(:ipKeyword) BETWEEN INET_ATON(ipFrom) AND INET_ATON(ipTo))").
|
||||
Param("ipKeyword", keyword)
|
||||
} else if iputils.IsIPv6(keyword) {
|
||||
query.Where("(type='all' OR ipFrom =:ipKeyword OR HEX(INET6_ATON(:ipKeyword)) BETWEEN HEX(INET6_ATON(ipFrom)) AND HEX(INET6_ATON(ipTo)))").
|
||||
Param("ipKeyword", keyword)
|
||||
}
|
||||
} else {
|
||||
query.Like("ipFrom", dbutils.QuoteLike(keyword))
|
||||
}
|
||||
@@ -582,6 +707,62 @@ func (this *IPItemDAO) ListAllEnabledIPItems(tx *dbs.Tx, sourceUserId int64, key
|
||||
return
|
||||
}
|
||||
|
||||
// ListAllIPItemIds 搜索所有IP Id列表
|
||||
func (this *IPItemDAO) ListAllIPItemIds(tx *dbs.Tx, sourceUserId int64, keyword string, ip string, listId int64, unread bool, eventLevel string, listType string, offset int64, size int64) (itemIds []int64, err error) {
|
||||
var query = this.Query(tx)
|
||||
if sourceUserId > 0 {
|
||||
if listId <= 0 {
|
||||
query.Where("((listId=" + types.String(firewallconfigs.GlobalListId) + " AND sourceUserId=:sourceUserId) OR listId IN (SELECT id FROM " + SharedIPListDAO.Table + " WHERE userId=:sourceUserId AND state=1))")
|
||||
query.Param("sourceUserId", sourceUserId)
|
||||
} else if listId == firewallconfigs.GlobalListId {
|
||||
query.Attr("sourceUserId", sourceUserId)
|
||||
query.UseIndex("sourceUserId")
|
||||
}
|
||||
}
|
||||
if len(keyword) > 0 {
|
||||
if net.ParseIP(keyword) != nil { // 是一个IP地址
|
||||
query.Attr("ipFrom", keyword)
|
||||
} else {
|
||||
query.Like("ipFrom", dbutils.QuoteLike(keyword))
|
||||
}
|
||||
}
|
||||
if len(ip) > 0 {
|
||||
query.Attr("ipFrom", ip)
|
||||
}
|
||||
if listId > 0 {
|
||||
query.Attr("listId", listId)
|
||||
} else {
|
||||
if len(listType) > 0 {
|
||||
query.Where("(listId=" + types.String(firewallconfigs.GlobalListId) + " OR listId IN (SELECT id FROM " + SharedIPListDAO.Table + " WHERE state=1 AND type=:listType))")
|
||||
query.Param("listType", listType)
|
||||
} else {
|
||||
query.Where("(listId=" + types.String(firewallconfigs.GlobalListId) + " OR listId IN (SELECT id FROM " + SharedIPListDAO.Table + " WHERE state=1))")
|
||||
}
|
||||
}
|
||||
if unread {
|
||||
query.Attr("isRead", 0)
|
||||
}
|
||||
if len(eventLevel) > 0 {
|
||||
query.Attr("eventLevel", eventLevel)
|
||||
}
|
||||
result, err := query.
|
||||
ResultPk().
|
||||
State(IPItemStateEnabled).
|
||||
Where("(expiredAt=0 OR expiredAt>:expiredAt)").
|
||||
Param("expiredAt", time.Now().Unix()).
|
||||
DescPk().
|
||||
Offset(offset).
|
||||
Size(size).
|
||||
FindAll()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, itemOne := range result {
|
||||
itemIds = append(itemIds, int64(itemOne.(*IPItem).Id))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// UpdateItemsRead 设置所有未已读
|
||||
func (this *IPItemDAO) UpdateItemsRead(tx *dbs.Tx, sourceUserId int64) error {
|
||||
var query = this.Query(tx).
|
||||
@@ -641,6 +822,60 @@ func (this *IPItemDAO) CleanExpiredIPItems(tx *dbs.Tx) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ParseIPValue 解析IP值
|
||||
func (this *IPItemDAO) ParseIPValue(value string) (newValue string, ipFrom string, ipTo string, ok bool) {
|
||||
if len(value) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
newValue = value
|
||||
|
||||
// ip1-ip2
|
||||
if strings.Contains(value, "-") {
|
||||
var pieces = strings.Split(value, "-")
|
||||
if len(pieces) != 2 {
|
||||
return
|
||||
}
|
||||
|
||||
ipFrom = strings.TrimSpace(pieces[0])
|
||||
ipTo = strings.TrimSpace(pieces[1])
|
||||
|
||||
if !iputils.IsValid(ipFrom) || !iputils.IsValid(ipTo) {
|
||||
return
|
||||
}
|
||||
|
||||
if !iputils.IsSameVersion(ipFrom, ipTo) {
|
||||
return
|
||||
}
|
||||
|
||||
if iputils.CompareIP(ipFrom, ipTo) > 0 {
|
||||
ipFrom, ipTo = ipTo, ipFrom
|
||||
newValue = ipFrom + "-" + ipTo
|
||||
}
|
||||
|
||||
ok = true
|
||||
return
|
||||
}
|
||||
|
||||
// ip/mask
|
||||
if strings.Contains(value, "/") {
|
||||
cidr, err := iputils.ParseCIDR(value)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return newValue, cidr.From().String(), cidr.To().String(), true
|
||||
}
|
||||
|
||||
// single value
|
||||
if iputils.IsValid(value) {
|
||||
ipFrom = value
|
||||
ok = true
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// NotifyUpdate 通知更新
|
||||
func (this *IPItemDAO) NotifyUpdate(tx *dbs.Tx, itemId int64) error {
|
||||
// 获取ListId
|
||||
|
||||
@@ -51,7 +51,8 @@ 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, false)
|
||||
var ip = "192." + types.String(rands.Int(0, 255)) + "." + types.String(rands.Int(0, 255)) + "." + types.String(rands.Int(0, 255))
|
||||
itemId, err := dao.CreateIPItem(tx, firewallconfigs.GlobalListId, ip, ip, "", time.Now().Unix()+86400, "test", models.IPItemTypeIPv4, "warning", 0, 0, 0, 0, 0, 0, 0, false)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -74,3 +75,16 @@ func TestIPItemDAO_DisableIPItemsWithIP(t *testing.T) {
|
||||
}
|
||||
t.Log("ok")
|
||||
}
|
||||
|
||||
func TestIPItemDAO_ParseIPValue(t *testing.T) {
|
||||
var dao = models.NewIPItemDAO()
|
||||
t.Log(dao.ParseIPValue("192.168.1.100"))
|
||||
t.Log(dao.ParseIPValue("192.168.1.100-192.168.1.200"))
|
||||
t.Log(dao.ParseIPValue("192.168.1.200-192.168.1.100"))
|
||||
t.Log(dao.ParseIPValue("192.168.1.100/24"))
|
||||
t.Log(dao.ParseIPValue("::1"))
|
||||
t.Log(dao.ParseIPValue("192.168.1.100-::2"))
|
||||
t.Log(dao.ParseIPValue("192"))
|
||||
t.Log(dao.ParseIPValue("192.168.1.200/256"))
|
||||
t.Log(dao.ParseIPValue("192.168.1.200-"))
|
||||
}
|
||||
|
||||
@@ -1,14 +1,44 @@
|
||||
package models
|
||||
|
||||
import "github.com/iwind/TeaGo/dbs"
|
||||
|
||||
const (
|
||||
IPItemField_Id dbs.FieldName = "id" // ID
|
||||
IPItemField_ListId dbs.FieldName = "listId" // 所属名单ID
|
||||
IPItemField_Value dbs.FieldName = "value" // 原始值
|
||||
IPItemField_Type dbs.FieldName = "type" // 类型
|
||||
IPItemField_IpFrom dbs.FieldName = "ipFrom" // 开始IP
|
||||
IPItemField_IpTo dbs.FieldName = "ipTo" // 结束IP
|
||||
IPItemField_IpFromLong dbs.FieldName = "ipFromLong" // 开始IP整型(弃用)
|
||||
IPItemField_IpToLong dbs.FieldName = "ipToLong" // 结束IP整型(弃用)
|
||||
IPItemField_Version dbs.FieldName = "version" // 版本
|
||||
IPItemField_CreatedAt dbs.FieldName = "createdAt" // 创建时间
|
||||
IPItemField_UpdatedAt dbs.FieldName = "updatedAt" // 修改时间
|
||||
IPItemField_Reason dbs.FieldName = "reason" // 加入说明
|
||||
IPItemField_EventLevel dbs.FieldName = "eventLevel" // 事件级别
|
||||
IPItemField_State dbs.FieldName = "state" // 状态
|
||||
IPItemField_ExpiredAt dbs.FieldName = "expiredAt" // 过期时间
|
||||
IPItemField_ServerId dbs.FieldName = "serverId" // 有效范围服务ID
|
||||
IPItemField_NodeId dbs.FieldName = "nodeId" // 有效范围节点ID
|
||||
IPItemField_SourceNodeId dbs.FieldName = "sourceNodeId" // 来源节点ID
|
||||
IPItemField_SourceServerId dbs.FieldName = "sourceServerId" // 来源服务ID
|
||||
IPItemField_SourceHTTPFirewallPolicyId dbs.FieldName = "sourceHTTPFirewallPolicyId" // 来源策略ID
|
||||
IPItemField_SourceHTTPFirewallRuleGroupId dbs.FieldName = "sourceHTTPFirewallRuleGroupId" // 来源规则集分组ID
|
||||
IPItemField_SourceHTTPFirewallRuleSetId dbs.FieldName = "sourceHTTPFirewallRuleSetId" // 来源规则集ID
|
||||
IPItemField_SourceUserId dbs.FieldName = "sourceUserId" // 用户ID
|
||||
IPItemField_IsRead dbs.FieldName = "isRead" // 是否已读
|
||||
)
|
||||
|
||||
// IPItem IP
|
||||
type IPItem struct {
|
||||
Id uint64 `field:"id"` // ID
|
||||
ListId uint32 `field:"listId"` // 所属名单ID
|
||||
Value string `field:"value"` // 原始值
|
||||
Type string `field:"type"` // 类型
|
||||
IpFrom string `field:"ipFrom"` // 开始IP
|
||||
IpTo string `field:"ipTo"` // 结束IP
|
||||
IpFromLong uint64 `field:"ipFromLong"` // 开始IP整型
|
||||
IpToLong uint64 `field:"ipToLong"` // 结束IP整型
|
||||
IpFromLong uint64 `field:"ipFromLong"` // 开始IP整型(弃用)
|
||||
IpToLong uint64 `field:"ipToLong"` // 结束IP整型(弃用)
|
||||
Version uint64 `field:"version"` // 版本
|
||||
CreatedAt uint64 `field:"createdAt"` // 创建时间
|
||||
UpdatedAt uint64 `field:"updatedAt"` // 修改时间
|
||||
@@ -30,11 +60,12 @@ type IPItem struct {
|
||||
type IPItemOperator struct {
|
||||
Id any // ID
|
||||
ListId any // 所属名单ID
|
||||
Value any // 原始值
|
||||
Type any // 类型
|
||||
IpFrom any // 开始IP
|
||||
IpTo any // 结束IP
|
||||
IpFromLong any // 开始IP整型
|
||||
IpToLong any // 结束IP整型
|
||||
IpFromLong any // 开始IP整型(弃用)
|
||||
IpToLong any // 结束IP整型(弃用)
|
||||
Version any // 版本
|
||||
CreatedAt any // 创建时间
|
||||
UpdatedAt any // 修改时间
|
||||
|
||||
@@ -1 +1,15 @@
|
||||
package models
|
||||
|
||||
// ComposeValue 组合原始值
|
||||
func (this *IPItem) ComposeValue() string {
|
||||
if len(this.Value) > 0 {
|
||||
return this.Value
|
||||
}
|
||||
|
||||
// 兼容以往版本
|
||||
if len(this.IpTo) > 0 {
|
||||
return this.IpFrom + "-" + this.IpTo
|
||||
}
|
||||
|
||||
return this.IpFrom
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"github.com/iwind/TeaGo/types"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -449,6 +450,14 @@ func (this *IPLibraryFileDAO) GenerateIPLibrary(tx *dbs.Tx, libraryFileId int64)
|
||||
for _, province := range dbProvinces {
|
||||
for _, code := range province.AllCodes() {
|
||||
provinceMap[types.String(province.CountryId)+"_"+code] = int64(province.ValueId)
|
||||
|
||||
for _, suffix := range regions.RegionProvinceSuffixes {
|
||||
if strings.HasSuffix(code, suffix) {
|
||||
provinceMap[types.String(province.CountryId)+"_"+strings.TrimSuffix(code, suffix)] = int64(province.ValueId)
|
||||
} else {
|
||||
provinceMap[types.String(province.CountryId)+"_"+(code+suffix)] = int64(province.ValueId)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ const (
|
||||
var listTypeCacheMap = map[int64]*IPList{} // listId => *IPList
|
||||
var DefaultGlobalIPList = &IPList{
|
||||
Id: uint32(firewallconfigs.GlobalListId),
|
||||
Name: "全局封锁名单",
|
||||
Name: "系统黑名单",
|
||||
IsPublic: true,
|
||||
IsGlobal: true,
|
||||
Type: "black",
|
||||
@@ -339,3 +339,16 @@ func (this *IPListDAO) NotifyUpdate(tx *dbs.Tx, listId int64, taskType NodeTaskT
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// FindServerIdWithListId 查找IP名单对应的网站ID
|
||||
func (this *IPListDAO) FindServerIdWithListId(tx *dbs.Tx, listId int64) (serverId int64, err error) {
|
||||
if listId <= 0 {
|
||||
return
|
||||
}
|
||||
|
||||
serverId, err = this.Query(tx).
|
||||
Pk(listId).
|
||||
Result("serverId").
|
||||
FindInt64Col(0)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -135,40 +135,16 @@ func (this *LoginSessionDAO) WriteSessionValue(tx *dbs.Tx, sid string, key strin
|
||||
sessionOp.UserId = userId
|
||||
|
||||
if isNewSession {
|
||||
// 删除此用户之前创建的SESSION,防止单个用户SESSION过多
|
||||
// TODO 将来改成按照活跃时间排序
|
||||
const maxSessionsPerUser = 10
|
||||
oldOnes, err := this.Query(tx).
|
||||
// 删除此用户之前创建的SESSION,不再保存以往的SESSION,避免安全问题
|
||||
err = this.Query(tx).
|
||||
ResultPk().
|
||||
Attr("adminId", adminId).
|
||||
Attr("userId", userId).
|
||||
Asc("createdAt").
|
||||
FindAll()
|
||||
Neq("sid", sid).
|
||||
DeleteQuickly()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var countOldOnes = len(oldOnes)
|
||||
if countOldOnes > maxSessionsPerUser {
|
||||
var countDeleted int
|
||||
for _, oldOne := range oldOnes {
|
||||
var oldSessionId = int64(oldOne.(*LoginSession).Id)
|
||||
if oldSessionId == sessionId {
|
||||
continue
|
||||
}
|
||||
|
||||
if countDeleted < countOldOnes-maxSessionsPerUser {
|
||||
err = this.Query(tx).
|
||||
Pk(oldSessionId).
|
||||
DeleteQuickly()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
countDeleted++
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@ import (
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/goman"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||
"github.com/go-sql-driver/mysql"
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"github.com/iwind/TeaGo/Tea"
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
@@ -14,8 +13,10 @@ import (
|
||||
"github.com/iwind/TeaGo/rands"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
timeutil "github.com/iwind/TeaGo/utils/time"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
@@ -40,6 +41,8 @@ func init() {
|
||||
|
||||
const MetricStatTablePartials = 20 // 表格Partial数量
|
||||
|
||||
var metricHashRegexp = regexp.MustCompile(`^\w+$`)
|
||||
|
||||
func NewMetricStatDAO() *MetricStatDAO {
|
||||
return dbs.NewDAO(&MetricStatDAO{
|
||||
DAOObject: dbs.DAOObject{
|
||||
@@ -124,18 +127,30 @@ func (this *MetricStatDAO) DeleteItemStats(tx *dbs.Tx, itemId int64) error {
|
||||
}
|
||||
|
||||
// DeleteNodeItemStats 删除某个节点的统计数据
|
||||
func (this *MetricStatDAO) DeleteNodeItemStats(tx *dbs.Tx, nodeId int64, serverId int64, itemId int64, time string) error {
|
||||
func (this *MetricStatDAO) DeleteNodeItemStats(tx *dbs.Tx, nodeId int64, serverId int64, itemId int64, time string, keepKeys []string) error {
|
||||
if serverId > 0 {
|
||||
_, err := this.Query(tx).
|
||||
var query = this.Query(tx).
|
||||
Table(this.partialTable(serverId)).
|
||||
Attr("nodeId", nodeId).
|
||||
Attr("serverId", serverId).
|
||||
Attr("itemId", itemId).
|
||||
Attr("time", time).
|
||||
Delete()
|
||||
if this.canIgnore(err) {
|
||||
Attr("time", time)
|
||||
if len(keepKeys) > 0 {
|
||||
query.Reuse(false)
|
||||
var s []string
|
||||
for _, k := range keepKeys {
|
||||
if metricHashRegexp.MatchString(k) {
|
||||
s = append(s, "'"+k+"@"+types.String(nodeId)+"'")
|
||||
}
|
||||
}
|
||||
query.Where("hash NOT IN (" + strings.Join(s, ",") + ")")
|
||||
}
|
||||
err := query.
|
||||
DeleteQuickly()
|
||||
if err == nil || this.canIgnore(err) {
|
||||
return nil
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -759,10 +774,5 @@ func (this *MetricStatDAO) canIgnore(err error) bool {
|
||||
}
|
||||
|
||||
// 忽略 Error 1213: Deadlock found 错误
|
||||
mysqlErr, ok := err.(*mysql.MySQLError)
|
||||
if ok && mysqlErr.Number == 1213 {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
return CheckSQLErrCode(err, 1213)
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ func TestMetricStatDAO_DeleteNodeItemStats(t *testing.T) {
|
||||
defer func() {
|
||||
t.Log(time.Since(before).Seconds()*1000, "ms")
|
||||
}()
|
||||
err := dao.DeleteNodeItemStats(nil, 1, 0, 1, timeutil.Format("Ymd"))
|
||||
err := dao.DeleteNodeItemStats(nil, 1, 0, 1, timeutil.Format("Ymd"), nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/goman"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||
"github.com/go-sql-driver/mysql"
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"github.com/iwind/TeaGo/Tea"
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
@@ -289,10 +288,5 @@ func (this *MetricSumStatDAO) canIgnore(err error) bool {
|
||||
}
|
||||
|
||||
// 忽略 Error 1213: Deadlock found 错误
|
||||
mysqlErr, ok := err.(*mysql.MySQLError)
|
||||
if ok && mysqlErr.Number == 1213 {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
return CheckSQLErrCode(err, 1213)
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ func (this *NodeClusterDAO) FindAllEnableClusterIds(tx *dbs.Tx) (result []int64,
|
||||
}
|
||||
|
||||
// CreateCluster 创建集群
|
||||
func (this *NodeClusterDAO) CreateCluster(tx *dbs.Tx, adminId int64, name string, grantId int64, installDir string, dnsDomainId int64, dnsName string, dnsTTL int32, cachePolicyId int64, httpFirewallPolicyId int64, systemServices map[string]maps.Map, globalServerConfig *serverconfigs.GlobalServerConfig, autoInstallNftables bool, autoSystemTuning bool) (clusterId int64, err error) {
|
||||
func (this *NodeClusterDAO) CreateCluster(tx *dbs.Tx, adminId int64, name string, grantId int64, installDir string, dnsDomainId int64, dnsName string, dnsTTL int32, cachePolicyId int64, httpFirewallPolicyId int64, systemServices map[string]maps.Map, globalServerConfig *serverconfigs.GlobalServerConfig, autoInstallNftables bool, autoSystemTuning bool, autoTrimDisks bool) (clusterId int64, err error) {
|
||||
uniqueId, err := this.GenUniqueId(tx)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
@@ -190,6 +190,7 @@ func (this *NodeClusterDAO) CreateCluster(tx *dbs.Tx, adminId int64, name string
|
||||
op.Secret = secret
|
||||
op.AutoInstallNftables = autoInstallNftables
|
||||
op.AutoSystemTuning = autoSystemTuning
|
||||
op.AutoTrimDisks = autoTrimDisks
|
||||
op.State = NodeClusterStateEnabled
|
||||
err = this.Save(tx, op)
|
||||
if err != nil {
|
||||
@@ -200,7 +201,7 @@ func (this *NodeClusterDAO) CreateCluster(tx *dbs.Tx, adminId int64, name string
|
||||
}
|
||||
|
||||
// UpdateCluster 修改集群
|
||||
func (this *NodeClusterDAO) UpdateCluster(tx *dbs.Tx, clusterId int64, name string, grantId int64, installDir string, timezone string, nodeMaxThreads int32, autoOpenPorts bool, clockConfig *nodeconfigs.ClockConfig, autoRemoteStart bool, autoInstallTables bool, sshParams *nodeconfigs.SSHParams, autoSystemTuning bool) error {
|
||||
func (this *NodeClusterDAO) UpdateCluster(tx *dbs.Tx, clusterId int64, name string, grantId int64, installDir string, timezone string, nodeMaxThreads int32, autoOpenPorts bool, clockConfig *nodeconfigs.ClockConfig, autoRemoteStart bool, autoInstallTables bool, sshParams *nodeconfigs.SSHParams, autoSystemTuning bool, autoTrimDisks bool) error {
|
||||
if clusterId <= 0 {
|
||||
return errors.New("invalid clusterId")
|
||||
}
|
||||
@@ -228,6 +229,7 @@ func (this *NodeClusterDAO) UpdateCluster(tx *dbs.Tx, clusterId int64, name stri
|
||||
op.AutoRemoteStart = autoRemoteStart
|
||||
op.AutoInstallNftables = autoInstallTables
|
||||
op.AutoSystemTuning = autoSystemTuning
|
||||
op.AutoTrimDisks = autoTrimDisks
|
||||
|
||||
if sshParams != nil {
|
||||
sshParamsJSON, err := json.Marshal(sshParams)
|
||||
@@ -264,13 +266,22 @@ func (this *NodeClusterDAO) CountAllEnabledClusters(tx *dbs.Tx, keyword string)
|
||||
}
|
||||
|
||||
// ListEnabledClusters 列出单页集群
|
||||
func (this *NodeClusterDAO) ListEnabledClusters(tx *dbs.Tx, keyword string, offset, size int64) (result []*NodeCluster, err error) {
|
||||
func (this *NodeClusterDAO) ListEnabledClusters(tx *dbs.Tx, keyword string, idDesc bool, idAsc bool, offset, size int64) (result []*NodeCluster, err error) {
|
||||
var query = this.Query(tx).
|
||||
State(NodeClusterStateEnabled)
|
||||
if len(keyword) > 0 {
|
||||
query.Where("(name LIKE :keyword OR dnsName like :keyword OR (dnsDomainId > 0 AND dnsDomainId IN (SELECT id FROM "+dns.SharedDNSDomainDAO.Table+" WHERE name LIKE :keyword AND state=1)))").
|
||||
Param("keyword", dbutils.QuoteLike(keyword))
|
||||
}
|
||||
|
||||
if idDesc {
|
||||
query.DescPk()
|
||||
} else if idAsc {
|
||||
query.AscPk()
|
||||
} else {
|
||||
query.Desc("isPinned").DescPk()
|
||||
}
|
||||
|
||||
_, err = query.
|
||||
Result(
|
||||
NodeClusterField_Id,
|
||||
@@ -295,8 +306,6 @@ func (this *NodeClusterDAO) ListEnabledClusters(tx *dbs.Tx, keyword string, offs
|
||||
Offset(offset).
|
||||
Limit(size).
|
||||
Slice(&result).
|
||||
Desc("isPinned").
|
||||
DescPk().
|
||||
FindAll()
|
||||
|
||||
return
|
||||
@@ -1021,7 +1030,7 @@ func (this *NodeClusterDAO) FindClusterBasicInfo(tx *dbs.Tx, clusterId int64, ca
|
||||
cluster, err := this.Query(tx).
|
||||
Pk(clusterId).
|
||||
State(NodeClusterStateEnabled).
|
||||
Result("id", "name", "timeZone", "nodeMaxThreads", "cachePolicyId", "httpFirewallPolicyId", "autoOpenPorts", "webp", "uam", "cc", "httpPages", "http3", "isOn", "ddosProtection", "clock", "globalServerConfig", "autoInstallNftables", "autoSystemTuning", "networkSecurity").
|
||||
Result("id", "name", "timeZone", "nodeMaxThreads", "cachePolicyId", "httpFirewallPolicyId", "autoOpenPorts", "webp", "uam", "cc", "httpPages", "http3", "isOn", "ddosProtection", "clock", "globalServerConfig", "autoInstallNftables", "autoSystemTuning", "networkSecurity", "autoTrimDisks", "secret").
|
||||
Find()
|
||||
if err != nil || cluster == nil {
|
||||
return nil, err
|
||||
@@ -1043,7 +1052,7 @@ func (this *NodeClusterDAO) UpdateClusterWebPPolicy(tx *dbs.Tx, clusterId int64,
|
||||
return err
|
||||
}
|
||||
|
||||
return this.NotifyUpdate(tx, clusterId)
|
||||
return this.NotifyWebPPolicyUpdate(tx, clusterId)
|
||||
}
|
||||
|
||||
webpPolicyJSON, err := json.Marshal(webpPolicy)
|
||||
@@ -1058,7 +1067,7 @@ func (this *NodeClusterDAO) UpdateClusterWebPPolicy(tx *dbs.Tx, clusterId int64,
|
||||
return err
|
||||
}
|
||||
|
||||
return this.NotifyUpdate(tx, clusterId)
|
||||
return this.NotifyWebPPolicyUpdate(tx, clusterId)
|
||||
}
|
||||
|
||||
// FindClusterWebPPolicy 查询WebP设置
|
||||
@@ -1083,7 +1092,7 @@ func (this *NodeClusterDAO) FindClusterWebPPolicy(tx *dbs.Tx, clusterId int64, c
|
||||
return nodeconfigs.DefaultWebPImagePolicy, nil
|
||||
}
|
||||
|
||||
var policy = &nodeconfigs.WebPImagePolicy{}
|
||||
var policy = nodeconfigs.NewWebPImagePolicy()
|
||||
err = json.Unmarshal(webpJSON, policy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -1518,6 +1527,11 @@ func (this *NodeClusterDAO) NotifyTOAUpdate(tx *dbs.Tx, clusterId int64) error {
|
||||
return SharedNodeTaskDAO.CreateClusterTask(tx, nodeconfigs.NodeRoleNode, clusterId, 0, 0, NodeTaskTypeTOAChanged)
|
||||
}
|
||||
|
||||
// NotifyWebPPolicyUpdate 通知WebP策略更新
|
||||
func (this *NodeClusterDAO) NotifyWebPPolicyUpdate(tx *dbs.Tx, clusterId int64) error {
|
||||
return SharedNodeTaskDAO.CreateClusterTask(tx, nodeconfigs.NodeRoleNode, clusterId, 0, 0, NodeTaskTypeWebPPolicyChanged)
|
||||
}
|
||||
|
||||
// NotifyDNSUpdate 通知DNS更新
|
||||
// TODO 更新新的DNS解析记录的同时,需要删除老的DNS解析记录
|
||||
func (this *NodeClusterDAO) NotifyDNSUpdate(tx *dbs.Tx, clusterId int64) error {
|
||||
|
||||
@@ -45,6 +45,7 @@ const (
|
||||
NodeClusterField_Http3 dbs.FieldName = "http3" // HTTP3设置
|
||||
NodeClusterField_AutoSystemTuning dbs.FieldName = "autoSystemTuning" // 是否自动调整系统参数
|
||||
NodeClusterField_NetworkSecurity dbs.FieldName = "networkSecurity" // 网络安全策略
|
||||
NodeClusterField_AutoTrimDisks dbs.FieldName = "autoTrimDisks" // 是否自动执行TRIM
|
||||
)
|
||||
|
||||
// NodeCluster 节点集群
|
||||
@@ -91,6 +92,7 @@ type NodeCluster struct {
|
||||
Http3 dbs.JSON `field:"http3"` // HTTP3设置
|
||||
AutoSystemTuning bool `field:"autoSystemTuning"` // 是否自动调整系统参数
|
||||
NetworkSecurity dbs.JSON `field:"networkSecurity"` // 网络安全策略
|
||||
AutoTrimDisks bool `field:"autoTrimDisks"` // 是否自动执行TRIM
|
||||
}
|
||||
|
||||
type NodeClusterOperator struct {
|
||||
@@ -136,6 +138,7 @@ type NodeClusterOperator struct {
|
||||
Http3 any // HTTP3设置
|
||||
AutoSystemTuning any // 是否自动调整系统参数
|
||||
NetworkSecurity any // 网络安全策略
|
||||
AutoTrimDisks any // 是否自动执行TRIM
|
||||
}
|
||||
|
||||
func NewNodeClusterOperator() *NodeClusterOperator {
|
||||
|
||||
@@ -882,9 +882,28 @@ func (this *NodeDAO) FindNodeStatus(tx *dbs.Tx, nodeId int64) (*nodeconfigs.Node
|
||||
return status, nil
|
||||
}
|
||||
|
||||
// UpdateNodeIsOn 修改节点启用状态
|
||||
func (this *NodeDAO) UpdateNodeIsOn(tx *dbs.Tx, nodeId int64, isOn bool) error {
|
||||
if nodeId <= 0 {
|
||||
return errors.New("invalid nodeId")
|
||||
}
|
||||
err := this.Query(tx).
|
||||
Pk(nodeId).
|
||||
Set("isOn", isOn).
|
||||
UpdateQuickly()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return this.NotifyDNSUpdate(tx, nodeId)
|
||||
}
|
||||
|
||||
// UpdateNodeIsActive 更改节点在线状态
|
||||
func (this *NodeDAO) UpdateNodeIsActive(tx *dbs.Tx, nodeId int64, isActive bool) error {
|
||||
b := "true"
|
||||
if nodeId <= 0 {
|
||||
return errors.New("invalid nodeId")
|
||||
}
|
||||
var b = "true"
|
||||
if !isActive {
|
||||
b = "false"
|
||||
}
|
||||
@@ -898,6 +917,9 @@ func (this *NodeDAO) UpdateNodeIsActive(tx *dbs.Tx, nodeId int64, isActive bool)
|
||||
|
||||
// UpdateNodeIsInstalled 设置节点安装状态
|
||||
func (this *NodeDAO) UpdateNodeIsInstalled(tx *dbs.Tx, nodeId int64, isInstalled bool) error {
|
||||
if nodeId <= 0 {
|
||||
return errors.New("invalid nodeId")
|
||||
}
|
||||
_, err := this.Query(tx).
|
||||
Pk(nodeId).
|
||||
Set("isInstalled", isInstalled).
|
||||
@@ -1083,6 +1105,11 @@ func (this *NodeDAO) ComposeNodeConfig(tx *dbs.Tx, nodeId int64, dataMap *shared
|
||||
continue
|
||||
}
|
||||
|
||||
// 集群密钥
|
||||
if len(config.ClusterSecret) == 0 {
|
||||
config.ClusterSecret = nodeCluster.Secret
|
||||
}
|
||||
|
||||
// 所有节点IP地址
|
||||
nodeIPAddresses, err := SharedNodeIPAddressDAO.FindAllAccessibleIPAddressesWithClusterId(tx, nodeconfigs.NodeRoleNode, clusterId, cacheMap)
|
||||
if err != nil {
|
||||
@@ -1151,7 +1178,7 @@ func (this *NodeDAO) ComposeNodeConfig(tx *dbs.Tx, nodeId int64, dataMap *shared
|
||||
|
||||
// webp
|
||||
if IsNotNull(nodeCluster.Webp) {
|
||||
var webpPolicy = &nodeconfigs.WebPImagePolicy{}
|
||||
var webpPolicy = nodeconfigs.NewWebPImagePolicy()
|
||||
err = json.Unmarshal(nodeCluster.Webp, webpPolicy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -1222,10 +1249,11 @@ func (this *NodeDAO) ComposeNodeConfig(tx *dbs.Tx, nodeId int64, dataMap *shared
|
||||
}
|
||||
}
|
||||
|
||||
// 自动安装nftables
|
||||
// 自动安装nftables等集群配置
|
||||
if clusterIndex == 0 {
|
||||
config.AutoInstallNftables = nodeCluster.AutoInstallNftables
|
||||
config.AutoSystemTuning = nodeCluster.AutoSystemTuning
|
||||
config.AutoTrimDisks = nodeCluster.AutoTrimDisks
|
||||
}
|
||||
|
||||
// 安全设置
|
||||
|
||||
@@ -4,7 +4,10 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"errors"
|
||||
teaconst "github.com/TeaOSLab/EdgeAPI/internal/const"
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
)
|
||||
|
||||
func (this *NodeDAO) CountAllAuthorityNodes(tx *dbs.Tx) (int64, error) {
|
||||
@@ -15,5 +18,18 @@ func (this *NodeDAO) CountAllAuthorityNodes(tx *dbs.Tx) (int64, error) {
|
||||
}
|
||||
|
||||
func (this *NodeDAO) CheckNodesLimit(tx *dbs.Tx) error {
|
||||
var maxNodes = teaconst.DefaultMaxNodes
|
||||
|
||||
// 检查节点数量
|
||||
if maxNodes > 0 {
|
||||
count, err := this.CountAllAuthorityNodes(tx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if count >= int64(maxNodes) {
|
||||
return errors.New("超出最大节点数限制:" + types.String(maxNodes) + ",当前已用:" + types.String(count) + ",请自行修改源码修改此限制(EdgeAPI/internal/const/const_community.go) 或者 购买商业版本授权。")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -31,8 +31,10 @@ const (
|
||||
NodeTaskTypeHTTPCCPolicyChanged NodeTaskType = "httpCCPolicyChanged" // CC策略变化
|
||||
NodeTaskTypeHTTP3PolicyChanged NodeTaskType = "http3PolicyChanged" // HTTP3策略变化
|
||||
NodeTaskTypeNetworkSecurityPolicyChanged NodeTaskType = "networkSecurityPolicyChanged" // 网络安全策略变化
|
||||
NodeTaskTypeWebPPolicyChanged NodeTaskType = "webPPolicyChanged" // WebP策略变化
|
||||
NodeTaskTypeUpdatingServers NodeTaskType = "updatingServers" // 更新一组服务
|
||||
NodeTaskTypeTOAChanged NodeTaskType = "toaChanged" // TOA配置变化
|
||||
NodeTaskTypePlanChanged NodeTaskType = "planChanged" // 套餐变化
|
||||
|
||||
// NS相关
|
||||
|
||||
|
||||
@@ -305,6 +305,19 @@ func (this *OriginDAO) UpdateOrigin(tx *dbs.Tx,
|
||||
return this.NotifyUpdate(tx, originId)
|
||||
}
|
||||
|
||||
// UpdateOriginIsOn 修改源站是否启用
|
||||
func (this *OriginDAO) UpdateOriginIsOn(tx *dbs.Tx, originId int64, isOn bool) error {
|
||||
err := this.Query(tx).
|
||||
Pk(originId).
|
||||
Set("isOn", isOn).
|
||||
UpdateQuickly()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return this.NotifyUpdate(tx, originId)
|
||||
}
|
||||
|
||||
// CloneOrigin 复制源站
|
||||
func (this *OriginDAO) CloneOrigin(tx *dbs.Tx, fromOriginId int64) (newOriginId int64, err error) {
|
||||
if fromOriginId <= 0 {
|
||||
@@ -538,6 +551,17 @@ func (this *OriginDAO) CheckUserOrigin(tx *dbs.Tx, userId int64, originId int64)
|
||||
return SharedReverseProxyDAO.CheckUserReverseProxy(tx, userId, reverseProxyId)
|
||||
}
|
||||
|
||||
// ExistsOrigin 检查源站是否存在
|
||||
func (this *OriginDAO) ExistsOrigin(tx *dbs.Tx, originId int64) (bool, error) {
|
||||
if originId <= 0 {
|
||||
return false, nil
|
||||
}
|
||||
return this.Query(tx).
|
||||
Pk(originId).
|
||||
State(OriginStateEnabled).
|
||||
Exist()
|
||||
}
|
||||
|
||||
// NotifyUpdate 通知更新
|
||||
func (this *OriginDAO) NotifyUpdate(tx *dbs.Tx, originId int64) error {
|
||||
reverseProxyId, err := SharedReverseProxyDAO.FindReverseProxyContainsOriginId(tx, originId)
|
||||
|
||||
@@ -49,7 +49,12 @@ func (this *PlanDAO) EnablePlan(tx *dbs.Tx, id uint32) error {
|
||||
|
||||
// DisablePlan 禁用条目
|
||||
func (this *PlanDAO) DisablePlan(tx *dbs.Tx, id int64) error {
|
||||
_, err := this.Query(tx).
|
||||
clusterId, err := this.FindPlanClusterId(tx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = this.Query(tx).
|
||||
Pk(id).
|
||||
Set("state", PlanStateDisabled).
|
||||
Update()
|
||||
@@ -57,7 +62,7 @@ func (this *PlanDAO) DisablePlan(tx *dbs.Tx, id int64) error {
|
||||
return err
|
||||
}
|
||||
|
||||
return this.NotifyUpdate(tx, id)
|
||||
return this.NotifyUpdate(tx, id, clusterId)
|
||||
}
|
||||
|
||||
// FindEnabledPlan 查找启用中的条目
|
||||
@@ -175,18 +180,18 @@ func (this *PlanDAO) FindEnabledPlanTrafficLimit(tx *dbs.Tx, planId int64, cache
|
||||
return config, nil
|
||||
}
|
||||
|
||||
// NotifyUpdate 通知变更
|
||||
func (this *PlanDAO) NotifyUpdate(tx *dbs.Tx, planId int64) error {
|
||||
// 这里不要加入状态参数,因为需要适应删除后的更新
|
||||
clusterId, err := this.Query(tx).
|
||||
// FindPlanClusterId 查找套餐所属集群
|
||||
func (this *PlanDAO) FindPlanClusterId(tx *dbs.Tx, planId int64) (clusterId int64, err error) {
|
||||
return this.Query(tx).
|
||||
Pk(planId).
|
||||
Result("clusterId").
|
||||
FindInt64Col(0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if clusterId > 0 {
|
||||
return SharedNodeClusterDAO.NotifyUpdate(tx, clusterId)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// NotifyUpdate 通知变更
|
||||
func (this *PlanDAO) NotifyUpdate(tx *dbs.Tx, planId int64, clusterId int64) error {
|
||||
if clusterId <= 0 {
|
||||
return nil
|
||||
}
|
||||
return SharedNodeClusterDAO.NotifyUpdate(tx, clusterId)
|
||||
}
|
||||
|
||||
@@ -3,70 +3,88 @@ package models
|
||||
import "github.com/iwind/TeaGo/dbs"
|
||||
|
||||
const (
|
||||
PlanField_Id dbs.FieldName = "id" // ID
|
||||
PlanField_IsOn dbs.FieldName = "isOn" // 是否启用
|
||||
PlanField_Name dbs.FieldName = "name" // 套餐名
|
||||
PlanField_ClusterId dbs.FieldName = "clusterId" // 集群ID
|
||||
PlanField_TrafficLimit dbs.FieldName = "trafficLimit" // 流量限制
|
||||
PlanField_Features dbs.FieldName = "features" // 允许的功能
|
||||
PlanField_TrafficPrice dbs.FieldName = "trafficPrice" // 流量价格设定
|
||||
PlanField_BandwidthPrice dbs.FieldName = "bandwidthPrice" // 带宽价格
|
||||
PlanField_MonthlyPrice dbs.FieldName = "monthlyPrice" // 月付
|
||||
PlanField_SeasonallyPrice dbs.FieldName = "seasonallyPrice" // 季付
|
||||
PlanField_YearlyPrice dbs.FieldName = "yearlyPrice" // 年付
|
||||
PlanField_PriceType dbs.FieldName = "priceType" // 价格类型
|
||||
PlanField_Order dbs.FieldName = "order" // 排序
|
||||
PlanField_State dbs.FieldName = "state" // 状态
|
||||
PlanField_TotalServers dbs.FieldName = "totalServers" // 可以绑定的网站数量
|
||||
PlanField_TotalServerNamesPerServer dbs.FieldName = "totalServerNamesPerServer" // 每个网站可以绑定的域名数量
|
||||
PlanField_TotalServerNames dbs.FieldName = "totalServerNames" // 总域名数量
|
||||
PlanField_MonthlyRequests dbs.FieldName = "monthlyRequests" // 每月访问量额度
|
||||
PlanField_DailyRequests dbs.FieldName = "dailyRequests" // 每日访问量额度
|
||||
PlanField_Id dbs.FieldName = "id" // ID
|
||||
PlanField_IsOn dbs.FieldName = "isOn" // 是否启用
|
||||
PlanField_Name dbs.FieldName = "name" // 套餐名
|
||||
PlanField_Description dbs.FieldName = "description" // 套餐简介
|
||||
PlanField_ClusterId dbs.FieldName = "clusterId" // 集群ID
|
||||
PlanField_TrafficLimit dbs.FieldName = "trafficLimit" // 流量限制
|
||||
PlanField_BandwidthLimitPerNode dbs.FieldName = "bandwidthLimitPerNode" // 单节点带宽限制
|
||||
PlanField_Features dbs.FieldName = "features" // 允许的功能
|
||||
PlanField_HasFullFeatures dbs.FieldName = "hasFullFeatures" // 是否有完整的功能
|
||||
PlanField_TrafficPrice dbs.FieldName = "trafficPrice" // 流量价格设定
|
||||
PlanField_BandwidthPrice dbs.FieldName = "bandwidthPrice" // 带宽价格
|
||||
PlanField_MonthlyPrice dbs.FieldName = "monthlyPrice" // 月付
|
||||
PlanField_SeasonallyPrice dbs.FieldName = "seasonallyPrice" // 季付
|
||||
PlanField_YearlyPrice dbs.FieldName = "yearlyPrice" // 年付
|
||||
PlanField_PriceType dbs.FieldName = "priceType" // 价格类型
|
||||
PlanField_Order dbs.FieldName = "order" // 排序
|
||||
PlanField_State dbs.FieldName = "state" // 状态
|
||||
PlanField_TotalServers dbs.FieldName = "totalServers" // 可以绑定的网站数量
|
||||
PlanField_TotalServerNamesPerServer dbs.FieldName = "totalServerNamesPerServer" // 每个网站可以绑定的域名数量
|
||||
PlanField_TotalServerNames dbs.FieldName = "totalServerNames" // 总域名数量
|
||||
PlanField_MonthlyRequests dbs.FieldName = "monthlyRequests" // 每月访问量额度
|
||||
PlanField_DailyRequests dbs.FieldName = "dailyRequests" // 每日访问量额度
|
||||
PlanField_DailyWebsocketConnections dbs.FieldName = "dailyWebsocketConnections" // 每日Websocket连接数
|
||||
PlanField_MonthlyWebsocketConnections dbs.FieldName = "monthlyWebsocketConnections" // 每月Websocket连接数
|
||||
PlanField_MaxUploadSize dbs.FieldName = "maxUploadSize" // 最大上传
|
||||
)
|
||||
|
||||
// Plan 用户套餐
|
||||
type Plan struct {
|
||||
Id uint32 `field:"id"` // ID
|
||||
IsOn bool `field:"isOn"` // 是否启用
|
||||
Name string `field:"name"` // 套餐名
|
||||
ClusterId uint32 `field:"clusterId"` // 集群ID
|
||||
TrafficLimit dbs.JSON `field:"trafficLimit"` // 流量限制
|
||||
Features dbs.JSON `field:"features"` // 允许的功能
|
||||
TrafficPrice dbs.JSON `field:"trafficPrice"` // 流量价格设定
|
||||
BandwidthPrice dbs.JSON `field:"bandwidthPrice"` // 带宽价格
|
||||
MonthlyPrice float64 `field:"monthlyPrice"` // 月付
|
||||
SeasonallyPrice float64 `field:"seasonallyPrice"` // 季付
|
||||
YearlyPrice float64 `field:"yearlyPrice"` // 年付
|
||||
PriceType string `field:"priceType"` // 价格类型
|
||||
Order uint32 `field:"order"` // 排序
|
||||
State uint8 `field:"state"` // 状态
|
||||
TotalServers uint32 `field:"totalServers"` // 可以绑定的网站数量
|
||||
TotalServerNamesPerServer uint32 `field:"totalServerNamesPerServer"` // 每个网站可以绑定的域名数量
|
||||
TotalServerNames uint32 `field:"totalServerNames"` // 总域名数量
|
||||
MonthlyRequests uint64 `field:"monthlyRequests"` // 每月访问量额度
|
||||
DailyRequests uint64 `field:"dailyRequests"` // 每日访问量额度
|
||||
Id uint32 `field:"id"` // ID
|
||||
IsOn bool `field:"isOn"` // 是否启用
|
||||
Name string `field:"name"` // 套餐名
|
||||
Description string `field:"description"` // 套餐简介
|
||||
ClusterId uint32 `field:"clusterId"` // 集群ID
|
||||
TrafficLimit dbs.JSON `field:"trafficLimit"` // 流量限制
|
||||
BandwidthLimitPerNode dbs.JSON `field:"bandwidthLimitPerNode"` // 单节点带宽限制
|
||||
Features dbs.JSON `field:"features"` // 允许的功能
|
||||
HasFullFeatures bool `field:"hasFullFeatures"` // 是否有完整的功能
|
||||
TrafficPrice dbs.JSON `field:"trafficPrice"` // 流量价格设定
|
||||
BandwidthPrice dbs.JSON `field:"bandwidthPrice"` // 带宽价格
|
||||
MonthlyPrice float64 `field:"monthlyPrice"` // 月付
|
||||
SeasonallyPrice float64 `field:"seasonallyPrice"` // 季付
|
||||
YearlyPrice float64 `field:"yearlyPrice"` // 年付
|
||||
PriceType string `field:"priceType"` // 价格类型
|
||||
Order uint32 `field:"order"` // 排序
|
||||
State uint8 `field:"state"` // 状态
|
||||
TotalServers uint32 `field:"totalServers"` // 可以绑定的网站数量
|
||||
TotalServerNamesPerServer uint32 `field:"totalServerNamesPerServer"` // 每个网站可以绑定的域名数量
|
||||
TotalServerNames uint32 `field:"totalServerNames"` // 总域名数量
|
||||
MonthlyRequests uint64 `field:"monthlyRequests"` // 每月访问量额度
|
||||
DailyRequests uint64 `field:"dailyRequests"` // 每日访问量额度
|
||||
DailyWebsocketConnections uint64 `field:"dailyWebsocketConnections"` // 每日Websocket连接数
|
||||
MonthlyWebsocketConnections uint64 `field:"monthlyWebsocketConnections"` // 每月Websocket连接数
|
||||
MaxUploadSize dbs.JSON `field:"maxUploadSize"` // 最大上传
|
||||
}
|
||||
|
||||
type PlanOperator struct {
|
||||
Id any // ID
|
||||
IsOn any // 是否启用
|
||||
Name any // 套餐名
|
||||
ClusterId any // 集群ID
|
||||
TrafficLimit any // 流量限制
|
||||
Features any // 允许的功能
|
||||
TrafficPrice any // 流量价格设定
|
||||
BandwidthPrice any // 带宽价格
|
||||
MonthlyPrice any // 月付
|
||||
SeasonallyPrice any // 季付
|
||||
YearlyPrice any // 年付
|
||||
PriceType any // 价格类型
|
||||
Order any // 排序
|
||||
State any // 状态
|
||||
TotalServers any // 可以绑定的网站数量
|
||||
TotalServerNamesPerServer any // 每个网站可以绑定的域名数量
|
||||
TotalServerNames any // 总域名数量
|
||||
MonthlyRequests any // 每月访问量额度
|
||||
DailyRequests any // 每日访问量额度
|
||||
Id any // ID
|
||||
IsOn any // 是否启用
|
||||
Name any // 套餐名
|
||||
Description any // 套餐简介
|
||||
ClusterId any // 集群ID
|
||||
TrafficLimit any // 流量限制
|
||||
BandwidthLimitPerNode any // 单节点带宽限制
|
||||
Features any // 允许的功能
|
||||
HasFullFeatures any // 是否有完整的功能
|
||||
TrafficPrice any // 流量价格设定
|
||||
BandwidthPrice any // 带宽价格
|
||||
MonthlyPrice any // 月付
|
||||
SeasonallyPrice any // 季付
|
||||
YearlyPrice any // 年付
|
||||
PriceType any // 价格类型
|
||||
Order any // 排序
|
||||
State any // 状态
|
||||
TotalServers any // 可以绑定的网站数量
|
||||
TotalServerNamesPerServer any // 每个网站可以绑定的域名数量
|
||||
TotalServerNames any // 总域名数量
|
||||
MonthlyRequests any // 每月访问量额度
|
||||
DailyRequests any // 每日访问量额度
|
||||
DailyWebsocketConnections any // 每日Websocket连接数
|
||||
MonthlyWebsocketConnections any // 每月Websocket连接数
|
||||
MaxUploadSize any // 最大上传
|
||||
}
|
||||
|
||||
func NewPlanOperator() *PlanOperator {
|
||||
|
||||
71
internal/db/models/posts/post_category_dao.go
Normal file
71
internal/db/models/posts/post_category_dao.go
Normal file
@@ -0,0 +1,71 @@
|
||||
package posts
|
||||
|
||||
import (
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"github.com/iwind/TeaGo/Tea"
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
)
|
||||
|
||||
const (
|
||||
PostCategoryStateEnabled = 1 // 已启用
|
||||
PostCategoryStateDisabled = 0 // 已禁用
|
||||
)
|
||||
|
||||
type PostCategoryDAO dbs.DAO
|
||||
|
||||
func NewPostCategoryDAO() *PostCategoryDAO {
|
||||
return dbs.NewDAO(&PostCategoryDAO{
|
||||
DAOObject: dbs.DAOObject{
|
||||
DB: Tea.Env,
|
||||
Table: "edgePostCategories",
|
||||
Model: new(PostCategory),
|
||||
PkName: "id",
|
||||
},
|
||||
}).(*PostCategoryDAO)
|
||||
}
|
||||
|
||||
var SharedPostCategoryDAO *PostCategoryDAO
|
||||
|
||||
func init() {
|
||||
dbs.OnReady(func() {
|
||||
SharedPostCategoryDAO = NewPostCategoryDAO()
|
||||
})
|
||||
}
|
||||
|
||||
// EnablePostCategory 启用条目
|
||||
func (this *PostCategoryDAO) EnablePostCategory(tx *dbs.Tx, categoryId int64) error {
|
||||
_, err := this.Query(tx).
|
||||
Pk(categoryId).
|
||||
Set("state", PostCategoryStateEnabled).
|
||||
Update()
|
||||
return err
|
||||
}
|
||||
|
||||
// DisablePostCategory 禁用条目
|
||||
func (this *PostCategoryDAO) DisablePostCategory(tx *dbs.Tx, categoryId int64) error {
|
||||
_, err := this.Query(tx).
|
||||
Pk(categoryId).
|
||||
Set("state", PostCategoryStateDisabled).
|
||||
Update()
|
||||
return err
|
||||
}
|
||||
|
||||
// FindEnabledPostCategory 查找启用中的条目
|
||||
func (this *PostCategoryDAO) FindEnabledPostCategory(tx *dbs.Tx, categoryId int64) (*PostCategory, error) {
|
||||
result, err := this.Query(tx).
|
||||
Pk(categoryId).
|
||||
State(PostCategoryStateEnabled).
|
||||
Find()
|
||||
if result == nil {
|
||||
return nil, err
|
||||
}
|
||||
return result.(*PostCategory), err
|
||||
}
|
||||
|
||||
// FindPostCategoryName 根据主键查找名称
|
||||
func (this *PostCategoryDAO) FindPostCategoryName(tx *dbs.Tx, categoryId int64) (string, error) {
|
||||
return this.Query(tx).
|
||||
Pk(categoryId).
|
||||
Result("name").
|
||||
FindStringCol("")
|
||||
}
|
||||
6
internal/db/models/posts/post_category_dao_test.go
Normal file
6
internal/db/models/posts/post_category_dao_test.go
Normal file
@@ -0,0 +1,6 @@
|
||||
package posts_test
|
||||
|
||||
import (
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
_ "github.com/iwind/TeaGo/bootstrap"
|
||||
)
|
||||
35
internal/db/models/posts/post_category_model.go
Normal file
35
internal/db/models/posts/post_category_model.go
Normal file
@@ -0,0 +1,35 @@
|
||||
package posts
|
||||
|
||||
import "github.com/iwind/TeaGo/dbs"
|
||||
|
||||
const (
|
||||
PostCategoryField_Id dbs.FieldName = "id" // ID
|
||||
PostCategoryField_Name dbs.FieldName = "name" // 分类名称
|
||||
PostCategoryField_IsOn dbs.FieldName = "isOn" // 是否启用
|
||||
PostCategoryField_Code dbs.FieldName = "code" // 代号
|
||||
PostCategoryField_Order dbs.FieldName = "order" // 排序
|
||||
PostCategoryField_State dbs.FieldName = "state" // 分类状态
|
||||
)
|
||||
|
||||
// PostCategory 文章分类
|
||||
type PostCategory struct {
|
||||
Id uint32 `field:"id"` // ID
|
||||
Name string `field:"name"` // 分类名称
|
||||
IsOn bool `field:"isOn"` // 是否启用
|
||||
Code string `field:"code"` // 代号
|
||||
Order uint32 `field:"order"` // 排序
|
||||
State uint8 `field:"state"` // 分类状态
|
||||
}
|
||||
|
||||
type PostCategoryOperator struct {
|
||||
Id any // ID
|
||||
Name any // 分类名称
|
||||
IsOn any // 是否启用
|
||||
Code any // 代号
|
||||
Order any // 排序
|
||||
State any // 分类状态
|
||||
}
|
||||
|
||||
func NewPostCategoryOperator() *PostCategoryOperator {
|
||||
return &PostCategoryOperator{}
|
||||
}
|
||||
1
internal/db/models/posts/post_category_model_ext.go
Normal file
1
internal/db/models/posts/post_category_model_ext.go
Normal file
@@ -0,0 +1 @@
|
||||
package posts
|
||||
63
internal/db/models/posts/post_dao.go
Normal file
63
internal/db/models/posts/post_dao.go
Normal file
@@ -0,0 +1,63 @@
|
||||
package posts
|
||||
|
||||
import (
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"github.com/iwind/TeaGo/Tea"
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
)
|
||||
|
||||
const (
|
||||
PostStateEnabled = 1 // 已启用
|
||||
PostStateDisabled = 0 // 已禁用
|
||||
)
|
||||
|
||||
type PostDAO dbs.DAO
|
||||
|
||||
func NewPostDAO() *PostDAO {
|
||||
return dbs.NewDAO(&PostDAO{
|
||||
DAOObject: dbs.DAOObject{
|
||||
DB: Tea.Env,
|
||||
Table: "edgePosts",
|
||||
Model: new(Post),
|
||||
PkName: "id",
|
||||
},
|
||||
}).(*PostDAO)
|
||||
}
|
||||
|
||||
var SharedPostDAO *PostDAO
|
||||
|
||||
func init() {
|
||||
dbs.OnReady(func() {
|
||||
SharedPostDAO = NewPostDAO()
|
||||
})
|
||||
}
|
||||
|
||||
// EnablePost 启用条目
|
||||
func (this *PostDAO) EnablePost(tx *dbs.Tx, postId int64) error {
|
||||
_, err := this.Query(tx).
|
||||
Pk(postId).
|
||||
Set("state", PostStateEnabled).
|
||||
Update()
|
||||
return err
|
||||
}
|
||||
|
||||
// DisablePost 禁用条目
|
||||
func (this *PostDAO) DisablePost(tx *dbs.Tx, postId int64) error {
|
||||
_, err := this.Query(tx).
|
||||
Pk(postId).
|
||||
Set("state", PostStateDisabled).
|
||||
Update()
|
||||
return err
|
||||
}
|
||||
|
||||
// FindEnabledPost 查找启用中的条目
|
||||
func (this *PostDAO) FindEnabledPost(tx *dbs.Tx, postId int64) (*Post, error) {
|
||||
result, err := this.Query(tx).
|
||||
Pk(postId).
|
||||
State(PostStateEnabled).
|
||||
Find()
|
||||
if result == nil {
|
||||
return nil, err
|
||||
}
|
||||
return result.(*Post), err
|
||||
}
|
||||
6
internal/db/models/posts/post_dao_test.go
Normal file
6
internal/db/models/posts/post_dao_test.go
Normal file
@@ -0,0 +1,6 @@
|
||||
package posts_test
|
||||
|
||||
import (
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
_ "github.com/iwind/TeaGo/bootstrap"
|
||||
)
|
||||
50
internal/db/models/posts/post_model.go
Normal file
50
internal/db/models/posts/post_model.go
Normal file
@@ -0,0 +1,50 @@
|
||||
package posts
|
||||
|
||||
import "github.com/iwind/TeaGo/dbs"
|
||||
|
||||
const (
|
||||
PostField_Id dbs.FieldName = "id" // ID
|
||||
PostField_CategoryId dbs.FieldName = "categoryId" // 文章分类
|
||||
PostField_Type dbs.FieldName = "type" // 类型:normal, url
|
||||
PostField_Url dbs.FieldName = "url" // URL
|
||||
PostField_Subject dbs.FieldName = "subject" // 标题
|
||||
PostField_Body dbs.FieldName = "body" // 内容
|
||||
PostField_CreatedAt dbs.FieldName = "createdAt" // 创建时间
|
||||
PostField_IsPublished dbs.FieldName = "isPublished" // 是否已发布
|
||||
PostField_PublishedAt dbs.FieldName = "publishedAt" // 发布时间
|
||||
PostField_ProductCode dbs.FieldName = "productCode" // 产品代号
|
||||
PostField_State dbs.FieldName = "state" // 状态
|
||||
)
|
||||
|
||||
// Post 文章管理
|
||||
type Post struct {
|
||||
Id uint32 `field:"id"` // ID
|
||||
CategoryId uint32 `field:"categoryId"` // 文章分类
|
||||
Type string `field:"type"` // 类型:normal, url
|
||||
Url string `field:"url"` // URL
|
||||
Subject string `field:"subject"` // 标题
|
||||
Body string `field:"body"` // 内容
|
||||
CreatedAt uint64 `field:"createdAt"` // 创建时间
|
||||
IsPublished bool `field:"isPublished"` // 是否已发布
|
||||
PublishedAt uint64 `field:"publishedAt"` // 发布时间
|
||||
ProductCode string `field:"productCode"` // 产品代号
|
||||
State uint8 `field:"state"` // 状态
|
||||
}
|
||||
|
||||
type PostOperator struct {
|
||||
Id any // ID
|
||||
CategoryId any // 文章分类
|
||||
Type any // 类型:normal, url
|
||||
Url any // URL
|
||||
Subject any // 标题
|
||||
Body any // 内容
|
||||
CreatedAt any // 创建时间
|
||||
IsPublished any // 是否已发布
|
||||
PublishedAt any // 发布时间
|
||||
ProductCode any // 产品代号
|
||||
State any // 状态
|
||||
}
|
||||
|
||||
func NewPostOperator() *PostOperator {
|
||||
return &PostOperator{}
|
||||
}
|
||||
1
internal/db/models/posts/post_model_ext.go
Normal file
1
internal/db/models/posts/post_model_ext.go
Normal file
@@ -0,0 +1 @@
|
||||
package posts
|
||||
@@ -98,6 +98,14 @@ func (this *RegionCountryDAO) FindRegionCountryName(tx *dbs.Tx, id int64) (strin
|
||||
return name, nil
|
||||
}
|
||||
|
||||
// FindRegionCountryRouteCode 查找国家|地区线路代号
|
||||
func (this *RegionCountryDAO) FindRegionCountryRouteCode(tx *dbs.Tx, countryId int64) (string, error) {
|
||||
return this.Query(tx).
|
||||
Attr("valueId", countryId).
|
||||
Result("routeCode").
|
||||
FindStringCol("")
|
||||
}
|
||||
|
||||
// FindCountryIdWithDataId 根据数据ID查找国家
|
||||
func (this *RegionCountryDAO) FindCountryIdWithDataId(tx *dbs.Tx, dataId string) (int64, error) {
|
||||
return this.Query(tx).
|
||||
|
||||
@@ -14,11 +14,12 @@ const (
|
||||
RegionCountryField_DataId dbs.FieldName = "dataId" // 原始数据ID
|
||||
RegionCountryField_Pinyin dbs.FieldName = "pinyin" // 拼音
|
||||
RegionCountryField_IsCommon dbs.FieldName = "isCommon" // 是否常用
|
||||
RegionCountryField_RouteCode dbs.FieldName = "routeCode" // 线路代号
|
||||
)
|
||||
|
||||
// RegionCountry 区域-国家/地区
|
||||
type RegionCountry struct {
|
||||
Id1 uint32 `field:"id"` // ID
|
||||
Id uint32 `field:"id"` // ID
|
||||
ValueId uint32 `field:"valueId"` // 实际ID
|
||||
ValueCode string `field:"valueCode"` // 值代号
|
||||
Name string `field:"name"` // 名称
|
||||
@@ -29,6 +30,7 @@ type RegionCountry struct {
|
||||
DataId string `field:"dataId"` // 原始数据ID
|
||||
Pinyin dbs.JSON `field:"pinyin"` // 拼音
|
||||
IsCommon bool `field:"isCommon"` // 是否常用
|
||||
RouteCode string `field:"routeCode"` // 线路代号
|
||||
}
|
||||
|
||||
type RegionCountryOperator struct {
|
||||
@@ -43,6 +45,7 @@ type RegionCountryOperator struct {
|
||||
DataId any // 原始数据ID
|
||||
Pinyin any // 拼音
|
||||
IsCommon any // 是否常用
|
||||
RouteCode any // 线路代号
|
||||
}
|
||||
|
||||
func NewRegionCountryOperator() *RegionCountryOperator {
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"github.com/iwind/TeaGo/types"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -18,6 +19,8 @@ const (
|
||||
RegionProvinceStateDisabled = 0 // 已禁用
|
||||
)
|
||||
|
||||
var RegionProvinceSuffixes = []string{"省", "州", "区", "大区", "特区", "港", "岛", "环礁", "谷地", "山", "口岸", "郡", "县", "城", "河", "河畔", "市"}
|
||||
|
||||
type RegionProvinceDAO dbs.DAO
|
||||
|
||||
func NewRegionProvinceDAO() *RegionProvinceDAO {
|
||||
@@ -77,6 +80,14 @@ func (this *RegionProvinceDAO) FindRegionProvinceName(tx *dbs.Tx, id int64) (str
|
||||
FindStringCol("")
|
||||
}
|
||||
|
||||
// FindRegionCountryId 获取省份对应的国家|地区
|
||||
func (this *RegionProvinceDAO) FindRegionCountryId(tx *dbs.Tx, provinceId int64) (int64, error) {
|
||||
return this.Query(tx).
|
||||
Attr("valueId", provinceId).
|
||||
Result("countryId").
|
||||
FindInt64Col(0)
|
||||
}
|
||||
|
||||
// FindProvinceIdWithDataId 根据数据ID查找省份
|
||||
func (this *RegionProvinceDAO) FindProvinceIdWithDataId(tx *dbs.Tx, dataId string) (int64, error) {
|
||||
return this.Query(tx).
|
||||
@@ -87,6 +98,37 @@ func (this *RegionProvinceDAO) FindProvinceIdWithDataId(tx *dbs.Tx, dataId strin
|
||||
|
||||
// FindProvinceIdWithName 根据省份名查找省份ID
|
||||
func (this *RegionProvinceDAO) FindProvinceIdWithName(tx *dbs.Tx, countryId int64, provinceName string) (int64, error) {
|
||||
{
|
||||
provinceId, err := this.findProvinceIdWithExactName(tx, countryId, provinceName)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if provinceId > 0 {
|
||||
return provinceId, nil
|
||||
}
|
||||
}
|
||||
|
||||
// 候选词
|
||||
for _, suffix := range RegionProvinceSuffixes {
|
||||
var name string
|
||||
if strings.HasSuffix(provinceName, suffix) {
|
||||
name = strings.TrimSuffix(provinceName, suffix)
|
||||
} else {
|
||||
name = provinceName + suffix
|
||||
}
|
||||
provinceId, err := this.findProvinceIdWithExactName(tx, countryId, name)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if provinceId > 0 {
|
||||
return provinceId, nil
|
||||
}
|
||||
}
|
||||
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func (this *RegionProvinceDAO) findProvinceIdWithExactName(tx *dbs.Tx, countryId int64, provinceName string) (int64, error) {
|
||||
return this.Query(tx).
|
||||
Attr("countryId", countryId).
|
||||
Where("(name=:provinceName OR customName=:provinceName OR JSON_CONTAINS(codes, :provinceNameJSON) OR JSON_CONTAINS(customCodes, :provinceNameJSON))").
|
||||
|
||||
@@ -26,6 +26,25 @@ func TestRegionProvinceDAO_FindProvinceIdWithName(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRegionProvinceDAO_FindProvinceIdWithName_Suffix(t *testing.T) {
|
||||
dbs.NotifyReady()
|
||||
|
||||
var tx *dbs.Tx
|
||||
for _, name := range []string{
|
||||
"维埃纳",
|
||||
"维埃纳省",
|
||||
"维埃纳大区",
|
||||
"维埃纳市",
|
||||
"维埃纳小区", // expect 0
|
||||
} {
|
||||
provinceId, err := SharedRegionProvinceDAO.FindProvinceIdWithName(tx, 74, name)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Log(name, "=>", provinceId)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRegionProvinceDAO_FindSimilarProvinces(t *testing.T) {
|
||||
dbs.NotifyReady()
|
||||
|
||||
|
||||
@@ -12,11 +12,12 @@ const (
|
||||
RegionProvinceField_CustomCodes dbs.FieldName = "customCodes" // 自定义代号
|
||||
RegionProvinceField_State dbs.FieldName = "state" // 状态
|
||||
RegionProvinceField_DataId dbs.FieldName = "dataId" // 原始数据ID
|
||||
RegionProvinceField_RouteCode dbs.FieldName = "routeCode" // 线路代号
|
||||
)
|
||||
|
||||
// RegionProvince 区域-省份
|
||||
type RegionProvince struct {
|
||||
Id1 uint32 `field:"id"` // ID
|
||||
Id uint32 `field:"id"` // ID
|
||||
ValueId uint32 `field:"valueId"` // 实际ID
|
||||
CountryId uint32 `field:"countryId"` // 国家ID
|
||||
Name string `field:"name"` // 名称
|
||||
@@ -25,6 +26,7 @@ type RegionProvince struct {
|
||||
CustomCodes dbs.JSON `field:"customCodes"` // 自定义代号
|
||||
State uint8 `field:"state"` // 状态
|
||||
DataId string `field:"dataId"` // 原始数据ID
|
||||
RouteCode string `field:"routeCode"` // 线路代号
|
||||
}
|
||||
|
||||
type RegionProvinceOperator struct {
|
||||
@@ -37,6 +39,7 @@ type RegionProvinceOperator struct {
|
||||
CustomCodes any // 自定义代号
|
||||
State any // 状态
|
||||
DataId any // 原始数据ID
|
||||
RouteCode any // 线路代号
|
||||
}
|
||||
|
||||
func NewRegionProvinceOperator() *RegionProvinceOperator {
|
||||
|
||||
@@ -376,14 +376,14 @@ func (this *ReverseProxyDAO) UpdateReverseProxyScheduling(tx *dbs.Tx, reversePro
|
||||
}
|
||||
|
||||
// UpdateReverseProxyPrimaryOrigins 修改主要源站
|
||||
func (this *ReverseProxyDAO) UpdateReverseProxyPrimaryOrigins(tx *dbs.Tx, reverseProxyId int64, origins []byte) error {
|
||||
func (this *ReverseProxyDAO) UpdateReverseProxyPrimaryOrigins(tx *dbs.Tx, reverseProxyId int64, originRefs []byte) error {
|
||||
if reverseProxyId <= 0 {
|
||||
return errors.New("invalid reverseProxyId")
|
||||
}
|
||||
var op = NewReverseProxyOperator()
|
||||
op.Id = reverseProxyId
|
||||
if len(origins) > 0 {
|
||||
op.PrimaryOrigins = origins
|
||||
if len(originRefs) > 0 {
|
||||
op.PrimaryOrigins = originRefs
|
||||
} else {
|
||||
op.PrimaryOrigins = "[]"
|
||||
}
|
||||
|
||||
@@ -1 +1,31 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||
"github.com/iwind/TeaGo/logs"
|
||||
)
|
||||
|
||||
// DecodePrimaryOrigins 解析主要源站
|
||||
func (this *ReverseProxy) DecodePrimaryOrigins() []*serverconfigs.OriginRef {
|
||||
var refs = []*serverconfigs.OriginRef{}
|
||||
if IsNotNull(this.PrimaryOrigins) {
|
||||
err := json.Unmarshal(this.PrimaryOrigins, &refs)
|
||||
if err != nil {
|
||||
logs.Error(err)
|
||||
}
|
||||
}
|
||||
return refs
|
||||
}
|
||||
|
||||
// DecodeBackupOrigins 解析备用源站
|
||||
func (this *ReverseProxy) DecodeBackupOrigins() []*serverconfigs.OriginRef {
|
||||
var refs = []*serverconfigs.OriginRef{}
|
||||
if IsNotNull(this.BackupOrigins) {
|
||||
err := json.Unmarshal(this.BackupOrigins, &refs)
|
||||
if err != nil {
|
||||
logs.Error(err)
|
||||
}
|
||||
}
|
||||
return refs
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ func init() {
|
||||
|
||||
// UpdateServerBandwidth 写入数据
|
||||
// 现在不需要把 userPlanId 加入到数据表unique key中,因为只会影响5分钟统计,影响非常有限
|
||||
func (this *ServerBandwidthStatDAO) UpdateServerBandwidth(tx *dbs.Tx, userId int64, serverId int64, regionId int64, userPlanId int64, day string, timeAt string, bandwidthBytes int64, totalBytes int64, cachedBytes int64, attackBytes int64, countRequests int64, countCachedRequests int64, countAttackRequests int64) error {
|
||||
func (this *ServerBandwidthStatDAO) UpdateServerBandwidth(tx *dbs.Tx, userId int64, serverId int64, regionId int64, userPlanId int64, day string, timeAt string, bandwidthBytes int64, totalBytes int64, cachedBytes int64, attackBytes int64, countRequests int64, countCachedRequests int64, countAttackRequests int64, countIPs int64) error {
|
||||
if serverId <= 0 {
|
||||
return errors.New("invalid server id '" + types.String(serverId) + "'")
|
||||
}
|
||||
@@ -78,6 +78,7 @@ func (this *ServerBandwidthStatDAO) UpdateServerBandwidth(tx *dbs.Tx, userId int
|
||||
Param("countRequests", countRequests).
|
||||
Param("countCachedRequests", countCachedRequests).
|
||||
Param("countAttackRequests", countAttackRequests).
|
||||
Param("countIPs", countIPs).
|
||||
InsertOrUpdateQuickly(maps.Map{
|
||||
"userId": userId,
|
||||
"serverId": serverId,
|
||||
@@ -93,6 +94,7 @@ func (this *ServerBandwidthStatDAO) UpdateServerBandwidth(tx *dbs.Tx, userId int
|
||||
"countCachedRequests": countCachedRequests,
|
||||
"countAttackRequests": countAttackRequests,
|
||||
"userPlanId": userPlanId,
|
||||
"countIPs": countIPs,
|
||||
}, maps.Map{
|
||||
"bytes": dbs.SQL("bytes+:bytes"),
|
||||
"avgBytes": dbs.SQL("(totalBytes+:totalBytes)/300"), // 因为生成SQL语句时会自动将avgBytes排在totalBytes之前,所以这里不用担心先后顺序的问题
|
||||
@@ -102,6 +104,7 @@ func (this *ServerBandwidthStatDAO) UpdateServerBandwidth(tx *dbs.Tx, userId int
|
||||
"countRequests": dbs.SQL("countRequests+:countRequests"),
|
||||
"countCachedRequests": dbs.SQL("countCachedRequests+:countCachedRequests"),
|
||||
"countAttackRequests": dbs.SQL("countAttackRequests+:countAttackRequests"),
|
||||
"countIPs": dbs.SQL("countIPs+:countIPs"),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -726,7 +729,7 @@ func (this *ServerBandwidthStatDAO) SumDailyStat(tx *dbs.Tx, serverId int64, reg
|
||||
|
||||
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")
|
||||
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, SUM(countIPs) AS countIPs")
|
||||
|
||||
query.Attr("serverId", serverId)
|
||||
|
||||
@@ -755,6 +758,7 @@ func (this *ServerBandwidthStatDAO) SumDailyStat(tx *dbs.Tx, serverId int64, reg
|
||||
stat.CountCachedRequests = one.GetInt64("countCachedRequests")
|
||||
stat.CountAttackRequests = one.GetInt64("countAttackRequests")
|
||||
stat.AttackBytes = one.GetInt64("attackBytes")
|
||||
stat.CountIPs = one.GetInt64("countIPs")
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -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, 0, 0, timeutil.Format("Ymd"), timeutil.FormatTime("Hi", time.Now().Unix()/300*300), 1024, 300, 0, 0, 0, 0, 0)
|
||||
err := dao.UpdateServerBandwidth(tx, 1, 1, 0, 0, timeutil.Format("Ymd"), timeutil.FormatTime("Hi", time.Now().Unix()/300*300), 1024, 300, 0, 0, 0, 0, 0, 0)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -33,7 +33,7 @@ func TestSeverBandwidthStatDAO_InsertManyStats(t *testing.T) {
|
||||
}
|
||||
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, int64(rands.Int(1, 10000)), 0, 0, day, minute, 1024, 300, 0, 0, 0, 0, 0)
|
||||
err := dao.UpdateServerBandwidth(tx, 1, int64(rands.Int(1, 10000)), 0, 0, day, minute, 1024, 300, 0, 0, 0, 0, 0, 0)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ const (
|
||||
ServerBandwidthStatField_CountCachedRequests dbs.FieldName = "countCachedRequests" // 缓存的请求数
|
||||
ServerBandwidthStatField_CountAttackRequests dbs.FieldName = "countAttackRequests" // 攻击请求数
|
||||
ServerBandwidthStatField_TotalBytes dbs.FieldName = "totalBytes" // 总流量
|
||||
ServerBandwidthStatField_CountIPs dbs.FieldName = "countIPs" // 独立IP
|
||||
)
|
||||
|
||||
// ServerBandwidthStat 服务峰值带宽统计
|
||||
@@ -37,6 +38,7 @@ type ServerBandwidthStat struct {
|
||||
CountCachedRequests uint64 `field:"countCachedRequests"` // 缓存的请求数
|
||||
CountAttackRequests uint64 `field:"countAttackRequests"` // 攻击请求数
|
||||
TotalBytes uint64 `field:"totalBytes"` // 总流量
|
||||
CountIPs uint64 `field:"countIPs"` // 独立IP
|
||||
}
|
||||
|
||||
type ServerBandwidthStatOperator struct {
|
||||
@@ -55,6 +57,7 @@ type ServerBandwidthStatOperator struct {
|
||||
CountCachedRequests any // 缓存的请求数
|
||||
CountAttackRequests any // 攻击请求数
|
||||
TotalBytes any // 总流量
|
||||
CountIPs any // 独立IP
|
||||
}
|
||||
|
||||
func NewServerBandwidthStatOperator() *ServerBandwidthStatOperator {
|
||||
|
||||
@@ -158,7 +158,6 @@ func (this *ServerDAO) CreateServer(tx *dbs.Tx,
|
||||
httpsJSON []byte,
|
||||
tcpJSON []byte,
|
||||
tlsJSON []byte,
|
||||
unixJSON []byte,
|
||||
udpJSON []byte,
|
||||
webId int64,
|
||||
reverseProxyJSON []byte,
|
||||
@@ -206,9 +205,6 @@ func (this *ServerDAO) CreateServer(tx *dbs.Tx,
|
||||
if IsNotNull(tlsJSON) {
|
||||
op.Tls = tlsJSON
|
||||
}
|
||||
if IsNotNull(unixJSON) {
|
||||
op.Unix = unixJSON
|
||||
}
|
||||
if IsNotNull(udpJSON) {
|
||||
op.Udp = udpJSON
|
||||
}
|
||||
@@ -757,14 +753,14 @@ func (this *ServerDAO) UpdateServerAuditing(tx *dbs.Tx, serverId int64, result *
|
||||
return this.NotifyDNSUpdate(tx, serverId)
|
||||
}
|
||||
|
||||
// UpdateServerReverseProxy 修改反向代理配置
|
||||
func (this *ServerDAO) UpdateServerReverseProxy(tx *dbs.Tx, serverId int64, config []byte) error {
|
||||
// UpdateServerReverseProxyRef 修改反向代理配置
|
||||
func (this *ServerDAO) UpdateServerReverseProxyRef(tx *dbs.Tx, serverId int64, reverseProxyRefJSON []byte) error {
|
||||
if serverId <= 0 {
|
||||
return errors.New("serverId should not be smaller than 0")
|
||||
}
|
||||
var op = NewServerOperator()
|
||||
op.Id = serverId
|
||||
op.ReverseProxy = JSONBytes(config)
|
||||
op.ReverseProxy = JSONBytes(reverseProxyRefJSON)
|
||||
err := this.Save(tx, op)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -773,6 +769,28 @@ func (this *ServerDAO) UpdateServerReverseProxy(tx *dbs.Tx, serverId int64, conf
|
||||
return this.NotifyUpdate(tx, serverId)
|
||||
}
|
||||
|
||||
// CreateServerReverseProxyRef 创建反向代理配置
|
||||
func (this *ServerDAO) CreateServerReverseProxyRef(tx *dbs.Tx, userId int64, serverId int64) (reverseProxyId int64, err error) {
|
||||
reverseProxyId, err = SharedReverseProxyDAO.CreateReverseProxy(tx, 0, userId, nil, []byte("[]"), []byte("[]"))
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
var reverseProxyRef = &serverconfigs.ReverseProxyRef{
|
||||
IsPrior: false,
|
||||
IsOn: true,
|
||||
ReverseProxyId: reverseProxyId,
|
||||
}
|
||||
reverseProxyRefJSON, err := json.Marshal(reverseProxyRef)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
err = this.UpdateServerReverseProxyRef(tx, serverId, reverseProxyRefJSON)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return reverseProxyId, nil
|
||||
}
|
||||
|
||||
// CountAllEnabledServers 计算所有可用服务数量
|
||||
func (this *ServerDAO) CountAllEnabledServers(tx *dbs.Tx) (int64, error) {
|
||||
return this.Query(tx).
|
||||
@@ -1214,18 +1232,6 @@ func (this *ServerDAO) ComposeServerConfig(tx *dbs.Tx, server *Server, ignoreCer
|
||||
}
|
||||
}
|
||||
|
||||
// Unix
|
||||
if IsNotNull(server.Unix) {
|
||||
var unixConfig = &serverconfigs.UnixProtocolConfig{}
|
||||
err := json.Unmarshal(server.Unix, unixConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !forNode || unixConfig.IsOn {
|
||||
config.Unix = unixConfig
|
||||
}
|
||||
}
|
||||
|
||||
// UDP
|
||||
if IsNotNull(server.Udp) {
|
||||
var udpConfig = &serverconfigs.UDPProtocolConfig{}
|
||||
@@ -1322,28 +1328,10 @@ func (this *ServerDAO) ComposeServerConfig(tx *dbs.Tx, server *Server, ignoreCer
|
||||
}
|
||||
|
||||
// 套餐是否依然有效
|
||||
plan, err := SharedPlanDAO.FindEnabledPlan(tx, int64(userPlan.PlanId), cacheMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if plan != nil {
|
||||
config.UserPlan = &serverconfigs.UserPlanConfig{
|
||||
Id: int64(userPlan.Id),
|
||||
DayTo: userPlan.DayTo,
|
||||
Plan: &serverconfigs.PlanConfig{
|
||||
Id: int64(plan.Id),
|
||||
Name: plan.Name,
|
||||
},
|
||||
}
|
||||
|
||||
if len(plan.TrafficLimit) > 0 && (config.TrafficLimit == nil || !config.TrafficLimit.IsOn) {
|
||||
var trafficLimitConfig = &serverconfigs.TrafficLimitConfig{}
|
||||
err = json.Unmarshal(plan.TrafficLimit, trafficLimitConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config.TrafficLimit = trafficLimitConfig
|
||||
}
|
||||
config.UserPlan = &serverconfigs.UserPlanConfig{
|
||||
Id: int64(userPlan.Id),
|
||||
DayTo: userPlan.DayTo,
|
||||
PlanId: int64(userPlan.PlanId),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1380,8 +1368,8 @@ func (this *ServerDAO) ComposeServerConfig(tx *dbs.Tx, server *Server, ignoreCer
|
||||
return config, nil
|
||||
}
|
||||
|
||||
// FindReverseProxyRef 根据条件获取反向代理配置
|
||||
func (this *ServerDAO) FindReverseProxyRef(tx *dbs.Tx, serverId int64) (*serverconfigs.ReverseProxyRef, error) {
|
||||
// FindServerReverseProxyRef 根据条件获取反向代理配置
|
||||
func (this *ServerDAO) FindServerReverseProxyRef(tx *dbs.Tx, serverId int64) (*serverconfigs.ReverseProxyRef, error) {
|
||||
reverseProxy, err := this.Query(tx).
|
||||
Pk(serverId).
|
||||
Result("reverseProxy").
|
||||
@@ -1392,7 +1380,7 @@ func (this *ServerDAO) FindReverseProxyRef(tx *dbs.Tx, serverId int64) (*serverc
|
||||
if len(reverseProxy) == 0 || reverseProxy == "null" {
|
||||
return nil, nil
|
||||
}
|
||||
config := &serverconfigs.ReverseProxyRef{}
|
||||
var config = &serverconfigs.ReverseProxyRef{}
|
||||
err = json.Unmarshal([]byte(reverseProxy), config)
|
||||
return config, err
|
||||
}
|
||||
@@ -2358,8 +2346,36 @@ func (this *ServerDAO) UpdateServerTrafficLimitConfig(tx *dbs.Tx, serverId int64
|
||||
|
||||
// RenewServerTrafficLimitStatus 根据限流配置更新网站的流量限制状态
|
||||
func (this *ServerDAO) RenewServerTrafficLimitStatus(tx *dbs.Tx, trafficLimitConfig *serverconfigs.TrafficLimitConfig, serverId int64, isUpdatingConfig bool) error {
|
||||
if serverId <= 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if !trafficLimitConfig.IsOn {
|
||||
if isUpdatingConfig {
|
||||
var oldStatus = &serverconfigs.TrafficLimitStatus{}
|
||||
trafficLimitStatus, err := this.Query(tx).
|
||||
Pk(serverId).
|
||||
Result("trafficLimitStatus").
|
||||
FindJSONCol()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if IsNotNull(trafficLimitStatus) {
|
||||
err = json.Unmarshal(trafficLimitStatus, oldStatus)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if oldStatus.PlanId == 0 /** 说明是网站自行设置的限制 **/ {
|
||||
err = this.Query(tx).
|
||||
Pk(serverId).
|
||||
Set("trafficLimitStatus", dbs.SQL("NULL")).
|
||||
UpdateQuickly()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return this.NotifyUpdate(tx, serverId)
|
||||
}
|
||||
return nil
|
||||
@@ -2470,7 +2486,9 @@ func (this *ServerDAO) UpdateServerTrafficLimitStatus(tx *dbs.Tx, serverId int64
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(oldStatus.UntilDay) > 0 && oldStatus.UntilDay >= day /** 如果已经限制,且比当前日期长,则无需重复 **/ {
|
||||
if len(oldStatus.UntilDay) > 0 &&
|
||||
oldStatus.UntilDay >= day /** 如果已经限制,且比当前日期长,则无需重复 **/ &&
|
||||
oldStatus.PlanId == planId {
|
||||
// no need to change
|
||||
return nil
|
||||
}
|
||||
@@ -2521,7 +2539,7 @@ func (this *ServerDAO) UpdateServersTrafficLimitStatusWithUserPlanId(tx *dbs.Tx,
|
||||
return nil
|
||||
}
|
||||
|
||||
// ResetServersTrafficLimitStatusWithPlanId 重置网站限流状态
|
||||
// ResetServersTrafficLimitStatusWithPlanId 重置某个套餐相关网站限流状态
|
||||
func (this *ServerDAO) ResetServersTrafficLimitStatusWithPlanId(tx *dbs.Tx, planId int64) error {
|
||||
return this.Query(tx).
|
||||
Where("JSON_EXTRACT(trafficLimitStatus, '$.planId')=:planId").
|
||||
@@ -2598,13 +2616,17 @@ func (this *ServerDAO) UpdateServerUserPlanId(tx *dbs.Tx, serverId int64, userPl
|
||||
return errors.New("serverId should not be smaller than 0")
|
||||
}
|
||||
|
||||
oldClusterId, err := this.Query(tx).
|
||||
oldServerOne, queryErr := SharedServerDAO.
|
||||
Query(tx).
|
||||
Pk(serverId).
|
||||
Result("clusterId").
|
||||
FindInt64Col(0)
|
||||
if err != nil {
|
||||
return err
|
||||
Result("clusterId", "userPlanId").
|
||||
Find()
|
||||
if queryErr != nil || oldServerOne == nil {
|
||||
return queryErr
|
||||
}
|
||||
var oldServer = oldServerOne.(*Server)
|
||||
var oldClusterId = int64(oldServer.ClusterId)
|
||||
var oldUserPlanId = int64(oldServer.UserPlanId)
|
||||
|
||||
// 取消套餐
|
||||
if userPlanId <= 0 {
|
||||
@@ -2636,6 +2658,15 @@ func (this *ServerDAO) UpdateServerUserPlanId(tx *dbs.Tx, serverId int64, userPl
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 重置以往的用户套餐状态
|
||||
if oldUserPlanId > 0 {
|
||||
err = SharedUserPlanStatDAO.ResetUserPlanStatsWithUserPlanId(tx, oldUserPlanId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
err = this.NotifyUpdate(tx, serverId)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -2683,6 +2714,21 @@ func (this *ServerDAO) UpdateServerUserPlanId(tx *dbs.Tx, serverId int64, userPl
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 重置以往的用户套餐统计状态
|
||||
if oldUserPlanId > 0 {
|
||||
err = SharedUserPlanStatDAO.ResetUserPlanStatsWithUserPlanId(tx, oldUserPlanId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// 重置当前用户套餐统计状态
|
||||
err = SharedUserPlanStatDAO.ResetUserPlanStatsWithUserPlanId(tx, userPlanId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = this.NotifyUpdate(tx, serverId)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -2986,6 +3032,17 @@ func (this *ServerDAO) CheckServerPlanQuota(tx *dbs.Tx, serverId int64, countSer
|
||||
return nil
|
||||
}
|
||||
|
||||
// ExistsServer 检查网站是否存在
|
||||
func (this *ServerDAO) ExistsServer(tx *dbs.Tx, serverId int64) (bool, error) {
|
||||
if serverId <= 0 {
|
||||
return false, nil
|
||||
}
|
||||
return this.Query(tx).
|
||||
Pk(serverId).
|
||||
State(ServerStateEnabled).
|
||||
Exist()
|
||||
}
|
||||
|
||||
// NotifyUpdate 同步服务所在的集群
|
||||
func (this *ServerDAO) NotifyUpdate(tx *dbs.Tx, serverId int64) error {
|
||||
if serverId <= 0 {
|
||||
|
||||
12
internal/db/models/server_dao_ext.go
Normal file
12
internal/db/models/server_dao_ext.go
Normal file
@@ -0,0 +1,12 @@
|
||||
// Copyright 2024 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
//go:build !plus
|
||||
|
||||
package models
|
||||
|
||||
import "github.com/iwind/TeaGo/dbs"
|
||||
|
||||
// ResetServersTrafficLimitStatusWithUserPlanId 重置用户套餐相关网站限流状态
|
||||
func (this *ServerDAO) ResetServersTrafficLimitStatusWithUserPlanId(tx *dbs.Tx, userPlanId int64) error {
|
||||
// stub
|
||||
return nil
|
||||
}
|
||||
@@ -177,10 +177,10 @@ func (this *SysSettingDAO) ReadUserUIConfig(tx *dbs.Tx) (*systemconfigs.UserUICo
|
||||
return nil, err
|
||||
}
|
||||
if len(valueJSON) == 0 {
|
||||
return systemconfigs.DefaultUserUIConfig(), nil
|
||||
return systemconfigs.NewUserUIConfig(), nil
|
||||
}
|
||||
|
||||
var config = systemconfigs.DefaultUserUIConfig()
|
||||
var config = systemconfigs.NewUserUIConfig()
|
||||
err = json.Unmarshal(valueJSON, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -59,7 +59,7 @@ func init() {
|
||||
|
||||
// UpdateUserPlanBandwidth 写入数据
|
||||
// 暂时不使用region区分
|
||||
func (this *UserPlanBandwidthStatDAO) UpdateUserPlanBandwidth(tx *dbs.Tx, userId int64, userPlanId int64, regionId int64, day string, timeAt string, bandwidthBytes int64, totalBytes int64, cachedBytes int64, attackBytes int64, countRequests int64, countCachedRequests int64, countAttackRequests int64) error {
|
||||
func (this *UserPlanBandwidthStatDAO) UpdateUserPlanBandwidth(tx *dbs.Tx, userId int64, userPlanId int64, regionId int64, day string, timeAt string, bandwidthBytes int64, totalBytes int64, cachedBytes int64, attackBytes int64, countRequests int64, countCachedRequests int64, countAttackRequests int64, countWebsocketConnections int64) error {
|
||||
if userId <= 0 || userPlanId <= 0 {
|
||||
return nil
|
||||
}
|
||||
@@ -73,29 +73,32 @@ func (this *UserPlanBandwidthStatDAO) UpdateUserPlanBandwidth(tx *dbs.Tx, userId
|
||||
Param("countRequests", countRequests).
|
||||
Param("countCachedRequests", countCachedRequests).
|
||||
Param("countAttackRequests", countAttackRequests).
|
||||
Param("countWebsocketConnections", countWebsocketConnections).
|
||||
InsertOrUpdateQuickly(maps.Map{
|
||||
"userId": userId,
|
||||
"userPlanId": userPlanId,
|
||||
"regionId": regionId,
|
||||
"day": day,
|
||||
"timeAt": timeAt,
|
||||
"bytes": bandwidthBytes,
|
||||
"totalBytes": totalBytes,
|
||||
"avgBytes": totalBytes / 300,
|
||||
"cachedBytes": cachedBytes,
|
||||
"attackBytes": attackBytes,
|
||||
"countRequests": countRequests,
|
||||
"countCachedRequests": countCachedRequests,
|
||||
"countAttackRequests": countAttackRequests,
|
||||
"userId": userId,
|
||||
"userPlanId": userPlanId,
|
||||
"regionId": regionId,
|
||||
"day": day,
|
||||
"timeAt": timeAt,
|
||||
"bytes": bandwidthBytes,
|
||||
"totalBytes": totalBytes,
|
||||
"avgBytes": totalBytes / 300,
|
||||
"cachedBytes": cachedBytes,
|
||||
"attackBytes": attackBytes,
|
||||
"countRequests": countRequests,
|
||||
"countCachedRequests": countCachedRequests,
|
||||
"countAttackRequests": countAttackRequests,
|
||||
"countWebsocketConnections": countWebsocketConnections,
|
||||
}, maps.Map{
|
||||
"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"),
|
||||
"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"),
|
||||
"countWebsocketConnections": dbs.SQL("countWebsocketConnections+:countWebsocketConnections"),
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -3,55 +3,58 @@ package models
|
||||
import "github.com/iwind/TeaGo/dbs"
|
||||
|
||||
const (
|
||||
UserPlanBandwidthStatField_Id dbs.FieldName = "id" // ID
|
||||
UserPlanBandwidthStatField_UserId dbs.FieldName = "userId" // 用户ID
|
||||
UserPlanBandwidthStatField_UserPlanId dbs.FieldName = "userPlanId" // 用户套餐ID
|
||||
UserPlanBandwidthStatField_Day dbs.FieldName = "day" // 日期YYYYMMDD
|
||||
UserPlanBandwidthStatField_TimeAt dbs.FieldName = "timeAt" // 时间点HHII
|
||||
UserPlanBandwidthStatField_Bytes dbs.FieldName = "bytes" // 带宽
|
||||
UserPlanBandwidthStatField_RegionId dbs.FieldName = "regionId" // 区域ID
|
||||
UserPlanBandwidthStatField_TotalBytes dbs.FieldName = "totalBytes" // 总流量
|
||||
UserPlanBandwidthStatField_AvgBytes dbs.FieldName = "avgBytes" // 平均流量
|
||||
UserPlanBandwidthStatField_CachedBytes dbs.FieldName = "cachedBytes" // 缓存的流量
|
||||
UserPlanBandwidthStatField_AttackBytes dbs.FieldName = "attackBytes" // 攻击流量
|
||||
UserPlanBandwidthStatField_CountRequests dbs.FieldName = "countRequests" // 请求数
|
||||
UserPlanBandwidthStatField_CountCachedRequests dbs.FieldName = "countCachedRequests" // 缓存的请求数
|
||||
UserPlanBandwidthStatField_CountAttackRequests dbs.FieldName = "countAttackRequests" // 攻击请求数
|
||||
UserPlanBandwidthStatField_Id dbs.FieldName = "id" // ID
|
||||
UserPlanBandwidthStatField_UserId dbs.FieldName = "userId" // 用户ID
|
||||
UserPlanBandwidthStatField_UserPlanId dbs.FieldName = "userPlanId" // 用户套餐ID
|
||||
UserPlanBandwidthStatField_Day dbs.FieldName = "day" // 日期YYYYMMDD
|
||||
UserPlanBandwidthStatField_TimeAt dbs.FieldName = "timeAt" // 时间点HHII
|
||||
UserPlanBandwidthStatField_Bytes dbs.FieldName = "bytes" // 带宽
|
||||
UserPlanBandwidthStatField_RegionId dbs.FieldName = "regionId" // 区域ID
|
||||
UserPlanBandwidthStatField_TotalBytes dbs.FieldName = "totalBytes" // 总流量
|
||||
UserPlanBandwidthStatField_AvgBytes dbs.FieldName = "avgBytes" // 平均流量
|
||||
UserPlanBandwidthStatField_CachedBytes dbs.FieldName = "cachedBytes" // 缓存的流量
|
||||
UserPlanBandwidthStatField_AttackBytes dbs.FieldName = "attackBytes" // 攻击流量
|
||||
UserPlanBandwidthStatField_CountRequests dbs.FieldName = "countRequests" // 请求数
|
||||
UserPlanBandwidthStatField_CountCachedRequests dbs.FieldName = "countCachedRequests" // 缓存的请求数
|
||||
UserPlanBandwidthStatField_CountAttackRequests dbs.FieldName = "countAttackRequests" // 攻击请求数
|
||||
UserPlanBandwidthStatField_CountWebsocketConnections dbs.FieldName = "countWebsocketConnections" // Websocket连接数
|
||||
)
|
||||
|
||||
// UserPlanBandwidthStat 用户套餐带宽峰值
|
||||
type UserPlanBandwidthStat struct {
|
||||
Id uint64 `field:"id"` // ID
|
||||
UserId uint64 `field:"userId"` // 用户ID
|
||||
UserPlanId uint64 `field:"userPlanId"` // 用户套餐ID
|
||||
Day string `field:"day"` // 日期YYYYMMDD
|
||||
TimeAt string `field:"timeAt"` // 时间点HHII
|
||||
Bytes uint64 `field:"bytes"` // 带宽
|
||||
RegionId uint32 `field:"regionId"` // 区域ID
|
||||
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"` // 攻击请求数
|
||||
Id uint64 `field:"id"` // ID
|
||||
UserId uint64 `field:"userId"` // 用户ID
|
||||
UserPlanId uint64 `field:"userPlanId"` // 用户套餐ID
|
||||
Day string `field:"day"` // 日期YYYYMMDD
|
||||
TimeAt string `field:"timeAt"` // 时间点HHII
|
||||
Bytes uint64 `field:"bytes"` // 带宽
|
||||
RegionId uint32 `field:"regionId"` // 区域ID
|
||||
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"` // 攻击请求数
|
||||
CountWebsocketConnections uint64 `field:"countWebsocketConnections"` // Websocket连接数
|
||||
}
|
||||
|
||||
type UserPlanBandwidthStatOperator struct {
|
||||
Id any // ID
|
||||
UserId any // 用户ID
|
||||
UserPlanId any // 用户套餐ID
|
||||
Day any // 日期YYYYMMDD
|
||||
TimeAt any // 时间点HHII
|
||||
Bytes any // 带宽
|
||||
RegionId any // 区域ID
|
||||
TotalBytes any // 总流量
|
||||
AvgBytes any // 平均流量
|
||||
CachedBytes any // 缓存的流量
|
||||
AttackBytes any // 攻击流量
|
||||
CountRequests any // 请求数
|
||||
CountCachedRequests any // 缓存的请求数
|
||||
CountAttackRequests any // 攻击请求数
|
||||
Id any // ID
|
||||
UserId any // 用户ID
|
||||
UserPlanId any // 用户套餐ID
|
||||
Day any // 日期YYYYMMDD
|
||||
TimeAt any // 时间点HHII
|
||||
Bytes any // 带宽
|
||||
RegionId any // 区域ID
|
||||
TotalBytes any // 总流量
|
||||
AvgBytes any // 平均流量
|
||||
CachedBytes any // 缓存的流量
|
||||
AttackBytes any // 攻击流量
|
||||
CountRequests any // 请求数
|
||||
CountCachedRequests any // 缓存的请求数
|
||||
CountAttackRequests any // 攻击请求数
|
||||
CountWebsocketConnections any // Websocket连接数
|
||||
}
|
||||
|
||||
func NewUserPlanBandwidthStatOperator() *UserPlanBandwidthStatOperator {
|
||||
|
||||
@@ -5,6 +5,12 @@ package models
|
||||
|
||||
import "github.com/iwind/TeaGo/dbs"
|
||||
|
||||
func (this *UserPlanStatDAO) IncreaseUserPlanStat(tx *dbs.Tx, userPlanId int64, trafficBytes int64, countRequests int64) error {
|
||||
func (this *UserPlanStatDAO) IncreaseUserPlanStat(tx *dbs.Tx, userPlanId int64, trafficBytes int64, countRequests int64, countWebsocketConnections int64) error {
|
||||
// stub
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this *UserPlanStatDAO) ResetUserPlanStatsWithUserPlanId(tx *dbs.Tx, userPlanId int64) error {
|
||||
// stub
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -3,34 +3,37 @@ package models
|
||||
import "github.com/iwind/TeaGo/dbs"
|
||||
|
||||
const (
|
||||
UserPlanStatField_Id dbs.FieldName = "id" // ID
|
||||
UserPlanStatField_UserPlanId dbs.FieldName = "userPlanId" // 用户套餐ID
|
||||
UserPlanStatField_Date dbs.FieldName = "date" // 日期:YYYYMMDD或YYYYMM
|
||||
UserPlanStatField_DateType dbs.FieldName = "dateType" // 日期类型:day|month
|
||||
UserPlanStatField_TrafficBytes dbs.FieldName = "trafficBytes" // 流量
|
||||
UserPlanStatField_CountRequests dbs.FieldName = "countRequests" // 总请求数
|
||||
UserPlanStatField_IsProcessed dbs.FieldName = "isProcessed" // 是否已处理
|
||||
UserPlanStatField_Id dbs.FieldName = "id" // ID
|
||||
UserPlanStatField_UserPlanId dbs.FieldName = "userPlanId" // 用户套餐ID
|
||||
UserPlanStatField_Date dbs.FieldName = "date" // 日期:YYYYMMDD或YYYYMM
|
||||
UserPlanStatField_DateType dbs.FieldName = "dateType" // 日期类型:day|month
|
||||
UserPlanStatField_TrafficBytes dbs.FieldName = "trafficBytes" // 流量
|
||||
UserPlanStatField_CountRequests dbs.FieldName = "countRequests" // 总请求数
|
||||
UserPlanStatField_CountWebsocketConnections dbs.FieldName = "countWebsocketConnections" // Websocket连接数
|
||||
UserPlanStatField_IsProcessed dbs.FieldName = "isProcessed" // 是否已处理
|
||||
)
|
||||
|
||||
// UserPlanStat 用户套餐统计
|
||||
type UserPlanStat struct {
|
||||
Id uint64 `field:"id"` // ID
|
||||
UserPlanId uint64 `field:"userPlanId"` // 用户套餐ID
|
||||
Date string `field:"date"` // 日期:YYYYMMDD或YYYYMM
|
||||
DateType string `field:"dateType"` // 日期类型:day|month
|
||||
TrafficBytes uint64 `field:"trafficBytes"` // 流量
|
||||
CountRequests uint64 `field:"countRequests"` // 总请求数
|
||||
IsProcessed bool `field:"isProcessed"` // 是否已处理
|
||||
Id uint64 `field:"id"` // ID
|
||||
UserPlanId uint64 `field:"userPlanId"` // 用户套餐ID
|
||||
Date string `field:"date"` // 日期:YYYYMMDD或YYYYMM
|
||||
DateType string `field:"dateType"` // 日期类型:day|month
|
||||
TrafficBytes uint64 `field:"trafficBytes"` // 流量
|
||||
CountRequests uint64 `field:"countRequests"` // 总请求数
|
||||
CountWebsocketConnections uint64 `field:"countWebsocketConnections"` // Websocket连接数
|
||||
IsProcessed bool `field:"isProcessed"` // 是否已处理
|
||||
}
|
||||
|
||||
type UserPlanStatOperator struct {
|
||||
Id any // ID
|
||||
UserPlanId any // 用户套餐ID
|
||||
Date any // 日期:YYYYMMDD或YYYYMM
|
||||
DateType any // 日期类型:day|month
|
||||
TrafficBytes any // 流量
|
||||
CountRequests any // 总请求数
|
||||
IsProcessed any // 是否已处理
|
||||
Id any // ID
|
||||
UserPlanId any // 用户套餐ID
|
||||
Date any // 日期:YYYYMMDD或YYYYMM
|
||||
DateType any // 日期类型:day|month
|
||||
TrafficBytes any // 流量
|
||||
CountRequests any // 总请求数
|
||||
CountWebsocketConnections any // Websocket连接数
|
||||
IsProcessed any // 是否已处理
|
||||
}
|
||||
|
||||
func NewUserPlanStatOperator() *UserPlanStatOperator {
|
||||
|
||||
33
internal/db/models/user_script_dao.go
Normal file
33
internal/db/models/user_script_dao.go
Normal file
@@ -0,0 +1,33 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"github.com/iwind/TeaGo/Tea"
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
)
|
||||
|
||||
const (
|
||||
UserScriptStateEnabled = 1 // 已启用
|
||||
UserScriptStateDisabled = 0 // 已禁用
|
||||
)
|
||||
|
||||
type UserScriptDAO dbs.DAO
|
||||
|
||||
func NewUserScriptDAO() *UserScriptDAO {
|
||||
return dbs.NewDAO(&UserScriptDAO{
|
||||
DAOObject: dbs.DAOObject{
|
||||
DB: Tea.Env,
|
||||
Table: "edgeUserScripts",
|
||||
Model: new(UserScript),
|
||||
PkName: "id",
|
||||
},
|
||||
}).(*UserScriptDAO)
|
||||
}
|
||||
|
||||
var SharedUserScriptDAO *UserScriptDAO
|
||||
|
||||
func init() {
|
||||
dbs.OnReady(func() {
|
||||
SharedUserScriptDAO = NewUserScriptDAO()
|
||||
})
|
||||
}
|
||||
6
internal/db/models/user_script_dao_test.go
Normal file
6
internal/db/models/user_script_dao_test.go
Normal file
@@ -0,0 +1,6 @@
|
||||
package models_test
|
||||
|
||||
import (
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
_ "github.com/iwind/TeaGo/bootstrap"
|
||||
)
|
||||
56
internal/db/models/user_script_model.go
Normal file
56
internal/db/models/user_script_model.go
Normal file
@@ -0,0 +1,56 @@
|
||||
package models
|
||||
|
||||
import "github.com/iwind/TeaGo/dbs"
|
||||
|
||||
const (
|
||||
UserScriptField_Id dbs.FieldName = "id" // ID
|
||||
UserScriptField_UserId dbs.FieldName = "userId" // 用户ID
|
||||
UserScriptField_AdminId dbs.FieldName = "adminId" // 操作管理员
|
||||
UserScriptField_Code dbs.FieldName = "code" // 代码
|
||||
UserScriptField_CodeMD5 dbs.FieldName = "codeMD5" // 代码MD5
|
||||
UserScriptField_CreatedAt dbs.FieldName = "createdAt" // 创建时间
|
||||
UserScriptField_IsRejected dbs.FieldName = "isRejected" // 是否已驳回
|
||||
UserScriptField_RejectedAt dbs.FieldName = "rejectedAt" // 驳回时间
|
||||
UserScriptField_RejectedReason dbs.FieldName = "rejectedReason" // 驳回原因
|
||||
UserScriptField_IsPassed dbs.FieldName = "isPassed" // 是否通过审核
|
||||
UserScriptField_PassedAt dbs.FieldName = "passedAt" // 通过时间
|
||||
UserScriptField_State dbs.FieldName = "state" // 状态
|
||||
UserScriptField_WebIds dbs.FieldName = "webIds" // WebId列表
|
||||
)
|
||||
|
||||
// UserScript 用户脚本审核
|
||||
type UserScript struct {
|
||||
Id uint64 `field:"id"` // ID
|
||||
UserId uint64 `field:"userId"` // 用户ID
|
||||
AdminId uint64 `field:"adminId"` // 操作管理员
|
||||
Code string `field:"code"` // 代码
|
||||
CodeMD5 string `field:"codeMD5"` // 代码MD5
|
||||
CreatedAt uint64 `field:"createdAt"` // 创建时间
|
||||
IsRejected bool `field:"isRejected"` // 是否已驳回
|
||||
RejectedAt uint64 `field:"rejectedAt"` // 驳回时间
|
||||
RejectedReason string `field:"rejectedReason"` // 驳回原因
|
||||
IsPassed bool `field:"isPassed"` // 是否通过审核
|
||||
PassedAt uint64 `field:"passedAt"` // 通过时间
|
||||
State uint8 `field:"state"` // 状态
|
||||
WebIds dbs.JSON `field:"webIds"` // WebId列表
|
||||
}
|
||||
|
||||
type UserScriptOperator struct {
|
||||
Id any // ID
|
||||
UserId any // 用户ID
|
||||
AdminId any // 操作管理员
|
||||
Code any // 代码
|
||||
CodeMD5 any // 代码MD5
|
||||
CreatedAt any // 创建时间
|
||||
IsRejected any // 是否已驳回
|
||||
RejectedAt any // 驳回时间
|
||||
RejectedReason any // 驳回原因
|
||||
IsPassed any // 是否通过审核
|
||||
PassedAt any // 通过时间
|
||||
State any // 状态
|
||||
WebIds any // WebId列表
|
||||
}
|
||||
|
||||
func NewUserScriptOperator() *UserScriptOperator {
|
||||
return &UserScriptOperator{}
|
||||
}
|
||||
1
internal/db/models/user_script_model_ext.go
Normal file
1
internal/db/models/user_script_model_ext.go
Normal file
@@ -0,0 +1 @@
|
||||
package models
|
||||
@@ -1,6 +1,7 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/go-sql-driver/mysql"
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
@@ -60,8 +61,8 @@ func CheckSQLErrCode(err error, code uint16) bool {
|
||||
}
|
||||
|
||||
// 快速判断错误方法
|
||||
mysqlErr, ok := err.(*mysql.MySQLError)
|
||||
if ok && mysqlErr.Number == code { // Error 1050: Table 'xxx' already exists
|
||||
var mysqlErr *mysql.MySQLError
|
||||
if errors.As(err, &mysqlErr) && mysqlErr.Number == code { // Error 1050: Table 'xxx' already exists
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -86,6 +87,6 @@ func IsMySQLError(err error) bool {
|
||||
if err == nil {
|
||||
return false
|
||||
}
|
||||
_, ok := err.(*mysql.MySQLError)
|
||||
return ok
|
||||
var mysqlErr *mysql.MySQLError
|
||||
return errors.As(err, &mysqlErr)
|
||||
}
|
||||
|
||||
39
internal/db/models/utils_test.go
Normal file
39
internal/db/models/utils_test.go
Normal file
@@ -0,0 +1,39 @@
|
||||
// Copyright 2024 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
|
||||
package models_test
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||
"github.com/iwind/TeaGo/assert"
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestIsMySQLError(t *testing.T) {
|
||||
var a = assert.NewAssertion(t)
|
||||
|
||||
{
|
||||
var err error
|
||||
a.IsFalse(models.IsMySQLError(err))
|
||||
}
|
||||
|
||||
{
|
||||
var err = errors.New("hello")
|
||||
a.IsFalse(models.IsMySQLError(err))
|
||||
}
|
||||
|
||||
{
|
||||
db, err := dbs.Default()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer func() {
|
||||
_ = db.Close()
|
||||
}()
|
||||
_, err = db.Exec("SELECT abc")
|
||||
a.IsTrue(models.IsMySQLError(err))
|
||||
a.IsTrue(models.CheckSQLErrCode(err, 1054))
|
||||
a.IsFalse(models.CheckSQLErrCode(err, 1000))
|
||||
}
|
||||
}
|
||||
@@ -42,6 +42,14 @@ func (this *AliDNSProvider) Auth(params maps.Map) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MaskParams 对参数进行掩码
|
||||
func (this *AliDNSProvider) MaskParams(params maps.Map) {
|
||||
if params == nil {
|
||||
return
|
||||
}
|
||||
params["accessKeySecret"] = MaskString(params.GetString("accessKeySecret"))
|
||||
}
|
||||
|
||||
// GetDomains 获取所有域名列表
|
||||
func (this *AliDNSProvider) GetDomains() (domains []string, err error) {
|
||||
var pageNumber = 1
|
||||
@@ -128,7 +136,7 @@ func (this *AliDNSProvider) GetRoutes(domain string) (routes []*dnstypes.Route,
|
||||
}
|
||||
for _, line := range resp.RecordLines.RecordLine {
|
||||
routes = append(routes, &dnstypes.Route{
|
||||
Name: line.LineName,
|
||||
Name: line.LineDisplayName,
|
||||
Code: line.LineCode,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -66,6 +66,14 @@ func (this *CloudFlareProvider) Auth(params maps.Map) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MaskParams 对参数进行掩码
|
||||
func (this *CloudFlareProvider) MaskParams(params maps.Map) {
|
||||
if params == nil {
|
||||
return
|
||||
}
|
||||
params["apiKey"] = MaskString(params.GetString("apiKey"))
|
||||
}
|
||||
|
||||
// GetDomains 获取所有域名列表
|
||||
func (this *CloudFlareProvider) GetDomains() (domains []string, err error) {
|
||||
for page := 1; page <= 500; page++ {
|
||||
|
||||
@@ -53,6 +53,11 @@ func (this *CustomHTTPProvider) Auth(params maps.Map) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MaskParams 对参数进行掩码
|
||||
func (this *CustomHTTPProvider) MaskParams(params maps.Map) {
|
||||
// 这里暂时不要掩码,避免用户忘记
|
||||
}
|
||||
|
||||
// GetDomains 获取所有域名列表
|
||||
func (this *CustomHTTPProvider) GetDomains() (domains []string, err error) {
|
||||
resp, err := this.post(maps.Map{
|
||||
|
||||
@@ -69,6 +69,19 @@ func (this *DNSPodProvider) Auth(params maps.Map) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MaskParams 对参数进行掩码
|
||||
func (this *DNSPodProvider) MaskParams(params maps.Map) {
|
||||
if params == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if params.GetString("apiType") == "tencentDNS" {
|
||||
params["accessKeySecret"] = MaskString(params.GetString("accessKeySecret"))
|
||||
} else {
|
||||
params["token"] = MaskString(params.GetString("token"))
|
||||
}
|
||||
}
|
||||
|
||||
// GetDomains 获取所有域名列表
|
||||
func (this *DNSPodProvider) GetDomains() (domains []string, err error) {
|
||||
if this.tencentDNSProvider != nil {
|
||||
|
||||
@@ -71,6 +71,14 @@ func (this *EdgeDNSAPIProvider) Auth(params maps.Map) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MaskParams 对参数进行掩码
|
||||
func (this *EdgeDNSAPIProvider) MaskParams(params maps.Map) {
|
||||
if params == nil {
|
||||
return
|
||||
}
|
||||
params["accessKeySecret"] = MaskString(params.GetString("accessKeySecret"))
|
||||
}
|
||||
|
||||
// GetDomains 获取所有域名列表
|
||||
func (this *EdgeDNSAPIProvider) GetDomains() (domains []string, err error) {
|
||||
var offset = 0
|
||||
|
||||
@@ -71,6 +71,14 @@ func (this *HuaweiDNSProvider) Auth(params maps.Map) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MaskParams 对参数进行掩码
|
||||
func (this *HuaweiDNSProvider) MaskParams(params maps.Map) {
|
||||
if params == nil {
|
||||
return
|
||||
}
|
||||
params["accessKeySecret"] = MaskString(params.GetString("accessKeySecret"))
|
||||
}
|
||||
|
||||
// GetDomains 获取所有域名列表
|
||||
func (this *HuaweiDNSProvider) GetDomains() (domains []string, err error) {
|
||||
var resp = new(huaweidns.ZonesResponse)
|
||||
@@ -177,13 +185,12 @@ func (this *HuaweiDNSProvider) GetRoutes(domain string) (routes []*dnstypes.Rout
|
||||
|
||||
{
|
||||
Code: "Pengboshi",
|
||||
|
||||
Name: "鹏博士",
|
||||
},
|
||||
|
||||
{
|
||||
Code: "CN",
|
||||
Name: "中国",
|
||||
Name: "中国大陆",
|
||||
},
|
||||
|
||||
{
|
||||
@@ -192,6 +199,944 @@ func (this *HuaweiDNSProvider) GetRoutes(domain string) (routes []*dnstypes.Rout
|
||||
},
|
||||
}...)
|
||||
|
||||
// 运营商线路细分
|
||||
routes = append(routes, []*dnstypes.Route{
|
||||
{
|
||||
Code: "Dianxin_Huabei",
|
||||
Name: "电信_华北地区",
|
||||
},
|
||||
{
|
||||
|
||||
Code: "Dianxin_Dongbei",
|
||||
Name: "电信_东北地区",
|
||||
},
|
||||
{
|
||||
|
||||
Code: "Dianxin_Huadong",
|
||||
Name: "电信_华东地区",
|
||||
},
|
||||
{
|
||||
|
||||
Code: "Dianxin_Huazhong",
|
||||
Name: "电信_华中地区",
|
||||
},
|
||||
{
|
||||
|
||||
Code: "Dianxin_Huanan",
|
||||
Name: "电信_华南地区",
|
||||
},
|
||||
{
|
||||
|
||||
Code: "Dianxin_Xinan",
|
||||
Name: "电信_西南地区",
|
||||
},
|
||||
{
|
||||
|
||||
Code: "Dianxin_Xibei",
|
||||
Name: "电信_西北地区",
|
||||
},
|
||||
{
|
||||
|
||||
Code: "Dianxin_Beijing",
|
||||
Name: "电信_北京",
|
||||
},
|
||||
|
||||
{
|
||||
Code: "Dianxin_Hebei",
|
||||
Name: "电信_河北",
|
||||
},
|
||||
{
|
||||
|
||||
Code: "Dianxin_Tianjin",
|
||||
Name: "电信_天津",
|
||||
},
|
||||
{
|
||||
Code: "Dianxin_Shanxi",
|
||||
Name: "电信_山西",
|
||||
},
|
||||
{
|
||||
Code: "Dianxin_Neimenggu",
|
||||
Name: "电信_内蒙古",
|
||||
},
|
||||
{
|
||||
Code: "Dianxin_Heilongjiang",
|
||||
Name: "电信_黑龙江",
|
||||
},
|
||||
{
|
||||
Code: "Dianxin_Jilin",
|
||||
Name: "电信_吉林",
|
||||
},
|
||||
{
|
||||
Code: "Dianxin_Liaoning",
|
||||
Name: "电信_辽宁",
|
||||
},
|
||||
{
|
||||
Code: "Dianxin_Jiangsu",
|
||||
Name: "电信_江苏",
|
||||
},
|
||||
{
|
||||
Code: "Dianxin_Shanghai",
|
||||
Name: "电信_上海",
|
||||
},
|
||||
{
|
||||
Code: "Dianxin_Zhejiang",
|
||||
Name: "电信_浙江",
|
||||
},
|
||||
{
|
||||
Code: "Dianxin_Anhui",
|
||||
Name: "电信_安徽",
|
||||
},
|
||||
{
|
||||
Code: "Dianxin_Fujian",
|
||||
Name: "电信_福建",
|
||||
},
|
||||
{
|
||||
Code: "Dianxin_Jiangxi",
|
||||
Name: "电信_江西",
|
||||
},
|
||||
{
|
||||
Code: "Dianxin_Shandong",
|
||||
Name: "电信_山东",
|
||||
},
|
||||
{
|
||||
Code: "Dianxin_Hubei",
|
||||
Name: "电信_湖北",
|
||||
},
|
||||
{
|
||||
Code: "Dianxin_Hunan",
|
||||
Name: "电信_湖南",
|
||||
},
|
||||
{
|
||||
Code: "Dianxin_Henan",
|
||||
Name: "电信_河南",
|
||||
},
|
||||
{
|
||||
Code: "Dianxin_Guangdong",
|
||||
Name: "电信_广东",
|
||||
},
|
||||
{
|
||||
Code: "Dianxin_Guangxi",
|
||||
Name: "电信_广西",
|
||||
},
|
||||
{
|
||||
Code: "Dianxin_Hainan",
|
||||
Name: "电信_海南",
|
||||
},
|
||||
{
|
||||
Code: "Dianxin_Sichuan",
|
||||
Name: "电信_四川",
|
||||
},
|
||||
{
|
||||
Code: "Dianxin_Xizang",
|
||||
Name: "电信_西藏",
|
||||
},
|
||||
{
|
||||
Code: "Dianxin_Chongqing",
|
||||
Name: "电信_重庆",
|
||||
},
|
||||
{
|
||||
Code: "Dianxin_Yunnan",
|
||||
Name: "电信_云南",
|
||||
},
|
||||
{
|
||||
Code: "Dianxin_Guizhou",
|
||||
Name: "电信_贵州",
|
||||
},
|
||||
{
|
||||
Code: "Dianxin_Gansu",
|
||||
Name: "电信_甘肃",
|
||||
},
|
||||
{
|
||||
Code: "Dianxin_Xinjiang",
|
||||
Name: "电信_新疆",
|
||||
},
|
||||
{
|
||||
Code: "Dianxin_Shaanxi",
|
||||
Name: "电信_陕西",
|
||||
},
|
||||
{
|
||||
Code: "Dianxin_Qinghai",
|
||||
Name: "电信_青海",
|
||||
},
|
||||
{
|
||||
Code: "Dianxin_Ningxia",
|
||||
Name: "电信_宁夏",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Huabei",
|
||||
Name: "移动_华北地区",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Dongbei",
|
||||
Name: "移动_东北地区",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Huadong",
|
||||
Name: "移动_华东地区",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Huazhong",
|
||||
Name: "移动_华中地区",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Huanan",
|
||||
Name: "移动_华南地区",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Xinan",
|
||||
Name: "移动_西南地区",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Xibei",
|
||||
Name: "移动_西北地区",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Beijing",
|
||||
Name: "移动_北京",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Hebei",
|
||||
Name: "移动_河北",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Tianjin",
|
||||
Name: "移动_天津",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Shanxi",
|
||||
Name: "移动_山西",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Neimenggu",
|
||||
Name: "移动_内蒙古",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Heilongjiang",
|
||||
Name: "移动_黑龙江",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Jilin",
|
||||
Name: "移动_吉林",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Liaoning",
|
||||
Name: "移动_辽宁",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Jiangsu",
|
||||
Name: "移动_江苏",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Shanghai",
|
||||
Name: "移动_上海",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Zhejiang",
|
||||
Name: "移动_浙江",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Anhui",
|
||||
Name: "移动_安徽",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Fujian",
|
||||
Name: "移动_福建",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Jiangxi",
|
||||
Name: "移动_江西",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Shandong",
|
||||
Name: "移动_山东",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Hubei",
|
||||
Name: "移动_湖北",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Hunan",
|
||||
Name: "移动_湖南",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Henan",
|
||||
Name: "移动_河南",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Guangdong",
|
||||
Name: "移动_广东",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Guangxi",
|
||||
Name: "移动_广西",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Hainan",
|
||||
Name: "移动_海南",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Sichuan",
|
||||
Name: "移动_四川",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Xizang",
|
||||
Name: "移动_西藏",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Chongqing",
|
||||
Name: "移动_重庆",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Yunnan",
|
||||
Name: "移动_云南",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Guizhou",
|
||||
Name: "移动_贵州",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Gansu",
|
||||
Name: "移动_甘肃",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Xinjiang",
|
||||
Name: "移动_新疆",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Shaanxi",
|
||||
Name: "移动_陕西",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Qinghai",
|
||||
Name: "移动_青海",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Ningxia",
|
||||
Name: "移动_宁夏",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Huabei",
|
||||
Name: "联通_华北地区",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Dongbei",
|
||||
Name: "联通_东北地区",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Huadong",
|
||||
Name: "联通_华东地区",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Huazhong",
|
||||
Name: "联通_华中地区",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Huanan",
|
||||
Name: "联通_华南地区",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Xinan",
|
||||
Name: "联通_西南地区",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Xibei",
|
||||
Name: "联通_西北地区",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Beijing",
|
||||
Name: "联通_北京",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Hebei",
|
||||
Name: "联通_河北",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Tianjin",
|
||||
Name: "联通_天津",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Shanxi",
|
||||
Name: "联通_山西",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Neimenggu",
|
||||
Name: "联通_内蒙古",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Heilongjiang",
|
||||
Name: "联通_黑龙江",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Jilin",
|
||||
Name: "联通_吉林",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Liaoning",
|
||||
Name: "联通_辽宁",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Jiangsu",
|
||||
Name: "联通_江苏",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Shanghai",
|
||||
Name: "联通_上海",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Zhejiang",
|
||||
Name: "联通_浙江",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Anhui",
|
||||
Name: "联通_安徽",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Fujian",
|
||||
Name: "联通_福建",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Jiangxi",
|
||||
Name: "联通_江西",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Shandong",
|
||||
Name: "联通_山东",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Hubei",
|
||||
Name: "联通_湖北",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Hunan",
|
||||
Name: "联通_湖南",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Henan",
|
||||
Name: "联通_河南",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Guangdong",
|
||||
Name: "联通_广东",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Guangxi",
|
||||
Name: "联通_广西",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Hainan",
|
||||
Name: "联通_海南",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Sichuan",
|
||||
Name: "联通_四川",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Xizang",
|
||||
Name: "联通_西藏",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Chongqing",
|
||||
Name: "联通_重庆",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Yunnan",
|
||||
Name: "联通_云南",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Guizhou",
|
||||
Name: "联通_贵州",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Gansu",
|
||||
Name: "联通_甘肃",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Xinjiang",
|
||||
Name: "联通_新疆",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Shaanxi",
|
||||
Name: "联通_陕西",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Qinghai",
|
||||
Name: "联通_青海",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Ningxia",
|
||||
Name: "联通_宁夏",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang",
|
||||
Name: "教育网默认",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Huabei",
|
||||
Name: "教育网_华北地区",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Dongbei",
|
||||
Name: "教育网_东北地区",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Huadong",
|
||||
Name: "教育网_华东地区",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Huazhong",
|
||||
Name: "教育网_华中地区",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Huanan",
|
||||
Name: "教育网_华南地区",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Xinan",
|
||||
Name: "教育网_西南地区",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Xibei",
|
||||
Name: "教育网_西北地区",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Beijing",
|
||||
Name: "教育网_北京",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Hebei",
|
||||
Name: "教育网_河北",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Tianjin",
|
||||
Name: "教育网_天津",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Shanxi",
|
||||
Name: "教育网_山西",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Neimenggu",
|
||||
Name: "教育网_内蒙古",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Heilongjiang",
|
||||
Name: "教育网_黑龙江",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Jilin",
|
||||
Name: "教育网_吉林",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Liaoning",
|
||||
Name: "教育网_辽宁",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Jiangsu",
|
||||
Name: "教育网_江苏",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Shanghai",
|
||||
Name: "教育网_上海",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Zhejiang",
|
||||
Name: "教育网_浙江",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Anhui",
|
||||
Name: "教育网_安徽",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Fujian",
|
||||
Name: "教育网_福建",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Jiangxi",
|
||||
Name: "教育网_江西",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Shandong",
|
||||
Name: "教育网_山东",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Hubei",
|
||||
Name: "教育网_湖北",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Hunan",
|
||||
Name: "教育网_湖南",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Henan",
|
||||
Name: "教育网_河南",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Guangdong",
|
||||
Name: "教育网_广东",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Guangxi",
|
||||
Name: "教育网_广西",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Hainan",
|
||||
Name: "教育网_海南",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Sichuan",
|
||||
Name: "教育网_四川",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Xizang",
|
||||
Name: "教育网_西藏",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Chongqing",
|
||||
Name: "教育网_重庆",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Yunnan",
|
||||
Name: "教育网_云南",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Guizhou",
|
||||
Name: "教育网_贵州",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Gansu",
|
||||
Name: "教育网_甘肃",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Xinjiang",
|
||||
Name: "教育网_新疆",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Shaanxi",
|
||||
Name: "教育网_陕西",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Qinghai",
|
||||
Name: "教育网_青海",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Ningxia",
|
||||
Name: "教育网_宁夏",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi",
|
||||
Name: "鹏博士默认",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Huabei",
|
||||
Name: "鹏博士_华北地区",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Dongbei",
|
||||
Name: "鹏博士_东北地区",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Huadong",
|
||||
Name: "鹏博士_华东地区",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Huazhong",
|
||||
Name: "鹏博士_华中地区",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Huanan",
|
||||
Name: "鹏博士_华南地区",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Xinan",
|
||||
Name: "鹏博士_西南",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Xibei",
|
||||
Name: "鹏博士_西北",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Beijing",
|
||||
Name: "鹏博士_北京",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Hebei",
|
||||
Name: "鹏博士_河北",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Tianjin",
|
||||
Name: "鹏博士_天津",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Shanxi",
|
||||
Name: "鹏博士_山西",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Neimenggu",
|
||||
Name: "鹏博士_内蒙古",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Heilongjiang",
|
||||
Name: "鹏博士_黑龙江",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Jilin",
|
||||
Name: "鹏博士_吉林",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Liaoning",
|
||||
Name: "鹏博士_辽宁",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Jiangsu",
|
||||
Name: "鹏博士_江苏",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Shanghai",
|
||||
Name: "鹏博士_上海",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Zhejiang",
|
||||
Name: "鹏博士_浙江",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Anhui",
|
||||
Name: "鹏博士_安徽",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Fujian",
|
||||
Name: "鹏博士_福建",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Jiangxi",
|
||||
Name: "鹏博士_江西",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Shandong",
|
||||
Name: "鹏博士_山东",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Hubei",
|
||||
Name: "鹏博士_湖北",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Hunan",
|
||||
Name: "鹏博士_湖南",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Henan",
|
||||
Name: "鹏博士_河南",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Guangdong",
|
||||
Name: "鹏博士_广东",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Guangxi",
|
||||
Name: "鹏博士_广西",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Hainan",
|
||||
Name: "鹏博士_海南",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Sichuan",
|
||||
Name: "鹏博士_四川",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Xizang",
|
||||
Name: "鹏博士_西藏",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Chongqing",
|
||||
Name: "鹏博士_重庆",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Yunnan",
|
||||
Name: "鹏博士_云南",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Guizhou",
|
||||
Name: "鹏博士_贵州",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Gansu",
|
||||
Name: "鹏博士_甘肃",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Xinjiang",
|
||||
Name: "鹏博士_新疆",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Shaanxi",
|
||||
Name: "鹏博士_陕西",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Qinghai",
|
||||
Name: "鹏博士_青海",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Ningxia",
|
||||
Name: "鹏博士_宁夏",
|
||||
},
|
||||
{
|
||||
Code: "Tietong",
|
||||
Name: "铁通默认",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Huabei",
|
||||
Name: "铁通_华北地区",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Dongbei",
|
||||
Name: "铁通_东北地区",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Huadong",
|
||||
Name: "铁通_华东地区",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Huazhong",
|
||||
Name: "铁通_华中地区",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Huanan",
|
||||
Name: "铁通_华南地区",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Xinan",
|
||||
Name: "铁通_西南地区",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Xibei",
|
||||
Name: "铁通_西北地区",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Beijing",
|
||||
Name: "铁通_北京",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Hebei",
|
||||
Name: "铁通_河北",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Tianjin",
|
||||
Name: "铁通_天津",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Shanxi",
|
||||
Name: "铁通_山西",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Neimenggu",
|
||||
Name: "铁通_内蒙古",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Heilongjiang",
|
||||
Name: "铁通_黑龙江",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Jilin",
|
||||
Name: "铁通_吉林",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Liaoning",
|
||||
Name: "铁通_辽宁",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Jiangsu",
|
||||
Name: "铁通_江苏",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Shanghai",
|
||||
Name: "铁通_上海",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Zhejiang",
|
||||
Name: "铁通_浙江",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Anhui",
|
||||
Name: "铁通_安徽",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Fujian",
|
||||
Name: "铁通_福建",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Jiangxi",
|
||||
Name: "铁通_江西",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Shandong",
|
||||
Name: "铁通_山东",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Hubei",
|
||||
Name: "铁通_湖北",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Hunan",
|
||||
Name: "铁通_湖南",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Henan",
|
||||
Name: "铁通_河南",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Guangdong",
|
||||
Name: "铁通_广东",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Guangxi",
|
||||
Name: "铁通_广西",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Hainan",
|
||||
Name: "铁通_海南",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Sichuan",
|
||||
Name: "铁通_四川",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Xizang",
|
||||
Name: "铁通_西藏",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Chongqing",
|
||||
Name: "铁通_重庆",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Yunnan",
|
||||
Name: "铁通_云南",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Guizhou",
|
||||
Name: "铁通_贵州",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Gansu",
|
||||
Name: "铁通_甘肃",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Xinjiang",
|
||||
Name: "铁通_新疆",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Shaanxi",
|
||||
Name: "铁通_陕西",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Qinghai",
|
||||
Name: "铁通_青海",
|
||||
},
|
||||
|
||||
{
|
||||
Code: "Tietong_Ningxia",
|
||||
Name: "铁通_宁夏",
|
||||
},
|
||||
}...)
|
||||
|
||||
// 地域线路细分(全球)
|
||||
routes = append(routes, []*dnstypes.Route{
|
||||
{
|
||||
|
||||
@@ -10,6 +10,9 @@ type ProviderInterface interface {
|
||||
// Auth 认证
|
||||
Auth(params maps.Map) error
|
||||
|
||||
// MaskParams 对参数进行掩码
|
||||
MaskParams(params maps.Map)
|
||||
|
||||
// GetDomains 获取所有域名列表
|
||||
GetDomains() (domains []string, err error)
|
||||
|
||||
|
||||
@@ -47,6 +47,14 @@ func (this *TencentDNSProvider) Auth(params maps.Map) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MaskParams 对参数进行掩码
|
||||
func (this *TencentDNSProvider) MaskParams(params maps.Map) {
|
||||
if params == nil {
|
||||
return
|
||||
}
|
||||
params["accessKeySecret"] = MaskString(params.GetString("accessKeySecret"))
|
||||
}
|
||||
|
||||
// GetDomains 获取所有域名列表
|
||||
func (this *TencentDNSProvider) GetDomains() (domains []string, err error) {
|
||||
var offset int64 = 0
|
||||
|
||||
67
internal/dnsclients/utils.go
Normal file
67
internal/dnsclients/utils.go
Normal file
@@ -0,0 +1,67 @@
|
||||
// Copyright 2024 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
|
||||
package dnsclients
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// MaskString 对字符串进行掩码
|
||||
func MaskString(s string) string {
|
||||
var l = len(s)
|
||||
if l == 0 {
|
||||
return ""
|
||||
}
|
||||
if l < 8 {
|
||||
return strings.Repeat("*", l)
|
||||
}
|
||||
return s[:4] + strings.Repeat("*", l-4)
|
||||
}
|
||||
|
||||
// IsMasked 判断字符串是否被掩码
|
||||
func IsMasked(s string) bool {
|
||||
if len(s) == 0 {
|
||||
return false
|
||||
}
|
||||
return s == strings.Repeat("*", len(s)) || strings.HasSuffix(s, "**")
|
||||
}
|
||||
|
||||
// UnmaskAPIParams 恢复API参数
|
||||
func UnmaskAPIParams(oldParamsJSON []byte, newParamsJSON []byte) (resultJSON []byte, err error) {
|
||||
var oldParams maps.Map
|
||||
var newParams maps.Map
|
||||
|
||||
if len(oldParamsJSON) == 0 || len(newParamsJSON) == 0 {
|
||||
return newParamsJSON, nil
|
||||
}
|
||||
err = json.Unmarshal(oldParamsJSON, &oldParams)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = json.Unmarshal(newParamsJSON, &newParams)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if oldParams == nil || newParams == nil {
|
||||
return newParamsJSON, nil
|
||||
}
|
||||
|
||||
for k, v := range newParams {
|
||||
if v != nil {
|
||||
s, ok := v.(string)
|
||||
if ok && IsMasked(s) {
|
||||
var oldV = oldParams.GetString(k)
|
||||
if len(oldV) > 0 {
|
||||
newParams[k] = oldV
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resultJSON, err = json.Marshal(newParams)
|
||||
return
|
||||
}
|
||||
35
internal/dnsclients/utils_test.go
Normal file
35
internal/dnsclients/utils_test.go
Normal file
@@ -0,0 +1,35 @@
|
||||
// Copyright 2024 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
|
||||
package dnsclients_test
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/dnsclients"
|
||||
"github.com/iwind/TeaGo/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestIsMasked(t *testing.T) {
|
||||
var a = assert.NewAssertion(t)
|
||||
a.IsFalse(dnsclients.IsMasked(""))
|
||||
a.IsFalse(dnsclients.IsMasked("abc"))
|
||||
a.IsFalse(dnsclients.IsMasked("abc*"))
|
||||
a.IsTrue(dnsclients.IsMasked("*"))
|
||||
a.IsTrue(dnsclients.IsMasked("**"))
|
||||
a.IsTrue(dnsclients.IsMasked("***"))
|
||||
a.IsTrue(dnsclients.IsMasked("*******"))
|
||||
a.IsTrue(dnsclients.IsMasked("abc**"))
|
||||
a.IsTrue(dnsclients.IsMasked("abcd*********"))
|
||||
}
|
||||
|
||||
func TestUnmaskAPIParams(t *testing.T) {
|
||||
data, err := dnsclients.UnmaskAPIParams([]byte(`{
|
||||
"key": "a",
|
||||
"secret": "abc12"
|
||||
}`), []byte(`{
|
||||
"secret": "abc**"
|
||||
}`))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Log(string(data))
|
||||
}
|
||||
39
internal/instances/README.md
Normal file
39
internal/instances/README.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# 实例
|
||||
|
||||
## 目录结构:
|
||||
~~~
|
||||
/opt/cache
|
||||
/usr/local/goedge/
|
||||
edge-admin/
|
||||
configs/
|
||||
api_admin.yaml
|
||||
api_db.yaml
|
||||
server.yaml
|
||||
edge-api/
|
||||
configs/api.yaml
|
||||
configs/db.yaml
|
||||
api-node/
|
||||
configs/api_node.yaml
|
||||
api-user/
|
||||
configs/api_user.yaml
|
||||
src/
|
||||
/usr/bin/
|
||||
edge-admin -> ...
|
||||
edge-api -> ...
|
||||
edge-node -> ...
|
||||
edge-user -> ...
|
||||
/usr/local/mysql
|
||||
~~~
|
||||
|
||||
* 其中 `->` 表示软链接。
|
||||
* `src/` 目录下放置zip格式的待安装压缩包
|
||||
|
||||
## 端口
|
||||
* Admin:7788
|
||||
* API:8001
|
||||
* API HTTP:8002
|
||||
* User: 7799
|
||||
* Server: 8080
|
||||
|
||||
## 数据库
|
||||
数据库名称为 `edges`
|
||||
16
internal/instances/api_config.go
Normal file
16
internal/instances/api_config.go
Normal file
@@ -0,0 +1,16 @@
|
||||
// Copyright 2024 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
|
||||
package instances
|
||||
|
||||
import "gopkg.in/yaml.v3"
|
||||
|
||||
type APIConfig struct {
|
||||
RPCEndpoints []string `yaml:"rpc.endpoints,flow,omitempty" json:"rpc.endpoints"`
|
||||
RPCDisableUpdate bool `yaml:"rpc.disableUpdate,omitempty" json:"rpc.disableUpdate"`
|
||||
NodeId string `yaml:"nodeId" json:"nodeId"`
|
||||
Secret string `yaml:"secret" json:"secret"`
|
||||
}
|
||||
|
||||
func (this *APIConfig) AsYAML() ([]byte, error) {
|
||||
return yaml.Marshal(this)
|
||||
}
|
||||
1047
internal/instances/instance.go
Normal file
1047
internal/instances/instance.go
Normal file
File diff suppressed because it is too large
Load Diff
98
internal/instances/instance_test.go
Normal file
98
internal/instances/instance_test.go
Normal file
@@ -0,0 +1,98 @@
|
||||
// Copyright 2024 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
|
||||
package instances_test
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/instances"
|
||||
"github.com/iwind/TeaGo/Tea"
|
||||
_ "github.com/iwind/TeaGo/bootstrap"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var instance = instances.NewInstance(instances.Options{
|
||||
Cacheable: true,
|
||||
WorkDir: Tea.Root + "/standalone-instance",
|
||||
SrcDir: Tea.Root + "/standalone-instance/src",
|
||||
DB: struct {
|
||||
Host string
|
||||
Port int
|
||||
Username string
|
||||
Password string
|
||||
Name string
|
||||
}{
|
||||
Host: "127.0.0.1",
|
||||
Port: 3306,
|
||||
Username: "root",
|
||||
Password: "123456",
|
||||
Name: "edges2",
|
||||
},
|
||||
AdminNode: struct {
|
||||
Port int
|
||||
}{
|
||||
Port: 7788,
|
||||
},
|
||||
APINode: struct {
|
||||
HTTPPort int
|
||||
RestHTTPPort int
|
||||
}{
|
||||
HTTPPort: 8001,
|
||||
RestHTTPPort: 8002,
|
||||
},
|
||||
Node: struct{ HTTPPort int }{
|
||||
HTTPPort: 8080,
|
||||
},
|
||||
UserNode: struct {
|
||||
HTTPPort int
|
||||
}{
|
||||
HTTPPort: 7799,
|
||||
},
|
||||
})
|
||||
|
||||
func TestInstanceSetupAll(t *testing.T) {
|
||||
err := instance.SetupAll()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInstance_SetupDB(t *testing.T) {
|
||||
err := instance.SetupDB()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInstance_SetupAdminNode(t *testing.T) {
|
||||
err := instance.SetupAdminNode()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInstance_SetupAPINode(t *testing.T) {
|
||||
err := instance.SetupAPINode()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInstance_SetupUserNode(t *testing.T) {
|
||||
err := instance.SetupUserNode()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInstance_SetupNode(t *testing.T) {
|
||||
err := instance.SetupNode()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInstance_Clean(t *testing.T) {
|
||||
err := instance.Clean()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
32
internal/instances/options.go
Normal file
32
internal/instances/options.go
Normal file
@@ -0,0 +1,32 @@
|
||||
// Copyright 2024 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
|
||||
package instances
|
||||
|
||||
type Options struct {
|
||||
IsTesting bool
|
||||
Verbose bool
|
||||
Cacheable bool
|
||||
|
||||
WorkDir string
|
||||
SrcDir string
|
||||
DB struct {
|
||||
Host string
|
||||
Port int
|
||||
Username string
|
||||
Password string
|
||||
Name string
|
||||
}
|
||||
AdminNode struct {
|
||||
Port int
|
||||
}
|
||||
APINode struct {
|
||||
HTTPPort int
|
||||
RestHTTPPort int
|
||||
}
|
||||
Node struct {
|
||||
HTTPPort int
|
||||
}
|
||||
UserNode struct {
|
||||
HTTPPort int
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,6 @@ import (
|
||||
"github.com/iwind/TeaGo/logs"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
stringutil "github.com/iwind/TeaGo/utils/string"
|
||||
"github.com/iwind/gosock/pkg/gosock"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
@@ -35,11 +34,13 @@ import (
|
||||
"net"
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/signal"
|
||||
"runtime"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
// grpc decompression
|
||||
@@ -92,6 +93,9 @@ func (this *APINode) Start() {
|
||||
return
|
||||
}
|
||||
|
||||
// 监听信号
|
||||
this.listenSignals()
|
||||
|
||||
// 启动IP库
|
||||
this.setProgress("IP_LIBRARY", "开始初始化IP库")
|
||||
remotelogs.Println("API_NODE", "initializing ip library ...")
|
||||
@@ -376,7 +380,7 @@ func (this *APINode) autoUpgrade() error {
|
||||
if one != nil {
|
||||
// 如果是同样的版本,则直接认为是最新版本
|
||||
var version = one.GetString("version")
|
||||
if stringutil.VersionCompare(version, setup.ComposeSQLVersion()) >= 0 {
|
||||
if setup.CompareVersion(version, setup.ComposeSQLVersion()) >= 0 {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@@ -921,3 +925,16 @@ func (this *APINode) setupTimeZone() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 监听一些信号
|
||||
func (this *APINode) listenSignals() {
|
||||
var queue = make(chan os.Signal, 8)
|
||||
signal.Notify(queue, syscall.SIGTERM, syscall.SIGINT, syscall.SIGKILL, syscall.SIGQUIT)
|
||||
goman.New(func() {
|
||||
for range queue {
|
||||
events.Notify(events.EventQuit)
|
||||
os.Exit(0)
|
||||
return
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -67,6 +67,11 @@ func (this *RestServer) handle(writer http.ResponseWriter, req *http.Request) {
|
||||
var matches = servicePathReg.FindStringSubmatch(path)
|
||||
if len(matches) != 3 {
|
||||
writer.WriteHeader(http.StatusNotFound)
|
||||
this.writeJSON(writer, maps.Map{
|
||||
"code": "404",
|
||||
"message": "invalid api path '" + path + "'",
|
||||
"data": maps.Map{},
|
||||
}, shouldPretty)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -76,11 +81,21 @@ func (this *RestServer) handle(writer http.ResponseWriter, req *http.Request) {
|
||||
serviceType, ok := restServicesMap[serviceName]
|
||||
if !ok {
|
||||
writer.WriteHeader(http.StatusNotFound)
|
||||
this.writeJSON(writer, maps.Map{
|
||||
"code": "404",
|
||||
"message": "service '" + serviceName + "' not found",
|
||||
"data": maps.Map{},
|
||||
}, shouldPretty)
|
||||
return
|
||||
}
|
||||
|
||||
if len(methodName) == 0 {
|
||||
writer.WriteHeader(http.StatusNotFound)
|
||||
this.writeJSON(writer, maps.Map{
|
||||
"code": "404",
|
||||
"message": "method '" + methodName + "' not found",
|
||||
"data": maps.Map{},
|
||||
}, shouldPretty)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -94,19 +109,39 @@ func (this *RestServer) handle(writer http.ResponseWriter, req *http.Request) {
|
||||
method = serviceType.MethodByName(methodName)
|
||||
if !method.IsValid() {
|
||||
writer.WriteHeader(http.StatusNotFound)
|
||||
this.writeJSON(writer, maps.Map{
|
||||
"code": "404",
|
||||
"message": "method '" + methodName + "' not found",
|
||||
"data": maps.Map{},
|
||||
}, shouldPretty)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
writer.WriteHeader(http.StatusNotFound)
|
||||
this.writeJSON(writer, maps.Map{
|
||||
"code": "404",
|
||||
"message": "method '" + methodName + "' not found",
|
||||
"data": maps.Map{},
|
||||
}, shouldPretty)
|
||||
return
|
||||
}
|
||||
}
|
||||
if method.Type().NumIn() != 2 || method.Type().NumOut() != 2 {
|
||||
writer.WriteHeader(http.StatusNotFound)
|
||||
this.writeJSON(writer, maps.Map{
|
||||
"code": "404",
|
||||
"message": "method '" + methodName + "' not found",
|
||||
"data": maps.Map{},
|
||||
}, shouldPretty)
|
||||
return
|
||||
}
|
||||
if method.Type().In(0).Name() != "Context" {
|
||||
writer.WriteHeader(http.StatusNotFound)
|
||||
this.writeJSON(writer, maps.Map{
|
||||
"code": "404",
|
||||
"message": "method '" + methodName + "' not found (or invalid context)",
|
||||
"data": maps.Map{},
|
||||
}, shouldPretty)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -166,7 +201,11 @@ func (this *RestServer) handle(writer http.ResponseWriter, req *http.Request) {
|
||||
body, err := io.ReadAll(io.LimitReader(req.Body, 32*sizes.M))
|
||||
if err != nil {
|
||||
writer.WriteHeader(http.StatusBadRequest)
|
||||
_, _ = writer.Write([]byte(err.Error()))
|
||||
this.writeJSON(writer, maps.Map{
|
||||
"code": 400,
|
||||
"message": err.Error(),
|
||||
"data": maps.Map{},
|
||||
}, shouldPretty)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -180,7 +219,11 @@ func (this *RestServer) handle(writer http.ResponseWriter, req *http.Request) {
|
||||
err = json.Unmarshal(body, reqValue)
|
||||
if err != nil {
|
||||
writer.WriteHeader(http.StatusBadRequest)
|
||||
_, _ = writer.Write([]byte("Decode request failed: " + err.Error() + ". Request body should be a valid JSON data"))
|
||||
this.writeJSON(writer, maps.Map{
|
||||
"code": 400,
|
||||
"message": "Decode request failed: " + err.Error() + ". Request body should be a valid JSON data",
|
||||
"data": maps.Map{},
|
||||
}, shouldPretty)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -104,6 +104,39 @@ func (this *AdminService) CheckAdminUsername(ctx context.Context, req *pb.CheckA
|
||||
return &pb.CheckAdminUsernameResponse{Exists: exists}, nil
|
||||
}
|
||||
|
||||
// FindAdminWithUsername 使用用管理员户名查找管理员信息
|
||||
func (this *AdminService) FindAdminWithUsername(ctx context.Context, req *pb.FindAdminWithUsernameRequest) (*pb.FindAdminWithUsernameResponse, error) {
|
||||
// 校验请求
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
if len(req.Username) == 0 {
|
||||
return nil, errors.New("require 'username'")
|
||||
}
|
||||
admin, err := models.SharedAdminDAO.FindAdminWithUsername(tx, req.Username)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if admin == nil {
|
||||
return &pb.FindAdminWithUsernameResponse{Admin: nil}, nil
|
||||
}
|
||||
|
||||
return &pb.FindAdminWithUsernameResponse{
|
||||
Admin: &pb.Admin{
|
||||
Id: int64(admin.Id),
|
||||
Fullname: admin.Fullname,
|
||||
Username: admin.Username,
|
||||
IsOn: admin.IsOn,
|
||||
IsSuper: admin.IsSuper,
|
||||
CanLogin: admin.CanLogin,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// FindAdminFullname 获取管理员名称
|
||||
func (this *AdminService) FindAdminFullname(ctx context.Context, req *pb.FindAdminFullnameRequest) (*pb.FindAdminFullnameResponse, error) {
|
||||
// 校验请求
|
||||
@@ -503,7 +536,7 @@ func (this *AdminService) ComposeAdminDashboard(ctx context.Context, req *pb.Com
|
||||
|
||||
// 默认集群
|
||||
this.BeginTag(ctx, "SharedNodeClusterDAO.ListEnabledClusters")
|
||||
nodeClusters, err := models.SharedNodeClusterDAO.ListEnabledClusters(tx, "", 0, 1)
|
||||
nodeClusters, err := models.SharedNodeClusterDAO.ListEnabledClusters(tx, "", true, false, 0, 1)
|
||||
this.EndTag(ctx, "SharedNodeClusterDAO.ListEnabledClusters")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -740,3 +773,18 @@ func (this *AdminService) UpdateAdminTheme(ctx context.Context, req *pb.UpdateAd
|
||||
}
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// UpdateAdminLang 修改管理员使用的语言
|
||||
func (this *AdminService) UpdateAdminLang(ctx context.Context, req *pb.UpdateAdminLangRequest) (*pb.RPCSuccess, error) {
|
||||
adminId, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var tx = this.NullTx()
|
||||
|
||||
err = models.SharedAdminDAO.UpdateAdminLang(tx, adminId, req.LangCode)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
@@ -10,9 +10,9 @@ import (
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/dnsclients/dnstypes"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/goman"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/utils/numberutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/dnsconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/iputils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
@@ -547,7 +547,7 @@ func (this *DNSDomainService) findClusterDNSChanges(cluster *models.NodeCluster,
|
||||
record, ok := nodeRecordMapping[key]
|
||||
if !ok {
|
||||
var recordType = dnstypes.RecordTypeA
|
||||
if utils.IsIPv6(ip) {
|
||||
if iputils.IsIPv6(ip) {
|
||||
recordType = dnstypes.RecordTypeAAAA
|
||||
}
|
||||
|
||||
|
||||
@@ -2,9 +2,11 @@ package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models/dns"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/dnsclients"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
)
|
||||
|
||||
// DNSProviderService DNS服务商相关服务
|
||||
@@ -42,6 +44,21 @@ func (this *DNSProviderService) UpdateDNSProvider(ctx context.Context, req *pb.U
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
provider, err := dns.SharedDNSProviderDAO.FindEnabledDNSProvider(tx, req.DnsProviderId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if provider == nil {
|
||||
// do nothing here
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// 恢复被掩码的数据
|
||||
req.ApiParamsJSON, err = dnsclients.UnmaskAPIParams(provider.ApiParams, req.ApiParamsJSON)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = dns.SharedDNSProviderDAO.UpdateDNSProvider(tx, req.DnsProviderId, req.Name, req.ApiParamsJSON)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -175,14 +192,34 @@ func (this *DNSProviderService) FindEnabledDNSProvider(ctx context.Context, req
|
||||
return &pb.FindEnabledDNSProviderResponse{DnsProvider: nil}, nil
|
||||
}
|
||||
|
||||
return &pb.FindEnabledDNSProviderResponse{DnsProvider: &pb.DNSProvider{
|
||||
Id: int64(provider.Id),
|
||||
Name: provider.Name,
|
||||
Type: provider.Type,
|
||||
TypeName: dnsclients.FindProviderTypeName(provider.Type),
|
||||
ApiParamsJSON: provider.ApiParams,
|
||||
DataUpdatedAt: int64(provider.DataUpdatedAt),
|
||||
}}, nil
|
||||
if req.MaskParams {
|
||||
var providerObj = dnsclients.FindProvider(provider.Type, int64(provider.Id))
|
||||
if providerObj != nil {
|
||||
var paramsMap = maps.Map{}
|
||||
if len(provider.ApiParams) > 0 {
|
||||
err = json.Unmarshal(provider.ApiParams, ¶msMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
providerObj.MaskParams(paramsMap)
|
||||
provider.ApiParams, err = json.Marshal(paramsMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return &pb.FindEnabledDNSProviderResponse{
|
||||
DnsProvider: &pb.DNSProvider{
|
||||
Id: int64(provider.Id),
|
||||
Name: provider.Name,
|
||||
Type: provider.Type,
|
||||
TypeName: dnsclients.FindProviderTypeName(provider.Type),
|
||||
ApiParamsJSON: provider.ApiParams,
|
||||
DataUpdatedAt: int64(provider.DataUpdatedAt),
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// FindAllDNSProviderTypes 取得所有服务商类型
|
||||
|
||||
@@ -353,14 +353,28 @@ func (this *HTTPCacheTaskService) FindEnabledHTTPCacheTask(ctx context.Context,
|
||||
key.Errors = nil
|
||||
}
|
||||
|
||||
// 集群信息
|
||||
var pbNodeCluster *pb.NodeCluster
|
||||
if !isFromUser && key.ClusterId > 0 {
|
||||
clusterName, findClusterErr := models.SharedNodeClusterDAO.FindNodeClusterName(tx, int64(key.ClusterId))
|
||||
if findClusterErr != nil {
|
||||
return nil, findClusterErr
|
||||
}
|
||||
pbNodeCluster = &pb.NodeCluster{
|
||||
Id: int64(key.ClusterId),
|
||||
Name: clusterName,
|
||||
}
|
||||
}
|
||||
|
||||
pbKeys = append(pbKeys, &pb.HTTPCacheTaskKey{
|
||||
Id: int64(key.Id),
|
||||
TaskId: int64(key.TaskId),
|
||||
Key: key.Key,
|
||||
KeyType: key.KeyType,
|
||||
IsDone: key.IsDone,
|
||||
IsDoing: !key.IsDone && len(key.DecodeNodes()) > 0,
|
||||
ErrorsJSON: key.Errors,
|
||||
Id: int64(key.Id),
|
||||
TaskId: int64(key.TaskId),
|
||||
Key: key.Key,
|
||||
KeyType: key.KeyType,
|
||||
IsDone: key.IsDone,
|
||||
IsDoing: !key.IsDone && len(key.DecodeNodes()) > 0,
|
||||
ErrorsJSON: key.Errors,
|
||||
NodeCluster: pbNodeCluster,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@ import (
|
||||
"encoding/json"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/iplibrary"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
|
||||
@@ -33,7 +32,7 @@ func (this *HTTPFirewallPolicyService) FindAllEnabledHTTPFirewallPolicies(ctx co
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := []*pb.HTTPFirewallPolicy{}
|
||||
var result = []*pb.HTTPFirewallPolicy{}
|
||||
for _, p := range policies {
|
||||
result = append(result, &pb.HTTPFirewallPolicy{
|
||||
Id: int64(p.Id),
|
||||
@@ -305,7 +304,7 @@ func (this *HTTPFirewallPolicyService) UpdateHTTPFirewallPolicy(ctx context.Cont
|
||||
req.MaxRequestBodySize = 0
|
||||
}
|
||||
|
||||
err = models.SharedHTTPFirewallPolicyDAO.UpdateFirewallPolicy(tx, req.HttpFirewallPolicyId, req.IsOn, req.Name, req.Description, inboundConfigJSON, outboundConfigJSON, req.BlockOptionsJSON, req.CaptchaOptionsJSON, req.Mode, req.UseLocalFirewall, synFloodConfig, logConfig, req.MaxRequestBodySize, req.DenyCountryHTML, req.DenyProvinceHTML)
|
||||
err = models.SharedHTTPFirewallPolicyDAO.UpdateFirewallPolicy(tx, req.HttpFirewallPolicyId, req.IsOn, req.Name, req.Description, inboundConfigJSON, outboundConfigJSON, req.BlockOptionsJSON, req.PageOptionsJSON, req.CaptchaOptionsJSON, req.JsCookieOptionsJSON, req.Mode, req.UseLocalFirewall, synFloodConfig, logConfig, req.MaxRequestBodySize, req.DenyCountryHTML, req.DenyProvinceHTML)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -395,7 +394,7 @@ func (this *HTTPFirewallPolicyService) ListEnabledHTTPFirewallPolicies(ctx conte
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := []*pb.HTTPFirewallPolicy{}
|
||||
var result = []*pb.HTTPFirewallPolicy{}
|
||||
for _, p := range policies {
|
||||
result = append(result, &pb.HTTPFirewallPolicy{
|
||||
Id: int64(p.Id),
|
||||
@@ -488,17 +487,22 @@ func (this *HTTPFirewallPolicyService) FindEnabledHTTPFirewallPolicy(ctx context
|
||||
if policy == nil {
|
||||
return &pb.FindEnabledHTTPFirewallPolicyResponse{HttpFirewallPolicy: nil}, nil
|
||||
}
|
||||
return &pb.FindEnabledHTTPFirewallPolicyResponse{HttpFirewallPolicy: &pb.HTTPFirewallPolicy{
|
||||
Id: int64(policy.Id),
|
||||
ServerId: int64(policy.ServerId),
|
||||
Name: policy.Name,
|
||||
Description: policy.Description,
|
||||
IsOn: policy.IsOn,
|
||||
InboundJSON: policy.Inbound,
|
||||
OutboundJSON: policy.Outbound,
|
||||
Mode: policy.Mode,
|
||||
SynFloodJSON: policy.SynFlood,
|
||||
}}, nil
|
||||
return &pb.FindEnabledHTTPFirewallPolicyResponse{
|
||||
HttpFirewallPolicy: &pb.HTTPFirewallPolicy{
|
||||
Id: int64(policy.Id),
|
||||
ServerId: int64(policy.ServerId),
|
||||
Name: policy.Name,
|
||||
Description: policy.Description,
|
||||
IsOn: policy.IsOn,
|
||||
InboundJSON: policy.Inbound,
|
||||
OutboundJSON: policy.Outbound,
|
||||
Mode: policy.Mode,
|
||||
SynFloodJSON: policy.SynFlood,
|
||||
BlockOptionsJSON: policy.BlockOptions,
|
||||
PageOptionsJSON: policy.PageOptions,
|
||||
CaptchaOptionsJSON: policy.CaptchaOptions,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ImportHTTPFirewallPolicy 导入策略数据
|
||||
@@ -659,22 +663,33 @@ func (this *HTTPFirewallPolicyService) ImportHTTPFirewallPolicy(ctx context.Cont
|
||||
|
||||
// CheckHTTPFirewallPolicyIPStatus 检查IP状态
|
||||
func (this *HTTPFirewallPolicyService) CheckHTTPFirewallPolicyIPStatus(ctx context.Context, req *pb.CheckHTTPFirewallPolicyIPStatusRequest) (*pb.CheckHTTPFirewallPolicyIPStatusResponse, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
// 检查权限
|
||||
if req.HttpFirewallPolicyId <= 0 {
|
||||
return nil, errors.New("invalid 'httpFirewallPolicyId'")
|
||||
}
|
||||
if userId > 0 {
|
||||
err = models.SharedHTTPFirewallPolicyDAO.CheckUserFirewallPolicy(tx, userId, req.HttpFirewallPolicyId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// 校验IP
|
||||
ip := net.ParseIP(req.Ip)
|
||||
var ip = net.ParseIP(req.Ip)
|
||||
if len(ip) == 0 {
|
||||
return &pb.CheckHTTPFirewallPolicyIPStatusResponse{
|
||||
IsOk: false,
|
||||
Error: "请输入正确的IP",
|
||||
}, nil
|
||||
}
|
||||
ipLong := utils.IP2Long(req.Ip)
|
||||
|
||||
var tx = this.NullTx()
|
||||
firewallPolicy, err := models.SharedHTTPFirewallPolicyDAO.ComposeFirewallPolicy(tx, req.HttpFirewallPolicyId, false, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -708,7 +723,7 @@ func (this *HTTPFirewallPolicyService) CheckHTTPFirewallPolicyIPStatus(ctx conte
|
||||
}
|
||||
|
||||
for _, listId := range listIds {
|
||||
item, err := models.SharedIPItemDAO.FindEnabledItemContainsIP(tx, listId, ipLong)
|
||||
item, err := models.SharedIPItemDAO.FindEnabledItemContainsIP(tx, listId, req.Ip)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -728,6 +743,7 @@ func (this *HTTPFirewallPolicyService) CheckHTTPFirewallPolicyIPStatus(ctx conte
|
||||
IpList: &pb.IPList{Name: listName, Id: listId},
|
||||
IpItem: &pb.IPItem{
|
||||
Id: int64(item.Id),
|
||||
Value: item.ComposeValue(),
|
||||
IpFrom: item.IpFrom,
|
||||
IpTo: item.IpTo,
|
||||
ExpiredAt: int64(item.ExpiredAt),
|
||||
@@ -763,7 +779,7 @@ func (this *HTTPFirewallPolicyService) CheckHTTPFirewallPolicyIPStatus(ctx conte
|
||||
}
|
||||
|
||||
for _, listId := range listIds {
|
||||
item, err := models.SharedIPItemDAO.FindEnabledItemContainsIP(tx, listId, ipLong)
|
||||
item, err := models.SharedIPItemDAO.FindEnabledItemContainsIP(tx, listId, req.Ip)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -783,6 +799,7 @@ func (this *HTTPFirewallPolicyService) CheckHTTPFirewallPolicyIPStatus(ctx conte
|
||||
IpList: &pb.IPList{Name: listName, Id: listId},
|
||||
IpItem: &pb.IPItem{
|
||||
Id: int64(item.Id),
|
||||
Value: item.ComposeValue(),
|
||||
IpFrom: item.IpFrom,
|
||||
IpTo: item.IpTo,
|
||||
ExpiredAt: int64(item.ExpiredAt),
|
||||
@@ -858,3 +875,29 @@ func (this *HTTPFirewallPolicyService) CheckHTTPFirewallPolicyIPStatus(ctx conte
|
||||
RegionProvince: nil,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// FindServerIdWithHTTPFirewallPolicyId 获取防火墙对应的网站ID
|
||||
func (this *HTTPFirewallPolicyService) FindServerIdWithHTTPFirewallPolicyId(ctx context.Context, req *pb.FindServerIdWithHTTPFirewallPolicyIdRequest) (*pb.FindServerIdWithHTTPFirewallPolicyIdResponse, error) {
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
serverId, err := models.SharedHTTPFirewallPolicyDAO.FindServerIdWithFirewallPolicyId(tx, req.HttpFirewallPolicyId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// check user
|
||||
if serverId > 0 && userId > 0 {
|
||||
err = models.SharedServerDAO.CheckUserServer(tx, userId, serverId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return &pb.FindServerIdWithHTTPFirewallPolicyIdResponse{
|
||||
ServerId: serverId,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -3,12 +3,16 @@ package services
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/utils/domainutils"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/utils/regexputils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
"github.com/iwind/TeaGo/lists"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type HTTPWebService struct {
|
||||
@@ -532,6 +536,49 @@ func (this *HTTPWebService) UpdateHTTPWebCache(ctx context.Context, req *pb.Upda
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
var cacheConfig = &serverconfigs.HTTPCacheConfig{}
|
||||
if len(req.CacheJSON) > 0 {
|
||||
err = json.Unmarshal(req.CacheJSON, cacheConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = cacheConfig.Init()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("validate cache config failed: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
// validate host
|
||||
if cacheConfig.Key != nil && cacheConfig.Key.IsOn {
|
||||
if cacheConfig.Key.Scheme != "http" && cacheConfig.Key.Scheme != "https" {
|
||||
return nil, errors.New("key scheme must be 'http' or 'https'")
|
||||
}
|
||||
|
||||
cacheConfig.Key.Host = strings.ToLower(cacheConfig.Key.Host)
|
||||
if !domainutils.ValidateDomainFormat(cacheConfig.Key.Host) {
|
||||
return nil, errors.New("key host must be a valid domain")
|
||||
}
|
||||
|
||||
serverId, err := models.SharedHTTPWebDAO.FindWebServerId(tx, req.HttpWebId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if serverId > 0 {
|
||||
serverNamesJSON, _, _, _, _, err := models.SharedServerDAO.FindServerServerNames(tx, serverId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var serverNames = []*serverconfigs.ServerNameConfig{}
|
||||
err = json.Unmarshal(serverNamesJSON, &serverNames)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !lists.ContainsString(serverconfigs.PlainServerNames(serverNames), cacheConfig.Key.Host) {
|
||||
return nil, errors.New("key host '" + cacheConfig.Key.Host + "' not exists in server names")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
err = models.SharedHTTPWebDAO.UpdateWebCache(tx, req.HttpWebId, req.CacheJSON)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -851,28 +898,6 @@ func (this *HTTPWebService) FindHTTPWebRequestLimit(ctx context.Context, req *pb
|
||||
return &pb.FindHTTPWebRequestLimitResponse{RequestLimitJSON: configJSON}, nil
|
||||
}
|
||||
|
||||
// UpdateHTTPWebRequestScripts 修改请求脚本
|
||||
func (this *HTTPWebService) UpdateHTTPWebRequestScripts(ctx context.Context, req *pb.UpdateHTTPWebRequestScriptsRequest) (*pb.RPCSuccess, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
var config = &serverconfigs.HTTPRequestScriptsConfig{}
|
||||
err = json.Unmarshal(req.RequestScriptsJSON, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = models.SharedHTTPWebDAO.UpdateWebRequestScripts(tx, req.HttpWebId, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// FindHTTPWebRequestScripts 查找请求脚本
|
||||
func (this *HTTPWebService) FindHTTPWebRequestScripts(ctx context.Context, req *pb.FindHTTPWebRequestScriptsRequest) (*pb.FindHTTPWebRequestScriptsResponse, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
@@ -947,18 +972,13 @@ func (this *HTTPWebService) FindHTTPWebReferers(ctx context.Context, req *pb.Fin
|
||||
}
|
||||
}
|
||||
|
||||
config, err := models.SharedHTTPWebDAO.FindWebReferers(tx, req.HttpWebId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
configJSON, err := json.Marshal(config)
|
||||
referersJSON, err := models.SharedHTTPWebDAO.FindWebReferers(tx, req.HttpWebId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &pb.FindHTTPWebReferersResponse{
|
||||
ReferersJSON: configJSON,
|
||||
ReferersJSON: referersJSON,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -1015,17 +1035,39 @@ func (this *HTTPWebService) FindHTTPWebUserAgent(ctx context.Context, req *pb.Fi
|
||||
}
|
||||
}
|
||||
|
||||
config, err := models.SharedHTTPWebDAO.FindWebUserAgent(tx, req.HttpWebId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
configJSON, err := json.Marshal(config)
|
||||
userAgentJSON, err := models.SharedHTTPWebDAO.FindWebUserAgent(tx, req.HttpWebId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &pb.FindHTTPWebUserAgentResponse{
|
||||
UserAgentJSON: configJSON,
|
||||
UserAgentJSON: userAgentJSON,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// FindServerIdWithHTTPWebId 根据WebId查找ServerId
|
||||
func (this *HTTPWebService) FindServerIdWithHTTPWebId(ctx context.Context, req *pb.FindServerIdWithHTTPWebIdRequest) (*pb.FindServerIdWithHTTPWebIdResponse, error) {
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if req.HttpWebId <= 0 {
|
||||
return nil, errors.New("invalid 'httpWebId'")
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
serverId, err := models.SharedHTTPWebDAO.FindWebServerId(tx, req.HttpWebId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if serverId > 0 && userId > 0 {
|
||||
err = models.SharedServerDAO.CheckUserServer(tx, userId, serverId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return &pb.FindServerIdWithHTTPWebIdResponse{ServerId: serverId}, nil
|
||||
}
|
||||
|
||||
@@ -27,3 +27,18 @@ func (this *HTTPWebService) UpdateHTTPWebCC(ctx context.Context, req *pb.UpdateH
|
||||
func (this *HTTPWebService) FindHTTPWebCC(ctx context.Context, req *pb.FindHTTPWebCCRequest) (*pb.FindHTTPWebCCResponse, error) {
|
||||
return nil, this.NotImplementedYet()
|
||||
}
|
||||
|
||||
// UpdateHTTPWebRequestScripts 修改请求脚本
|
||||
func (this *HTTPWebService) UpdateHTTPWebRequestScripts(ctx context.Context, req *pb.UpdateHTTPWebRequestScriptsRequest) (*pb.RPCSuccess, error) {
|
||||
return nil, this.NotImplementedYet()
|
||||
}
|
||||
|
||||
// UpdateHTTPWebHLS 修改HLS设置
|
||||
func (this *HTTPWebService) UpdateHTTPWebHLS(ctx context.Context, req *pb.UpdateHTTPWebHLSRequest) (*pb.RPCSuccess, error) {
|
||||
return nil, this.NotImplementedYet()
|
||||
}
|
||||
|
||||
// FindHTTPWebHLS 查找HLS设置
|
||||
func (this *HTTPWebService) FindHTTPWebHLS(ctx context.Context, req *pb.FindHTTPWebHLSRequest) (*pb.FindHTTPWebHLSResponse, error) {
|
||||
return nil, this.NotImplementedYet()
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
||||
rpcutils "github.com/TeaOSLab/EdgeAPI/internal/rpc/utils"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/iputils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
|
||||
"net"
|
||||
@@ -25,19 +26,31 @@ func (this *IPItemService) CreateIPItem(ctx context.Context, req *pb.CreateIPIte
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(req.IpFrom) == 0 {
|
||||
return nil, errors.New("'ipFrom' should not be empty")
|
||||
}
|
||||
if len(req.Value) > 0 {
|
||||
newValue, ipFrom, ipTo, ok := models.SharedIPItemDAO.ParseIPValue(req.Value)
|
||||
if !ok {
|
||||
return nil, errors.New("invalid 'value' format")
|
||||
}
|
||||
|
||||
var ipFrom = net.ParseIP(req.IpFrom)
|
||||
if ipFrom == nil {
|
||||
return nil, errors.New("invalid 'ipFrom'")
|
||||
}
|
||||
req.Value = newValue
|
||||
req.IpFrom = ipFrom
|
||||
req.IpTo = ipTo
|
||||
} else if req.Type != models.IPItemTypeAll {
|
||||
if !iputils.IsValid(req.IpFrom) {
|
||||
return nil, errors.New("invalid 'ipFrom'")
|
||||
}
|
||||
if len(req.IpTo) > 0 {
|
||||
if !iputils.IsValid(req.IpTo) {
|
||||
return nil, errors.New("invalid 'ipTo'")
|
||||
}
|
||||
|
||||
if len(req.IpTo) > 0 {
|
||||
ipTo := net.ParseIP(req.IpTo)
|
||||
if ipTo == nil {
|
||||
return nil, errors.New("invalid 'ipTo'")
|
||||
if !iputils.IsSameVersion(req.IpFrom, req.IpTo) {
|
||||
return nil, errors.New("'ipFrom' and 'ipTo' should be in same version")
|
||||
}
|
||||
|
||||
if iputils.CompareIP(req.IpFrom, req.IpTo) > 0 {
|
||||
req.IpFrom, req.IpTo = req.IpTo, req.IpFrom
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,7 +77,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, true)
|
||||
itemId, err := models.SharedIPItemDAO.CreateIPItem(tx, req.IpListId, req.Value, 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
|
||||
}
|
||||
@@ -84,19 +97,30 @@ func (this *IPItemService) CreateIPItems(ctx context.Context, req *pb.CreateIPIt
|
||||
|
||||
// 校验
|
||||
for _, item := range req.IpItems {
|
||||
if len(item.IpFrom) == 0 {
|
||||
return nil, errors.New("'ipFrom' should not be empty")
|
||||
}
|
||||
if len(item.Value) > 0 {
|
||||
newValue, ipFrom, ipTo, ok := models.SharedIPItemDAO.ParseIPValue(item.Value)
|
||||
if !ok {
|
||||
return nil, errors.New("invalid 'value': " + item.Value)
|
||||
}
|
||||
item.Value = newValue
|
||||
item.IpFrom = ipFrom
|
||||
item.IpTo = ipTo
|
||||
} else if item.Type != models.IPItemTypeAll {
|
||||
if !iputils.IsValid(item.IpFrom) {
|
||||
return nil, errors.New("invalid 'ipFrom': " + item.IpFrom)
|
||||
}
|
||||
if len(item.IpTo) > 0 {
|
||||
if !iputils.IsValid(item.IpTo) {
|
||||
return nil, errors.New("invalid 'ipTo': " + item.IpTo)
|
||||
}
|
||||
|
||||
var ipFrom = net.ParseIP(item.IpFrom)
|
||||
if ipFrom == nil {
|
||||
return nil, errors.New("invalid 'ipFrom'")
|
||||
}
|
||||
if !iputils.IsSameVersion(item.IpFrom, item.IpTo) {
|
||||
return nil, errors.New("'ipFrom' (" + item.IpFrom + ") and 'ipTo' (" + item.IpTo + ") should be in same version")
|
||||
}
|
||||
|
||||
if len(item.IpTo) > 0 {
|
||||
ipTo := net.ParseIP(item.IpTo)
|
||||
if ipTo == nil {
|
||||
return nil, errors.New("invalid 'ipTo'")
|
||||
if iputils.CompareIP(item.IpFrom, item.IpTo) > 0 {
|
||||
item.IpFrom, item.IpTo = item.IpTo, item.IpFrom
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,21 +141,21 @@ func (this *IPItemService) CreateIPItems(ctx context.Context, req *pb.CreateIPIt
|
||||
}
|
||||
|
||||
// 创建
|
||||
// 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 len(item.Value) > 0 {
|
||||
err = models.SharedIPItemDAO.DeleteOldItemWithValue(tx, item.IpListId, item.Value)
|
||||
} else {
|
||||
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
|
||||
}
|
||||
itemId, err := models.SharedIPItemDAO.CreateIPItem(tx, item.IpListId, item.Value, 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
|
||||
}
|
||||
@@ -153,6 +177,34 @@ func (this *IPItemService) UpdateIPItem(ctx context.Context, req *pb.UpdateIPIte
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
// validate ip
|
||||
if len(req.Value) > 0 {
|
||||
newValue, ipFrom, ipTo, ok := models.SharedIPItemDAO.ParseIPValue(req.Value)
|
||||
if !ok {
|
||||
return nil, errors.New("invalid 'value' format")
|
||||
}
|
||||
req.Value = newValue
|
||||
req.IpFrom = ipFrom
|
||||
req.IpTo = ipTo
|
||||
} else if req.Type != models.IPItemTypeAll {
|
||||
if !iputils.IsValid(req.IpFrom) {
|
||||
return nil, errors.New("invalid 'ipFrom'")
|
||||
}
|
||||
if len(req.IpTo) > 0 {
|
||||
if !iputils.IsValid(req.IpTo) {
|
||||
return nil, errors.New("invalid 'ipTo'")
|
||||
}
|
||||
|
||||
if !iputils.IsSameVersion(req.IpFrom, req.IpTo) {
|
||||
return nil, errors.New("'ipFrom' and 'ipTo' should be in same version")
|
||||
}
|
||||
|
||||
if iputils.CompareIP(req.IpFrom, req.IpTo) > 0 {
|
||||
req.IpFrom, req.IpTo = req.IpTo, req.IpFrom
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if userId > 0 {
|
||||
listId, err := models.SharedIPItemDAO.FindItemListId(tx, req.IpItemId)
|
||||
if err != nil {
|
||||
@@ -169,7 +221,7 @@ func (this *IPItemService) UpdateIPItem(ctx context.Context, req *pb.UpdateIPIte
|
||||
req.Type = models.IPItemTypeIPv4
|
||||
}
|
||||
|
||||
err = models.SharedIPItemDAO.UpdateIPItem(tx, req.IpItemId, req.IpFrom, req.IpTo, req.ExpiredAt, req.Reason, req.Type, req.EventLevel)
|
||||
err = models.SharedIPItemDAO.UpdateIPItem(tx, req.IpItemId, req.Value, req.IpFrom, req.IpTo, req.ExpiredAt, req.Reason, req.Type, req.EventLevel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -187,12 +239,34 @@ func (this *IPItemService) DeleteIPItem(ctx context.Context, req *pb.DeleteIPIte
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
if req.IpItemId <= 0 && len(req.Value) == 0 && len(req.IpFrom) == 0 {
|
||||
return nil, errors.New("one of 'ipItemId', 'value' or 'ipFrom' params required")
|
||||
}
|
||||
|
||||
// 如果是使用IPItemId删除
|
||||
if req.IpItemId > 0 {
|
||||
err = models.SharedIPItemDAO.DisableIPItem(tx, req.IpItemId, userId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// 使用value删除
|
||||
if len(req.Value) > 0 {
|
||||
// 检查IP列表
|
||||
if req.IpListId > 0 && userId > 0 && req.IpListId != firewallconfigs.GlobalListId {
|
||||
err = models.SharedIPListDAO.CheckUserIPList(tx, userId, req.IpListId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
err = models.SharedIPItemDAO.DisableIPItemsWithIPValue(tx, req.Value, userId, req.IpListId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// 如果是使用ipFrom+ipTo删除
|
||||
@@ -209,6 +283,7 @@ func (this *IPItemService) DeleteIPItem(ctx context.Context, req *pb.DeleteIPIte
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
return this.Success()
|
||||
@@ -345,6 +420,7 @@ func (this *IPItemService) ListIPItemsWithListId(ctx context.Context, req *pb.Li
|
||||
|
||||
result = append(result, &pb.IPItem{
|
||||
Id: int64(item.Id),
|
||||
Value: item.ComposeValue(),
|
||||
IpFrom: item.IpFrom,
|
||||
IpTo: item.IpTo,
|
||||
Version: int64(item.Version),
|
||||
@@ -402,6 +478,7 @@ func (this *IPItemService) FindEnabledIPItem(ctx context.Context, req *pb.FindEn
|
||||
|
||||
return &pb.FindEnabledIPItemResponse{IpItem: &pb.IPItem{
|
||||
Id: int64(item.Id),
|
||||
Value: item.ComposeValue(),
|
||||
IpFrom: item.IpFrom,
|
||||
IpTo: item.IpTo,
|
||||
Version: int64(item.Version),
|
||||
@@ -456,6 +533,7 @@ func (this *IPItemService) ListIPItemsAfterVersion(ctx context.Context, req *pb.
|
||||
|
||||
result = append(result, &pb.IPItem{
|
||||
Id: int64(item.Id),
|
||||
Value: item.ComposeValue(),
|
||||
IpFrom: item.IpFrom,
|
||||
IpTo: item.IpTo,
|
||||
Version: int64(item.Version),
|
||||
@@ -484,14 +562,13 @@ func (this *IPItemService) CheckIPItemStatus(ctx context.Context, req *pb.CheckI
|
||||
}
|
||||
|
||||
// 校验IP
|
||||
ip := net.ParseIP(req.Ip)
|
||||
var ip = net.ParseIP(req.Ip)
|
||||
if len(ip) == 0 {
|
||||
return &pb.CheckIPItemStatusResponse{
|
||||
IsOk: false,
|
||||
Error: "请输入正确的IP",
|
||||
}, nil
|
||||
}
|
||||
ipLong := utils.IP2Long(req.Ip)
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
@@ -509,7 +586,7 @@ func (this *IPItemService) CheckIPItemStatus(ctx context.Context, req *pb.CheckI
|
||||
var isAllowed = list.Type == "white"
|
||||
|
||||
// 检查IP名单
|
||||
item, err := models.SharedIPItemDAO.FindEnabledItemContainsIP(tx, req.IpListId, ipLong)
|
||||
item, err := models.SharedIPItemDAO.FindEnabledItemContainsIP(tx, req.IpListId, req.Ip)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -521,6 +598,7 @@ func (this *IPItemService) CheckIPItemStatus(ctx context.Context, req *pb.CheckI
|
||||
IsAllowed: isAllowed,
|
||||
IpItem: &pb.IPItem{
|
||||
Id: int64(item.Id),
|
||||
Value: item.ComposeValue(),
|
||||
IpFrom: item.IpFrom,
|
||||
IpTo: item.IpTo,
|
||||
CreatedAt: int64(item.CreatedAt),
|
||||
@@ -676,6 +754,7 @@ func (this *IPItemService) ListAllEnabledIPItems(ctx context.Context, req *pb.Li
|
||||
|
||||
var pbItem = &pb.IPItem{
|
||||
Id: int64(item.Id),
|
||||
Value: item.ComposeValue(),
|
||||
IpFrom: item.IpFrom,
|
||||
IpTo: item.IpTo,
|
||||
Version: int64(item.Version),
|
||||
@@ -768,6 +847,29 @@ func (this *IPItemService) ListAllEnabledIPItems(ctx context.Context, req *pb.Li
|
||||
return &pb.ListAllEnabledIPItemsResponse{Results: results}, nil
|
||||
}
|
||||
|
||||
// ListAllIPItemIds 列出所有名单中的IP ID
|
||||
func (this *IPItemService) ListAllIPItemIds(ctx context.Context, req *pb.ListAllIPItemIdsRequest) (*pb.ListAllIPItemIdsResponse, error) {
|
||||
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
|
||||
}
|
||||
itemIds, err := models.SharedIPItemDAO.ListAllIPItemIds(tx, userId, req.Keyword, req.Ip, listId, req.Unread, req.EventLevel, req.ListType, req.Offset, req.Size)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &pb.ListAllIPItemIdsResponse{IpItemIds: itemIds}, nil
|
||||
}
|
||||
|
||||
// UpdateIPItemsRead 设置所有为已读
|
||||
func (this *IPItemService) UpdateIPItemsRead(ctx context.Context, req *pb.UpdateIPItemsReadRequest) (*pb.RPCSuccess, error) {
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
@@ -782,3 +884,38 @@ func (this *IPItemService) UpdateIPItemsRead(ctx context.Context, req *pb.Update
|
||||
}
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// FindServerIdWithIPItemId 查找IP对应的名单所属网站ID
|
||||
func (this *IPItemService) FindServerIdWithIPItemId(ctx context.Context, req *pb.FindServerIdWithIPItemIdRequest) (*pb.FindServerIdWithIPItemIdResponse, error) {
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
listId, err := models.SharedIPItemDAO.FindItemListId(tx, req.IpItemId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if listId > 0 {
|
||||
var serverId int64
|
||||
serverId, err = models.SharedIPListDAO.FindServerIdWithListId(tx, listId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if serverId > 0 {
|
||||
// check user
|
||||
if userId > 0 {
|
||||
err = models.SharedServerDAO.CheckUserServer(tx, userId, serverId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return &pb.FindServerIdWithIPItemIdResponse{ServerId: serverId}, nil
|
||||
}
|
||||
}
|
||||
|
||||
return &pb.FindServerIdWithIPItemIdResponse{ServerId: 0}, nil
|
||||
}
|
||||
|
||||
@@ -224,3 +224,29 @@ func (this *IPListService) FindEnabledIPListContainsIP(ctx context.Context, req
|
||||
}
|
||||
return &pb.FindEnabledIPListContainsIPResponse{IpLists: pbLists}, nil
|
||||
}
|
||||
|
||||
// FindServerIdWithIPListId 查找IP名单对应的网站ID
|
||||
func (this *IPListService) FindServerIdWithIPListId(ctx context.Context, req *pb.FindServerIdWithIPListIdRequest) (*pb.FindServerIdWithIPListIdResponse, error) {
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
serverId, err := models.SharedIPListDAO.FindServerIdWithListId(tx, req.IpListId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// check user
|
||||
if serverId > 0 && userId > 0 {
|
||||
err = models.SharedServerDAO.CheckUserServer(tx, userId, serverId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return &pb.FindServerIdWithIPListIdResponse{
|
||||
ServerId: serverId,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -71,16 +71,18 @@ func init() {
|
||||
}()
|
||||
}
|
||||
|
||||
err = models.SharedMetricStatDAO.DeleteNodeItemStats(tx, nodeId, serverId, itemId, req.Time)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, stat := range req.MetricStats {
|
||||
err := models.SharedMetricStatDAO.CreateStat(tx, stat.Hash, clusterId, nodeId, req.ServerId, req.ItemId, stat.Keys, float64(stat.Value), req.Time, req.Version)
|
||||
if len(req.MetricStats) > 0 {
|
||||
err = models.SharedMetricStatDAO.DeleteNodeItemStats(tx, nodeId, serverId, itemId, req.Time, req.KeepKeys)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, stat := range req.MetricStats {
|
||||
err = models.SharedMetricStatDAO.CreateStat(tx, stat.Hash, clusterId, nodeId, req.ServerId, req.ItemId, stat.Keys, float64(stat.Value), req.Time, req.Version)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 保存总和
|
||||
|
||||
@@ -2257,3 +2257,55 @@ func (this *NodeService) UpdateNodeAPIConfig(ctx context.Context, req *pb.Update
|
||||
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// FindNodeWebPPolicies 查找节点的WebP策略
|
||||
func (this *NodeService) FindNodeWebPPolicies(ctx context.Context, req *pb.FindNodeWebPPoliciesRequest) (*pb.FindNodeWebPPoliciesResponse, 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.FindNodeWebPPoliciesResponse_WebPPolicy{}
|
||||
for _, clusterId := range clusterIds {
|
||||
policy, err := models.SharedNodeClusterDAO.FindClusterWebPPolicy(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.FindNodeWebPPoliciesResponse_WebPPolicy{
|
||||
NodeClusterId: clusterId,
|
||||
WebPPolicyJSON: policyJSON,
|
||||
})
|
||||
}
|
||||
return &pb.FindNodeWebPPoliciesResponse{
|
||||
WebPPolicies: pbPolicies,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// UpdateNodeIsOn 修改节点的启用状态
|
||||
func (this *NodeService) UpdateNodeIsOn(ctx context.Context, req *pb.UpdateNodeIsOnRequest) (*pb.RPCSuccess, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
err = models.SharedNodeDAO.UpdateNodeIsOn(tx, req.NodeId, req.IsOn)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ func (this *NodeClusterService) CreateNodeCluster(ctx context.Context, req *pb.C
|
||||
req.DnsTTL = 0
|
||||
}
|
||||
|
||||
clusterId, err = models.SharedNodeClusterDAO.CreateCluster(tx, adminId, req.Name, req.NodeGrantId, req.InstallDir, req.DnsDomainId, req.DnsName, req.DnsTTL, req.HttpCachePolicyId, req.HttpFirewallPolicyId, systemServices, serverGlobalConfig, req.AutoInstallNftables, req.AutoSystemTuning)
|
||||
clusterId, err = models.SharedNodeClusterDAO.CreateCluster(tx, adminId, req.Name, req.NodeGrantId, req.InstallDir, req.DnsDomainId, req.DnsName, req.DnsTTL, req.HttpCachePolicyId, req.HttpFirewallPolicyId, systemServices, serverGlobalConfig, req.AutoInstallNftables, req.AutoSystemTuning, req.AutoTrimDisks)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -127,7 +127,7 @@ func (this *NodeClusterService) UpdateNodeCluster(ctx context.Context, req *pb.U
|
||||
}
|
||||
}
|
||||
|
||||
err = models.SharedNodeClusterDAO.UpdateCluster(tx, req.NodeClusterId, req.Name, req.NodeGrantId, req.InstallDir, req.TimeZone, req.NodeMaxThreads, req.AutoOpenPorts, clockConfig, req.AutoRemoteStart, req.AutoInstallNftables, sshParams, req.AutoSystemTuning)
|
||||
err = models.SharedNodeClusterDAO.UpdateCluster(tx, req.NodeClusterId, req.Name, req.NodeGrantId, req.InstallDir, req.TimeZone, req.NodeMaxThreads, req.AutoOpenPorts, clockConfig, req.AutoRemoteStart, req.AutoInstallNftables, sshParams, req.AutoSystemTuning, req.AutoTrimDisks)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -234,6 +234,7 @@ func (this *NodeClusterService) FindEnabledNodeCluster(ctx context.Context, req
|
||||
AutoRemoteStart: cluster.AutoRemoteStart,
|
||||
AutoInstallNftables: cluster.AutoInstallNftables,
|
||||
AutoSystemTuning: cluster.AutoSystemTuning,
|
||||
AutoTrimDisks: cluster.AutoTrimDisks,
|
||||
}}, nil
|
||||
}
|
||||
|
||||
@@ -349,12 +350,12 @@ func (this *NodeClusterService) ListEnabledNodeClusters(ctx context.Context, req
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
clusters, err := models.SharedNodeClusterDAO.ListEnabledClusters(tx, req.Keyword, req.Offset, req.Size)
|
||||
clusters, err := models.SharedNodeClusterDAO.ListEnabledClusters(tx, req.Keyword, req.IdDesc, req.IdAsc, req.Offset, req.Size)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := []*pb.NodeCluster{}
|
||||
var result = []*pb.NodeCluster{}
|
||||
for _, cluster := range clusters {
|
||||
result = append(result, &pb.NodeCluster{
|
||||
Id: int64(cluster.Id),
|
||||
@@ -1126,14 +1127,14 @@ func (this *NodeClusterService) FindEnabledNodeClusterConfigInfo(ctx context.Con
|
||||
|
||||
// webp
|
||||
if models.IsNotNull(cluster.Webp) {
|
||||
var webpPolicy = &nodeconfigs.WebPImagePolicy{}
|
||||
var webpPolicy = nodeconfigs.NewWebPImagePolicy()
|
||||
err = json.Unmarshal(cluster.Webp, webpPolicy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result.WebpIsOn = webpPolicy.IsOn
|
||||
result.WebPIsOn = webpPolicy.IsOn
|
||||
} else {
|
||||
result.WebpIsOn = nodeconfigs.DefaultWebPImagePolicy.IsOn
|
||||
result.WebPIsOn = nodeconfigs.DefaultWebPImagePolicy.IsOn
|
||||
}
|
||||
|
||||
// UAM
|
||||
@@ -1247,8 +1248,8 @@ func (this *NodeClusterService) UpdateNodeClusterWebPPolicy(ctx context.Context,
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var webpPolicy = &nodeconfigs.WebPImagePolicy{}
|
||||
err = json.Unmarshal(req.WebpPolicyJSON, webpPolicy)
|
||||
var webpPolicy = nodeconfigs.NewWebPImagePolicy()
|
||||
err = json.Unmarshal(req.WebPPolicyJSON, webpPolicy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -10,6 +10,8 @@ import (
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"golang.org/x/crypto/ssh"
|
||||
"net"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -48,6 +50,25 @@ func (this *NodeGrantService) UpdateNodeGrant(ctx context.Context, req *pb.Updat
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
// 从掩码中恢复密码和私钥
|
||||
grant, err := models.SharedNodeGrantDAO.FindEnabledNodeGrant(tx, req.NodeGrantId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if grant == nil {
|
||||
// do nothing here
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
var maskReg = regexp.MustCompile(`^\*+$`)
|
||||
if len(req.Password) > 0 && maskReg.MatchString(req.Password) {
|
||||
req.Password = grant.Password
|
||||
}
|
||||
|
||||
if len(req.PrivateKey) > 0 && strings.HasSuffix(req.PrivateKey, "********") {
|
||||
req.PrivateKey = grant.PrivateKey
|
||||
}
|
||||
|
||||
err = models.SharedNodeGrantDAO.UpdateGrant(tx, req.NodeGrantId, req.Name, req.Method, req.Username, req.Password, req.PrivateKey, req.Passphrase, req.Description, req.NodeId, req.Su)
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
@@ -248,3 +248,27 @@ func (this *OriginService) FindEnabledOriginConfig(ctx context.Context, req *pb.
|
||||
|
||||
return &pb.FindEnabledOriginConfigResponse{OriginJSON: configData}, nil
|
||||
}
|
||||
|
||||
// UpdateOriginIsOn 修改源站是否启用
|
||||
func (this *OriginService) UpdateOriginIsOn(ctx context.Context, req *pb.UpdateOriginIsOnRequest) (*pb.RPCSuccess, error) {
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
if userId > 0 {
|
||||
err = models.SharedOriginDAO.CheckUserOrigin(tx, userId, req.OriginId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
err = models.SharedOriginDAO.UpdateOriginIsOn(tx, req.OriginId, req.IsOn)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
//go:build !plus
|
||||
// +build !plus
|
||||
|
||||
package services
|
||||
|
||||
@@ -34,6 +33,11 @@ func (this *PlanService) FindEnabledPlan(ctx context.Context, req *pb.FindEnable
|
||||
return &pb.FindEnabledPlanResponse{Plan: nil}, nil
|
||||
}
|
||||
|
||||
// FindBasicPlan 查找套餐基本信息
|
||||
func (this *PlanService) FindBasicPlan(ctx context.Context, req *pb.FindBasicPlanRequest) (*pb.FindBasicPlanResponse, error) {
|
||||
return nil, this.NotImplementedYet()
|
||||
}
|
||||
|
||||
// CountAllEnabledPlans 计算套餐数量
|
||||
func (this *PlanService) CountAllEnabledPlans(ctx context.Context, req *pb.CountAllEnabledPlansRequest) (*pb.RPCCountResponse, error) {
|
||||
return this.SuccessCount(0)
|
||||
@@ -48,3 +52,13 @@ func (this *PlanService) ListEnabledPlans(ctx context.Context, req *pb.ListEnabl
|
||||
func (this *PlanService) SortPlans(ctx context.Context, req *pb.SortPlansRequest) (*pb.RPCSuccess, error) {
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// FindAllAvailablePlans 列出所有可用的套餐
|
||||
func (this *PlanService) FindAllAvailablePlans(ctx context.Context, req *pb.FindAllAvailablePlansRequest) (*pb.FindAllAvailablePlansResponse, error) {
|
||||
return nil, this.NotImplementedYet()
|
||||
}
|
||||
|
||||
// FindAllAvailableBasicPlans 列出所有可用的套餐的基本信息
|
||||
func (this *PlanService) FindAllAvailableBasicPlans(ctx context.Context, req *pb.FindAllAvailableBasicPlansRequest) (*pb.FindAllAvailableBasicPlansResponse, error) {
|
||||
return nil, this.NotImplementedYet()
|
||||
}
|
||||
|
||||
@@ -88,9 +88,9 @@ func (this *RegionProvinceService) FindAllRegionProvincesWithRegionCountryId(ctx
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var result = []*pb.RegionProvince{}
|
||||
var pbProvinces = []*pb.RegionProvince{}
|
||||
for _, province := range provinces {
|
||||
result = append(result, &pb.RegionProvince{
|
||||
pbProvinces = append(pbProvinces, &pb.RegionProvince{
|
||||
Id: int64(province.ValueId),
|
||||
Name: province.Name,
|
||||
Codes: province.DecodeCodes(),
|
||||
@@ -101,7 +101,61 @@ func (this *RegionProvinceService) FindAllRegionProvincesWithRegionCountryId(ctx
|
||||
}
|
||||
|
||||
return &pb.FindAllRegionProvincesWithRegionCountryIdResponse{
|
||||
RegionProvinces: result,
|
||||
RegionProvinces: pbProvinces,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// FindAllRegionProvinces 查找所有国家|地区的所有省份
|
||||
func (this *RegionProvinceService) FindAllRegionProvinces(ctx context.Context, req *pb.FindAllRegionProvincesRequest) (*pb.FindAllRegionProvincesResponse, error) {
|
||||
_, _, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
provinces, err := regions.SharedRegionProvinceDAO.FindAllEnabledProvinces(tx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var pbProvinces = []*pb.RegionProvince{}
|
||||
var countryRouteCodeCache = map[int64]string{} // countryId => routeCode
|
||||
for _, province := range provinces {
|
||||
// 国家|地区ID
|
||||
var countryId = int64(province.CountryId)
|
||||
if countryId <= 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
// 国家|地区线路
|
||||
countryRouteCode, ok := countryRouteCodeCache[countryId]
|
||||
if !ok {
|
||||
countryRouteCode, err = regions.SharedRegionCountryDAO.FindRegionCountryRouteCode(tx, countryId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
countryRouteCodeCache[countryId] = countryRouteCode
|
||||
}
|
||||
if len(countryRouteCode) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
pbProvinces = append(pbProvinces, &pb.RegionProvince{
|
||||
Id: int64(province.ValueId),
|
||||
Name: province.Name,
|
||||
Codes: province.DecodeCodes(),
|
||||
CustomName: province.CustomName,
|
||||
CustomCodes: province.DecodeCustomCodes(),
|
||||
DisplayName: province.DisplayName(),
|
||||
RegionCountryId: countryId,
|
||||
RegionCountry: &pb.RegionCountry{
|
||||
Id: countryId,
|
||||
RouteCode: countryRouteCode,
|
||||
},
|
||||
})
|
||||
}
|
||||
return &pb.FindAllRegionProvincesResponse{
|
||||
RegionProvinces: pbProvinces,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -181,7 +181,7 @@ func (this *ServerService) CreateServer(ctx context.Context, req *pb.CreateServe
|
||||
}
|
||||
}
|
||||
|
||||
serverId, err := models.SharedServerDAO.CreateServer(tx, req.AdminId, req.UserId, req.Type, req.Name, req.Description, serverNamesJSON, isAuditing, auditingServerNamesJSON, req.HttpJSON, req.HttpsJSON, req.TcpJSON, req.TlsJSON, req.UnixJSON, req.UdpJSON, req.WebId, req.ReverseProxyJSON, req.NodeClusterId, req.IncludeNodesJSON, req.ExcludeNodesJSON, req.ServerGroupIds, req.UserPlanId)
|
||||
serverId, err := models.SharedServerDAO.CreateServer(tx, req.AdminId, req.UserId, req.Type, req.Name, req.Description, serverNamesJSON, isAuditing, auditingServerNamesJSON, req.HttpJSON, req.HttpsJSON, req.TcpJSON, req.TlsJSON, req.UdpJSON, req.WebId, req.ReverseProxyJSON, req.NodeClusterId, req.IncludeNodesJSON, req.ExcludeNodesJSON, req.ServerGroupIds, req.UserPlanId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -451,7 +451,7 @@ func (this *ServerService) CreateBasicHTTPServer(ctx context.Context, req *pb.Cr
|
||||
}
|
||||
|
||||
// finally, we create ...
|
||||
serverId, err := models.SharedServerDAO.CreateServer(tx, adminId, req.UserId, serverconfigs.ServerTypeHTTPProxy, req.Domains[0], "", serverNamesJSON, isAuditing, auditingServerNamesJSON, httpJSON, httpsJSON, nil, nil, nil, nil, webId, reverseProxyJSON, req.NodeClusterId, nil, nil, nil, 0)
|
||||
serverId, err := models.SharedServerDAO.CreateServer(tx, adminId, req.UserId, serverconfigs.ServerTypeHTTPProxy, req.Domains[0], "", serverNamesJSON, isAuditing, auditingServerNamesJSON, httpJSON, httpsJSON, nil, nil, nil, webId, reverseProxyJSON, req.NodeClusterId, nil, nil, nil, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -687,7 +687,7 @@ func (this *ServerService) CreateBasicTCPServer(ctx context.Context, req *pb.Cre
|
||||
}
|
||||
|
||||
// finally, we create ...
|
||||
serverId, err := models.SharedServerDAO.CreateServer(tx, adminId, req.UserId, serverconfigs.ServerTypeTCPProxy, "TCP Service", "", nil, false, nil, nil, nil, tcpJSON, tlsJSON, nil, nil, 0, reverseProxyJSON, req.NodeClusterId, nil, nil, nil, 0)
|
||||
serverId, err := models.SharedServerDAO.CreateServer(tx, adminId, req.UserId, serverconfigs.ServerTypeTCPProxy, "TCP Service", "", nil, false, nil, nil, nil, tcpJSON, tlsJSON, nil, 0, reverseProxyJSON, req.NodeClusterId, nil, nil, nil, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -695,6 +695,218 @@ func (this *ServerService) CreateBasicTCPServer(ctx context.Context, req *pb.Cre
|
||||
return &pb.CreateBasicTCPServerResponse{ServerId: serverId}, nil
|
||||
}
|
||||
|
||||
// AddServerOrigin 为网站添加源站
|
||||
func (this *ServerService) AddServerOrigin(ctx context.Context, req *pb.AddServerOriginRequest) (*pb.RPCSuccess, error) {
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if req.ServerId <= 0 {
|
||||
return nil, errors.New("require 'serverId'")
|
||||
}
|
||||
if req.OriginId <= 0 {
|
||||
return nil, errors.New("require 'originId'")
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
// check user
|
||||
if userId > 0 {
|
||||
err = models.SharedServerDAO.CheckUserServer(tx, userId, req.ServerId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = models.SharedOriginDAO.CheckUserOrigin(tx, userId, req.OriginId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
// check server
|
||||
existsServer, err := models.SharedServerDAO.ExistsServer(tx, req.ServerId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !existsServer {
|
||||
return nil, errors.New("server '" + types.String(req.ServerId) + "' not found")
|
||||
}
|
||||
|
||||
// check origin
|
||||
existsOrigin, err := models.SharedOriginDAO.ExistsOrigin(tx, req.OriginId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !existsOrigin {
|
||||
return nil, errors.New("origin '" + types.String(req.OriginId) + "' not found")
|
||||
}
|
||||
}
|
||||
|
||||
reverseProxyRef, err := models.SharedServerDAO.FindServerReverseProxyRef(tx, req.ServerId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if reverseProxyRef == nil || reverseProxyRef.ReverseProxyId <= 0 {
|
||||
reverseProxyId, err := models.SharedServerDAO.CreateServerReverseProxyRef(tx, userId, req.ServerId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
reverseProxyRef = &serverconfigs.ReverseProxyRef{
|
||||
IsPrior: false,
|
||||
IsOn: true,
|
||||
ReverseProxyId: reverseProxyId,
|
||||
}
|
||||
}
|
||||
|
||||
reverseProxy, err := models.SharedReverseProxyDAO.FindEnabledReverseProxy(tx, reverseProxyRef.ReverseProxyId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if reverseProxy == nil {
|
||||
return nil, errors.New("can not found reverse proxy")
|
||||
}
|
||||
|
||||
if req.IsPrimary {
|
||||
var refs = reverseProxy.DecodePrimaryOrigins()
|
||||
refs = append(refs, &serverconfigs.OriginRef{
|
||||
IsOn: true,
|
||||
OriginId: req.OriginId,
|
||||
})
|
||||
refsJSON, err := json.Marshal(refs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = models.SharedReverseProxyDAO.UpdateReverseProxyPrimaryOrigins(tx, int64(reverseProxy.Id), refsJSON)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
var refs = reverseProxy.DecodeBackupOrigins()
|
||||
refs = append(refs, &serverconfigs.OriginRef{
|
||||
IsOn: true,
|
||||
OriginId: req.OriginId,
|
||||
})
|
||||
refsJSON, err := json.Marshal(refs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = models.SharedReverseProxyDAO.UpdateReverseProxyBackupOrigins(tx, int64(reverseProxy.Id), refsJSON)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// DeleteServerOrigin 从网站中删除某个源站
|
||||
func (this *ServerService) DeleteServerOrigin(ctx context.Context, req *pb.DeleteServerOriginRequest) (*pb.RPCSuccess, error) {
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if req.ServerId <= 0 {
|
||||
return nil, errors.New("require 'serverId'")
|
||||
}
|
||||
if req.OriginId <= 0 {
|
||||
return nil, errors.New("require 'originId'")
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
// check user
|
||||
if userId > 0 {
|
||||
err = models.SharedServerDAO.CheckUserServer(tx, userId, req.ServerId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = models.SharedOriginDAO.CheckUserOrigin(tx, userId, req.OriginId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
// check server
|
||||
existsServer, err := models.SharedServerDAO.ExistsServer(tx, req.ServerId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !existsServer {
|
||||
return nil, errors.New("server '" + types.String(req.ServerId) + "' not found")
|
||||
}
|
||||
|
||||
// check origin
|
||||
existsOrigin, err := models.SharedOriginDAO.ExistsOrigin(tx, req.OriginId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !existsOrigin {
|
||||
return nil, errors.New("origin '" + types.String(req.OriginId) + "' not found")
|
||||
}
|
||||
}
|
||||
|
||||
reverseProxyRef, err := models.SharedServerDAO.FindServerReverseProxyRef(tx, req.ServerId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if reverseProxyRef == nil || reverseProxyRef.ReverseProxyId <= 0 {
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
reverseProxy, err := models.SharedReverseProxyDAO.FindEnabledReverseProxy(tx, reverseProxyRef.ReverseProxyId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if reverseProxy == nil {
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
var primaryOrigins = reverseProxy.DecodePrimaryOrigins()
|
||||
var newPrimaryOrigins = []*serverconfigs.OriginRef{}
|
||||
var found = false
|
||||
for _, origin := range primaryOrigins {
|
||||
if origin.OriginId == req.OriginId {
|
||||
found = true
|
||||
continue
|
||||
}
|
||||
newPrimaryOrigins = append(newPrimaryOrigins, origin)
|
||||
}
|
||||
if found {
|
||||
newPrimaryOriginsJSON, err := json.Marshal(newPrimaryOrigins)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = models.SharedReverseProxyDAO.UpdateReverseProxyPrimaryOrigins(tx, int64(reverseProxy.Id), newPrimaryOriginsJSON)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
var backupOrigins = reverseProxy.DecodeBackupOrigins()
|
||||
var newBackupOrigins = []*serverconfigs.OriginRef{}
|
||||
found = false
|
||||
for _, origin := range backupOrigins {
|
||||
if origin.OriginId == req.OriginId {
|
||||
found = true
|
||||
continue
|
||||
}
|
||||
newBackupOrigins = append(newBackupOrigins, origin)
|
||||
}
|
||||
if found {
|
||||
newBackupOriginsJSON, err := json.Marshal(newBackupOrigins)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = models.SharedReverseProxyDAO.UpdateReverseProxyBackupOrigins(tx, int64(reverseProxy.Id), newBackupOriginsJSON)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// UpdateServerBasic 修改服务基本信息
|
||||
func (this *ServerService) UpdateServerBasic(ctx context.Context, req *pb.UpdateServerBasicRequest) (*pb.RPCSuccess, error) {
|
||||
// 校验请求
|
||||
@@ -904,29 +1116,6 @@ func (this *ServerService) UpdateServerTLS(ctx context.Context, req *pb.UpdateSe
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// UpdateServerUnix 修改Unix服务
|
||||
func (this *ServerService) UpdateServerUnix(ctx context.Context, req *pb.UpdateServerUnixRequest) (*pb.RPCSuccess, error) {
|
||||
// 校验请求
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if req.ServerId <= 0 {
|
||||
return nil, errors.New("invalid serverId")
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
// 修改配置
|
||||
err = models.SharedServerDAO.UpdateServerUnix(tx, req.ServerId, req.UnixJSON)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// UpdateServerUDP 修改UDP服务
|
||||
func (this *ServerService) UpdateServerUDP(ctx context.Context, req *pb.UpdateServerUDPRequest) (*pb.RPCSuccess, error) {
|
||||
// 校验请求
|
||||
@@ -1001,7 +1190,7 @@ func (this *ServerService) UpdateServerReverseProxy(ctx context.Context, req *pb
|
||||
}
|
||||
|
||||
// 修改配置
|
||||
err = models.SharedServerDAO.UpdateServerReverseProxy(tx, req.ServerId, req.ReverseProxyJSON)
|
||||
err = models.SharedServerDAO.UpdateServerReverseProxyRef(tx, req.ServerId, req.ReverseProxyJSON)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1433,7 +1622,6 @@ func (this *ServerService) ListEnabledServersMatch(ctx context.Context, req *pb.
|
||||
HttpsJSON: server.Https,
|
||||
TcpJSON: server.Tcp,
|
||||
TlsJSON: server.Tls,
|
||||
UnixJSON: server.Unix,
|
||||
UdpJSON: server.Udp,
|
||||
IncludeNodes: server.IncludeNodes,
|
||||
ExcludeNodes: server.ExcludeNodes,
|
||||
@@ -1462,7 +1650,7 @@ func (this *ServerService) ListEnabledServersMatch(ctx context.Context, req *pb.
|
||||
return &pb.ListEnabledServersMatchResponse{Servers: result}, nil
|
||||
}
|
||||
|
||||
// DeleteServer 禁用某服务
|
||||
// DeleteServer 删除某网站
|
||||
func (this *ServerService) DeleteServer(ctx context.Context, req *pb.DeleteServerRequest) (*pb.RPCSuccess, error) {
|
||||
// 校验请求
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
@@ -1479,7 +1667,7 @@ func (this *ServerService) DeleteServer(ctx context.Context, req *pb.DeleteServe
|
||||
}
|
||||
}
|
||||
|
||||
// 禁用服务
|
||||
// 禁用网站
|
||||
err = models.SharedServerDAO.DisableServer(tx, req.ServerId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -1488,6 +1676,37 @@ func (this *ServerService) DeleteServer(ctx context.Context, req *pb.DeleteServe
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// DeleteServers 删除一组网站
|
||||
func (this *ServerService) DeleteServers(ctx context.Context, req *pb.DeleteServersRequest) (*pb.RPCSuccess, error) {
|
||||
// 校验请求
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
for _, serverId := range req.ServerIds {
|
||||
if serverId <= 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
// 检查权限
|
||||
if userId > 0 {
|
||||
err = models.SharedServerDAO.CheckUserServer(tx, userId, serverId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// 禁用网站
|
||||
err = models.SharedServerDAO.DisableServer(tx, serverId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// FindEnabledServer 查找单个服务
|
||||
func (this *ServerService) FindEnabledServer(ctx context.Context, req *pb.FindEnabledServerRequest) (*pb.FindEnabledServerResponse, error) {
|
||||
// 校验请求
|
||||
@@ -1587,7 +1806,6 @@ func (this *ServerService) FindEnabledServer(ctx context.Context, req *pb.FindEn
|
||||
HttpsJSON: server.Https,
|
||||
TcpJSON: server.Tcp,
|
||||
TlsJSON: server.Tls,
|
||||
UnixJSON: server.Unix,
|
||||
UdpJSON: server.Udp,
|
||||
WebId: int64(server.WebId),
|
||||
ReverseProxyJSON: server.ReverseProxy,
|
||||
@@ -1674,7 +1892,7 @@ func (this *ServerService) FindAndInitServerReverseProxyConfig(ctx context.Conte
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
reverseProxyRef, err := models.SharedServerDAO.FindReverseProxyRef(tx, req.ServerId)
|
||||
reverseProxyRef, err := models.SharedServerDAO.FindServerReverseProxyRef(tx, req.ServerId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1693,7 +1911,7 @@ func (this *ServerService) FindAndInitServerReverseProxyConfig(ctx context.Conte
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = models.SharedServerDAO.UpdateServerReverseProxy(tx, req.ServerId, refJSON)
|
||||
err = models.SharedServerDAO.UpdateServerReverseProxyRef(tx, req.ServerId, refJSON)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -2414,7 +2632,7 @@ func (this *ServerService) UploadServerHTTPRequestStat(ctx context.Context, req
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// CheckServerNameDuplicationInNodeCluster 检查域名是否已经存在
|
||||
// CheckServerNameDuplicationInNodeCluster 检查域名是否在集群中已经存在
|
||||
func (this *ServerService) CheckServerNameDuplicationInNodeCluster(ctx context.Context, req *pb.CheckServerNameDuplicationInNodeClusterRequest) (*pb.CheckServerNameDuplicationInNodeClusterResponse, error) {
|
||||
_, _, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
@@ -2441,6 +2659,47 @@ func (this *ServerService) CheckServerNameDuplicationInNodeCluster(ctx context.C
|
||||
return &pb.CheckServerNameDuplicationInNodeClusterResponse{DuplicatedServerNames: duplicatedServerNames}, nil
|
||||
}
|
||||
|
||||
// CheckServerNameInServer 检查域名是否在网站中已经绑定
|
||||
func (this *ServerService) CheckServerNameInServer(ctx context.Context, req *pb.CheckServerNameInServerRequest) (*pb.CheckServerNameInServerResponse, error) {
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if req.ServerId <= 0 {
|
||||
return nil, errors.New("invalid serverId '" + types.String(req.ServerId) + "'")
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
if userId > 0 {
|
||||
err = models.SharedServerDAO.CheckUserServer(tx, userId, req.ServerId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if len(req.ServerName) == 0 {
|
||||
return &pb.CheckServerNameInServerResponse{
|
||||
Exists: false,
|
||||
}, nil
|
||||
}
|
||||
|
||||
serverNamesJSON, _, _, _, _, err := models.SharedServerDAO.FindServerServerNames(tx, req.ServerId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var serverNames = []*serverconfigs.ServerNameConfig{}
|
||||
err = json.Unmarshal(serverNamesJSON, &serverNames)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &pb.CheckServerNameInServerResponse{
|
||||
Exists: lists.ContainsString(serverconfigs.PlainServerNames(serverNames), req.ServerName),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// FindLatestServers 查找最近访问的服务
|
||||
func (this *ServerService) FindLatestServers(ctx context.Context, req *pb.FindLatestServersRequest) (*pb.FindLatestServersResponse, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
@@ -2849,6 +3108,7 @@ func (this *ServerService) FindServerUserPlan(ctx context.Context, req *pb.FindS
|
||||
User: nil,
|
||||
Plan: &pb.Plan{
|
||||
Id: int64(plan.Id),
|
||||
IsOn: plan.IsOn,
|
||||
Name: plan.Name,
|
||||
PriceType: plan.PriceType,
|
||||
TrafficPriceJSON: plan.TrafficPrice,
|
||||
@@ -2856,6 +3116,8 @@ func (this *ServerService) FindServerUserPlan(ctx context.Context, req *pb.FindS
|
||||
TotalServers: types.Int32(plan.TotalServers),
|
||||
TotalServerNames: types.Int32(plan.TotalServerNames),
|
||||
TotalServerNamesPerServer: types.Int32(plan.TotalServerNamesPerServer),
|
||||
HasFullFeatures: plan.HasFullFeatures,
|
||||
FeaturesJSON: plan.Features,
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user