Compare commits
35 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 |
@@ -115,7 +115,11 @@ function build() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# building api node
|
# 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
|
# delete hidden files
|
||||||
find "$DIST" -name ".DS_Store" -delete
|
find "$DIST" -name ".DS_Store" -delete
|
||||||
|
|||||||
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")
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
package teaconst
|
package teaconst
|
||||||
|
|
||||||
const (
|
const (
|
||||||
Version = "1.3.2"
|
Version = "1.3.4"
|
||||||
|
|
||||||
ProductName = "Edge API"
|
ProductName = "Edge API"
|
||||||
ProcessName = "edge-api"
|
ProcessName = "edge-api"
|
||||||
@@ -20,7 +20,7 @@ const (
|
|||||||
|
|
||||||
// 其他节点版本号,用来检测是否有需要升级的节点
|
// 其他节点版本号,用来检测是否有需要升级的节点
|
||||||
|
|
||||||
NodeVersion = "1.3.2"
|
NodeVersion = "1.3.4"
|
||||||
|
|
||||||
// SQLVersion SQL版本号
|
// SQLVersion SQL版本号
|
||||||
SQLVersion = "11"
|
SQLVersion = "11"
|
||||||
|
|||||||
@@ -130,6 +130,19 @@ func (this *AdminDAO) FindAdminIdWithUsername(tx *dbs.Tx, username string) (int6
|
|||||||
return int64(one.(*Admin).Id), nil
|
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 更改管理员密码
|
// UpdateAdminPassword 更改管理员密码
|
||||||
func (this *AdminDAO) UpdateAdminPassword(tx *dbs.Tx, adminId int64, password string) error {
|
func (this *AdminDAO) UpdateAdminPassword(tx *dbs.Tx, adminId int64, password string) error {
|
||||||
if adminId <= 0 {
|
if adminId <= 0 {
|
||||||
@@ -212,7 +225,7 @@ func (this *AdminDAO) UpdateAdmin(tx *dbs.Tx, adminId int64, username string, ca
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CheckAdminUsername 检查用户名是否存在
|
// CheckAdminUsername 检查管理员用户名是否存在
|
||||||
func (this *AdminDAO) CheckAdminUsername(tx *dbs.Tx, adminId int64, username string) (bool, error) {
|
func (this *AdminDAO) CheckAdminUsername(tx *dbs.Tx, adminId int64, username string) (bool, error) {
|
||||||
query := this.Query(tx).
|
query := this.Query(tx).
|
||||||
State(AdminStateEnabled).
|
State(AdminStateEnabled).
|
||||||
|
|||||||
@@ -149,6 +149,14 @@ func (this *HTTPFirewallPolicyDAO) CreateFirewallPolicy(tx *dbs.Tx, userId int64
|
|||||||
}
|
}
|
||||||
op.BlockOptions = blockOptionsJSON
|
op.BlockOptions = blockOptionsJSON
|
||||||
|
|
||||||
|
// page options
|
||||||
|
var pageOptions = firewallconfigs.DefaultHTTPFirewallPageAction()
|
||||||
|
pageOptionsJSON, err := json.Marshal(pageOptions)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
op.PageOptions = pageOptionsJSON
|
||||||
|
|
||||||
// captcha options
|
// captcha options
|
||||||
var captchaOptions = firewallconfigs.DefaultHTTPFirewallCaptchaAction()
|
var captchaOptions = firewallconfigs.DefaultHTTPFirewallCaptchaAction()
|
||||||
captchaOptionsJSON, err := json.Marshal(captchaOptions)
|
captchaOptionsJSON, err := json.Marshal(captchaOptions)
|
||||||
@@ -313,6 +321,7 @@ func (this *HTTPFirewallPolicyDAO) UpdateFirewallPolicy(tx *dbs.Tx,
|
|||||||
inboundJSON []byte,
|
inboundJSON []byte,
|
||||||
outboundJSON []byte,
|
outboundJSON []byte,
|
||||||
blockOptionsJSON []byte,
|
blockOptionsJSON []byte,
|
||||||
|
pageOptionsJSON []byte,
|
||||||
captchaOptionsJSON []byte,
|
captchaOptionsJSON []byte,
|
||||||
mode firewallconfigs.FirewallMode,
|
mode firewallconfigs.FirewallMode,
|
||||||
useLocalFirewall bool,
|
useLocalFirewall bool,
|
||||||
@@ -343,6 +352,9 @@ func (this *HTTPFirewallPolicyDAO) UpdateFirewallPolicy(tx *dbs.Tx,
|
|||||||
if IsNotNull(blockOptionsJSON) {
|
if IsNotNull(blockOptionsJSON) {
|
||||||
op.BlockOptions = blockOptionsJSON
|
op.BlockOptions = blockOptionsJSON
|
||||||
}
|
}
|
||||||
|
if IsNotNull(pageOptionsJSON) {
|
||||||
|
op.PageOptions = pageOptionsJSON
|
||||||
|
}
|
||||||
if IsNotNull(captchaOptionsJSON) {
|
if IsNotNull(captchaOptionsJSON) {
|
||||||
op.CaptchaOptions = captchaOptionsJSON
|
op.CaptchaOptions = captchaOptionsJSON
|
||||||
}
|
}
|
||||||
@@ -524,6 +536,16 @@ func (this *HTTPFirewallPolicyDAO) ComposeFirewallPolicy(tx *dbs.Tx, policyId in
|
|||||||
config.BlockOptions = blockAction
|
config.BlockOptions = blockAction
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Page动作配置
|
||||||
|
if IsNotNull(policy.PageOptions) {
|
||||||
|
var pageAction = firewallconfigs.DefaultHTTPFirewallPageAction()
|
||||||
|
err = json.Unmarshal(policy.PageOptions, pageAction)
|
||||||
|
if err != nil {
|
||||||
|
return config, err
|
||||||
|
}
|
||||||
|
config.PageOptions = pageAction
|
||||||
|
}
|
||||||
|
|
||||||
// Captcha动作配置
|
// Captcha动作配置
|
||||||
if IsNotNull(policy.CaptchaOptions) {
|
if IsNotNull(policy.CaptchaOptions) {
|
||||||
var captchaAction = &firewallconfigs.HTTPFirewallCaptchaAction{}
|
var captchaAction = &firewallconfigs.HTTPFirewallCaptchaAction{}
|
||||||
|
|||||||
@@ -16,8 +16,9 @@ const (
|
|||||||
HTTPFirewallPolicyField_Description dbs.FieldName = "description" // 描述
|
HTTPFirewallPolicyField_Description dbs.FieldName = "description" // 描述
|
||||||
HTTPFirewallPolicyField_Inbound dbs.FieldName = "inbound" // 入站规则
|
HTTPFirewallPolicyField_Inbound dbs.FieldName = "inbound" // 入站规则
|
||||||
HTTPFirewallPolicyField_Outbound dbs.FieldName = "outbound" // 出站规则
|
HTTPFirewallPolicyField_Outbound dbs.FieldName = "outbound" // 出站规则
|
||||||
HTTPFirewallPolicyField_BlockOptions dbs.FieldName = "blockOptions" // BLOCK选项
|
HTTPFirewallPolicyField_BlockOptions dbs.FieldName = "blockOptions" // BLOCK动作选项
|
||||||
HTTPFirewallPolicyField_CaptchaOptions dbs.FieldName = "captchaOptions" // 验证码选项
|
HTTPFirewallPolicyField_PageOptions dbs.FieldName = "pageOptions" // PAGE动作选项
|
||||||
|
HTTPFirewallPolicyField_CaptchaOptions dbs.FieldName = "captchaOptions" // 验证码动作选项
|
||||||
HTTPFirewallPolicyField_Mode dbs.FieldName = "mode" // 模式
|
HTTPFirewallPolicyField_Mode dbs.FieldName = "mode" // 模式
|
||||||
HTTPFirewallPolicyField_UseLocalFirewall dbs.FieldName = "useLocalFirewall" // 是否自动使用本地防火墙
|
HTTPFirewallPolicyField_UseLocalFirewall dbs.FieldName = "useLocalFirewall" // 是否自动使用本地防火墙
|
||||||
HTTPFirewallPolicyField_SynFlood dbs.FieldName = "synFlood" // SynFlood防御设置
|
HTTPFirewallPolicyField_SynFlood dbs.FieldName = "synFlood" // SynFlood防御设置
|
||||||
@@ -42,8 +43,9 @@ type HTTPFirewallPolicy struct {
|
|||||||
Description string `field:"description"` // 描述
|
Description string `field:"description"` // 描述
|
||||||
Inbound dbs.JSON `field:"inbound"` // 入站规则
|
Inbound dbs.JSON `field:"inbound"` // 入站规则
|
||||||
Outbound dbs.JSON `field:"outbound"` // 出站规则
|
Outbound dbs.JSON `field:"outbound"` // 出站规则
|
||||||
BlockOptions dbs.JSON `field:"blockOptions"` // BLOCK选项
|
BlockOptions dbs.JSON `field:"blockOptions"` // BLOCK动作选项
|
||||||
CaptchaOptions dbs.JSON `field:"captchaOptions"` // 验证码选项
|
PageOptions dbs.JSON `field:"pageOptions"` // PAGE动作选项
|
||||||
|
CaptchaOptions dbs.JSON `field:"captchaOptions"` // 验证码动作选项
|
||||||
Mode string `field:"mode"` // 模式
|
Mode string `field:"mode"` // 模式
|
||||||
UseLocalFirewall uint8 `field:"useLocalFirewall"` // 是否自动使用本地防火墙
|
UseLocalFirewall uint8 `field:"useLocalFirewall"` // 是否自动使用本地防火墙
|
||||||
SynFlood dbs.JSON `field:"synFlood"` // SynFlood防御设置
|
SynFlood dbs.JSON `field:"synFlood"` // SynFlood防御设置
|
||||||
@@ -67,8 +69,9 @@ type HTTPFirewallPolicyOperator struct {
|
|||||||
Description any // 描述
|
Description any // 描述
|
||||||
Inbound any // 入站规则
|
Inbound any // 入站规则
|
||||||
Outbound any // 出站规则
|
Outbound any // 出站规则
|
||||||
BlockOptions any // BLOCK选项
|
BlockOptions any // BLOCK动作选项
|
||||||
CaptchaOptions any // 验证码选项
|
PageOptions any // PAGE动作选项
|
||||||
|
CaptchaOptions any // 验证码动作选项
|
||||||
Mode any // 模式
|
Mode any // 模式
|
||||||
UseLocalFirewall any // 是否自动使用本地防火墙
|
UseLocalFirewall any // 是否自动使用本地防火墙
|
||||||
SynFlood any // SynFlood防御设置
|
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 {
|
if cacheMap != nil {
|
||||||
cacheMap.Put(cacheKey, config)
|
cacheMap.Put(cacheKey, config)
|
||||||
}
|
}
|
||||||
@@ -1454,7 +1466,7 @@ func (this *HTTPWebDAO) UpdateWebReferers(tx *dbs.Tx, webId int64, referersConfi
|
|||||||
return this.NotifyUpdate(tx, webId)
|
return this.NotifyUpdate(tx, webId)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindWebReferers 查找服务的防盗链配置
|
// FindWebReferers 查找网站的防盗链配置
|
||||||
func (this *HTTPWebDAO) FindWebReferers(tx *dbs.Tx, webId int64) ([]byte, error) {
|
func (this *HTTPWebDAO) FindWebReferers(tx *dbs.Tx, webId int64) ([]byte, error) {
|
||||||
return this.Query(tx).
|
return this.Query(tx).
|
||||||
Pk(webId).
|
Pk(webId).
|
||||||
@@ -1464,6 +1476,10 @@ func (this *HTTPWebDAO) FindWebReferers(tx *dbs.Tx, webId int64) ([]byte, error)
|
|||||||
|
|
||||||
// UpdateWebUserAgent 修改User-Agent设置
|
// UpdateWebUserAgent 修改User-Agent设置
|
||||||
func (this *HTTPWebDAO) UpdateWebUserAgent(tx *dbs.Tx, webId int64, userAgentConfig *serverconfigs.UserAgentConfig) error {
|
func (this *HTTPWebDAO) UpdateWebUserAgent(tx *dbs.Tx, webId int64, userAgentConfig *serverconfigs.UserAgentConfig) error {
|
||||||
|
if webId <= 0 {
|
||||||
|
return errors.New("require 'webId'")
|
||||||
|
}
|
||||||
|
|
||||||
if userAgentConfig == nil {
|
if userAgentConfig == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ const (
|
|||||||
HTTPWebField_Referers dbs.FieldName = "referers" // 防盗链设置
|
HTTPWebField_Referers dbs.FieldName = "referers" // 防盗链设置
|
||||||
HTTPWebField_UserAgent dbs.FieldName = "userAgent" // UserAgent设置
|
HTTPWebField_UserAgent dbs.FieldName = "userAgent" // UserAgent设置
|
||||||
HTTPWebField_Optimization dbs.FieldName = "optimization" // 页面优化配置
|
HTTPWebField_Optimization dbs.FieldName = "optimization" // 页面优化配置
|
||||||
|
HTTPWebField_Hls dbs.FieldName = "hls" // HLS设置
|
||||||
)
|
)
|
||||||
|
|
||||||
// HTTPWeb HTTP Web
|
// HTTPWeb HTTP Web
|
||||||
@@ -83,6 +84,7 @@ type HTTPWeb struct {
|
|||||||
Referers dbs.JSON `field:"referers"` // 防盗链设置
|
Referers dbs.JSON `field:"referers"` // 防盗链设置
|
||||||
UserAgent dbs.JSON `field:"userAgent"` // UserAgent设置
|
UserAgent dbs.JSON `field:"userAgent"` // UserAgent设置
|
||||||
Optimization dbs.JSON `field:"optimization"` // 页面优化配置
|
Optimization dbs.JSON `field:"optimization"` // 页面优化配置
|
||||||
|
Hls dbs.JSON `field:"hls"` // HLS设置
|
||||||
}
|
}
|
||||||
|
|
||||||
type HTTPWebOperator struct {
|
type HTTPWebOperator struct {
|
||||||
@@ -124,6 +126,7 @@ type HTTPWebOperator struct {
|
|||||||
Referers any // 防盗链设置
|
Referers any // 防盗链设置
|
||||||
UserAgent any // UserAgent设置
|
UserAgent any // UserAgent设置
|
||||||
Optimization any // 页面优化配置
|
Optimization any // 页面优化配置
|
||||||
|
Hls any // HLS设置
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHTTPWebOperator() *HTTPWebOperator {
|
func NewHTTPWebOperator() *HTTPWebOperator {
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import (
|
|||||||
"github.com/iwind/TeaGo/types"
|
"github.com/iwind/TeaGo/types"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -449,6 +450,14 @@ func (this *IPLibraryFileDAO) GenerateIPLibrary(tx *dbs.Tx, libraryFileId int64)
|
|||||||
for _, province := range dbProvinces {
|
for _, province := range dbProvinces {
|
||||||
for _, code := range province.AllCodes() {
|
for _, code := range province.AllCodes() {
|
||||||
provinceMap[types.String(province.CountryId)+"_"+code] = int64(province.ValueId)
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -135,40 +135,16 @@ func (this *LoginSessionDAO) WriteSessionValue(tx *dbs.Tx, sid string, key strin
|
|||||||
sessionOp.UserId = userId
|
sessionOp.UserId = userId
|
||||||
|
|
||||||
if isNewSession {
|
if isNewSession {
|
||||||
// 删除此用户之前创建的SESSION,防止单个用户SESSION过多
|
// 删除此用户之前创建的SESSION,不再保存以往的SESSION,避免安全问题
|
||||||
// TODO 将来改成按照活跃时间排序
|
err = this.Query(tx).
|
||||||
const maxSessionsPerUser = 10
|
|
||||||
oldOnes, err := this.Query(tx).
|
|
||||||
ResultPk().
|
ResultPk().
|
||||||
Attr("adminId", adminId).
|
Attr("adminId", adminId).
|
||||||
Attr("userId", userId).
|
Attr("userId", userId).
|
||||||
Asc("createdAt").
|
Neq("sid", sid).
|
||||||
FindAll()
|
DeleteQuickly()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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/goman"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
|
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||||
"github.com/go-sql-driver/mysql"
|
|
||||||
_ "github.com/go-sql-driver/mysql"
|
_ "github.com/go-sql-driver/mysql"
|
||||||
"github.com/iwind/TeaGo/Tea"
|
"github.com/iwind/TeaGo/Tea"
|
||||||
"github.com/iwind/TeaGo/dbs"
|
"github.com/iwind/TeaGo/dbs"
|
||||||
@@ -759,10 +758,5 @@ func (this *MetricStatDAO) canIgnore(err error) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 忽略 Error 1213: Deadlock found 错误
|
// 忽略 Error 1213: Deadlock found 错误
|
||||||
mysqlErr, ok := err.(*mysql.MySQLError)
|
return CheckSQLErrCode(err, 1213)
|
||||||
if ok && mysqlErr.Number == 1213 {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import (
|
|||||||
"github.com/TeaOSLab/EdgeAPI/internal/goman"
|
"github.com/TeaOSLab/EdgeAPI/internal/goman"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
|
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||||
"github.com/go-sql-driver/mysql"
|
|
||||||
_ "github.com/go-sql-driver/mysql"
|
_ "github.com/go-sql-driver/mysql"
|
||||||
"github.com/iwind/TeaGo/Tea"
|
"github.com/iwind/TeaGo/Tea"
|
||||||
"github.com/iwind/TeaGo/dbs"
|
"github.com/iwind/TeaGo/dbs"
|
||||||
@@ -289,10 +288,5 @@ func (this *MetricSumStatDAO) canIgnore(err error) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 忽略 Error 1213: Deadlock found 错误
|
// 忽略 Error 1213: Deadlock found 错误
|
||||||
mysqlErr, ok := err.(*mysql.MySQLError)
|
return CheckSQLErrCode(err, 1213)
|
||||||
if ok && mysqlErr.Number == 1213 {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -264,13 +264,22 @@ func (this *NodeClusterDAO) CountAllEnabledClusters(tx *dbs.Tx, keyword string)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ListEnabledClusters 列出单页集群
|
// 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).
|
var query = this.Query(tx).
|
||||||
State(NodeClusterStateEnabled)
|
State(NodeClusterStateEnabled)
|
||||||
if len(keyword) > 0 {
|
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)))").
|
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))
|
Param("keyword", dbutils.QuoteLike(keyword))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if idDesc {
|
||||||
|
query.DescPk()
|
||||||
|
} else if idAsc {
|
||||||
|
query.AscPk()
|
||||||
|
} else {
|
||||||
|
query.Desc("isPinned").DescPk()
|
||||||
|
}
|
||||||
|
|
||||||
_, err = query.
|
_, err = query.
|
||||||
Result(
|
Result(
|
||||||
NodeClusterField_Id,
|
NodeClusterField_Id,
|
||||||
@@ -295,8 +304,6 @@ func (this *NodeClusterDAO) ListEnabledClusters(tx *dbs.Tx, keyword string, offs
|
|||||||
Offset(offset).
|
Offset(offset).
|
||||||
Limit(size).
|
Limit(size).
|
||||||
Slice(&result).
|
Slice(&result).
|
||||||
Desc("isPinned").
|
|
||||||
DescPk().
|
|
||||||
FindAll()
|
FindAll()
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -882,9 +882,28 @@ func (this *NodeDAO) FindNodeStatus(tx *dbs.Tx, nodeId int64) (*nodeconfigs.Node
|
|||||||
return status, nil
|
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 更改节点在线状态
|
// UpdateNodeIsActive 更改节点在线状态
|
||||||
func (this *NodeDAO) UpdateNodeIsActive(tx *dbs.Tx, nodeId int64, isActive bool) error {
|
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 {
|
if !isActive {
|
||||||
b = "false"
|
b = "false"
|
||||||
}
|
}
|
||||||
@@ -898,6 +917,9 @@ func (this *NodeDAO) UpdateNodeIsActive(tx *dbs.Tx, nodeId int64, isActive bool)
|
|||||||
|
|
||||||
// UpdateNodeIsInstalled 设置节点安装状态
|
// UpdateNodeIsInstalled 设置节点安装状态
|
||||||
func (this *NodeDAO) UpdateNodeIsInstalled(tx *dbs.Tx, nodeId int64, isInstalled bool) error {
|
func (this *NodeDAO) UpdateNodeIsInstalled(tx *dbs.Tx, nodeId int64, isInstalled bool) error {
|
||||||
|
if nodeId <= 0 {
|
||||||
|
return errors.New("invalid nodeId")
|
||||||
|
}
|
||||||
_, err := this.Query(tx).
|
_, err := this.Query(tx).
|
||||||
Pk(nodeId).
|
Pk(nodeId).
|
||||||
Set("isInstalled", isInstalled).
|
Set("isInstalled", isInstalled).
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ const (
|
|||||||
NodeTaskTypeWebPPolicyChanged NodeTaskType = "webPPolicyChanged" // WebP策略变化
|
NodeTaskTypeWebPPolicyChanged NodeTaskType = "webPPolicyChanged" // WebP策略变化
|
||||||
NodeTaskTypeUpdatingServers NodeTaskType = "updatingServers" // 更新一组服务
|
NodeTaskTypeUpdatingServers NodeTaskType = "updatingServers" // 更新一组服务
|
||||||
NodeTaskTypeTOAChanged NodeTaskType = "toaChanged" // TOA配置变化
|
NodeTaskTypeTOAChanged NodeTaskType = "toaChanged" // TOA配置变化
|
||||||
|
NodeTaskTypePlanChanged NodeTaskType = "planChanged" // 套餐变化
|
||||||
|
|
||||||
// NS相关
|
// NS相关
|
||||||
|
|
||||||
|
|||||||
@@ -538,6 +538,17 @@ func (this *OriginDAO) CheckUserOrigin(tx *dbs.Tx, userId int64, originId int64)
|
|||||||
return SharedReverseProxyDAO.CheckUserReverseProxy(tx, userId, reverseProxyId)
|
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 通知更新
|
// NotifyUpdate 通知更新
|
||||||
func (this *OriginDAO) NotifyUpdate(tx *dbs.Tx, originId int64) error {
|
func (this *OriginDAO) NotifyUpdate(tx *dbs.Tx, originId int64) error {
|
||||||
reverseProxyId, err := SharedReverseProxyDAO.FindReverseProxyContainsOriginId(tx, originId)
|
reverseProxyId, err := SharedReverseProxyDAO.FindReverseProxyContainsOriginId(tx, originId)
|
||||||
|
|||||||
@@ -49,7 +49,12 @@ func (this *PlanDAO) EnablePlan(tx *dbs.Tx, id uint32) error {
|
|||||||
|
|
||||||
// DisablePlan 禁用条目
|
// DisablePlan 禁用条目
|
||||||
func (this *PlanDAO) DisablePlan(tx *dbs.Tx, id int64) error {
|
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).
|
Pk(id).
|
||||||
Set("state", PlanStateDisabled).
|
Set("state", PlanStateDisabled).
|
||||||
Update()
|
Update()
|
||||||
@@ -57,7 +62,7 @@ func (this *PlanDAO) DisablePlan(tx *dbs.Tx, id int64) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.NotifyUpdate(tx, id)
|
return this.NotifyUpdate(tx, id, clusterId)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindEnabledPlan 查找启用中的条目
|
// FindEnabledPlan 查找启用中的条目
|
||||||
@@ -175,18 +180,18 @@ func (this *PlanDAO) FindEnabledPlanTrafficLimit(tx *dbs.Tx, planId int64, cache
|
|||||||
return config, nil
|
return config, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// NotifyUpdate 通知变更
|
// FindPlanClusterId 查找套餐所属集群
|
||||||
func (this *PlanDAO) NotifyUpdate(tx *dbs.Tx, planId int64) error {
|
func (this *PlanDAO) FindPlanClusterId(tx *dbs.Tx, planId int64) (clusterId int64, err error) {
|
||||||
// 这里不要加入状态参数,因为需要适应删除后的更新
|
return this.Query(tx).
|
||||||
clusterId, err := this.Query(tx).
|
|
||||||
Pk(planId).
|
Pk(planId).
|
||||||
Result("clusterId").
|
Result("clusterId").
|
||||||
FindInt64Col(0)
|
FindInt64Col(0)
|
||||||
if err != nil {
|
}
|
||||||
return err
|
|
||||||
}
|
// NotifyUpdate 通知变更
|
||||||
if clusterId > 0 {
|
func (this *PlanDAO) NotifyUpdate(tx *dbs.Tx, planId int64, clusterId int64) error {
|
||||||
return SharedNodeClusterDAO.NotifyUpdate(tx, clusterId)
|
if clusterId <= 0 {
|
||||||
}
|
return nil
|
||||||
return nil
|
}
|
||||||
|
return SharedNodeClusterDAO.NotifyUpdate(tx, clusterId)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,9 +6,10 @@ const (
|
|||||||
PlanField_Id dbs.FieldName = "id" // ID
|
PlanField_Id dbs.FieldName = "id" // ID
|
||||||
PlanField_IsOn dbs.FieldName = "isOn" // 是否启用
|
PlanField_IsOn dbs.FieldName = "isOn" // 是否启用
|
||||||
PlanField_Name dbs.FieldName = "name" // 套餐名
|
PlanField_Name dbs.FieldName = "name" // 套餐名
|
||||||
PlanField_Description dbs.FieldName = "description" // 描述
|
PlanField_Description dbs.FieldName = "description" // 套餐简介
|
||||||
PlanField_ClusterId dbs.FieldName = "clusterId" // 集群ID
|
PlanField_ClusterId dbs.FieldName = "clusterId" // 集群ID
|
||||||
PlanField_TrafficLimit dbs.FieldName = "trafficLimit" // 流量限制
|
PlanField_TrafficLimit dbs.FieldName = "trafficLimit" // 流量限制
|
||||||
|
PlanField_BandwidthLimitPerNode dbs.FieldName = "bandwidthLimitPerNode" // 单节点带宽限制
|
||||||
PlanField_Features dbs.FieldName = "features" // 允许的功能
|
PlanField_Features dbs.FieldName = "features" // 允许的功能
|
||||||
PlanField_HasFullFeatures dbs.FieldName = "hasFullFeatures" // 是否有完整的功能
|
PlanField_HasFullFeatures dbs.FieldName = "hasFullFeatures" // 是否有完整的功能
|
||||||
PlanField_TrafficPrice dbs.FieldName = "trafficPrice" // 流量价格设定
|
PlanField_TrafficPrice dbs.FieldName = "trafficPrice" // 流量价格设定
|
||||||
@@ -26,6 +27,7 @@ const (
|
|||||||
PlanField_DailyRequests dbs.FieldName = "dailyRequests" // 每日访问量额度
|
PlanField_DailyRequests dbs.FieldName = "dailyRequests" // 每日访问量额度
|
||||||
PlanField_DailyWebsocketConnections dbs.FieldName = "dailyWebsocketConnections" // 每日Websocket连接数
|
PlanField_DailyWebsocketConnections dbs.FieldName = "dailyWebsocketConnections" // 每日Websocket连接数
|
||||||
PlanField_MonthlyWebsocketConnections dbs.FieldName = "monthlyWebsocketConnections" // 每月Websocket连接数
|
PlanField_MonthlyWebsocketConnections dbs.FieldName = "monthlyWebsocketConnections" // 每月Websocket连接数
|
||||||
|
PlanField_MaxUploadSize dbs.FieldName = "maxUploadSize" // 最大上传
|
||||||
)
|
)
|
||||||
|
|
||||||
// Plan 用户套餐
|
// Plan 用户套餐
|
||||||
@@ -33,9 +35,10 @@ type Plan struct {
|
|||||||
Id uint32 `field:"id"` // ID
|
Id uint32 `field:"id"` // ID
|
||||||
IsOn bool `field:"isOn"` // 是否启用
|
IsOn bool `field:"isOn"` // 是否启用
|
||||||
Name string `field:"name"` // 套餐名
|
Name string `field:"name"` // 套餐名
|
||||||
Description string `field:"description"` // 描述
|
Description string `field:"description"` // 套餐简介
|
||||||
ClusterId uint32 `field:"clusterId"` // 集群ID
|
ClusterId uint32 `field:"clusterId"` // 集群ID
|
||||||
TrafficLimit dbs.JSON `field:"trafficLimit"` // 流量限制
|
TrafficLimit dbs.JSON `field:"trafficLimit"` // 流量限制
|
||||||
|
BandwidthLimitPerNode dbs.JSON `field:"bandwidthLimitPerNode"` // 单节点带宽限制
|
||||||
Features dbs.JSON `field:"features"` // 允许的功能
|
Features dbs.JSON `field:"features"` // 允许的功能
|
||||||
HasFullFeatures bool `field:"hasFullFeatures"` // 是否有完整的功能
|
HasFullFeatures bool `field:"hasFullFeatures"` // 是否有完整的功能
|
||||||
TrafficPrice dbs.JSON `field:"trafficPrice"` // 流量价格设定
|
TrafficPrice dbs.JSON `field:"trafficPrice"` // 流量价格设定
|
||||||
@@ -53,15 +56,17 @@ type Plan struct {
|
|||||||
DailyRequests uint64 `field:"dailyRequests"` // 每日访问量额度
|
DailyRequests uint64 `field:"dailyRequests"` // 每日访问量额度
|
||||||
DailyWebsocketConnections uint64 `field:"dailyWebsocketConnections"` // 每日Websocket连接数
|
DailyWebsocketConnections uint64 `field:"dailyWebsocketConnections"` // 每日Websocket连接数
|
||||||
MonthlyWebsocketConnections uint64 `field:"monthlyWebsocketConnections"` // 每月Websocket连接数
|
MonthlyWebsocketConnections uint64 `field:"monthlyWebsocketConnections"` // 每月Websocket连接数
|
||||||
|
MaxUploadSize dbs.JSON `field:"maxUploadSize"` // 最大上传
|
||||||
}
|
}
|
||||||
|
|
||||||
type PlanOperator struct {
|
type PlanOperator struct {
|
||||||
Id any // ID
|
Id any // ID
|
||||||
IsOn any // 是否启用
|
IsOn any // 是否启用
|
||||||
Name any // 套餐名
|
Name any // 套餐名
|
||||||
Description any // 描述
|
Description any // 套餐简介
|
||||||
ClusterId any // 集群ID
|
ClusterId any // 集群ID
|
||||||
TrafficLimit any // 流量限制
|
TrafficLimit any // 流量限制
|
||||||
|
BandwidthLimitPerNode any // 单节点带宽限制
|
||||||
Features any // 允许的功能
|
Features any // 允许的功能
|
||||||
HasFullFeatures any // 是否有完整的功能
|
HasFullFeatures any // 是否有完整的功能
|
||||||
TrafficPrice any // 流量价格设定
|
TrafficPrice any // 流量价格设定
|
||||||
@@ -79,6 +84,7 @@ type PlanOperator struct {
|
|||||||
DailyRequests any // 每日访问量额度
|
DailyRequests any // 每日访问量额度
|
||||||
DailyWebsocketConnections any // 每日Websocket连接数
|
DailyWebsocketConnections any // 每日Websocket连接数
|
||||||
MonthlyWebsocketConnections any // 每月Websocket连接数
|
MonthlyWebsocketConnections any // 每月Websocket连接数
|
||||||
|
MaxUploadSize any // 最大上传
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPlanOperator() *PlanOperator {
|
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
|
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查找国家
|
// FindCountryIdWithDataId 根据数据ID查找国家
|
||||||
func (this *RegionCountryDAO) FindCountryIdWithDataId(tx *dbs.Tx, dataId string) (int64, error) {
|
func (this *RegionCountryDAO) FindCountryIdWithDataId(tx *dbs.Tx, dataId string) (int64, error) {
|
||||||
return this.Query(tx).
|
return this.Query(tx).
|
||||||
|
|||||||
@@ -14,11 +14,12 @@ const (
|
|||||||
RegionCountryField_DataId dbs.FieldName = "dataId" // 原始数据ID
|
RegionCountryField_DataId dbs.FieldName = "dataId" // 原始数据ID
|
||||||
RegionCountryField_Pinyin dbs.FieldName = "pinyin" // 拼音
|
RegionCountryField_Pinyin dbs.FieldName = "pinyin" // 拼音
|
||||||
RegionCountryField_IsCommon dbs.FieldName = "isCommon" // 是否常用
|
RegionCountryField_IsCommon dbs.FieldName = "isCommon" // 是否常用
|
||||||
|
RegionCountryField_RouteCode dbs.FieldName = "routeCode" // 线路代号
|
||||||
)
|
)
|
||||||
|
|
||||||
// RegionCountry 区域-国家/地区
|
// RegionCountry 区域-国家/地区
|
||||||
type RegionCountry struct {
|
type RegionCountry struct {
|
||||||
Id1 uint32 `field:"id"` // ID
|
Id uint32 `field:"id"` // ID
|
||||||
ValueId uint32 `field:"valueId"` // 实际ID
|
ValueId uint32 `field:"valueId"` // 实际ID
|
||||||
ValueCode string `field:"valueCode"` // 值代号
|
ValueCode string `field:"valueCode"` // 值代号
|
||||||
Name string `field:"name"` // 名称
|
Name string `field:"name"` // 名称
|
||||||
@@ -29,6 +30,7 @@ type RegionCountry struct {
|
|||||||
DataId string `field:"dataId"` // 原始数据ID
|
DataId string `field:"dataId"` // 原始数据ID
|
||||||
Pinyin dbs.JSON `field:"pinyin"` // 拼音
|
Pinyin dbs.JSON `field:"pinyin"` // 拼音
|
||||||
IsCommon bool `field:"isCommon"` // 是否常用
|
IsCommon bool `field:"isCommon"` // 是否常用
|
||||||
|
RouteCode string `field:"routeCode"` // 线路代号
|
||||||
}
|
}
|
||||||
|
|
||||||
type RegionCountryOperator struct {
|
type RegionCountryOperator struct {
|
||||||
@@ -43,6 +45,7 @@ type RegionCountryOperator struct {
|
|||||||
DataId any // 原始数据ID
|
DataId any // 原始数据ID
|
||||||
Pinyin any // 拼音
|
Pinyin any // 拼音
|
||||||
IsCommon any // 是否常用
|
IsCommon any // 是否常用
|
||||||
|
RouteCode any // 线路代号
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRegionCountryOperator() *RegionCountryOperator {
|
func NewRegionCountryOperator() *RegionCountryOperator {
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import (
|
|||||||
"github.com/iwind/TeaGo/types"
|
"github.com/iwind/TeaGo/types"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -18,6 +19,8 @@ const (
|
|||||||
RegionProvinceStateDisabled = 0 // 已禁用
|
RegionProvinceStateDisabled = 0 // 已禁用
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var RegionProvinceSuffixes = []string{"省", "州", "区", "大区", "特区", "港", "岛", "环礁", "谷地", "山", "口岸", "郡", "县", "城", "河", "河畔", "市"}
|
||||||
|
|
||||||
type RegionProvinceDAO dbs.DAO
|
type RegionProvinceDAO dbs.DAO
|
||||||
|
|
||||||
func NewRegionProvinceDAO() *RegionProvinceDAO {
|
func NewRegionProvinceDAO() *RegionProvinceDAO {
|
||||||
@@ -77,6 +80,14 @@ func (this *RegionProvinceDAO) FindRegionProvinceName(tx *dbs.Tx, id int64) (str
|
|||||||
FindStringCol("")
|
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查找省份
|
// FindProvinceIdWithDataId 根据数据ID查找省份
|
||||||
func (this *RegionProvinceDAO) FindProvinceIdWithDataId(tx *dbs.Tx, dataId string) (int64, error) {
|
func (this *RegionProvinceDAO) FindProvinceIdWithDataId(tx *dbs.Tx, dataId string) (int64, error) {
|
||||||
return this.Query(tx).
|
return this.Query(tx).
|
||||||
@@ -87,6 +98,37 @@ func (this *RegionProvinceDAO) FindProvinceIdWithDataId(tx *dbs.Tx, dataId strin
|
|||||||
|
|
||||||
// FindProvinceIdWithName 根据省份名查找省份ID
|
// FindProvinceIdWithName 根据省份名查找省份ID
|
||||||
func (this *RegionProvinceDAO) FindProvinceIdWithName(tx *dbs.Tx, countryId int64, provinceName string) (int64, error) {
|
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).
|
return this.Query(tx).
|
||||||
Attr("countryId", countryId).
|
Attr("countryId", countryId).
|
||||||
Where("(name=:provinceName OR customName=:provinceName OR JSON_CONTAINS(codes, :provinceNameJSON) OR JSON_CONTAINS(customCodes, :provinceNameJSON))").
|
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) {
|
func TestRegionProvinceDAO_FindSimilarProvinces(t *testing.T) {
|
||||||
dbs.NotifyReady()
|
dbs.NotifyReady()
|
||||||
|
|
||||||
|
|||||||
@@ -12,11 +12,12 @@ const (
|
|||||||
RegionProvinceField_CustomCodes dbs.FieldName = "customCodes" // 自定义代号
|
RegionProvinceField_CustomCodes dbs.FieldName = "customCodes" // 自定义代号
|
||||||
RegionProvinceField_State dbs.FieldName = "state" // 状态
|
RegionProvinceField_State dbs.FieldName = "state" // 状态
|
||||||
RegionProvinceField_DataId dbs.FieldName = "dataId" // 原始数据ID
|
RegionProvinceField_DataId dbs.FieldName = "dataId" // 原始数据ID
|
||||||
|
RegionProvinceField_RouteCode dbs.FieldName = "routeCode" // 线路代号
|
||||||
)
|
)
|
||||||
|
|
||||||
// RegionProvince 区域-省份
|
// RegionProvince 区域-省份
|
||||||
type RegionProvince struct {
|
type RegionProvince struct {
|
||||||
Id1 uint32 `field:"id"` // ID
|
Id uint32 `field:"id"` // ID
|
||||||
ValueId uint32 `field:"valueId"` // 实际ID
|
ValueId uint32 `field:"valueId"` // 实际ID
|
||||||
CountryId uint32 `field:"countryId"` // 国家ID
|
CountryId uint32 `field:"countryId"` // 国家ID
|
||||||
Name string `field:"name"` // 名称
|
Name string `field:"name"` // 名称
|
||||||
@@ -25,6 +26,7 @@ type RegionProvince struct {
|
|||||||
CustomCodes dbs.JSON `field:"customCodes"` // 自定义代号
|
CustomCodes dbs.JSON `field:"customCodes"` // 自定义代号
|
||||||
State uint8 `field:"state"` // 状态
|
State uint8 `field:"state"` // 状态
|
||||||
DataId string `field:"dataId"` // 原始数据ID
|
DataId string `field:"dataId"` // 原始数据ID
|
||||||
|
RouteCode string `field:"routeCode"` // 线路代号
|
||||||
}
|
}
|
||||||
|
|
||||||
type RegionProvinceOperator struct {
|
type RegionProvinceOperator struct {
|
||||||
@@ -37,6 +39,7 @@ type RegionProvinceOperator struct {
|
|||||||
CustomCodes any // 自定义代号
|
CustomCodes any // 自定义代号
|
||||||
State any // 状态
|
State any // 状态
|
||||||
DataId any // 原始数据ID
|
DataId any // 原始数据ID
|
||||||
|
RouteCode any // 线路代号
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRegionProvinceOperator() *RegionProvinceOperator {
|
func NewRegionProvinceOperator() *RegionProvinceOperator {
|
||||||
|
|||||||
@@ -376,14 +376,14 @@ func (this *ReverseProxyDAO) UpdateReverseProxyScheduling(tx *dbs.Tx, reversePro
|
|||||||
}
|
}
|
||||||
|
|
||||||
// UpdateReverseProxyPrimaryOrigins 修改主要源站
|
// 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 {
|
if reverseProxyId <= 0 {
|
||||||
return errors.New("invalid reverseProxyId")
|
return errors.New("invalid reverseProxyId")
|
||||||
}
|
}
|
||||||
var op = NewReverseProxyOperator()
|
var op = NewReverseProxyOperator()
|
||||||
op.Id = reverseProxyId
|
op.Id = reverseProxyId
|
||||||
if len(origins) > 0 {
|
if len(originRefs) > 0 {
|
||||||
op.PrimaryOrigins = origins
|
op.PrimaryOrigins = originRefs
|
||||||
} else {
|
} else {
|
||||||
op.PrimaryOrigins = "[]"
|
op.PrimaryOrigins = "[]"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1,31 @@
|
|||||||
package models
|
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
|
||||||
|
}
|
||||||
|
|||||||
@@ -757,14 +757,14 @@ func (this *ServerDAO) UpdateServerAuditing(tx *dbs.Tx, serverId int64, result *
|
|||||||
return this.NotifyDNSUpdate(tx, serverId)
|
return this.NotifyDNSUpdate(tx, serverId)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateServerReverseProxy 修改反向代理配置
|
// UpdateServerReverseProxyRef 修改反向代理配置
|
||||||
func (this *ServerDAO) UpdateServerReverseProxy(tx *dbs.Tx, serverId int64, config []byte) error {
|
func (this *ServerDAO) UpdateServerReverseProxyRef(tx *dbs.Tx, serverId int64, reverseProxyRefJSON []byte) error {
|
||||||
if serverId <= 0 {
|
if serverId <= 0 {
|
||||||
return errors.New("serverId should not be smaller than 0")
|
return errors.New("serverId should not be smaller than 0")
|
||||||
}
|
}
|
||||||
var op = NewServerOperator()
|
var op = NewServerOperator()
|
||||||
op.Id = serverId
|
op.Id = serverId
|
||||||
op.ReverseProxy = JSONBytes(config)
|
op.ReverseProxy = JSONBytes(reverseProxyRefJSON)
|
||||||
err := this.Save(tx, op)
|
err := this.Save(tx, op)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -773,6 +773,28 @@ func (this *ServerDAO) UpdateServerReverseProxy(tx *dbs.Tx, serverId int64, conf
|
|||||||
return this.NotifyUpdate(tx, serverId)
|
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 计算所有可用服务数量
|
// CountAllEnabledServers 计算所有可用服务数量
|
||||||
func (this *ServerDAO) CountAllEnabledServers(tx *dbs.Tx) (int64, error) {
|
func (this *ServerDAO) CountAllEnabledServers(tx *dbs.Tx) (int64, error) {
|
||||||
return this.Query(tx).
|
return this.Query(tx).
|
||||||
@@ -1322,28 +1344,10 @@ func (this *ServerDAO) ComposeServerConfig(tx *dbs.Tx, server *Server, ignoreCer
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 套餐是否依然有效
|
// 套餐是否依然有效
|
||||||
plan, err := SharedPlanDAO.FindEnabledPlan(tx, int64(userPlan.PlanId), cacheMap)
|
config.UserPlan = &serverconfigs.UserPlanConfig{
|
||||||
if err != nil {
|
Id: int64(userPlan.Id),
|
||||||
return nil, err
|
DayTo: userPlan.DayTo,
|
||||||
}
|
PlanId: int64(userPlan.PlanId),
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1380,8 +1384,8 @@ func (this *ServerDAO) ComposeServerConfig(tx *dbs.Tx, server *Server, ignoreCer
|
|||||||
return config, nil
|
return config, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindReverseProxyRef 根据条件获取反向代理配置
|
// FindServerReverseProxyRef 根据条件获取反向代理配置
|
||||||
func (this *ServerDAO) FindReverseProxyRef(tx *dbs.Tx, serverId int64) (*serverconfigs.ReverseProxyRef, error) {
|
func (this *ServerDAO) FindServerReverseProxyRef(tx *dbs.Tx, serverId int64) (*serverconfigs.ReverseProxyRef, error) {
|
||||||
reverseProxy, err := this.Query(tx).
|
reverseProxy, err := this.Query(tx).
|
||||||
Pk(serverId).
|
Pk(serverId).
|
||||||
Result("reverseProxy").
|
Result("reverseProxy").
|
||||||
@@ -1392,7 +1396,7 @@ func (this *ServerDAO) FindReverseProxyRef(tx *dbs.Tx, serverId int64) (*serverc
|
|||||||
if len(reverseProxy) == 0 || reverseProxy == "null" {
|
if len(reverseProxy) == 0 || reverseProxy == "null" {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
config := &serverconfigs.ReverseProxyRef{}
|
var config = &serverconfigs.ReverseProxyRef{}
|
||||||
err = json.Unmarshal([]byte(reverseProxy), config)
|
err = json.Unmarshal([]byte(reverseProxy), config)
|
||||||
return config, err
|
return config, err
|
||||||
}
|
}
|
||||||
@@ -2358,8 +2362,36 @@ func (this *ServerDAO) UpdateServerTrafficLimitConfig(tx *dbs.Tx, serverId int64
|
|||||||
|
|
||||||
// RenewServerTrafficLimitStatus 根据限流配置更新网站的流量限制状态
|
// RenewServerTrafficLimitStatus 根据限流配置更新网站的流量限制状态
|
||||||
func (this *ServerDAO) RenewServerTrafficLimitStatus(tx *dbs.Tx, trafficLimitConfig *serverconfigs.TrafficLimitConfig, serverId int64, isUpdatingConfig bool) error {
|
func (this *ServerDAO) RenewServerTrafficLimitStatus(tx *dbs.Tx, trafficLimitConfig *serverconfigs.TrafficLimitConfig, serverId int64, isUpdatingConfig bool) error {
|
||||||
|
if serverId <= 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
if !trafficLimitConfig.IsOn {
|
if !trafficLimitConfig.IsOn {
|
||||||
if isUpdatingConfig {
|
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 this.NotifyUpdate(tx, serverId)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -2470,7 +2502,9 @@ func (this *ServerDAO) UpdateServerTrafficLimitStatus(tx *dbs.Tx, serverId int64
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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
|
// no need to change
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -2986,6 +3020,17 @@ func (this *ServerDAO) CheckServerPlanQuota(tx *dbs.Tx, serverId int64, countSer
|
|||||||
return nil
|
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 同步服务所在的集群
|
// NotifyUpdate 同步服务所在的集群
|
||||||
func (this *ServerDAO) NotifyUpdate(tx *dbs.Tx, serverId int64) error {
|
func (this *ServerDAO) NotifyUpdate(tx *dbs.Tx, serverId int64) error {
|
||||||
if serverId <= 0 {
|
if serverId <= 0 {
|
||||||
|
|||||||
@@ -177,10 +177,10 @@ func (this *SysSettingDAO) ReadUserUIConfig(tx *dbs.Tx) (*systemconfigs.UserUICo
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if len(valueJSON) == 0 {
|
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)
|
err = json.Unmarshal(valueJSON, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"github.com/go-sql-driver/mysql"
|
"github.com/go-sql-driver/mysql"
|
||||||
"github.com/iwind/TeaGo/dbs"
|
"github.com/iwind/TeaGo/dbs"
|
||||||
"github.com/iwind/TeaGo/types"
|
"github.com/iwind/TeaGo/types"
|
||||||
@@ -60,8 +61,8 @@ func CheckSQLErrCode(err error, code uint16) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 快速判断错误方法
|
// 快速判断错误方法
|
||||||
mysqlErr, ok := err.(*mysql.MySQLError)
|
var mysqlErr *mysql.MySQLError
|
||||||
if ok && mysqlErr.Number == code { // Error 1050: Table 'xxx' already exists
|
if errors.As(err, &mysqlErr) && mysqlErr.Number == code { // Error 1050: Table 'xxx' already exists
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,6 +87,6 @@ func IsMySQLError(err error) bool {
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
_, ok := err.(*mysql.MySQLError)
|
var mysqlErr *mysql.MySQLError
|
||||||
return ok
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MaskParams 对参数进行掩码
|
||||||
|
func (this *AliDNSProvider) MaskParams(params maps.Map) {
|
||||||
|
if params == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
params["accessKeySecret"] = MaskString(params.GetString("accessKeySecret"))
|
||||||
|
}
|
||||||
|
|
||||||
// GetDomains 获取所有域名列表
|
// GetDomains 获取所有域名列表
|
||||||
func (this *AliDNSProvider) GetDomains() (domains []string, err error) {
|
func (this *AliDNSProvider) GetDomains() (domains []string, err error) {
|
||||||
var pageNumber = 1
|
var pageNumber = 1
|
||||||
|
|||||||
@@ -66,6 +66,14 @@ func (this *CloudFlareProvider) Auth(params maps.Map) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MaskParams 对参数进行掩码
|
||||||
|
func (this *CloudFlareProvider) MaskParams(params maps.Map) {
|
||||||
|
if params == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
params["apiKey"] = MaskString(params.GetString("apiKey"))
|
||||||
|
}
|
||||||
|
|
||||||
// GetDomains 获取所有域名列表
|
// GetDomains 获取所有域名列表
|
||||||
func (this *CloudFlareProvider) GetDomains() (domains []string, err error) {
|
func (this *CloudFlareProvider) GetDomains() (domains []string, err error) {
|
||||||
for page := 1; page <= 500; page++ {
|
for page := 1; page <= 500; page++ {
|
||||||
|
|||||||
@@ -53,6 +53,11 @@ func (this *CustomHTTPProvider) Auth(params maps.Map) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MaskParams 对参数进行掩码
|
||||||
|
func (this *CustomHTTPProvider) MaskParams(params maps.Map) {
|
||||||
|
// 这里暂时不要掩码,避免用户忘记
|
||||||
|
}
|
||||||
|
|
||||||
// GetDomains 获取所有域名列表
|
// GetDomains 获取所有域名列表
|
||||||
func (this *CustomHTTPProvider) GetDomains() (domains []string, err error) {
|
func (this *CustomHTTPProvider) GetDomains() (domains []string, err error) {
|
||||||
resp, err := this.post(maps.Map{
|
resp, err := this.post(maps.Map{
|
||||||
|
|||||||
@@ -69,6 +69,19 @@ func (this *DNSPodProvider) Auth(params maps.Map) error {
|
|||||||
return nil
|
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 获取所有域名列表
|
// GetDomains 获取所有域名列表
|
||||||
func (this *DNSPodProvider) GetDomains() (domains []string, err error) {
|
func (this *DNSPodProvider) GetDomains() (domains []string, err error) {
|
||||||
if this.tencentDNSProvider != nil {
|
if this.tencentDNSProvider != nil {
|
||||||
|
|||||||
@@ -71,6 +71,14 @@ func (this *EdgeDNSAPIProvider) Auth(params maps.Map) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MaskParams 对参数进行掩码
|
||||||
|
func (this *EdgeDNSAPIProvider) MaskParams(params maps.Map) {
|
||||||
|
if params == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
params["accessKeySecret"] = MaskString(params.GetString("accessKeySecret"))
|
||||||
|
}
|
||||||
|
|
||||||
// GetDomains 获取所有域名列表
|
// GetDomains 获取所有域名列表
|
||||||
func (this *EdgeDNSAPIProvider) GetDomains() (domains []string, err error) {
|
func (this *EdgeDNSAPIProvider) GetDomains() (domains []string, err error) {
|
||||||
var offset = 0
|
var offset = 0
|
||||||
|
|||||||
@@ -71,6 +71,14 @@ func (this *HuaweiDNSProvider) Auth(params maps.Map) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MaskParams 对参数进行掩码
|
||||||
|
func (this *HuaweiDNSProvider) MaskParams(params maps.Map) {
|
||||||
|
if params == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
params["accessKeySecret"] = MaskString(params.GetString("accessKeySecret"))
|
||||||
|
}
|
||||||
|
|
||||||
// GetDomains 获取所有域名列表
|
// GetDomains 获取所有域名列表
|
||||||
func (this *HuaweiDNSProvider) GetDomains() (domains []string, err error) {
|
func (this *HuaweiDNSProvider) GetDomains() (domains []string, err error) {
|
||||||
var resp = new(huaweidns.ZonesResponse)
|
var resp = new(huaweidns.ZonesResponse)
|
||||||
|
|||||||
@@ -10,6 +10,9 @@ type ProviderInterface interface {
|
|||||||
// Auth 认证
|
// Auth 认证
|
||||||
Auth(params maps.Map) error
|
Auth(params maps.Map) error
|
||||||
|
|
||||||
|
// MaskParams 对参数进行掩码
|
||||||
|
MaskParams(params maps.Map)
|
||||||
|
|
||||||
// GetDomains 获取所有域名列表
|
// GetDomains 获取所有域名列表
|
||||||
GetDomains() (domains []string, err error)
|
GetDomains() (domains []string, err error)
|
||||||
|
|
||||||
|
|||||||
@@ -47,6 +47,14 @@ func (this *TencentDNSProvider) Auth(params maps.Map) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MaskParams 对参数进行掩码
|
||||||
|
func (this *TencentDNSProvider) MaskParams(params maps.Map) {
|
||||||
|
if params == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
params["accessKeySecret"] = MaskString(params.GetString("accessKeySecret"))
|
||||||
|
}
|
||||||
|
|
||||||
// GetDomains 获取所有域名列表
|
// GetDomains 获取所有域名列表
|
||||||
func (this *TencentDNSProvider) GetDomains() (domains []string, err error) {
|
func (this *TencentDNSProvider) GetDomains() (domains []string, err error) {
|
||||||
var offset int64 = 0
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -67,6 +67,11 @@ func (this *RestServer) handle(writer http.ResponseWriter, req *http.Request) {
|
|||||||
var matches = servicePathReg.FindStringSubmatch(path)
|
var matches = servicePathReg.FindStringSubmatch(path)
|
||||||
if len(matches) != 3 {
|
if len(matches) != 3 {
|
||||||
writer.WriteHeader(http.StatusNotFound)
|
writer.WriteHeader(http.StatusNotFound)
|
||||||
|
this.writeJSON(writer, maps.Map{
|
||||||
|
"code": "404",
|
||||||
|
"message": "invalid api path '" + path + "'",
|
||||||
|
"data": maps.Map{},
|
||||||
|
}, shouldPretty)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,11 +81,21 @@ func (this *RestServer) handle(writer http.ResponseWriter, req *http.Request) {
|
|||||||
serviceType, ok := restServicesMap[serviceName]
|
serviceType, ok := restServicesMap[serviceName]
|
||||||
if !ok {
|
if !ok {
|
||||||
writer.WriteHeader(http.StatusNotFound)
|
writer.WriteHeader(http.StatusNotFound)
|
||||||
|
this.writeJSON(writer, maps.Map{
|
||||||
|
"code": "404",
|
||||||
|
"message": "service '" + serviceName + "' not found",
|
||||||
|
"data": maps.Map{},
|
||||||
|
}, shouldPretty)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(methodName) == 0 {
|
if len(methodName) == 0 {
|
||||||
writer.WriteHeader(http.StatusNotFound)
|
writer.WriteHeader(http.StatusNotFound)
|
||||||
|
this.writeJSON(writer, maps.Map{
|
||||||
|
"code": "404",
|
||||||
|
"message": "method '" + methodName + "' not found",
|
||||||
|
"data": maps.Map{},
|
||||||
|
}, shouldPretty)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,19 +109,39 @@ func (this *RestServer) handle(writer http.ResponseWriter, req *http.Request) {
|
|||||||
method = serviceType.MethodByName(methodName)
|
method = serviceType.MethodByName(methodName)
|
||||||
if !method.IsValid() {
|
if !method.IsValid() {
|
||||||
writer.WriteHeader(http.StatusNotFound)
|
writer.WriteHeader(http.StatusNotFound)
|
||||||
|
this.writeJSON(writer, maps.Map{
|
||||||
|
"code": "404",
|
||||||
|
"message": "method '" + methodName + "' not found",
|
||||||
|
"data": maps.Map{},
|
||||||
|
}, shouldPretty)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
writer.WriteHeader(http.StatusNotFound)
|
writer.WriteHeader(http.StatusNotFound)
|
||||||
|
this.writeJSON(writer, maps.Map{
|
||||||
|
"code": "404",
|
||||||
|
"message": "method '" + methodName + "' not found",
|
||||||
|
"data": maps.Map{},
|
||||||
|
}, shouldPretty)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if method.Type().NumIn() != 2 || method.Type().NumOut() != 2 {
|
if method.Type().NumIn() != 2 || method.Type().NumOut() != 2 {
|
||||||
writer.WriteHeader(http.StatusNotFound)
|
writer.WriteHeader(http.StatusNotFound)
|
||||||
|
this.writeJSON(writer, maps.Map{
|
||||||
|
"code": "404",
|
||||||
|
"message": "method '" + methodName + "' not found",
|
||||||
|
"data": maps.Map{},
|
||||||
|
}, shouldPretty)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if method.Type().In(0).Name() != "Context" {
|
if method.Type().In(0).Name() != "Context" {
|
||||||
writer.WriteHeader(http.StatusNotFound)
|
writer.WriteHeader(http.StatusNotFound)
|
||||||
|
this.writeJSON(writer, maps.Map{
|
||||||
|
"code": "404",
|
||||||
|
"message": "method '" + methodName + "' not found (or invalid context)",
|
||||||
|
"data": maps.Map{},
|
||||||
|
}, shouldPretty)
|
||||||
return
|
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))
|
body, err := io.ReadAll(io.LimitReader(req.Body, 32*sizes.M))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writer.WriteHeader(http.StatusBadRequest)
|
writer.WriteHeader(http.StatusBadRequest)
|
||||||
_, _ = writer.Write([]byte(err.Error()))
|
this.writeJSON(writer, maps.Map{
|
||||||
|
"code": 400,
|
||||||
|
"message": err.Error(),
|
||||||
|
"data": maps.Map{},
|
||||||
|
}, shouldPretty)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -180,7 +219,11 @@ func (this *RestServer) handle(writer http.ResponseWriter, req *http.Request) {
|
|||||||
err = json.Unmarshal(body, reqValue)
|
err = json.Unmarshal(body, reqValue)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writer.WriteHeader(http.StatusBadRequest)
|
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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -104,6 +104,39 @@ func (this *AdminService) CheckAdminUsername(ctx context.Context, req *pb.CheckA
|
|||||||
return &pb.CheckAdminUsernameResponse{Exists: exists}, nil
|
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 获取管理员名称
|
// FindAdminFullname 获取管理员名称
|
||||||
func (this *AdminService) FindAdminFullname(ctx context.Context, req *pb.FindAdminFullnameRequest) (*pb.FindAdminFullnameResponse, error) {
|
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")
|
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")
|
this.EndTag(ctx, "SharedNodeClusterDAO.ListEnabledClusters")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -2,9 +2,11 @@ package services
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models/dns"
|
"github.com/TeaOSLab/EdgeAPI/internal/db/models/dns"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/dnsclients"
|
"github.com/TeaOSLab/EdgeAPI/internal/dnsclients"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
|
"github.com/iwind/TeaGo/maps"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DNSProviderService DNS服务商相关服务
|
// DNSProviderService DNS服务商相关服务
|
||||||
@@ -42,6 +44,21 @@ func (this *DNSProviderService) UpdateDNSProvider(ctx context.Context, req *pb.U
|
|||||||
|
|
||||||
var tx = this.NullTx()
|
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)
|
err = dns.SharedDNSProviderDAO.UpdateDNSProvider(tx, req.DnsProviderId, req.Name, req.ApiParamsJSON)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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: nil}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return &pb.FindEnabledDNSProviderResponse{DnsProvider: &pb.DNSProvider{
|
if req.MaskParams {
|
||||||
Id: int64(provider.Id),
|
var providerObj = dnsclients.FindProvider(provider.Type, int64(provider.Id))
|
||||||
Name: provider.Name,
|
if providerObj != nil {
|
||||||
Type: provider.Type,
|
var paramsMap = maps.Map{}
|
||||||
TypeName: dnsclients.FindProviderTypeName(provider.Type),
|
if len(provider.ApiParams) > 0 {
|
||||||
ApiParamsJSON: provider.ApiParams,
|
err = json.Unmarshal(provider.ApiParams, ¶msMap)
|
||||||
DataUpdatedAt: int64(provider.DataUpdatedAt),
|
if err != nil {
|
||||||
}}, 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 取得所有服务商类型
|
// FindAllDNSProviderTypes 取得所有服务商类型
|
||||||
|
|||||||
@@ -353,14 +353,28 @@ func (this *HTTPCacheTaskService) FindEnabledHTTPCacheTask(ctx context.Context,
|
|||||||
key.Errors = nil
|
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{
|
pbKeys = append(pbKeys, &pb.HTTPCacheTaskKey{
|
||||||
Id: int64(key.Id),
|
Id: int64(key.Id),
|
||||||
TaskId: int64(key.TaskId),
|
TaskId: int64(key.TaskId),
|
||||||
Key: key.Key,
|
Key: key.Key,
|
||||||
KeyType: key.KeyType,
|
KeyType: key.KeyType,
|
||||||
IsDone: key.IsDone,
|
IsDone: key.IsDone,
|
||||||
IsDoing: !key.IsDone && len(key.DecodeNodes()) > 0,
|
IsDoing: !key.IsDone && len(key.DecodeNodes()) > 0,
|
||||||
ErrorsJSON: key.Errors,
|
ErrorsJSON: key.Errors,
|
||||||
|
NodeCluster: pbNodeCluster,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -305,7 +305,7 @@ func (this *HTTPFirewallPolicyService) UpdateHTTPFirewallPolicy(ctx context.Cont
|
|||||||
req.MaxRequestBodySize = 0
|
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.Mode, req.UseLocalFirewall, synFloodConfig, logConfig, req.MaxRequestBodySize, req.DenyCountryHTML, req.DenyProvinceHTML)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -500,6 +500,7 @@ func (this *HTTPFirewallPolicyService) FindEnabledHTTPFirewallPolicy(ctx context
|
|||||||
Mode: policy.Mode,
|
Mode: policy.Mode,
|
||||||
SynFloodJSON: policy.SynFlood,
|
SynFloodJSON: policy.SynFlood,
|
||||||
BlockOptionsJSON: policy.BlockOptions,
|
BlockOptionsJSON: policy.BlockOptions,
|
||||||
|
PageOptionsJSON: policy.PageOptions,
|
||||||
CaptchaOptionsJSON: policy.CaptchaOptions,
|
CaptchaOptionsJSON: policy.CaptchaOptions,
|
||||||
},
|
},
|
||||||
}, nil
|
}, nil
|
||||||
|
|||||||
@@ -972,18 +972,13 @@ func (this *HTTPWebService) FindHTTPWebReferers(ctx context.Context, req *pb.Fin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
config, err := models.SharedHTTPWebDAO.FindWebReferers(tx, req.HttpWebId)
|
referersJSON, err := models.SharedHTTPWebDAO.FindWebReferers(tx, req.HttpWebId)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
configJSON, err := json.Marshal(config)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &pb.FindHTTPWebReferersResponse{
|
return &pb.FindHTTPWebReferersResponse{
|
||||||
ReferersJSON: configJSON,
|
ReferersJSON: referersJSON,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1040,18 +1035,13 @@ func (this *HTTPWebService) FindHTTPWebUserAgent(ctx context.Context, req *pb.Fi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
config, err := models.SharedHTTPWebDAO.FindWebUserAgent(tx, req.HttpWebId)
|
userAgentJSON, err := models.SharedHTTPWebDAO.FindWebUserAgent(tx, req.HttpWebId)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
configJSON, err := json.Marshal(config)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &pb.FindHTTPWebUserAgentResponse{
|
return &pb.FindHTTPWebUserAgentResponse{
|
||||||
UserAgentJSON: configJSON,
|
UserAgentJSON: userAgentJSON,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,3 +32,13 @@ func (this *HTTPWebService) FindHTTPWebCC(ctx context.Context, req *pb.FindHTTPW
|
|||||||
func (this *HTTPWebService) UpdateHTTPWebRequestScripts(ctx context.Context, req *pb.UpdateHTTPWebRequestScriptsRequest) (*pb.RPCSuccess, error) {
|
func (this *HTTPWebService) UpdateHTTPWebRequestScripts(ctx context.Context, req *pb.UpdateHTTPWebRequestScriptsRequest) (*pb.RPCSuccess, error) {
|
||||||
return nil, this.NotImplementedYet()
|
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()
|
||||||
|
}
|
||||||
|
|||||||
@@ -2293,3 +2293,19 @@ func (this *NodeService) FindNodeWebPPolicies(ctx context.Context, req *pb.FindN
|
|||||||
WebPPolicies: pbPolicies,
|
WebPPolicies: pbPolicies,
|
||||||
}, nil
|
}, 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()
|
||||||
|
}
|
||||||
|
|||||||
@@ -349,12 +349,12 @@ func (this *NodeClusterService) ListEnabledNodeClusters(ctx context.Context, req
|
|||||||
|
|
||||||
var tx = this.NullTx()
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
result := []*pb.NodeCluster{}
|
var result = []*pb.NodeCluster{}
|
||||||
for _, cluster := range clusters {
|
for _, cluster := range clusters {
|
||||||
result = append(result, &pb.NodeCluster{
|
result = append(result, &pb.NodeCluster{
|
||||||
Id: int64(cluster.Id),
|
Id: int64(cluster.Id),
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ import (
|
|||||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
"golang.org/x/crypto/ssh"
|
"golang.org/x/crypto/ssh"
|
||||||
"net"
|
"net"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -48,6 +50,25 @@ func (this *NodeGrantService) UpdateNodeGrant(ctx context.Context, req *pb.Updat
|
|||||||
|
|
||||||
var tx = this.NullTx()
|
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)
|
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()
|
return this.Success()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||||
//go:build !plus
|
//go:build !plus
|
||||||
// +build !plus
|
|
||||||
|
|
||||||
package services
|
package services
|
||||||
|
|
||||||
@@ -34,6 +33,11 @@ func (this *PlanService) FindEnabledPlan(ctx context.Context, req *pb.FindEnable
|
|||||||
return &pb.FindEnabledPlanResponse{Plan: nil}, nil
|
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 计算套餐数量
|
// CountAllEnabledPlans 计算套餐数量
|
||||||
func (this *PlanService) CountAllEnabledPlans(ctx context.Context, req *pb.CountAllEnabledPlansRequest) (*pb.RPCCountResponse, error) {
|
func (this *PlanService) CountAllEnabledPlans(ctx context.Context, req *pb.CountAllEnabledPlansRequest) (*pb.RPCCountResponse, error) {
|
||||||
return this.SuccessCount(0)
|
return this.SuccessCount(0)
|
||||||
@@ -53,3 +57,8 @@ func (this *PlanService) SortPlans(ctx context.Context, req *pb.SortPlansRequest
|
|||||||
func (this *PlanService) FindAllAvailablePlans(ctx context.Context, req *pb.FindAllAvailablePlansRequest) (*pb.FindAllAvailablePlansResponse, error) {
|
func (this *PlanService) FindAllAvailablePlans(ctx context.Context, req *pb.FindAllAvailablePlansRequest) (*pb.FindAllAvailablePlansResponse, error) {
|
||||||
return nil, this.NotImplementedYet()
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var result = []*pb.RegionProvince{}
|
var pbProvinces = []*pb.RegionProvince{}
|
||||||
for _, province := range provinces {
|
for _, province := range provinces {
|
||||||
result = append(result, &pb.RegionProvince{
|
pbProvinces = append(pbProvinces, &pb.RegionProvince{
|
||||||
Id: int64(province.ValueId),
|
Id: int64(province.ValueId),
|
||||||
Name: province.Name,
|
Name: province.Name,
|
||||||
Codes: province.DecodeCodes(),
|
Codes: province.DecodeCodes(),
|
||||||
@@ -101,7 +101,61 @@ func (this *RegionProvinceService) FindAllRegionProvincesWithRegionCountryId(ctx
|
|||||||
}
|
}
|
||||||
|
|
||||||
return &pb.FindAllRegionProvincesWithRegionCountryIdResponse{
|
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
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -695,6 +695,218 @@ func (this *ServerService) CreateBasicTCPServer(ctx context.Context, req *pb.Cre
|
|||||||
return &pb.CreateBasicTCPServerResponse{ServerId: serverId}, nil
|
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 修改服务基本信息
|
// UpdateServerBasic 修改服务基本信息
|
||||||
func (this *ServerService) UpdateServerBasic(ctx context.Context, req *pb.UpdateServerBasicRequest) (*pb.RPCSuccess, error) {
|
func (this *ServerService) UpdateServerBasic(ctx context.Context, req *pb.UpdateServerBasicRequest) (*pb.RPCSuccess, error) {
|
||||||
// 校验请求
|
// 校验请求
|
||||||
@@ -1001,7 +1213,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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -1462,7 +1674,7 @@ func (this *ServerService) ListEnabledServersMatch(ctx context.Context, req *pb.
|
|||||||
return &pb.ListEnabledServersMatchResponse{Servers: result}, nil
|
return &pb.ListEnabledServersMatchResponse{Servers: result}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteServer 禁用某服务
|
// DeleteServer 删除某网站
|
||||||
func (this *ServerService) DeleteServer(ctx context.Context, req *pb.DeleteServerRequest) (*pb.RPCSuccess, error) {
|
func (this *ServerService) DeleteServer(ctx context.Context, req *pb.DeleteServerRequest) (*pb.RPCSuccess, error) {
|
||||||
// 校验请求
|
// 校验请求
|
||||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||||
@@ -1479,7 +1691,7 @@ func (this *ServerService) DeleteServer(ctx context.Context, req *pb.DeleteServe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 禁用服务
|
// 禁用网站
|
||||||
err = models.SharedServerDAO.DisableServer(tx, req.ServerId)
|
err = models.SharedServerDAO.DisableServer(tx, req.ServerId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -1488,6 +1700,37 @@ func (this *ServerService) DeleteServer(ctx context.Context, req *pb.DeleteServe
|
|||||||
return this.Success()
|
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 查找单个服务
|
// FindEnabledServer 查找单个服务
|
||||||
func (this *ServerService) FindEnabledServer(ctx context.Context, req *pb.FindEnabledServerRequest) (*pb.FindEnabledServerResponse, error) {
|
func (this *ServerService) FindEnabledServer(ctx context.Context, req *pb.FindEnabledServerRequest) (*pb.FindEnabledServerResponse, error) {
|
||||||
// 校验请求
|
// 校验请求
|
||||||
@@ -1674,7 +1917,7 @@ func (this *ServerService) FindAndInitServerReverseProxyConfig(ctx context.Conte
|
|||||||
|
|
||||||
var tx = this.NullTx()
|
var tx = this.NullTx()
|
||||||
|
|
||||||
reverseProxyRef, err := models.SharedServerDAO.FindReverseProxyRef(tx, req.ServerId)
|
reverseProxyRef, err := models.SharedServerDAO.FindServerReverseProxyRef(tx, req.ServerId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -1693,7 +1936,7 @@ func (this *ServerService) FindAndInitServerReverseProxyConfig(ctx context.Conte
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
err = models.SharedServerDAO.UpdateServerReverseProxy(tx, req.ServerId, refJSON)
|
err = models.SharedServerDAO.UpdateServerReverseProxyRef(tx, req.ServerId, refJSON)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -56,6 +56,12 @@ func (this *SQLExecutor) Run(showLog bool) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// prevent default configure loading
|
||||||
|
var globalConfig = dbs.GlobalConfig()
|
||||||
|
if globalConfig != nil && len(globalConfig.DBs) == 0 {
|
||||||
|
globalConfig.DBs = map[string]*dbs.DBConfig{"prod": this.dbConfig}
|
||||||
|
}
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
_ = db.Close()
|
_ = db.Close()
|
||||||
}()
|
}()
|
||||||
@@ -91,56 +97,56 @@ func (this *SQLExecutor) checkData(db *dbs.DB) error {
|
|||||||
// 检查管理员平台节点
|
// 检查管理员平台节点
|
||||||
err := this.checkAdminNode(db)
|
err := this.checkAdminNode(db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("check admin node failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查用户平台节点
|
// 检查用户平台节点
|
||||||
err = this.checkUserNode(db)
|
err = this.checkUserNode(db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("check user node failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查集群配置
|
// 检查集群配置
|
||||||
err = this.checkCluster(db)
|
err = this.checkCluster(db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("check cluster failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查初始化用户
|
// 检查初始化用户
|
||||||
// 需要放在检查集群后面
|
// 需要放在检查集群后面
|
||||||
err = this.checkUser(db)
|
err = this.checkUser(db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("check user failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查IP名单
|
// 检查IP名单
|
||||||
err = this.checkIPList(db)
|
err = this.checkIPList(db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("check ip list failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查指标设置
|
// 检查指标设置
|
||||||
err = this.checkMetricItems(db)
|
err = this.checkMetricItems(db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("check metric items failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查自建DNS全局设置
|
// 检查自建DNS全局设置
|
||||||
err = this.checkNS(db)
|
err = this.checkNS(db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("check ns failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新Agents
|
// 更新Agents
|
||||||
err = this.checkClientAgents(db)
|
err = this.checkClientAgents(db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("check client agents failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新版本号
|
// 更新版本号
|
||||||
err = this.updateVersion(db, ComposeSQLVersion())
|
err = this.updateVersion(db, ComposeSQLVersion())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("update version failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -180,13 +186,13 @@ func (this *SQLExecutor) checkAdminNode(db *dbs.DB) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
count := types.Int(col)
|
var count = types.Int(col)
|
||||||
if count > 0 {
|
if count > 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
nodeId := rands.HexString(32)
|
var nodeId = rands.HexString(32)
|
||||||
secret := rands.String(32)
|
var secret = rands.String(32)
|
||||||
_, err = db.Exec("INSERT INTO edgeAPITokens (nodeId, secret, role) VALUES (?, ?, ?)", nodeId, secret, "admin")
|
_, err = db.Exec("INSERT INTO edgeAPITokens (nodeId, secret, role) VALUES (?, ?, ?)", nodeId, secret, "admin")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -208,13 +214,13 @@ func (this *SQLExecutor) checkUserNode(db *dbs.DB) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
count := types.Int(col)
|
var count = types.Int(col)
|
||||||
if count > 0 {
|
if count > 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
nodeId := rands.HexString(32)
|
var nodeId = rands.HexString(32)
|
||||||
secret := rands.String(32)
|
var secret = rands.String(32)
|
||||||
_, err = db.Exec("INSERT INTO edgeAPITokens (nodeId, secret, role) VALUES (?, ?, ?)", nodeId, secret, "user")
|
_, err = db.Exec("INSERT INTO edgeAPITokens (nodeId, secret, role) VALUES (?, ?, ?)", nodeId, secret, "user")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -225,7 +231,7 @@ func (this *SQLExecutor) checkUserNode(db *dbs.DB) error {
|
|||||||
|
|
||||||
// 检查集群配置
|
// 检查集群配置
|
||||||
func (this *SQLExecutor) checkCluster(db *dbs.DB) error {
|
func (this *SQLExecutor) checkCluster(db *dbs.DB) error {
|
||||||
/// 检查是否有集群数字
|
/// 检查是否有集群数据
|
||||||
stmt, err := db.Prepare("SELECT COUNT(*) FROM edgeNodeClusters")
|
stmt, err := db.Prepare("SELECT COUNT(*) FROM edgeNodeClusters")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("query clusters failed: %w", err)
|
return fmt.Errorf("query clusters failed: %w", err)
|
||||||
@@ -238,7 +244,7 @@ func (this *SQLExecutor) checkCluster(db *dbs.DB) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("query clusters failed: %w", err)
|
return fmt.Errorf("query clusters failed: %w", err)
|
||||||
}
|
}
|
||||||
count := types.Int(col)
|
var count = types.Int(col)
|
||||||
if count > 0 {
|
if count > 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -281,6 +287,7 @@ func (this *SQLExecutor) checkCluster(db *dbs.DB) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 默认缓存策略
|
// 默认缓存策略
|
||||||
|
|
||||||
models.SharedHTTPCachePolicyDAO = models.NewHTTPCachePolicyDAO()
|
models.SharedHTTPCachePolicyDAO = models.NewHTTPCachePolicyDAO()
|
||||||
models.SharedHTTPCachePolicyDAO.Instance = db
|
models.SharedHTTPCachePolicyDAO.Instance = db
|
||||||
policyId, err := models.SharedHTTPCachePolicyDAO.CreateDefaultCachePolicy(nil, "默认集群")
|
policyId, err := models.SharedHTTPCachePolicyDAO.CreateDefaultCachePolicy(nil, "默认集群")
|
||||||
@@ -305,6 +312,15 @@ func (this *SQLExecutor) checkCluster(db *dbs.DB) error {
|
|||||||
models.SharedHTTPFirewallRuleDAO = models.NewHTTPFirewallRuleDAO()
|
models.SharedHTTPFirewallRuleDAO = models.NewHTTPFirewallRuleDAO()
|
||||||
models.SharedHTTPFirewallRuleDAO.Instance = db
|
models.SharedHTTPFirewallRuleDAO.Instance = db
|
||||||
|
|
||||||
|
models.SharedHTTPWebDAO = models.NewHTTPWebDAO()
|
||||||
|
models.SharedHTTPWebDAO.Instance = db
|
||||||
|
|
||||||
|
models.SharedServerDAO = models.NewServerDAO()
|
||||||
|
models.SharedServerDAO.Instance = db
|
||||||
|
|
||||||
|
models.SharedNodeClusterDAO = models.NewNodeClusterDAO()
|
||||||
|
models.SharedNodeClusterDAO.Instance = db
|
||||||
|
|
||||||
policyId, err = models.SharedHTTPFirewallPolicyDAO.CreateDefaultFirewallPolicy(nil, "默认集群")
|
policyId, err = models.SharedHTTPFirewallPolicyDAO.CreateDefaultFirewallPolicy(nil, "默认集群")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -331,7 +347,7 @@ func (this *SQLExecutor) checkIPList(db *dbs.DB) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("query ip lists failed: %w", err)
|
return fmt.Errorf("query ip lists failed: %w", err)
|
||||||
}
|
}
|
||||||
count := types.Int(col)
|
var count = types.Int(col)
|
||||||
if count > 0 {
|
if count > 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -388,7 +404,7 @@ func (this *SQLExecutor) checkMetricItems(db *dbs.DB) error {
|
|||||||
|
|
||||||
// chart
|
// chart
|
||||||
for _, chartMap := range chartMaps {
|
for _, chartMap := range chartMaps {
|
||||||
chartCode := chartMap.GetString("code")
|
var chartCode = chartMap.GetString("code")
|
||||||
one, err := db.FindOne("SELECT id FROM edgeMetricCharts WHERE itemId=? AND code=? LIMIT 1", itemId, chartCode)
|
one, err := db.FindOne("SELECT id FROM edgeMetricCharts WHERE itemId=? AND code=? LIMIT 1", itemId, chartCode)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -528,7 +544,7 @@ func (this *SQLExecutor) updateVersion(db *dbs.DB, version string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("query version failed: %w", err)
|
return fmt.Errorf("query version failed: %w", err)
|
||||||
}
|
}
|
||||||
count := types.Int(col)
|
var count = types.Int(col)
|
||||||
if count > 0 {
|
if count > 0 {
|
||||||
_, err = db.Exec("UPDATE edgeVersions SET version=?", version)
|
_, err = db.Exec("UPDATE edgeVersions SET version=?", version)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -106,6 +106,9 @@ var upgradeFuncs = []*upgradeVersion{
|
|||||||
{
|
{
|
||||||
"1.3.2", upgradeV1_3_2,
|
"1.3.2", upgradeV1_3_2,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"1.3.4", upgradeV1_3_4,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpgradeSQLData 升级SQL数据
|
// UpgradeSQLData 升级SQL数据
|
||||||
@@ -1230,3 +1233,13 @@ func upgradeV1_3_2(db *dbs.DB) error {
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 1.3.4
|
||||||
|
func upgradeV1_3_4(db *dbs.DB) error {
|
||||||
|
_, err := db.Exec("DELETE FROM edgeLoginSessions WHERE adminId>0")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -27,3 +27,26 @@ func TestUpgradeSQLData_v0_5_6(t *testing.T) {
|
|||||||
}
|
}
|
||||||
t.Log("ok")
|
t.Log("ok")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func TestUpgradeSQLData_v1_3_4(t *testing.T) {
|
||||||
|
db, err := dbs.NewInstanceFromConfig(&dbs.DBConfig{
|
||||||
|
Driver: "mysql",
|
||||||
|
Dsn: "root:123456@tcp(127.0.0.1:3306)/db_edge?charset=utf8mb4&timeout=30s",
|
||||||
|
Prefix: "edge",
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
_ = db.Close()
|
||||||
|
}()
|
||||||
|
|
||||||
|
err = upgradeV1_3_4(db)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
t.Log("ok")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -113,6 +113,12 @@ func (this *ServiceManager) installSystemdService(systemd, exePath string, args
|
|||||||
shortName := teaconst.SystemdServiceName
|
shortName := teaconst.SystemdServiceName
|
||||||
longName := "GoEdge API" // TODO 将来可以修改
|
longName := "GoEdge API" // TODO 将来可以修改
|
||||||
|
|
||||||
|
var startCmd = exePath + " daemon"
|
||||||
|
bashPath, _ := executils.LookPath("bash")
|
||||||
|
if len(bashPath) > 0 {
|
||||||
|
startCmd = bashPath + " -c \"" + startCmd + "\""
|
||||||
|
}
|
||||||
|
|
||||||
desc := `### BEGIN INIT INFO
|
desc := `### BEGIN INIT INFO
|
||||||
# Provides: ` + shortName + `
|
# Provides: ` + shortName + `
|
||||||
# Required-Start: $all
|
# Required-Start: $all
|
||||||
@@ -131,7 +137,7 @@ After=network-online.target
|
|||||||
Type=simple
|
Type=simple
|
||||||
Restart=always
|
Restart=always
|
||||||
RestartSec=1s
|
RestartSec=1s
|
||||||
ExecStart=` + exePath + ` daemon
|
ExecStart=` + startCmd + `
|
||||||
ExecStop=` + exePath + ` stop
|
ExecStop=` + exePath + ` stop
|
||||||
ExecReload=` + exePath + ` reload
|
ExecReload=` + exePath + ` reload
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user